diff options
-rw-r--r-- | cgen.c | 19 | ||||
-rw-r--r-- | data_structures.c | 7 | ||||
-rw-r--r-- | eval.c | 24 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | test.toc | 33 | ||||
-rw-r--r-- | types.c | 19 | ||||
-rw-r--r-- | types.h | 9 |
7 files changed, 95 insertions, 17 deletions
@@ -1165,6 +1165,16 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { cgen_write(g, "extern void *stdout;"); cgen_nl(g); break; + case BUILTIN_STDERR: + cgen_write(g, "extern void *stderr;"); + cgen_nl(g); + break; + case BUILTIN_STDIN: + cgen_write(g, "extern void *stdin;"); + cgen_nl(g); + break; + case BUILTIN_COMPILING: + break; } break; case EXPR_LITERAL_INT: @@ -1463,6 +1473,15 @@ static bool cgen_expr(CGenerator *g, Expression *e) { case BUILTIN_STDOUT: cgen_write(g, "stdout"); break; + case BUILTIN_STDERR: + cgen_write(g, "stderr"); + break; + case BUILTIN_STDIN: + cgen_write(g, "stdin"); + break; + case BUILTIN_COMPILING: + cgen_write(g, "false"); + break; } break; case EXPR_CAST: { diff --git a/data_structures.c b/data_structures.c index 19f4efd..3393c6b 100644 --- a/data_structures.c +++ b/data_structures.c @@ -88,12 +88,11 @@ static void arr_cleara_(void **arr, size_t size, Allocator *allocr) { } } +/* does NOT shrink the array! */ static void arr_set_len_(void **arr, size_t n, size_t item_sz) { - if (n == 0) { - arr_clear_(arr); - return; + if (n > arr_len(*arr)) { + arr_resv_(arr, n, item_sz); } - arr_resv_(arr, n, item_sz); arr_hdr(*arr)->len = n; } static void arr_set_lena_(void **arr, size_t n, size_t item_sz, Allocator *a) { @@ -1050,7 +1050,12 @@ static bool eval_ident(Evaluator *ev, Identifier ident, Value *v, Location where d = idecl->decl; if (d->flags & DECL_FOREIGN) { if (!(d->flags & DECL_FOUND_VAL)) { - err_print(where, "Cannot access foreign declaration at compile time (you can only call foreign functions)"); +#if COMPILE_TIME_FOREIGN_FN_SUPPORT + err_print(where, "Cannot access foreign declaration at compile time. " + "If you are calling a function, you need to provide the library it's in."); +#else + err_print(where, "Cannot access foreign declaration at compile time."); +#endif return false; } v->fn = d->val.fn; @@ -1465,9 +1470,11 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { /* 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 */ + /* set parameter values */ Declaration *params = fn->params; - fn_enter(fn, 0); long arg = 0; arr_foreach(params, Declaration, p) { int idx = 0; @@ -1476,12 +1483,21 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (!eval_expr(ev, &e->call.arg_exprs[arg], &arg_val)) return false; Type *type = p->type.kind == TYPE_TUPLE ? &p->type.tuple[idx++] : &p->type; - IdentDecl *id = ident_decl(*i); + IdentDecl *id = ident_add_decl(*i, p, &fn->body); copy_val(NULL, &id->val, &arg_val, type); id->flags |= IDECL_HAS_VAL; + + arr_set_len(&(*i)->decls, arr_len((*i)->decls)-1); + ++arg; } } + arr_foreach(params, Declaration, p) { + arr_foreach(p->idents, Identifier, i) { + arr_set_len(&(*i)->decls, arr_len((*i)->decls)+1); + } + } + arr_foreach(fn->ret_decls, Declaration, d) { int idx = 0; Value val; @@ -1501,6 +1517,8 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { } ++idx; } + if (!add_ident_decls(&fn->body, d, 0)) + return false; } if (!eval_block(ev, &fn->body, &e->type, v)) { fn_exit(fn); @@ -22,6 +22,7 @@ TODO: - sizeof(int) (size of C int type), sizeof(long), sizeof(size_t) etc. - compiling - true if @ compile time, false otherwise - stdout, stderr, stdin - pointers to C FILEs +fully re-test default args & return decls clean up copy_expr each=>for @@ -1,20 +1,41 @@ +voidptr ::= &u8; -getstdout ::= fn() &u8 { - #builtin("stdout") +getstdout ::= fn() voidptr { + #builtin("stdout") }; -fwrite :: fn(&u8, u64, u64, &u8) = #foreign "fwrite"; +getstdin ::= fn() voidptr { + #builtin("stdin") +}; + +fwrite :: fn(voidptr, u64, u64, voidptr) u64 = #foreign "fwrite", "libc.so.6"; +fputc :: fn(i32, voidptr) i32 = #foreign "fputc", "libc.so.6"; +fgets :: fn(&char, i32, voidptr) &char = #foreign "fgets", "libc.so.6"; + +writes ::= fn(x : []char) { + fwrite(&x[0] as voidptr, 1, x.len as u64, getstdout()); +}; puts ::= fn(x : []char) { - fwrite(&x[0] as &u8 as &u16 as &u8, 1, x.len as u64, getstdout()); + writes(x); + fputc('\n' as i32, getstdout()); }; hw ::= fn() int { - hw(); + name : [1024]char; + writes("Name? "); + fgets(&name[0], name.len as i32, getstdin()); + + writes("Hello, "); + if #builtin("compiling") { + writes("compiling "); + } + + writes(name[:]); // fgets already has a newline 2 }; main ::= fn() { hw(); x ::= hw(); -}; +};
\ No newline at end of file @@ -233,6 +233,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { t->kind = TYPE_FN; t->fn.types = NULL; t->fn.constness = NULL; /* OPTIM: constness doesn't need to be a dynamic array */ + t->flags = 0; bool success = true; bool entered_fn = false; size_t param_idx; @@ -372,7 +373,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { } } } - + t->flags |= TYPE_IS_RESOLVED; } *ret_type = f->ret_type; @@ -931,6 +932,15 @@ static void get_builtin_val(BuiltinVal val, Value *v) { case BUILTIN_STDOUT: v->ptr = stdout; break; + case BUILTIN_STDERR: + v->ptr = stderr; + break; + case BUILTIN_STDIN: + v->ptr = stdin; + break; + case BUILTIN_COMPILING: + v->boolv = true; + break; } } @@ -938,12 +948,19 @@ static void get_builtin_val_type(Allocator *a, BuiltinVal val, Type *t) { t->flags = TYPE_IS_RESOLVED; switch (val) { case BUILTIN_STDOUT: + case BUILTIN_STDERR: + case BUILTIN_STDIN: + /* use &u8 for FILE * */ t->kind = TYPE_PTR; t->ptr = allocr_calloc(a, 1, sizeof *t->ptr); t->ptr->flags = TYPE_IS_RESOLVED; t->ptr->kind = TYPE_BUILTIN; t->ptr->builtin = BUILTIN_U8; break; + case BUILTIN_COMPILING: + t->kind = TYPE_BUILTIN; + t->builtin = BUILTIN_BOOL; + break; } } @@ -673,11 +673,14 @@ typedef struct SliceExpr { } SliceExpr; typedef enum { - BUILTIN_STDOUT -#define BUILTIN_VAL_COUNT (BUILTIN_STDOUT+1) + BUILTIN_STDOUT, + BUILTIN_STDERR, + BUILTIN_STDIN, + BUILTIN_COMPILING +#define BUILTIN_VAL_COUNT (BUILTIN_COMPILING+1) } BuiltinVal; -const char *const builtin_val_names[BUILTIN_VAL_COUNT] = {"stdout"}; +const char *const builtin_val_names[BUILTIN_VAL_COUNT] = {"stdout", "stderr", "stdin", "compiling"}; enum { EXPR_FOUND_TYPE = 0x01 |