diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-02-12 21:26:23 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-02-12 21:26:23 -0500 |
commit | ef29776bb66629a28a3f4dfeac2d450c83a22b7b (patch) | |
tree | 45befe36398e6f346f17fb44aba8fd0e8af1a958 | |
parent | 8d94800921520a45284164e09e5dd21da6115973 (diff) |
got rid of #cache; decided it wasnt the way to go
-rw-r--r-- | copy.c | 3 | ||||
-rw-r--r-- | eval.c | 83 | ||||
-rw-r--r-- | main.c | 10 | ||||
-rw-r--r-- | parse.c | 6 | ||||
-rw-r--r-- | test.toc | 15 | ||||
-rw-r--r-- | tokenizer.c | 2 | ||||
-rw-r--r-- | types.c | 10 | ||||
-rw-r--r-- | types.h | 22 |
8 files changed, 62 insertions, 89 deletions
@@ -118,6 +118,7 @@ static void copy_type(Copier *c, Type *out, Type *in) { out->slice = copy_type_(c, in->slice); break; case TYPE_STRUCT: { + /* FIXME */ out->struc = allocr_malloc(c->allocr, sizeof *out->struc); *out->struc = *in->struc; size_t nfields = arr_len(in->struc->fields); @@ -366,6 +367,8 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { } static void copy_block(Copier *c, Block *out, Block *in, U8 flags) { + assert(!(in->flags & BLOCK_FINDING_TYPES)); + Identifiers out_idents = out->idents; *out = *in; if (flags & COPY_BLOCK_DONT_CREATE_IDENTS) @@ -1523,15 +1523,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { return false; break; } - /* make sure function body is typed before calling it */ - if (!types_block(ev->typer, &fn->body)) { - return false; - } - /* NOTE: we're not calling fn_enter because we're manually entering the function */ - - Value *ret_val; - Value *arg_tuple = NULL; - Type *arg_type_tuple = NULL; /* set parameter values */ Declaration *params = fn->params; @@ -1549,42 +1540,12 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { Type *type = is_tuple ? &p->type.tuple[idx] : &p->type; Value *ival = multiple_idents ? &pval->tuple[idx] : pval; copy_val(NULL, ival, &arg_val, type); - if (fn->flags & FN_EXPR_CACHE) { - Value *arg_tuple_member = arr_add(&arg_tuple); - *(Type *)arr_add(&arg_type_tuple) = *type; - copy_val(ev->allocr, arg_tuple_member, &arg_val, type); - } ++arg; ++idx; } ++arr_hdr(p->val_stack)->len; } - if (fn->flags & FN_EXPR_CACHE) { - Value args; - args.tuple = arg_tuple; - Type args_type = {0}; - args_type.flags = TYPE_IS_RESOLVED; - args_type.tuple = arg_type_tuple; - bool already_there; - Instance *i = instance_table_adda(ev->allocr, fn->cache, args, &args_type, &already_there); - arr_clear(&arg_tuple); - arr_clear(&arg_type_tuple); - if (already_there) { - *v = *i->ret_val; - return true; - } else { - ret_val = i->ret_val = evalr_calloc(ev, 1, sizeof *ret_val); - if (type_is_builtin(&e->type, BUILTIN_TYPE)) { - /* placeholder type, overwritten when done */ - ret_val->type = evalr_calloc(ev, 1, sizeof *ret_val); - ret_val->type->kind = TYPE_UNKNOWN; - ret_val->type->flags = TYPE_IS_RESOLVED; - } - } - - } - arr_foreach(fn->ret_decls, Declaration, d) { int idx = 0; Value ret_decl_val; @@ -1605,6 +1566,11 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { ++idx; } } + + /* make sure function body is typed before calling it */ + if (!types_block(ev->typer, &fn->body)) + return false; + if (!eval_block(ev, &fn->body, v)) { return false; } @@ -1642,13 +1608,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { decl_remove_val(p); arr_foreach(fn->ret_decls, Declaration, d) decl_remove_val(d); - if (fn->flags & FN_EXPR_CACHE) { - if (type_is_builtin(&e->type, BUILTIN_TYPE)) { - *ret_val->type = *v->type; - } else { - *ret_val = *v; - } - } } break; case EXPR_SLICE: { SliceExpr *s = &e->slice; @@ -1792,21 +1751,33 @@ static void eval_exit_stmts(Statement *stmts) { } static bool eval_block(Evaluator *ev, Block *b, Value *v) { + Block *prev = ev->typer->block; + ev->typer->block = b; + bool success = true; arr_foreach(b->stmts, Statement, stmt) { - if (!eval_stmt(ev, stmt)) - return false; + if (!eval_stmt(ev, stmt)) { + success = false; + goto ret; + } if (ev->returning) break; } if (!ev->returning && b->ret_expr) { Value r; - if (!eval_expr(ev, b->ret_expr, &r)) - return false; - /* make a copy so that r's data isn't freed when we exit the block */ - copy_val(NULL, v, &r, &b->ret_expr->type); - if (b->ret_expr->kind == EXPR_TUPLE) - free(r.tuple); + if (!eval_expr(ev, b->ret_expr, &r)) { + success = false; + goto ret; + } + if (!type_is_builtin(&b->ret_expr->type, BUILTIN_TYPE)) { + /* make a copy so that r's data isn't freed when we exit the block */ + copy_val(NULL, v, &r, &b->ret_expr->type); + if (b->ret_expr->kind == EXPR_TUPLE) + free(r.tuple); + } else { + *v = r; + } } eval_exit_stmts(b->stmts); - - return true; + ret: + ev->typer->block = prev; + return success; } @@ -18,7 +18,11 @@ /* TODO: -allow circular dependencies in types +fix circular dependencies in types +struct parameters +fix struct copying +replace is_reference in type_resolve_ with system for checking if type is + circularly dependent in a bad way, with compiler_sizeof foo, _ := bar(); nice syntax for #including something into a namespace run stuff at compile time without assigning it to a constant @@ -35,14 +39,14 @@ don't allow while {3; 5} or for 0..10 { 3; 5 } (once break is added) do we need was_expr? (now that, presumably, we have struct arguments) any odd number of "s for a string make sure futurely/currently-declared types are only used by pointer/slice -allow omission of trailing ; in foo ::= fn() {...} or foo ::= nms {...} ? +allow omission of trailing ; in foo ::= fn() {...} or foo ::= nms {...} or foo ::= struct { ... }? */ #include "toc.c" -#if defined TOC_DEBUG && defined __linux__ +#if defined TOC_DEBUG && defined __linux__ && defined __GNU_LIBRARY__ #include <signal.h> #include <execinfo.h> #include <unistd.h> @@ -866,11 +866,6 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) { /* only called when token is fn */ assert(token_is_kw(t->token, KW_FN)); ++t->token; - if (token_is_direct(t->token, DIRECT_CACHE)) { - f->flags |= FN_EXPR_CACHE; - f->cache = parser_calloc(p, 1, sizeof *f->cache); - ++t->token; - } if (!token_is_kw(t->token, KW_LPAREN)) { tokr_err(t, "Expected '(' after 'fn'."); return false; @@ -1775,7 +1770,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { case DIRECT_FOREIGN: case DIRECT_EXPORT: case DIRECT_INCLUDE: - case DIRECT_CACHE: tokr_err(t, "Unrecognized expression."); return false; case DIRECT_COUNT: assert(0); break; @@ -1,14 +1,9 @@ -io ::= nms{ - #include "std/io.toc"; +b ::= struct { + next : &a; }; - -ll ::= fn() Type { - struct { - head : int; - tail : &ll(); - } +a::=struct { + next : &b; }; - main ::= fn() { - l : ll(); + l : ll; }; diff --git a/tokenizer.c b/tokenizer.c index 36d9aa5..5a7e272 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -19,7 +19,7 @@ static const char *const keywords[KW_COUNT] = static inline const char *kw_to_str(Keyword k) { return keywords[k]; } static const char *directives[DIRECT_COUNT] = - {"C", "sizeof", "alignof", "export", "foreign", "builtin", "include", "cache"}; + {"C", "sizeof", "alignof", "export", "foreign", "builtin", "include"}; /* Returns KW_COUNT if it's not a keyword */ /* OPTIM: don't use strncmp so much */ @@ -2213,6 +2213,14 @@ static bool types_expr(Typer *tr, Expression *e) { static bool types_block(Typer *tr, Block *b) { if (b->flags & BLOCK_FOUND_TYPES) return true; + + if (b->flags & BLOCK_FINDING_TYPES) { + err_print(b->where, "A circular dependency was found when finding types in this block.\n" + "You are using recursion in a way that is not allowed by this language. Sorry!"); + return false; + } + b->flags |= BLOCK_FINDING_TYPES; + typer_block_enter(tr, b); bool success = true; arr_foreach(b->stmts, Statement, s) { @@ -2248,6 +2256,8 @@ static bool types_block(Typer *tr, Block *b) { ret: typer_block_exit(tr); b->flags |= BLOCK_FOUND_TYPES; + b->flags &= (BlockFlags)~(BlockFlags)BLOCK_FINDING_TYPES; + return success; } @@ -230,7 +230,6 @@ typedef enum { DIRECT_FOREIGN, DIRECT_BUILTIN, DIRECT_INCLUDE, - DIRECT_CACHE, DIRECT_COUNT } Directive; @@ -472,10 +471,12 @@ typedef struct StructDef { enum { BLOCK_IS_FN = 0x01, BLOCK_IS_NMS = 0x02, - BLOCK_FOUND_TYPES = 0x04 + BLOCK_FINDING_TYPES = 0x04, + BLOCK_FOUND_TYPES = 0x08 }; +typedef U8 BlockFlags; typedef struct Block { - U8 flags; + BlockFlags flags; Location where; Identifiers idents; struct Statement *stmts; @@ -596,8 +597,7 @@ typedef struct ForExpr { enum { FN_EXPR_FOREIGN = 0x01, - FN_EXPR_EXPORT = 0x02, /* set by sdecls_cgen.c */ - FN_EXPR_CACHE = 0x04 + FN_EXPR_EXPORT = 0x02 /* set by sdecls_cgen.c */ }; typedef struct FnExpr { @@ -617,7 +617,6 @@ typedef struct FnExpr { the first element is a u64 value whose ith bit (1<<i) is 1 if the ith semi-constant parameter is constant. */ - HashTable *cache; /* only set for FN_EXPR_CACHE */ struct { /* if name = NULL, this is an anonymous function, and id will be the ID of the fn. */ Identifier name; @@ -628,14 +627,11 @@ typedef struct FnExpr { typedef struct Instance { Value val; /* key into hash table */ - union { + struct { + FnExpr *fn; /* the typed function */ struct { - FnExpr *fn; /* the typed function */ - struct { - U64 id; - } c; - }; - Value *ret_val; /* return value (for #cached functions). pointer must stay fixed, so this is a Value * */ + U64 id; + } c; }; } Instance; |