diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-18 11:19:01 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-18 11:19:01 -0400 |
commit | ea40420c8dbf784f764956926af1e3d408afc185 (patch) | |
tree | 89471f777f15f0ae8b06e6f86dd5c50282a415bc | |
parent | 9167bb6d98fbbf858b90f3ffafd1ab2aeb47ac2d (diff) |
while, block exprs
-rw-r--r-- | cgen.c | 128 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | out.c | 15 | ||||
-rw-r--r-- | parse.c | 2 | ||||
-rw-r--r-- | test.toc | 6 |
5 files changed, 101 insertions, 52 deletions
@@ -362,49 +362,6 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E return true; } -static bool cgen_if_pre(CGenerator *g, Expression *e) { - char ret_name[64]; - IfExpr *curr = &e->if_; - curr->c.id = g->ident_counter++; - cgen_ident_id_to_str(ret_name, curr->c.id); - char *p = ret_name + strlen(ret_name); - if (e->type.kind != TYPE_VOID) { - if (e->type.kind == TYPE_TUPLE) { - for (unsigned long i = 0; i < arr_len(e->type.tuple); i++) { - sprintf(p, "%lu_", i); - if (!cgen_type_pre(g, &e->type.tuple[i], e->where)) return false; - cgen_write(g, " %s", ret_name); - if (!cgen_type_post(g, &e->type.tuple[i], e->where)) return false; - cgen_write(g, "; "); - } - - } else { - cgen_type_pre(g, &e->type, e->where); - cgen_write(g, " %s", ret_name); - cgen_type_post(g, &e->type, e->where); - cgen_write(g, ";"); - cgen_nl(g); - } - } - *p = 0; /* clear tuple suffixes */ - - while (1) { - if (curr->cond) { - cgen_write(g, "if ("); - if (!cgen_expr(g, curr->cond)) - return false; - cgen_write(g, ") "); - } - if (!cgen_block(g, &curr->body, ret_name)) - return false; - if (curr->next_elif) { - cgen_write(g, " else "); - curr = &curr->next_elif->if_; - } else break; - } - return true; -} - /* one of exprs, idents, and prefix should be NULL. */ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, const char *prefix, Expression *to) { IdentID prefix_id; /* ID of prefix for block */ @@ -459,6 +416,12 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, case EXPR_IF: prefix_id = to->if_.c.id; goto prefixed; + case EXPR_BLOCK: + prefix_id = to->block_ret_id; + goto prefixed; + case EXPR_WHILE: + prefix_id = to->while_.c.id; + goto prefixed; prefixed: for (unsigned long i = 0; i < (unsigned long)arr_len(to->type.tuple); i++) { cgen_write(g, "("); @@ -495,13 +458,77 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, } static bool cgen_expr_pre(CGenerator *g, Expression *e) { + IdentID id; + char ret_name[64]; switch (e->kind) { case EXPR_IF: - cgen_if_pre(g, e); - break; case EXPR_WHILE: - break; + case EXPR_BLOCK: { + id = g->ident_counter++; + + cgen_ident_id_to_str(ret_name, id); + char *p = ret_name + strlen(ret_name); + if (e->type.kind != TYPE_VOID) { + if (e->type.kind == TYPE_TUPLE) { + for (unsigned long i = 0; i < arr_len(e->type.tuple); i++) { + sprintf(p, "%lu_", i); + if (!cgen_type_pre(g, &e->type.tuple[i], e->where)) return false; + cgen_write(g, " %s", ret_name); + if (!cgen_type_post(g, &e->type.tuple[i], e->where)) return false; + cgen_write(g, "; "); + } + + } else { + cgen_type_pre(g, &e->type, e->where); + cgen_write(g, " %s", ret_name); + cgen_type_post(g, &e->type, e->where); + cgen_write(g, ";"); + cgen_nl(g); + } + } + *p = 0; /* clear tuple suffixes */ + + } break; + default: break; + } + + switch (e->kind) { + case EXPR_IF: { + IfExpr *curr = &e->if_; + curr->c.id = id; + while (1) { + if (curr->cond) { + cgen_write(g, "if ("); + if (!cgen_expr(g, curr->cond)) + return false; + cgen_write(g, ") "); + } + if (!cgen_block(g, &curr->body, ret_name)) + return false; + if (curr->next_elif) { + cgen_write(g, " else "); + curr = &curr->next_elif->if_; + } else break; + } + } break; + case EXPR_WHILE: { + WhileExpr *w = &e->while_; + w->c.id = id; + cgen_write(g, "while ("); + if (w->cond) { + if (!cgen_expr(g, w->cond)) + return false; + } else { + cgen_write(g, "true"); + } + cgen_write(g, ") "); + if (!cgen_block(g, &w->body, ret_name)) + return false; + } break; case EXPR_BLOCK: + e->block_ret_id = id; + if (!cgen_block(g, &e->block, ret_name)) + return false; break; case EXPR_CALL: if (!cgen_expr_pre(g, e->call.fn)) return false; @@ -641,6 +668,13 @@ static bool cgen_expr(CGenerator *g, Expression *e) { case EXPR_IF: cgen_ident_id(g, e->if_.c.id); break; + case EXPR_WHILE: + if (e->type.kind != TYPE_VOID) + cgen_ident_id(g, e->while_.c.id); + break; + case EXPR_BLOCK: + cgen_ident_id(g, e->block_ret_id); + break; case EXPR_CALL: cgen_write(g, "("); if (!cgen_expr(g, e->call.fn)) @@ -699,8 +733,8 @@ static bool cgen_expr(CGenerator *g, Expression *e) { */ static bool cgen_block(CGenerator *g, Block *b, const char *ret_name) { Block *prev = g->block; - cgen_block_enter(g, b); cgen_write(g, "{"); + cgen_block_enter(g, b); cgen_nl(g); arr_foreach(b->stmts, Statement, s) if (!cgen_stmt(g, s)) @@ -3,8 +3,8 @@ TODO: blocks which return tuples new run-time type resolution unicode variable names -re-do cgen make sure initializers for global variables are compile-time constants +don't allow while {3; 5} (once break is added) any odd number of "s for a string modifiable strings: s := ["sakjdfhkjh ksjdahfkjsd ahs ahdf hsdaf khsadkjfh"]; @@ -27,13 +27,13 @@ int main() { #include <stdio.h> ; void puti(i64 x) { - { +{ printf("%ld\n", (long)x); }} void main__(void) { - { +{ i64 a0_0_; i64 a0_1_; if (0) { (a0_0_) = 3;(a0_1_) = 5; } else { @@ -41,3 +41,14 @@ void main__(void) { }i64 A; i64 B; (A) = a0_0_; (B) = a0_1_; (puti(A)); (puti(B)); + i64 y = 0; + while ((y<10)) { + i64 a2_; + { + y = (y+1);; + a2_ = y; + }(puti(a2_)); + }; +}} + + @@ -1536,7 +1536,7 @@ static void fprint_expr(FILE *out, Expression *e) { break; case EXPR_WHILE: fprintf(out, "while "); - fprint_expr(out, e->while_.cond); + if (e->while_.cond) fprint_expr(out, e->while_.cond); fprint_block(out, &e->while_.body); break; case EXPR_CALL: @@ -9,5 +9,9 @@ main @= fn() { // A, B := 3, 5; puti(A); puti(B); - asdfas := new (int, int); + y:int; + while y < 10 { + puti({y = y + 1; y}); + } + };
\ No newline at end of file |