From c12e005630f77c608b4fdebbb5054c5f46ab4df0 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sat, 25 Jan 2020 17:50:34 -0500 Subject: more #builtin. realized theres a problem with pkgs... --- cgen.c | 21 ++++++++++++++- eval.c | 4 +-- identifiers.c | 6 +++++ package.c | 17 +++++++++---- std/io.toc | 28 +++++++++++++++++--- test.toc | 18 +++++-------- types.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- types.h | 25 ++++++++++++++++-- 8 files changed, 170 insertions(+), 31 deletions(-) diff --git a/cgen.c b/cgen.c index dc633d0..65281fe 100644 --- a/cgen.c +++ b/cgen.c @@ -1228,7 +1228,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { cgen_write(g, "extern void *stdin;"); cgen_nl(g); break; - case BUILTIN_COMPILING: + default: break; } break; @@ -1539,6 +1539,25 @@ static bool cgen_expr(CGenerator *g, Expression *e) { case BUILTIN_COMPILING: cgen_write(g, "false"); break; + case BUILTIN_SIZEOF_SHORT: + case BUILTIN_SIZEOF_INT: + case BUILTIN_SIZEOF_LONG: + case BUILTIN_SIZEOF_LONG_LONG: + case BUILTIN_SIZEOF_FLOAT: + case BUILTIN_SIZEOF_DOUBLE: + case BUILTIN_SIZEOF_LONG_DOUBLE: + case BUILTIN_TSIZEOF_SHORT: + case BUILTIN_TSIZEOF_INT: + case BUILTIN_TSIZEOF_LONG: + case BUILTIN_TSIZEOF_LONG_LONG: + case BUILTIN_TSIZEOF_FLOAT: + case BUILTIN_TSIZEOF_DOUBLE: + case BUILTIN_TSIZEOF_LONG_DOUBLE: + case BUILTIN_SIZEOF_SIZE_T: + case BUILTIN_TSIZEOF_SIZE_T: { + Value val = get_builtin_val(e->builtin.which.val); + cgen_write(g, "%"I64_FMT, val.i64); + } break; } break; case EXPR_CAST: { diff --git a/eval.c b/eval.c index c617fd0..3d6cde6 100644 --- a/eval.c +++ b/eval.c @@ -10,7 +10,7 @@ static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v); static bool eval_expr(Evaluator *ev, Expression *e, Value *v); static bool block_enter(Block *b, Statement *stmts, U16 flags); static void block_exit(Block *b, Statement *stmts); -static void get_builtin_val(BuiltinVal val, Value *v); +static Value get_builtin_val(BuiltinVal val); static void evalr_create(Evaluator *ev, Typer *tr, Allocator *allocr) { ev->returning = NULL; @@ -1426,7 +1426,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { err_print(e->where, "Cannot run C code at compile time."); return false; case EXPR_BUILTIN: - get_builtin_val(e->builtin.which.val, v); + *v = get_builtin_val(e->builtin.which.val); break; case EXPR_NEW: /* it's not strictly necessary to do the if here */ diff --git a/identifiers.c b/identifiers.c index 5e0f531..10fe844 100644 --- a/identifiers.c +++ b/identifiers.c @@ -93,6 +93,12 @@ static Identifier ident_insert(Identifiers *ids, char **s) { } static char *ident_to_str(Identifier i) { + if (i->anonymous) { + char *s = malloc(4); + strcpy(s, "???"); + return s; + } + char *str = err_malloc(i->len + 1); /* for some reason, GCC thinks that i->len is -1 when this is called from type_to_str_ (in release mode) TODO: test this now (some stuff was changed) diff --git a/package.c b/package.c index b383117..f904405 100644 --- a/package.c +++ b/package.c @@ -169,7 +169,7 @@ static void export_location(Exporter *ex, Location where) { } static Location import_location(Importer *im) { Location l; - l.file = &im->importing_from; + l.file = im->importing_from; l.start = NULL; l.simple_location.line = (U32)import_vlq(im); return l; @@ -220,13 +220,14 @@ static void exptr_start(Exporter *ex, const char *pkg_name, size_t pkg_name_len) /* where = where was this imported. don't free fname while imported stuff is in use. */ static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname, ErrCtx *parent_ctx, Location where) { Importer i = {0}; - i.importing_from.filename = fname; - i.importing_from.ctx = parent_ctx; + i.allocr = allocr; + i.importing_from = imptr_calloc(&i, 1, sizeof *i.importing_from); + i.importing_from->filename = fname; + i.importing_from->ctx = parent_ctx; idents_create(&p->idents); i.pkg = p; i.in = f; i.import_location = where; - i.allocr = allocr; /* read header */ U8 toc[3]; toc[0] = import_u8(&i); @@ -255,7 +256,7 @@ static bool import_pkg(Allocator *allocr, Package *p, FILE *f, const char *fname if (has_code) { size_t code_len = import_len(&i); char *code = import_str(&i, code_len); - i.importing_from.contents = code; + i.importing_from->contents = code; } long decls_offset = ftell(f); fseek(f, (long)footer_offset, SEEK_SET); @@ -637,6 +638,7 @@ static bool export_expr(Exporter *ex, Expression *e) { export_u8(ex, (U8)e->flags); assert(e->kind < 256); export_u8(ex, (U8)e->kind); + export_location(ex, e->where); unsigned found_type = e->flags & EXPR_FOUND_TYPE; if (found_type) { if (!export_type(ex, &e->type, e->where)) @@ -813,6 +815,7 @@ static inline Expression *import_expr_(Importer *im) { static void import_expr(Importer *im, Expression *e) { e->flags = import_u8(im); e->kind = import_u8(im); + e->where = import_location(im); unsigned found_type = e->flags & EXPR_FOUND_TYPE; if (found_type) { import_type(im, &e->type); @@ -888,6 +891,7 @@ static void import_expr(Importer *im, Expression *e) { break; case EXPR_CALL: { CallExpr *c = &e->call; + memset(c, 0, sizeof *c); c->fn = import_expr_(im); if (found_type) { import_arr(im, &c->arg_exprs); @@ -1037,6 +1041,7 @@ static bool export_stmt(Exporter *ex, Statement *s) { possibly_static_assert(sizeof s->flags == 1); export_u8(ex, s->flags); export_u8(ex, (U8)s->kind); + export_location(ex, s->where); switch (s->kind) { case STMT_EXPR: if (!export_expr(ex, &s->expr)) @@ -1060,6 +1065,7 @@ static bool export_stmt(Exporter *ex, Statement *s) { static void import_stmt(Importer *im, Statement *s) { s->flags = import_u8(im); s->kind = import_u8(im); + s->where = import_location(im); switch (s->kind) { case STMT_EXPR: import_expr(im, &s->expr); @@ -1073,6 +1079,7 @@ static void import_stmt(Importer *im, Statement *s) { import_expr(im, &s->expr); break; } + fprint_stmt(stdout, s); printf("\n"); } static bool export_block(Exporter *ex, Block *b) { diff --git a/std/io.toc b/std/io.toc index ab3549b..f864c3c 100644 --- a/std/io.toc +++ b/std/io.toc @@ -1,10 +1,32 @@ pkg "io"; -c_putchar :: fn(i32) i32 = #foreign "putchar", "libc.so.6"; +get_type_with_size ::= fn(size :: i64) Type { + if size == 1 { i8 } + elif size == 2 { i16 } + elif size == 4 { i32 } + elif size == 8 { i64 } + else { f32 } +}; + +get_utype_with_size ::= fn(size :: i64) Type { + if size == 1 { u8 } + elif size == 2 { u16 } + elif size == 4 { u32 } + elif size == 8 { u64 } + else { f32 } +}; + +c_int ::= get_type_with_size(#builtin("sizeof int")); +c_size_t ::= get_utype_with_size(#builtin("sizeof size_t")); + +c_putchar :: fn(c_int) c_int = #foreign "putchar", "libc.so.6"; +toc_putchar ::= fn(x: char) { + c_putchar(x as c_int); +}; #export puts ::= fn(x: []char) { for c := x { - c_putchar(c as i32); + toc_putchar(c); }; - c_putchar('\n' as i32); + toc_putchar('\n'); }; \ No newline at end of file diff --git a/test.toc b/test.toc index 786bd03..7a3bf46 100644 --- a/test.toc +++ b/test.toc @@ -1,15 +1,9 @@ -Point ::= struct { - x, y : int; +io ::= pkg "std/io"; +hw ::= fn() int { + io.puts("Hello, world!"); + 3 }; - -p :: fn(Point) int = #foreign "p", "./test.so"; - -mkpoint ::= fn(x:int,y:int) p : Point { - p.x = x; - p.y = y; -}; - main ::= fn() { - point ::= mkpoint(-3,-5); - total ::= p(point); +x::=hw(); +hw(); }; \ No newline at end of file diff --git a/types.c b/types.c index 9108872..55c5e07 100644 --- a/types.c +++ b/types.c @@ -366,7 +366,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { */ arr_foreach(f->params, Declaration, param) { if (!(param->flags & DECL_IS_CONST)) { - char *s = type_to_str(ret_type); + char *s = type_to_str(&f->ret_type); warn_print(param->where, "Non-constant parameter in function which returns %s (which is a type which can only be used at run time).", s); free(s); break; @@ -927,21 +927,72 @@ static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Type *fn_type, A return true; } -static void get_builtin_val(BuiltinVal val, Value *v) { +static Value get_builtin_val(BuiltinVal val) { + Value v; switch (val) { case BUILTIN_STDOUT: - v->ptr = stdout; + v.ptr = stdout; break; case BUILTIN_STDERR: - v->ptr = stderr; + v.ptr = stderr; break; case BUILTIN_STDIN: - v->ptr = stdin; + v.ptr = stdin; break; case BUILTIN_COMPILING: - v->boolv = true; + v.boolv = true; + break; + case BUILTIN_SIZEOF_SHORT: + v.i64 = (I64)sizeof(short); + break; + case BUILTIN_SIZEOF_INT: + v.i64 = (I64)sizeof(int); + break; + case BUILTIN_SIZEOF_LONG: + v.i64 = (I64)sizeof(long); + break; + case BUILTIN_SIZEOF_LONG_LONG: + v.i64 = (I64)sizeof(long long); + break; + case BUILTIN_SIZEOF_FLOAT: + v.i64 = (I64)sizeof(float); + break; + case BUILTIN_SIZEOF_DOUBLE: + v.i64 = (I64)sizeof(double); + break; + case BUILTIN_SIZEOF_LONG_DOUBLE: + v.i64 = (I64)sizeof(long double); + break; + case BUILTIN_SIZEOF_SIZE_T: + v.i64 = (I64)sizeof(size_t); + break; + /* TODO(eventually): fix these for cross compilation */ + case BUILTIN_TSIZEOF_SHORT: + v.i64 = (I64)sizeof(short); + break; + case BUILTIN_TSIZEOF_INT: + v.i64 = (I64)sizeof(int); + break; + case BUILTIN_TSIZEOF_LONG: + v.i64 = (I64)sizeof(long); + break; + case BUILTIN_TSIZEOF_LONG_LONG: + v.i64 = (I64)sizeof(long long); + break; + case BUILTIN_TSIZEOF_FLOAT: + v.i64 = (I64)sizeof(float); + break; + case BUILTIN_TSIZEOF_DOUBLE: + v.i64 = (I64)sizeof(double); + break; + case BUILTIN_TSIZEOF_LONG_DOUBLE: + v.i64 = (I64)sizeof(long double); + break; + case BUILTIN_TSIZEOF_SIZE_T: + v.i64 =(I64)sizeof(size_t); break; } + return v; } static void get_builtin_val_type(Allocator *a, BuiltinVal val, Type *t) { @@ -961,6 +1012,25 @@ static void get_builtin_val_type(Allocator *a, BuiltinVal val, Type *t) { t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_BOOL; break; + case BUILTIN_SIZEOF_SHORT: + case BUILTIN_SIZEOF_INT: + case BUILTIN_SIZEOF_LONG: + case BUILTIN_SIZEOF_LONG_LONG: + case BUILTIN_SIZEOF_FLOAT: + case BUILTIN_SIZEOF_DOUBLE: + case BUILTIN_SIZEOF_LONG_DOUBLE: + case BUILTIN_TSIZEOF_SHORT: + case BUILTIN_TSIZEOF_INT: + case BUILTIN_TSIZEOF_LONG: + case BUILTIN_TSIZEOF_LONG_LONG: + case BUILTIN_TSIZEOF_FLOAT: + case BUILTIN_TSIZEOF_DOUBLE: + case BUILTIN_TSIZEOF_LONG_DOUBLE: + case BUILTIN_SIZEOF_SIZE_T: + case BUILTIN_TSIZEOF_SIZE_T: + t->kind = TYPE_BUILTIN; + t->builtin = BUILTIN_I64; + break; } } diff --git a/types.h b/types.h index 3b89e49..c218bf3 100644 --- a/types.h +++ b/types.h @@ -679,11 +679,32 @@ typedef enum { BUILTIN_STDOUT, BUILTIN_STDERR, BUILTIN_STDIN, + BUILTIN_SIZEOF_SHORT, + BUILTIN_TSIZEOF_SHORT, /* target sizeof(short) */ + BUILTIN_SIZEOF_INT, + BUILTIN_TSIZEOF_INT, + BUILTIN_SIZEOF_LONG, + BUILTIN_TSIZEOF_LONG, + BUILTIN_SIZEOF_LONG_LONG, + BUILTIN_TSIZEOF_LONG_LONG, + BUILTIN_SIZEOF_SIZE_T, + BUILTIN_TSIZEOF_SIZE_T, + BUILTIN_SIZEOF_FLOAT, + BUILTIN_TSIZEOF_FLOAT, + BUILTIN_SIZEOF_DOUBLE, + BUILTIN_TSIZEOF_DOUBLE, + BUILTIN_SIZEOF_LONG_DOUBLE, + BUILTIN_TSIZEOF_LONG_DOUBLE, BUILTIN_COMPILING #define BUILTIN_VAL_COUNT (BUILTIN_COMPILING+1) } BuiltinVal; -const char *const builtin_val_names[BUILTIN_VAL_COUNT] = {"stdout", "stderr", "stdin", "compiling"}; +const char *const builtin_val_names[BUILTIN_VAL_COUNT] = + {"stdout", "stderr", "stdin", "sizeof short", "target sizeof short", + "sizeof int", "target sizeof int", "sizeof long", "target sizeof long", + "sizeof long long", "target sizeof long long", "sizeof size_t", "target sizeof size_t", + "sizeof float", "target sizeof float", "sizeof double", "target sizeof double", + "sizeof long double", "target sizeof long double", "compiling"}; enum { EXPR_FOUND_TYPE = 0x01 @@ -904,7 +925,7 @@ typedef struct Exporter { typedef struct Importer { FILE *in; - File importing_from; + File *importing_from; Package *pkg; Allocator *allocr; Identifier *ident_map; /* [i] = value of identifier with ID i */ -- cgit v1.2.3