summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-08-24 21:22:22 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-08-24 21:22:22 -0400
commit22fe17e12d0a0891bc6452e0a55dc474ae74c4e8 (patch)
treee62b110c26845881858dbc05755467fe8e4c6f40
parent32ab8c03cc4382401f4b0a5948354c6d14d08650 (diff)
Added main function
-rw-r--r--base_cgen.c13
-rw-r--r--cgen.c6
-rw-r--r--identifiers.c19
-rw-r--r--main.c2
-rw-r--r--out.c10
-rw-r--r--out.h4
-rw-r--r--test.toc3
-rw-r--r--types_cgen.c11
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 */
}
diff --git a/cgen.c b/cgen.c
index 1c13039..152baf6 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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++)
diff --git a/main.c b/main.c
index 118f8a6..2776f59 100644
--- a/main.c
+++ b/main.c
@@ -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");
diff --git a/out.c b/out.c
index 7d51729..dfdc298 100644
--- a/out.c
+++ b/out.c
@@ -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;
+}
diff --git a/out.h b/out.h
index 20f1ebe..6479cc4 100644
--- a/out.h
+++ b/out.h
@@ -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);
diff --git a/test.toc b/test.toc
index c43db3a..e8ae1b1 100644
--- a/test.toc
+++ b/test.toc
@@ -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;
}