From f7693131699eef1617a4eea239eb10d3d97b0008 Mon Sep 17 00:00:00 2001 From: samsonium Date: Thu, 29 Oct 2026 22:13:28 +0300 Subject: [PATCH] feat: implement extern block reading and parsing --- CMakeLists.txt | 5 + exl/linking.fzs | 2 +- include/compiler/fzl_parser.h | 56 +++++++- include/compiler/internals/parser.h | 6 + src/compiler/fzl_parser.c | 29 +++++ src/compiler/main.c | 2 +- src/compiler/parser/pa_extern.c | 192 ++++++++++++++++++++++++++++ src/compiler/parser/pa_externfn.c | 154 ++++++++++++++++++++++ src/compiler/parser/pa_ref.c | 38 ++++++ src/compiler/parser/pa_statement.c | 3 + src/compiler/parser/pa_struct.c | 133 +++++++++++++++++++ src/compiler/parser/pa_typedef.c | 81 ++++++++++++ src/compiler/reader/rd_name.c | 21 +++ 13 files changed, 719 insertions(+), 3 deletions(-) create mode 100644 src/compiler/parser/pa_extern.c create mode 100644 src/compiler/parser/pa_externfn.c create mode 100644 src/compiler/parser/pa_ref.c create mode 100644 src/compiler/parser/pa_struct.c create mode 100644 src/compiler/parser/pa_typedef.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e40d174..d20174c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,8 @@ if (NOT FZL_SKIP_C) src/compiler/parser/pa_class.c src/compiler/parser/pa_cond.c src/compiler/parser/pa_expression.c + src/compiler/parser/pa_extern.c + src/compiler/parser/pa_externfn.c src/compiler/parser/pa_factor.c src/compiler/parser/pa_for.c src/compiler/parser/pa_function.c @@ -76,9 +78,12 @@ if (NOT FZL_SKIP_C) src/compiler/parser/pa_power.c src/compiler/parser/pa_primary.c src/compiler/parser/pa_program.c + src/compiler/parser/pa_ref.c src/compiler/parser/pa_return.c src/compiler/parser/pa_statement.c + src/compiler/parser/pa_struct.c src/compiler/parser/pa_term.c + src/compiler/parser/pa_typedef.c src/compiler/parser/pa_unary.c src/compiler/parser/pa_while.c src/compiler/parser/utility.c diff --git a/exl/linking.fzs b/exl/linking.fzs index 513aee3..c2fb8d3 100644 --- a/exl/linking.fzs +++ b/exl/linking.fzs @@ -12,7 +12,7 @@ extern "libglfw" { int greenBits; int blueBits; int refreshRate; - } + }; /// GLFWvidmode* type GLFWvidmodeRef ref GLFWvidmode; diff --git a/include/compiler/fzl_parser.h b/include/compiler/fzl_parser.h index d61ba9e..c91dde9 100644 --- a/include/compiler/fzl_parser.h +++ b/include/compiler/fzl_parser.h @@ -8,17 +8,31 @@ // AST node type typedef enum { + FZL_NODETYPE_TYPEDEF, + FZL_NODETYPE_HANDLE, + FZL_NODETYPE_ALIAS, + FZL_NODETYPE_STRUCT, + FZL_NODETYPE_REFERENCE, + FZL_NODETYPE_EXTERN_FN, + + FZL_NODETYPE_EXTERN, FZL_NODETYPE_BLOCK, - FZL_NODETYPE_CALL, + FZL_NODETYPE_LITERAL, FZL_NODETYPE_FMT_STRING, + FZL_NODETYPE_IDENTIFIER, + FZL_NODETYPE_CONDITIONAL, + FZL_NODETYPE_FUNCTION, FZL_NODETYPE_RETURN, + FZL_NODETYPE_CALL, + FZL_NODETYPE_CLASS, FZL_NODETYPE_FIELD, FZL_NODETYPE_CONSTRUCT, + FZL_NODETYPE_LOOP, FZL_NODETYPE_BREAK, @@ -153,6 +167,46 @@ typedef struct fzl_node struct fzl_node *body; } loop; + + // Extern library + struct + { + char *libname; + + struct fzl_node **typedefs; + size_t typedefs_count; + + struct fzl_node **fns; + size_t fns_count; + } ext; + + // Type definition + struct + { + char *typename; + struct fzl_node *type; + } typedefinition; + + // Structure + struct + { + char *original_name; + + struct fzl_node **entries; + size_t entries_count; + } structure; + + // External function + struct + { + char *name; + char *original_name; + + fzl_token_t *type; + + struct fzl_node **args; + size_t args_count; + } ext_fn; }; } fzl_node_t; diff --git a/include/compiler/internals/parser.h b/include/compiler/internals/parser.h index 58ea577..d68d9c3 100644 --- a/include/compiler/internals/parser.h +++ b/include/compiler/internals/parser.h @@ -29,6 +29,11 @@ fzl_node_t *pa_new(fzl_parser_t *parser); fzl_node_t *pa_assignment(fzl_parser_t *parser); fzl_node_t *pa_expression(fzl_parser_t *parser); +fzl_node_t *pa_struct(fzl_parser_t *parser); +fzl_node_t *pa_ref(fzl_parser_t *parser); +fzl_node_t *pa_typedef(fzl_parser_t *parser); +fzl_node_t *pa_externfn(fzl_parser_t *parser); + fzl_node_t *pa_class(fzl_parser_t *parser); fzl_node_t *pa_function(fzl_parser_t *parser); fzl_node_t *pa_return(fzl_parser_t *parser); @@ -38,6 +43,7 @@ fzl_node_t *pa_for(fzl_parser_t *parser); fzl_node_t *pa_while(fzl_parser_t *parser); fzl_node_t *pa_loop(fzl_parser_t *parser); fzl_node_t *pa_break(fzl_parser_t *parser); +fzl_node_t *pa_extern(fzl_parser_t *parser); fzl_node_t *pa_statement(fzl_parser_t *parser); fzl_node_t *pa_program(fzl_parser_t *parser); diff --git a/src/compiler/fzl_parser.c b/src/compiler/fzl_parser.c index cb6e54b..411e948 100644 --- a/src/compiler/fzl_parser.c +++ b/src/compiler/fzl_parser.c @@ -94,11 +94,40 @@ void fzl_freeast(fzl_node_t *root) { switch (root->type) { + case FZL_NODETYPE_REFERENCE: + case FZL_NODETYPE_ALIAS: + case FZL_NODETYPE_HANDLE: case FZL_NODETYPE_BREAK: case FZL_NODETYPE_IDENTIFIER: case FZL_NODETYPE_LITERAL: break; + case FZL_NODETYPE_EXTERN: + for (size_t i = 0; i < root->ext.typedefs_count; i++) + fzl_freeast(root->ext.typedefs[i]); + free(root->ext.typedefs); + + for (size_t i = 0; i < root->ext.fns_count; i++) + fzl_freeast(root->ext.fns[i]); + free(root->ext.fns); + break; + + case FZL_NODETYPE_EXTERN_FN: + for (size_t i = 0; i < root->ext_fn.args_count; i++) + fzl_freeast(root->ext_fn.args[i]); + free(root->ext_fn.args); + break; + + case FZL_NODETYPE_STRUCT: + for (size_t i = 0; i < root->structure.entries_count; i++) + fzl_freeast(root->structure.entries[i]); + free(root->structure.entries); + break; + + case FZL_NODETYPE_TYPEDEF: + fzl_freeast(root->typedefinition.type); + break; + case FZL_NODETYPE_FMT_STRING: case FZL_NODETYPE_BLOCK: if (root->list.entries) diff --git a/src/compiler/main.c b/src/compiler/main.c index 8abd8b8..5c7e64c 100644 --- a/src/compiler/main.c +++ b/src/compiler/main.c @@ -200,7 +200,7 @@ int main(int argc, char **argv) { if (i > 0 && i < walker->op_count) printf("->"); - printf("%lu", walker->ops[i]); + printf("%lX", walker->ops[i]); } printf("\n"); diff --git a/src/compiler/parser/pa_extern.c b/src/compiler/parser/pa_extern.c new file mode 100644 index 0000000..56ca589 --- /dev/null +++ b/src/compiler/parser/pa_extern.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include +#include +#include + +// Parse extern definition +fzl_node_t *pa_extern(fzl_parser_t *parser) +{ + if (!parser || !peek(parser)) + return NULL; + + fzl_token_t *kw = consume(parser); + if (!kw || kw->type != FZL_TOKTYPE_EXTERN) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected 'extern' keyword", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_token_t *libname = consume(parser); + if (!libname || libname->type != FZL_TOKTYPE_STR_LITERAL) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected library name after 'extern'", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_token_t *lbra = consume(parser); + if (!lbra || lbra->type != FZL_TOKTYPE_LBRACE) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected '{' after library name", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + // Typedefs array + size_t td_remainder = 2; + size_t td_count = 0; + fzl_node_t **td = malloc(td_remainder * sizeof(fzl_node_t *)); + if (!td) + { + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + + // Functions array + size_t fn_remainder = 2; + size_t fn_count = 0; + fzl_node_t **fn = malloc(fn_remainder * sizeof(fzl_node_t *)); + if (!fn) + { + free(td); + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + + bool error = false; + while (peek(parser)) + { + if (is(parser, FZL_TOKTYPE_RBRACE)) + break; + + if (td_remainder <= td_count) + { + td_remainder *= 2; + fzl_node_t **newarr = realloc(td, td_remainder * sizeof(fzl_node_t *)); + if (!newarr) + { + snprintf(plast_err, sizeof(plast_err), "out of memory"); + error = true; + break; + } + + td = newarr; + } + + if (fn_remainder <= fn_count) + { + fn_remainder *= 2; + fzl_node_t **newarr = realloc(fn, fn_remainder * sizeof(fzl_node_t *)); + if (!newarr) + { + snprintf(plast_err, sizeof(plast_err), "out of memory"); + error = true; + break; + } + + fn = newarr; + } + + if (is(parser, FZL_TOKTYPE_TYPEDEF)) + { + fzl_node_t *result = pa_typedef(parser); + if (!result) + { + error = true; + break; + } + + td[td_count++] = result; + } + else if (is(parser, FZL_TOKTYPE_FUNCTION)) + { + fzl_node_t *result = pa_externfn(parser); + if (!result) + { + error = true; + break; + } + + fn[fn_count++] = result; + } + else + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => unexpected statement inside extern block", + last_known_tok->filename, last_known_tok->ln, + last_known_tok->cn); + error = true; + break; + } + + fzl_token_t *sc = consume(parser); + if (!sc || sc->type != FZL_TOKTYPE_SEMICOLON) + { + snprintf(plast_err, sizeof(plast_err), "'%s':%zu:%zu => missing ';'", + last_known_tok->filename, last_known_tok->ln, + last_known_tok->cn); + error = true; + break; + } + } + + if (error) + { + for (size_t i = 0; i < td_count; i++) + fzl_freeast(td[i]); + free(td); + + for (size_t i = 0; i < fn_count; i++) + fzl_freeast(fn[i]); + free(fn); + + return NULL; + } + + fzl_token_t *rbra = consume(parser); + if (!rbra || rbra->type != FZL_TOKTYPE_RBRACE) + { + for (size_t i = 0; i < td_count; i++) + fzl_freeast(td[i]); + free(td); + + for (size_t i = 0; i < fn_count; i++) + fzl_freeast(fn[i]); + free(fn); + + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected '}' after extern block", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_node_t *node = fzl_mknode(FZL_NODETYPE_EXTERN, kw); + if (!node) + { + for (size_t i = 0; i < td_count; i++) + fzl_freeast(td[i]); + free(td); + + for (size_t i = 0; i < fn_count; i++) + fzl_freeast(fn[i]); + free(fn); + + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + + node->ext.libname = (char *)libname->value; + node->ext.typedefs = td; + node->ext.typedefs_count = td_count; + node->ext.fns = fn; + node->ext.fns_count = fn_count; + + return node; +} diff --git a/src/compiler/parser/pa_externfn.c b/src/compiler/parser/pa_externfn.c new file mode 100644 index 0000000..66f6738 --- /dev/null +++ b/src/compiler/parser/pa_externfn.c @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include + +// Parse external function +fzl_node_t *pa_externfn(fzl_parser_t *parser) +{ + if (!parser || !peek(parser)) + return NULL; + + fzl_token_t *tok = consume(parser); + if (!tok || tok->type != FZL_TOKTYPE_FUNCTION) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected 'function' keyword", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_token_t *name = consume(parser); + if (!name || name->type != FZL_TOKTYPE_NAME) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected function name after 'fn'", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_token_t *lpar = consume(parser); + if (!lpar || lpar->type != FZL_TOKTYPE_LPAREN) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected '(' after function name", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + size_t remainder = 2; + size_t count = 0; + fzl_node_t **args = malloc(remainder * sizeof(fzl_node_t *)); + if (!args) + { + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + + while (peek(parser) && !is(parser, FZL_TOKTYPE_RPAREN)) + { + if (remainder <= count) + { + remainder *= 2; + fzl_node_t **newarr = realloc(args, remainder * sizeof(fzl_node_t *)); + if (!newarr) + { + for (size_t i = 0; i < count; i++) + fzl_freeast(args[i]); + free(args); + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + args = newarr; + } + + bool is_out = false; + if (is(parser, FZL_TOKTYPE_OUT)) + { + consume(parser); + is_out = true; + } + (void)is_out; + + fzl_node_t *node = pa_expression(parser); + if (!node || node->type != FZL_NODETYPE_DECLARATION) + { + for (size_t i = 0; i < count; i++) + fzl_freeast(args[i]); + free(args); + + if (!plast_err[0]) + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected declaration", + last_known_tok->filename, last_known_tok->ln, + last_known_tok->cn); + return NULL; + } + + args[count++] = node; + + if (is(parser, FZL_TOKTYPE_RPAREN)) + break; + + fzl_token_t *comma = consume(parser); + if (!comma || comma->type != FZL_TOKTYPE_COMMA) + { + for (size_t i = 0; i < count; i++) + fzl_freeast(args[i]); + free(args); + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => missing ',' between arguments", + last_known_tok->filename, last_known_tok->ln, + last_known_tok->cn); + return NULL; + } + } + + fzl_token_t *rpar = consume(parser); + if (!rpar || rpar->type != FZL_TOKTYPE_RPAREN) + { + for (size_t i = 0; i < count; i++) + fzl_freeast(args[i]); + free(args); + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected ')' after arguments list", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + char *original_name = NULL; + fzl_token_t *type = &null_tok; + if (is(parser, FZL_TOKTYPE_NAME) || is(parser, FZL_TOKTYPE_TYPE)) + type = consume(parser); + + if (is(parser, FZL_TOKTYPE_EQ)) + { + consume(parser); + fzl_token_t *orig = consume(parser); + + if (!orig || orig->type != FZL_TOKTYPE_STR_LITERAL) + { + for (size_t i = 0; i < count; i++) + fzl_freeast(args[i]); + free(args); + + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected original function name", + last_known_tok->filename, last_known_tok->ln, + last_known_tok->cn); + return NULL; + } + + original_name = (char *)orig->value; + } + + fzl_node_t *node = fzl_mknode(FZL_NODETYPE_EXTERN_FN, tok); + node->ext_fn.name = (char *)name->value; + node->ext_fn.original_name = original_name; + node->ext_fn.args_count = count; + node->ext_fn.args = args; + node->ext_fn.type = type; + + return node; +} diff --git a/src/compiler/parser/pa_ref.c b/src/compiler/parser/pa_ref.c new file mode 100644 index 0000000..193eea5 --- /dev/null +++ b/src/compiler/parser/pa_ref.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +// Parse reference definition +fzl_node_t *pa_ref(fzl_parser_t *parser) +{ + if (!parser || !peek(parser)) + return NULL; + + fzl_token_t *tok = consume(parser); + if (!tok || tok->type != FZL_TOKTYPE_REFERENCE) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected 'ref' keyword", last_known_tok->filename, + last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_token_t *name = consume(parser); + if (!name || name->type != FZL_TOKTYPE_NAME) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected name after 'ref'", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_node_t *node = fzl_mknode(FZL_NODETYPE_REFERENCE, name); + if (!node) + { + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + + return node; +} diff --git a/src/compiler/parser/pa_statement.c b/src/compiler/parser/pa_statement.c index e9915a6..8014ca8 100644 --- a/src/compiler/parser/pa_statement.c +++ b/src/compiler/parser/pa_statement.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -24,6 +25,8 @@ fzl_node_t *pa_statement(fzl_parser_t *parser) return pa_loop(parser); else if (is(parser, FZL_TOKTYPE_BREAK)) res = pa_break(parser); + else if (is(parser, FZL_TOKTYPE_EXTERN)) + return pa_extern(parser); if (!res) res = pa_expression(parser); diff --git a/src/compiler/parser/pa_struct.c b/src/compiler/parser/pa_struct.c new file mode 100644 index 0000000..5d121a6 --- /dev/null +++ b/src/compiler/parser/pa_struct.c @@ -0,0 +1,133 @@ +#include +#include +#include +#include +#include +#include + +// Parse structure +fzl_node_t *pa_struct(fzl_parser_t *parser) +{ + if (!parser || !peek(parser)) + return NULL; + + fzl_token_t *tok = consume(parser); + if (!tok || tok->type != FZL_TOKTYPE_STRUCT) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected 'struct' keyword", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + char *original = NULL; + if (is(parser, FZL_TOKTYPE_NAME)) + { + fzl_token_t *name = consume(parser); + if (!name || name->type != FZL_TOKTYPE_NAME) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected struct name after 'struct'", + last_known_tok->filename, last_known_tok->ln, + last_known_tok->cn); + return NULL; + } + + original = (char *)name->value; + } + + fzl_token_t *lbra = consume(parser); + if (!lbra || lbra->type != FZL_TOKTYPE_LBRACE) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected '{' after structure name", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + size_t remainder = 2; + size_t count = 0; + fzl_node_t **entries = malloc(remainder * sizeof(fzl_node_t *)); + if (!entries) + { + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + + while (peek(parser)) + { + if (is(parser, FZL_TOKTYPE_RBRACE)) + break; + + if (remainder <= count) + { + remainder *= 2; + fzl_node_t **newarr = realloc(entries, remainder * sizeof(fzl_node_t *)); + if (!newarr) + { + free(entries); + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + entries = newarr; + } + + fzl_node_t *entry = pa_statement(parser); + if (!entry) + { + for (size_t i = 0; i < count; i++) + fzl_freeast(entries[i]); + free(entries); + return NULL; + } + + if (entry->type != FZL_NODETYPE_DECLARATION && + entry->type != FZL_NODETYPE_IDENTIFIER) + { + fzl_freeast(entry); + + for (size_t i = 0; i < count; i++) + fzl_freeast(entries[i]); + free(entries); + + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => structure entry must be a declaration or " + "another structure name", + last_known_tok->filename, last_known_tok->ln, + last_known_tok->cn); + return NULL; + } + + entries[count++] = entry; + } + + fzl_token_t *rbra = consume(parser); + if (!rbra || rbra->type != FZL_TOKTYPE_RBRACE) + { + for (size_t i = 0; i < count; i++) + fzl_freeast(entries[i]); + free(entries); + + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected '}' after structure fields", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_node_t *node = fzl_mknode(FZL_NODETYPE_STRUCT, tok); + if (!node) + { + for (size_t i = 0; i < count; i++) + fzl_freeast(entries[i]); + free(entries); + + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + + node->structure.original_name = original; + node->structure.entries = entries; + node->structure.entries_count = count; + + return node; +} diff --git a/src/compiler/parser/pa_typedef.c b/src/compiler/parser/pa_typedef.c new file mode 100644 index 0000000..56811eb --- /dev/null +++ b/src/compiler/parser/pa_typedef.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + +// Parse type definition +fzl_node_t *pa_typedef(fzl_parser_t *parser) +{ + if (!parser || !peek(parser)) + return NULL; + + fzl_token_t *tok = consume(parser); + if (!tok || tok->type != FZL_TOKTYPE_TYPEDEF) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected 'type' keyword", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_token_t *name = consume(parser); + if (!name || name->type != FZL_TOKTYPE_NAME) + { + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => expected type name after 'type'", + last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); + return NULL; + } + + fzl_node_t *result = NULL; + + if (is(parser, FZL_TOKTYPE_HANDLE)) + { + result = fzl_mknode(FZL_NODETYPE_HANDLE, consume(parser)); + if (!result) + { + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + } + else if (is(parser, FZL_TOKTYPE_STRUCT)) + { + result = pa_struct(parser); + } + else if (is(parser, FZL_TOKTYPE_TYPE)) + { + result = fzl_mknode(FZL_NODETYPE_ALIAS, consume(parser)); + if (!result) + { + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + } + else if (is(parser, FZL_TOKTYPE_REFERENCE)) + { + result = pa_ref(parser); + } + + if (!result) + { + if (!plast_err[0]) + snprintf(plast_err, sizeof(plast_err), + "'%s':%zu:%zu => unsupported typedef type", + last_known_tok->filename, last_known_tok->ln, + last_known_tok->cn); + return NULL; + } + + fzl_node_t *node = fzl_mknode(FZL_NODETYPE_TYPEDEF, tok); + if (!node) + { + fzl_freeast(result); + snprintf(plast_err, sizeof(plast_err), "out of memory"); + return NULL; + } + + node->typedefinition.typename = (char *)name->value; + node->typedefinition.type = result; + + return node; +} diff --git a/src/compiler/reader/rd_name.c b/src/compiler/reader/rd_name.c index 5858e12..c271886 100644 --- a/src/compiler/reader/rd_name.c +++ b/src/compiler/reader/rd_name.c @@ -1,3 +1,4 @@ +#include "compiler/fzl_token.h" #include #include #include @@ -38,6 +39,26 @@ fzl_token_t *rd_name(fzl_reader_t *reader) if (strcmp(value, "class") == 0) tok = fzl_mktoken(FZL_TOKTYPE_CLASS, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "import") == 0) + tok = + fzl_mktoken(FZL_TOKTYPE_IMPORT, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "extern") == 0) + tok = + fzl_mktoken(FZL_TOKTYPE_EXTERN, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "type") == 0) + tok = fzl_mktoken(FZL_TOKTYPE_TYPEDEF, l.line, l.col, value, size, + l.filename); + else if (strcmp(value, "handle") == 0) + tok = + fzl_mktoken(FZL_TOKTYPE_HANDLE, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "struct") == 0) + tok = + fzl_mktoken(FZL_TOKTYPE_STRUCT, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "ref") == 0) + tok = fzl_mktoken(FZL_TOKTYPE_REFERENCE, l.line, l.col, value, size, + l.filename); + else if (strcmp(value, "out") == 0) + tok = fzl_mktoken(FZL_TOKTYPE_OUT, l.line, l.col, value, size, l.filename); else if (strcmp(value, "for") == 0) tok = fzl_mktoken(FZL_TOKTYPE_FOR, l.line, l.col, value, size, l.filename); else if (strcmp(value, "while") == 0)