From e56b2a88ec1f85ecdb731b7873e3c470833445ef Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Sun, 6 Nov 2022 23:20:09 -0500 Subject: [PATCH 1/9] Remove extraneous newline from error message --- src/driver/compiler-backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/driver/compiler-backend.c b/src/driver/compiler-backend.c index 0948e35..7475643 100644 --- a/src/driver/compiler-backend.c +++ b/src/driver/compiler-backend.c @@ -289,7 +289,7 @@ int yf_ensure_entry_point( } if (total_entries != 1) - YF_PRINT_ERROR("total 'main' functions found: %d\n", total_entries); + YF_PRINT_ERROR("total 'main' functions found: %d", total_entries); return total_entries != 1; From f7aa4a1266f620db97def8226fb7d79e9d890090 Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Mon, 7 Nov 2022 00:49:33 -0500 Subject: [PATCH 2/9] Make funcdecl dump also say name --- src/api/cst-dump.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/cst-dump.c b/src/api/cst-dump.c index 0c96f2b..b1b77cc 100644 --- a/src/api/cst-dump.c +++ b/src/api/cst-dump.c @@ -121,6 +121,7 @@ static void yf_dump_vardecl(struct yfcs_vardecl * node, FILE * out) { static void yf_dump_funcdecl(struct yfcs_funcdecl * node, FILE * out) { yf_print_line(out, "funcdecl"); indent(); + yf_print_line(out, "name: %s", node->name); yf_print_line(out, "params"); indent(); struct yf_parse_node * param; From 48bab48e7ff5fdb3abb5664ea3d7b4354b1342cc Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Mon, 7 Nov 2022 00:50:26 -0500 Subject: [PATCH 3/9] Dump correct member --- src/api/cst-dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/cst-dump.c b/src/api/cst-dump.c index b1b77cc..cdcdc6e 100644 --- a/src/api/cst-dump.c +++ b/src/api/cst-dump.c @@ -121,7 +121,7 @@ static void yf_dump_vardecl(struct yfcs_vardecl * node, FILE * out) { static void yf_dump_funcdecl(struct yfcs_funcdecl * node, FILE * out) { yf_print_line(out, "funcdecl"); indent(); - yf_print_line(out, "name: %s", node->name); + yf_print_line(out, "name: %s", node->name.name); yf_print_line(out, "params"); indent(); struct yf_parse_node * param; From 93609bdef60d5f6708ab5e01edac5f9449d0be34 Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Tue, 8 Nov 2022 10:30:54 -0500 Subject: [PATCH 4/9] Move type creation to symtab --- src/semantics/symtab.c | 10 ++++++++ src/semantics/types.c | 40 +++++++++++++++++++++++++++++ src/semantics/types.h | 7 ++++++ src/semantics/validate/validate.c | 42 ------------------------------- 4 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/semantics/symtab.c b/src/semantics/symtab.c index 9571b2a..964c63f 100644 --- a/src/semantics/symtab.c +++ b/src/semantics/symtab.c @@ -1,6 +1,9 @@ #include "symtab.h" +#include + #include +#include #include #include @@ -18,6 +21,9 @@ int yfs_build_symtab(struct yf_compile_analyse_job * data) { YF_PRINT_ERROR("symtab: failed to allocate table"); return 3; /* Memory error */ } + + yfh_init(&data->types.table); + yfv_add_builtin_types(data); ret = 0; YF_LIST_FOREACH(data->parse_tree.program.decls, node) { @@ -102,6 +108,10 @@ static int yfs_add_fn(struct yf_hashmap * symtab, struct yf_parse_node * f) { } + /* TODO -- actually look up custom types once those exist. */ + fsym->fn.rtype->kind = YFS_T_PRIMITIVE; + strcpy(fsym->fn.rtype->name, fn->ret.databuf); + yfh_set(symtab, fsym->fn.name, fsym); return 0; diff --git a/src/semantics/types.c b/src/semantics/types.c index 830bd35..1bd06b6 100644 --- a/src/semantics/types.c +++ b/src/semantics/types.c @@ -1,5 +1,45 @@ #include "types.h" +void yft_add_type( + struct yf_compile_analyse_job * udata, + char * name, int size, enum yfpt_format fmt +) { + + struct yfs_type * type = yf_malloc(sizeof (struct yfs_type)); + type->primitive.size = size; + type->kind = YFS_T_PRIMITIVE; + type->primitive.type = fmt; + type->name = name; + yfv_add_type(udata, type); + +} + +void yfv_add_builtin_types(struct yf_compile_analyse_job * udata) { + + /* All types are signed for now - unsigned types are not yet supported. */ + + /* "standard" types. */ + yft_add_type(udata, "char", 8, YFS_F_INT ); + yft_add_type(udata, "short", 16, YFS_F_INT ); + yft_add_type(udata, "int", 32, YFS_F_INT ); + yft_add_type(udata, "long", 64, YFS_F_INT ); + yft_add_type(udata, "void", 0, YFS_F_NONE ); + yft_add_type(udata, "float", 32, YFS_F_FLOAT); + yft_add_type(udata, "double", 64, YFS_F_FLOAT); + + /* Convenience types. */ + yft_add_type(udata, "i16", 16, YFS_F_INT ); + yft_add_type(udata, "i32", 32, YFS_F_INT ); + yft_add_type(udata, "i64", 64, YFS_F_INT ); + yft_add_type(udata, "f16", 16, YFS_F_FLOAT); + yft_add_type(udata, "f32", 32, YFS_F_FLOAT); + yft_add_type(udata, "f64", 64, YFS_F_FLOAT); + + /* We're considering bool to be one bit for conversion purposes. */ + yft_add_type(udata, "bool", 1, YFS_F_INT ); + +} + enum yfs_conversion_allowedness yfs_is_safe_conversion( struct yfs_type * from, struct yfs_type * to ) { diff --git a/src/semantics/types.h b/src/semantics/types.h index 7a2b37e..0ecd62f 100644 --- a/src/semantics/types.h +++ b/src/semantics/types.h @@ -11,6 +11,13 @@ #include #include +void yft_add_type( + struct yf_compile_analyse_job * udata, + char * name, int size, enum yfpt_format fmt +); + +void yfv_add_builtin_types(struct yf_compile_analyse_job * udata); + enum yfs_conversion_allowedness { YFS_CONVERSION_OK, YFS_CONVERSION_LOSSY, /* like i64 -> bool */ diff --git a/src/semantics/validate/validate.c b/src/semantics/validate/validate.c index aa6168d..cff97f9 100644 --- a/src/semantics/validate/validate.c +++ b/src/semantics/validate/validate.c @@ -4,53 +4,11 @@ #include #include -static void add_type( - struct yf_compile_analyse_job * udata, - char * name, int size, enum yfpt_format fmt -) { - - struct yfs_type * type = yf_malloc(sizeof (struct yfs_type)); - type->primitive.size = size; - type->kind = YFS_T_PRIMITIVE; - type->primitive.type = fmt; - type->name = name; - yfv_add_type(udata, type); - -} - -static void yfv_add_builtin_types(struct yf_compile_analyse_job * udata) { - - /* All types are signed for now - unsigned types are not yet supported. */ - - /* "standard" types. */ - add_type(udata, "char", 8, YFS_F_INT ); - add_type(udata, "short", 16, YFS_F_INT ); - add_type(udata, "int", 32, YFS_F_INT ); - add_type(udata, "long", 64, YFS_F_INT ); - add_type(udata, "void", 0, YFS_F_NONE ); - add_type(udata, "float", 32, YFS_F_FLOAT); - add_type(udata, "double", 64, YFS_F_FLOAT); - - /* Convenience types. */ - add_type(udata, "i16", 16, YFS_F_INT ); - add_type(udata, "i32", 32, YFS_F_INT ); - add_type(udata, "i64", 64, YFS_F_INT ); - add_type(udata, "f16", 16, YFS_F_FLOAT); - add_type(udata, "f32", 32, YFS_F_FLOAT); - add_type(udata, "f64", 64, YFS_F_FLOAT); - - /* We're considering bool to be one bit for conversion purposes. */ - add_type(udata, "bool", 1, YFS_F_INT ); - -} - int yfs_validate( struct yf_compile_analyse_job * udata, struct yf_compilation_data * pdata ) { - yfh_init(&udata->types.table); - yfv_add_builtin_types(udata); struct yfv_validator validator = { /* Root symbol table is the global scope of the program. */ .current_scope = &udata->symtab, From 61301b3b7101480fc064021b5937deffc112d4f1 Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Tue, 8 Nov 2022 10:36:03 -0500 Subject: [PATCH 5/9] Convert rtype to plain struct --- src/api/sym.h | 2 +- src/gen/gen.c | 4 ++-- src/semantics/symtab.c | 4 ++-- src/semantics/types.c | 2 +- src/semantics/validate/validate-func.c | 6 +++++- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/api/sym.h b/src/api/sym.h index 325060b..7807308 100644 --- a/src/api/sym.h +++ b/src/api/sym.h @@ -67,7 +67,7 @@ struct yfsn_param { struct yfs_fn { char * name; - struct yfs_type * rtype; /* "return type" */ + struct yfs_type rtype; /* "return type" */ struct yf_list params; /* list of param */ }; diff --git a/src/gen/gen.c b/src/gen/gen.c index 43c0ee5..37c279f 100644 --- a/src/gen/gen.c +++ b/src/gen/gen.c @@ -102,7 +102,7 @@ static void yf_gen_funcdecl( struct yf_ast_node * child; int argct = 0; char typebuf[256]; - yfg_ctype(256, typebuf, node->name->fn.rtype); + yfg_ctype(256, typebuf, &node->name->fn.rtype); /* Hacky fix -- but it should work. */ /* We need to check if the function is called "main" because the C compiler @@ -116,7 +116,7 @@ static void yf_gen_funcdecl( fprintf( out, "%s /* %s */ %s$$%s", typebuf, - node->name->fn.rtype->name, + node->name->fn.rtype.name, i->gen_prefix, node->name->fn.name ); diff --git a/src/semantics/symtab.c b/src/semantics/symtab.c index 964c63f..71169d2 100644 --- a/src/semantics/symtab.c +++ b/src/semantics/symtab.c @@ -109,8 +109,8 @@ static int yfs_add_fn(struct yf_hashmap * symtab, struct yf_parse_node * f) { } /* TODO -- actually look up custom types once those exist. */ - fsym->fn.rtype->kind = YFS_T_PRIMITIVE; - strcpy(fsym->fn.rtype->name, fn->ret.databuf); + fsym->fn.rtype.kind = YFS_T_PRIMITIVE; + fsym->fn.rtype.name = fn->ret.databuf; yfh_set(symtab, fsym->fn.name, fsym); diff --git a/src/semantics/types.c b/src/semantics/types.c index 1bd06b6..1021e6e 100644 --- a/src/semantics/types.c +++ b/src/semantics/types.c @@ -133,7 +133,7 @@ struct yfs_type * yfse_get_expr_type( } break; case YFA_E_FUNCCALL: - return expr->as.call.name->fn.rtype; + return &expr->as.call.name->fn.rtype; } } diff --git a/src/semantics/validate/validate-func.c b/src/semantics/validate/validate-func.c index 1195d8c..bdaed31 100644 --- a/src/semantics/validate/validate-func.c +++ b/src/semantics/validate/validate-func.c @@ -24,7 +24,9 @@ int validate_funcdecl( return 2; } - if ((a->name->fn.rtype = yfv_get_type_t( + struct yfs_type * ty; + + if ((ty = yfv_get_type_t( validator->udata, c->ret )) == NULL) { YF_PRINT_ERROR( @@ -36,6 +38,8 @@ int validate_funcdecl( return 2; } + a->name->fn.rtype = *ty; + /* Now, validate the argument list. */ /* Also, open a new scope for arguments. */ enter_scope(validator, &a->param_scope); From 1824f35d8beca55f9705a1051c0f98e5230b0ecb Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Tue, 8 Nov 2022 10:46:43 -0500 Subject: [PATCH 6/9] Add proper type lookup for function symbols --- src/semantics/symtab.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/semantics/symtab.c b/src/semantics/symtab.c index 71169d2..318493d 100644 --- a/src/semantics/symtab.c +++ b/src/semantics/symtab.c @@ -7,8 +7,10 @@ #include #include -static int yfs_add_var(struct yf_hashmap * symtab, struct yf_parse_node *); -static int yfs_add_fn(struct yf_hashmap * symtab, struct yf_parse_node *); +static int yfs_add_var(struct yf_compile_analyse_job *, +struct yf_hashmap * symtab, struct yf_parse_node *); +static int yfs_add_fn(struct yf_compile_analyse_job *, +struct yf_hashmap * symtab, struct yf_parse_node *); int yfs_build_symtab(struct yf_compile_analyse_job * data) { @@ -29,11 +31,11 @@ int yfs_build_symtab(struct yf_compile_analyse_job * data) { YF_LIST_FOREACH(data->parse_tree.program.decls, node) { switch (node->type) { case YFCS_VARDECL: - if (yfs_add_var(&data->symtab.table, node)) + if (yfs_add_var(data, &data->symtab.table, node)) ret = 1; break; case YFCS_FUNCDECL: - if (yfs_add_fn(&data->symtab.table, node)) + if (yfs_add_fn(data, &data->symtab.table, node)) ret = 1; break; default: @@ -46,7 +48,10 @@ int yfs_build_symtab(struct yf_compile_analyse_job * data) { } -static int yfs_add_var(struct yf_hashmap * symtab, struct yf_parse_node * n) { +static int yfs_add_var( + struct yf_compile_analyse_job * data, + struct yf_hashmap * symtab, struct yf_parse_node * n +) { struct yfcs_vardecl * v = &n->vardecl; struct yf_sym * vsym, * dupl; @@ -74,7 +79,10 @@ static int yfs_add_var(struct yf_hashmap * symtab, struct yf_parse_node * n) { } -static int yfs_add_fn(struct yf_hashmap * symtab, struct yf_parse_node * f) { +static int yfs_add_fn( + struct yf_compile_analyse_job * udata, struct yf_hashmap * symtab, + struct yf_parse_node * f +) { struct yfcs_funcdecl * fn = &f->funcdecl; @@ -109,8 +117,7 @@ static int yfs_add_fn(struct yf_hashmap * symtab, struct yf_parse_node * f) { } /* TODO -- actually look up custom types once those exist. */ - fsym->fn.rtype.kind = YFS_T_PRIMITIVE; - fsym->fn.rtype.name = fn->ret.databuf; + fsym->fn.rtype = *yfv_get_type_s(udata, fn->ret.databuf); yfh_set(symtab, fsym->fn.name, fsym); From dd45140f633bdb471026dda94ed79d214f6af141 Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Tue, 8 Nov 2022 13:14:21 -0500 Subject: [PATCH 7/9] Add total compilation data as argument to gen --- src/driver/compile.c | 2 +- src/driver/compiler-backend.c | 7 ++++--- src/driver/compiler-backend.h | 2 +- src/gen/gen.c | 5 ++++- src/gen/gen.h | 5 ++++- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/driver/compile.c b/src/driver/compile.c index 9400869..61ac2dc 100644 --- a/src/driver/compile.c +++ b/src/driver/compile.c @@ -421,7 +421,7 @@ static int yfc_validate_compile( if (yf_ensure_entry_point(pdata)) { return 1; } - retval = yf_backend_generate_code(adata); + retval = yf_backend_generate_code(pdata, adata); } return retval; diff --git a/src/driver/compiler-backend.c b/src/driver/compiler-backend.c index 7475643..a348ea0 100644 --- a/src/driver/compiler-backend.c +++ b/src/driver/compiler-backend.c @@ -116,8 +116,9 @@ static int create_output_file_name( * Generate C code */ static int yf_gen_c( + struct yf_compilation_data * data, struct yf_compile_analyse_job * fdata, struct yf_gen_info * info) { - return yfg_gen(fdata, info); + return yfg_gen(data, fdata, info); } /** @@ -296,7 +297,7 @@ int yf_ensure_entry_point( } int yf_backend_generate_code( - struct yf_compile_analyse_job * data + struct yf_compilation_data * cdata, struct yf_compile_analyse_job * data ) { struct yf_gen_info ginfo = { .yf_prefix = data->unit_info->file_prefix, @@ -305,5 +306,5 @@ int yf_backend_generate_code( create_formatted_prefix( ginfo.yf_prefix, ginfo.gen_prefix, 256 ); - return yf_gen_c(data, &ginfo); + return yf_gen_c(cdata, data, &ginfo); } diff --git a/src/driver/compiler-backend.h b/src/driver/compiler-backend.h index fab7ece..e6daf7b 100644 --- a/src/driver/compiler-backend.h +++ b/src/driver/compiler-backend.h @@ -34,7 +34,7 @@ int yf_backend_add_link_job( ); int yf_backend_generate_code( - struct yf_compile_analyse_job * + struct yf_compilation_data*, struct yf_compile_analyse_job * ); /** diff --git a/src/gen/gen.c b/src/gen/gen.c index 37c279f..eaa0a77 100644 --- a/src/gen/gen.c +++ b/src/gen/gen.c @@ -254,7 +254,10 @@ static int create_all_parent_dirs(char * path) { return 0; } -int yfg_gen(struct yf_compile_analyse_job * data, struct yf_gen_info * info) { +int yfg_gen( + struct yf_compilation_data * cdata, + struct yf_compile_analyse_job * data, struct yf_gen_info * info +) { create_all_parent_dirs(data->unit_info->output_file); diff --git a/src/gen/gen.h b/src/gen/gen.h index fb837c6..8f4f021 100644 --- a/src/gen/gen.h +++ b/src/gen/gen.h @@ -8,6 +8,9 @@ #include #include -int yfg_gen(struct yf_compile_analyse_job * data, struct yf_gen_info * info); +int yfg_gen( + struct yf_compilation_data * cdata, + struct yf_compile_analyse_job * data, struct yf_gen_info * info +); #endif /* GEN_GEN_H */ From d2fa50d22e5a7ad4d0b2501dba3edc29c8e2b50a Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Tue, 8 Nov 2022 13:14:35 -0500 Subject: [PATCH 8/9] Add empty main as test --- tests/sem/misc.yf | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/sem/misc.yf diff --git a/tests/sem/misc.yf b/tests/sem/misc.yf new file mode 100644 index 0000000..d974d48 --- /dev/null +++ b/tests/sem/misc.yf @@ -0,0 +1,3 @@ +main() { + +} From df4e9f5984510075f4082118d6ccef4b4c1ec9ce Mon Sep 17 00:00:00 2001 From: adamhutchings Date: Tue, 8 Nov 2022 21:14:01 -0500 Subject: [PATCH 9/9] Add framework for symbol dumping --- src/gen/gen.c | 3 +++ src/gen/symgen.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/gen/symgen.h | 19 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 src/gen/symgen.c create mode 100644 src/gen/symgen.h diff --git a/src/gen/gen.c b/src/gen/gen.c index eaa0a77..7fb92ab 100644 --- a/src/gen/gen.c +++ b/src/gen/gen.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -271,6 +272,8 @@ int yfg_gen( fprintf(out, "/* Generated by yfc. */\n\n"); fprintf(out, "#include \n\n"); + yfg_output_syms(cdata, data, out); + yf_gen_node(&data->ast_tree, out, info); fclose(out); diff --git a/src/gen/symgen.c b/src/gen/symgen.c new file mode 100644 index 0000000..3b5735d --- /dev/null +++ b/src/gen/symgen.c @@ -0,0 +1,43 @@ +#include "symgen.h" + +#include + +static int dump_symbol( + FILE * out, + struct yf_sym * sym +) { + /* TODO */ + return 0; +} + +int yfg_output_syms( + struct yf_compilation_data * cdata, + struct yf_compile_analyse_job * data, + FILE * out +) { + + struct yfh_cursor cursor; + struct yfs_symtab * fsymtab; + + /* We iterate through all symtabs and dump all decls into the file */ + for (yfh_cursor_init(&cursor, &cdata->symtables); !yfh_cursor_next(&cursor); ) { + + yfh_cursor_get(&cursor, NULL, (void **)&fsymtab); + + struct yfh_cursor inner_cursor; + struct yf_sym * sym; + int fail; + + for (yfh_cursor_init(&inner_cursor, &fsymtab->table); !yfh_cursor_next(&cursor); ) { + yfh_cursor_get(&inner_cursor, NULL, (void **)&sym); + if ((fail = dump_symbol(out, sym))) { + YF_PRINT_ERROR("gen: panic: error in dumping symbol"); + return fail; + } + } + + } + + return 0; + +} diff --git a/src/gen/symgen.h b/src/gen/symgen.h new file mode 100644 index 0000000..6ecdb3c --- /dev/null +++ b/src/gen/symgen.h @@ -0,0 +1,19 @@ +/** + * For projects -- dumping all symbols from other files as forward declarations + * in the current file. + */ + +#ifndef GEN_SYMGEN_H +#define GEN_SYMGEN_H + +#include /* FILE */ + +#include + +int yfg_output_syms( + struct yf_compilation_data * cdata, + struct yf_compile_analyse_job * data, + FILE * out +); + +#endif /* GEN_SYMGEN_H */