diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-08-24 21:22:22 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-08-24 21:22:22 -0400 |
commit | 22fe17e12d0a0891bc6452e0a55dc474ae74c4e8 (patch) | |
tree | e62b110c26845881858dbc05755467fe8e4c6f40 | |
parent | 32ab8c03cc4382401f4b0a5948354c6d14d08650 (diff) |
Added main function
-rw-r--r-- | base_cgen.c | 13 | ||||
-rw-r--r-- | cgen.c | 6 | ||||
-rw-r--r-- | identifiers.c | 19 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | out.c | 10 | ||||
-rw-r--r-- | out.h | 4 | ||||
-rw-r--r-- | test.toc | 3 | ||||
-rw-r--r-- | types_cgen.c | 11 |
8 files changed, 58 insertions, 10 deletions
diff --git a/base_cgen.c b/base_cgen.c index 52cd3d6..c2aa9da 100644 --- a/base_cgen.c +++ b/base_cgen.c @@ -81,11 +81,13 @@ static void cgen_create(CGenerator *g, FILE *c_out, FILE *h_out, const char *h_f g->anon_fn_count = 0; g->indent_level = 0; g->block = NULL; - g->writing_to = CGEN_WRITING_TO_C; - g->indent_next = true; + g->indent_next = true; - cgen_write(g, "#include \"%s\"\n", h_filename); + g->writing_to = CGEN_WRITING_TO_H; cgen_write(g, "#include <stdint.h>\n"); + + g->writing_to = CGEN_WRITING_TO_C; + cgen_write(g, "#include \"%s\"\n", h_filename); cgen_writeln(g, ""); /* extra newline between includes and code */ } @@ -138,6 +140,11 @@ static void cgen_fn_name(CGenerator *g, FnExpr *f) { static bool cgen_fn_header(CGenerator *g, FnExpr *f) { CGenWritingTo writing_to_before = g->writing_to; + if (ident_eq_str(f->name, "main")) { + /* don't use actual main function */ + cgen_write(g, "void main__(void)"); + return true; + } if (!f->name || g->block != NULL) { cgen_write(g, "static "); /* anonymous functions only exist in this translation unit */ } @@ -159,5 +159,11 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) { arr_foreach(&f->stmts, Statement, s) { if (!cgen_fns_in_stmt(g, s)) return false; } + g->writing_to = CGEN_WRITING_TO_C; + /* write actual main function */ + cgen_write(g, "\nint main(void) {\n" + "\tmain__();\n" + "\treturn 0;\n" + "}\n"); return ret; } diff --git a/identifiers.c b/identifiers.c index b577082..ca6050f 100644 --- a/identifiers.c +++ b/identifiers.c @@ -12,6 +12,7 @@ typedef struct IdentTree { struct IdentTree *parent; Array decls; /* array of declarations of this identifier */ unsigned long c_fn_reps; /* number of repetitions of this identifier in the C output--only used for functions */ + size_t depth; } IdentTree; typedef IdentTree *Identifier; @@ -51,8 +52,10 @@ static Identifier ident_tree_insert(IdentTree *t, char **s) { if (!t->children) { /* allocate children */ t->children = err_calloc(NIDENTIFIER_CHARS, sizeof *t->children); - for (int i = 0; i < NIDENTIFIER_CHARS; i++) + for (int i = 0; i < NIDENTIFIER_CHARS; i++) { t->children[i].parent = t; /* child's parent = self */ + t->children[i].depth = t->depth + 1; + } } t = &t->children[ident_char_index(c)]; (*s)++; @@ -73,6 +76,20 @@ static void fprint_ident(FILE *out, Identifier id) { fputc(identifier_chars[id - id->parent->children /* index of self in parent */], out); } +static bool ident_eq_str(Identifier i, const char *s) { + size_t len = strlen(s); + if (i->depth != len) return false; + s += len - 1; + while (i->parent != NULL) { + if (identifier_chars[i - i->parent->children /* index of self in parent */] != *s) + return false; + i = i->parent; + if (i->parent != NULL) + s--; + } + return true; +} + static void idents_free_tree(IdentTree *tree) { if (!tree->children) return; for (int i = 0; i < NIDENTIFIER_CHARS; i++) @@ -55,7 +55,7 @@ int main(int argc, char **argv) { fprint_parsed_file(stdout, &f); tokr_free(&t); - + /* TODO (eventually): use a tmp file (don't overwrite old output if there's an error) */ const char *c_out_filename = "out.c"; const char *h_out_filename = "out.h"; FILE *c_out = fopen(c_out_filename, "w"); @@ -1,12 +1,18 @@ #include "out.h" -#include <stdint.h> /* toc */ static void bar(); -void main() { +void asfdhjfdsaf() { +} +void main__(void) { int64_t x = ((12+(-(-3)))+3); } int8_t foo(int64_t x, float y, double z) { } void bar() { } + +int main(void) { + main__(); + return 0; +} @@ -1,2 +1,4 @@ -void main(); +#include <stdint.h> +void asfdhjfdsaf(); +void main__(void); static int8_t foo(int64_t x, float y, double z); @@ -1,3 +1,6 @@ +asfdhjfdsaf @= fn() { +}; + main @= fn() { foo @= fn(x: int, y: float, z: double) i8 { }; diff --git a/types_cgen.c b/types_cgen.c index fb1e690..0eaa4b3 100644 --- a/types_cgen.c +++ b/types_cgen.c @@ -57,9 +57,14 @@ static bool cgen_types_stmt(CGenerator *g, Statement *s) { /* e.g. foo @= fn() {}; (we want to set the function's name to "foo") */ if (d->expr.kind == EXPR_FN) { d->expr.fn.name = *(Identifier*)d->idents.data; + if (ident_eq_str(d->expr.fn.name, "main") && g->block != NULL) { + /* TODO (eventually): Consider just renaming the function */ + err_print(d->where, "main function defined in local scope."); + return false; + } } } - cgen_types_expr(g, &d->expr); + return cgen_types_expr(g, &d->expr); } break; } @@ -68,7 +73,9 @@ static bool cgen_types_stmt(CGenerator *g, Statement *s) { static bool cgen_types(CGenerator *g, ParsedFile *f) { arr_foreach(&f->stmts, Statement, s) { - cgen_types_stmt(g, s); + if (!cgen_types_stmt(g, s)) { + return false; + } } return true; } |