summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c21
-rw-r--r--eval.c4
-rw-r--r--identifiers.c6
-rw-r--r--package.c17
-rw-r--r--std/io.toc28
-rw-r--r--test.toc18
-rw-r--r--types.c82
-rw-r--r--types.h25
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 */