summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c19
-rw-r--r--data_structures.c7
-rw-r--r--eval.c24
-rw-r--r--main.c1
-rw-r--r--test.toc33
-rw-r--r--types.c19
-rw-r--r--types.h9
7 files changed, 95 insertions, 17 deletions
diff --git a/cgen.c b/cgen.c
index 1c26ac2..0de47dd 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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) {
diff --git a/eval.c b/eval.c
index bc97a3e..1c682ff 100644
--- a/eval.c
+++ b/eval.c
@@ -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);
diff --git a/main.c b/main.c
index 7f2dce3..0bc34e1 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/test.toc b/test.toc
index 38fc2df..e14881f 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/types.c b/types.c
index 22f8648..b5cfad9 100644
--- a/types.c
+++ b/types.c
@@ -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;
}
}
diff --git a/types.h b/types.h
index a32c9a0..9667647 100644
--- a/types.h
+++ b/types.h
@@ -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