summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-19 13:33:57 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-19 13:33:57 -0400
commitbfd0a7f6fbf22914631337b3871011f452d3fb94 (patch)
tree1550849f77516ac252bbfc95d54da6e6611e0fb7
parent867b25643fc182d0db6045ecc5ca70b6b127b529 (diff)
parameters passed as pointers
-rw-r--r--cgen.c74
-rw-r--r--decls_cgen.c5
-rw-r--r--main.c8
-rw-r--r--out.c37
-rw-r--r--test.toc22
-rw-r--r--types.c11
-rw-r--r--types.h1
7 files changed, 99 insertions, 59 deletions
diff --git a/cgen.c b/cgen.c
index 3c0c501..ff389e1 100644
--- a/cgen.c
+++ b/cgen.c
@@ -18,7 +18,7 @@ static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *e
g->anon_fns = NULL;
}
-static void cgen_block_enter(CGenerator *g, Block *b) {
+static bool cgen_block_enter(CGenerator *g, Block *b) {
g->block = b;
Statement *stmts;
if (b == NULL) {
@@ -27,7 +27,7 @@ static void cgen_block_enter(CGenerator *g, Block *b) {
stmts = b->stmts;
}
if (b) g->indent_lvl++;
- block_enter(b, stmts);
+ return block_enter(b, stmts);
}
static void cgen_block_exit(CGenerator *g, Block *into) {
@@ -106,7 +106,12 @@ static void cgen_ident(CGenerator *g, Identifier i) {
cgen_write(g, "main__");
} else {
cgen_indent(g);
+ IdentDecl *idecl = ident_decl(i);
+ if (idecl->flags & IDECL_FLAG_CGEN_PTR)
+ cgen_write(g, "(*");
fprint_ident(cgen_writing_to(g), i);
+ if (idecl->flags & IDECL_FLAG_CGEN_PTR)
+ cgen_write(g, ")");
}
}
@@ -202,17 +207,33 @@ static bool cgen_type_post(CGenerator *g, Type *t, Location where) {
cgen_write(g, ", ");
if (!cgen_type_pre(g, &t->fn.types[i], where))
return false;
+ if (cgen_uses_ptr(&t->fn.types[i]))
+ cgen_write(g, "(*)");
if (!cgen_type_post(g, &t->fn.types[i], where))
return false;
}
if (out_param) {
+ Type *ret_type = &t->fn.types[0];
if (arr_len(t->fn.types) > 1)
cgen_write(g, ", ");
- if (!cgen_type_pre(g, &t->fn.types[0], where))
- return false;
- cgen_write(g, "(*)");
- if (!cgen_type_post(g, &t->fn.types[0], where))
- return false;
+ if (ret_type->kind == TYPE_TUPLE) {
+ arr_foreach(ret_type->tuple, Type, x) {
+ if (!cgen_type_pre(g, x, where))
+ return false;
+ cgen_write(g, "(*)");
+ if (!cgen_type_post(g, x, where))
+ return false;
+ if (x != arr_last(ret_type->tuple)) {
+ cgen_write(g, ", ");
+ }
+ }
+ } else {
+ if (!cgen_type_pre(g, ret_type, where))
+ return false;
+ cgen_write(g, "(*)");
+ if (!cgen_type_post(g, ret_type, where))
+ return false;
+ }
}
if (arr_len(t->fn.types) == 1 && !out_param)
cgen_write(g, "void");
@@ -261,6 +282,14 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) {
if (!cgen_type_pre(g, &d->type, where))
return false;
cgen_write(g, " ");
+ bool ptr = cgen_uses_ptr(&d->type);
+ if (ptr) {
+ fprint_type(stdout, &d->type);
+ puts("");
+ IdentDecl *idecl = ident_decl(*i);
+ assert(idecl);
+ idecl->flags |= IDECL_FLAG_CGEN_PTR;
+ }
cgen_ident(g, *i);
if (!cgen_type_post(g, &d->type, where))
return false;
@@ -340,20 +369,20 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E
cgen_write(g, "(*arr__in)");
if (!cgen_type_post(g, type->arr.of, where)) return false;
cgen_write(g, " = ");
- if (set_expr) {
- if (!cgen_expr(g, set_expr)) return false;
+ if (to_expr) {
+ if (!cgen_expr(g, to_expr)) return false;
} else {
- cgen_write(g, set_str);
+ cgen_write(g, to_str);
}
cgen_write(g, "; ");
if (!cgen_type_pre(g, type->arr.of, where)) return false;
cgen_write(g, "(*arr__out)");
if (!cgen_type_post(g, type->arr.of, where)) return false;
cgen_write(g, " = ");
- if (to_expr) {
- if (!cgen_expr(g, to_expr)) return false;
+ if (set_expr) {
+ if (!cgen_expr(g, set_expr)) return false;
} else {
- cgen_write(g, to_str);
+ cgen_write(g, set_str);
}
cgen_write(g, ";");
cgen_nl(g);
@@ -404,6 +433,8 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
arr_foreach(to->call.arg_exprs, Expression, arg) {
if (arg != to->call.arg_exprs)
cgen_write(g, ", ");
+ if (cgen_uses_ptr(&arg->type))
+ cgen_write(g, "&");
if (!cgen_expr(g, arg))
return false;
}
@@ -720,7 +751,11 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
cgen_write(g, ")(");
if (!cgen_expr(g, e->cast.expr))
return false;
- cgen_write(g, "))");
+ cgen_write(g, ")");
+ if (e->cast.expr->type.kind == TYPE_SLICE
+ && e->cast.type.kind != TYPE_SLICE) /* casting from a slice to a non-slice */
+ cgen_write(g, ".data");
+ cgen_write(g, ")");
break;
case EXPR_TUPLE:
/* the only time this should happen is if you're stating
@@ -747,7 +782,8 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
static bool cgen_block(CGenerator *g, Block *b, const char *ret_name) {
Block *prev = g->block;
cgen_write(g, "{");
- cgen_block_enter(g, b);
+ if (!cgen_block_enter(g, b))
+ return false;
cgen_nl(g);
arr_foreach(b->stmts, Statement, s)
if (!cgen_stmt(g, s))
@@ -794,6 +830,7 @@ static void cgen_zero_value(CGenerator *g, Type *t) {
}
static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) {
+ fn_enter(f);
if (!cgen_fn_header(g, f, where))
return false;
cgen_write(g, " ");
@@ -802,7 +839,8 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) {
cgen_write(g, "{");
cgen_nl(g);
arr_foreach(f->ret_decls, Declaration, d) {
- cgen_decl(g, d);
+ if (!cgen_decl(g, d))
+ return false;
}
if (!cgen_block(g, &f->body, NULL))
return false;
@@ -818,6 +856,7 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) {
}
cgen_write(g, "}");
+ fn_exit(f);
cgen_nl(g);
g->fn = prev_fn;
cgen_nl(g);
@@ -936,6 +975,7 @@ static bool cgen_stmt(CGenerator *g, Statement *s) {
static bool cgen_decls_file(CGenerator *g, ParsedFile *f);
static bool cgen_file(CGenerator *g, ParsedFile *f) {
+ g->block = NULL;
g->file = f;
cgen_write(g, "#include <stdint.h>\n"
"#include <stdlib.h>\n"
@@ -953,11 +993,9 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) {
"typedef struct { void *data; u64 n; } slice_;\n"
"#define false ((bool)0)\n"
"#define true ((bool)1)\n\n\n");
- cgen_block_enter(g, NULL);
if (!cgen_decls_file(g, f))
return false;
cgen_write(g, "/* code */\n");
- cgen_block_exit(g, NULL);
cgen_write(g, "int main() {\n\tmain__();\n\treturn 0;\n}\n\n");
arr_foreach(f->stmts, Statement, s)
diff --git a/decls_cgen.c b/decls_cgen.c
index 990a21b..ca29bfc 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -74,7 +74,8 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) {
static bool cgen_decls_block(CGenerator *g, Block *b) {
Block *prev = g->block;
- cgen_block_enter(g, b);
+ if (!cgen_block_enter(g, b))
+ return false;
arr_foreach(b->stmts, Statement, s)
cgen_decls_stmt(g, s);
cgen_block_exit(g, prev);
@@ -84,12 +85,14 @@ static bool cgen_decls_block(CGenerator *g, Block *b) {
static bool cgen_decls_decl(CGenerator *g, Declaration *d) {
if (cgen_fn_is_direct(g, d)) {
d->expr.fn.c.name = d->idents[0];
+ fn_enter(&d->expr.fn);
if (!cgen_fn_header(g, &d->expr.fn, d->where))
return false;
cgen_write(g, ";");
cgen_nl(g);
if (!cgen_decls_block(g, &d->expr.fn.body))
return false;
+ fn_exit(&d->expr.fn);
} else if (d->flags & DECL_FLAG_HAS_EXPR) {
if (!cgen_decls_expr(g, &d->expr))
return false;
diff --git a/main.c b/main.c
index 92a207c..ee75bc4 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,5 @@
/*
TODO:
-fix casting for slice => ptr/arr
-parameters can be passed as pointers
new returns a *slice*
unicode variable names
make sure initializers for global variables are compile-time constants
@@ -77,6 +75,10 @@ int main(int argc, char **argv) {
Evaluator ev;
evalr_create(&ev);
typer_create(&tr, &ev);
+
+ if (!block_enter(NULL, f.stmts)) /* enter global scope */
+ return false;
+
if (!types_file(&tr, &f)) {
err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n"));
return EXIT_FAILURE;
@@ -93,6 +95,8 @@ int main(int argc, char **argv) {
cgen_create(&g, out, &file_idents, &ev);
cgen_file(&g, &f);
+ block_exit(NULL, f.stmts); /* exit global scope */
+
tokr_free(&t);
free(contents);
diff --git a/out.c b/out.c
index de9c865..450acad 100644
--- a/out.c
+++ b/out.c
@@ -18,6 +18,7 @@ typedef struct { void *data; u64 n; } slice_;
/* declarations */
void puti(i64 x);
+void asdf(i64( (*x)[3]), i64 y, i64(*ret0_), i64((*ret1_)[3]));
void main__(void);
/* code */
int main() {
@@ -33,25 +34,27 @@ void puti(i64 x) {
}}
+void asdf(i64( (*x)[3]), i64 y, i64(*ret0_), i64((*ret1_)[3])) {
+{
+}(*ret0_) = y;{
+size_t i;i64(*arr__in) = (*x); i64(*arr__out) = (*ret1_);
+for (i = 0; i < 3; i++) arr__out[i] = arr__in[i];
+}return;
+}
+
+
void main__(void) {
{
- i64 a0_0_; i64 a0_1_; if (0) {
- (a0_0_) = 3;(a0_1_) = 5;
- } else {
- (a0_0_) = 4;(a0_1_) = 6;
- }i64 A; i64 B; (A) = a0_0_; (B) = a0_1_;
- (puti(A));
- (puti(B));
- i64 y = 0;
- while ((y<10)) {
- i64 a2_;
- {
- y = (y+1);;
- a2_ = y;
- }(puti(a2_));
- };
- slice_ foo = {NULL, 0};
- slice_ bar = {NULL, 0};
+ i64( a[3]) = {0};
+ i64 b = 0;
+ (a[0]) = 17;;
+ b = 5489;;
+ i64 c; i64( d[3]); asdf(&a, b, &c, &d);
+
+ (puti(c));
+ (puti((d[0])));
+ void (* asdfasdf)(i64((*)[3]), i64, i64(*), i64((*)[3])); {
+ void (* expr__)(i64((*)[3]), i64, i64(*), i64((*)[3])); expr__ = asdf;asdfasdf = expr__;}
}}
diff --git a/test.toc b/test.toc
index 6bb39f3..d21f355 100644
--- a/test.toc
+++ b/test.toc
@@ -4,16 +4,16 @@ puti @= fn(x: int) {
#C("printf(\"%ld\\n\", (long)x)");
};
+asdf @= fn(x: [3]int, y : int) (int, [3]int) {
+ y, x
+};
+
main @= fn() {
- A, B := if 0 { 3, 5 } else { 4, 6 };
- // A, B := 3, 5;
- puti(A);
- puti(B);
- y:int;
- while y < 10 {
- puti({y = y + 1; y});
- }
- foo : []int;
- bar : []float;
-
+ a : [3]int;
+ b : int;
+ a[0] = 17;
+ b = 5489;
+ c, d := asdf(a, b);
+ puti(c); puti(d[0]);
+ asdfasdf := asdf;
}; \ No newline at end of file
diff --git a/types.c b/types.c
index cedc75d..387edef 100644
--- a/types.c
+++ b/types.c
@@ -471,22 +471,16 @@ static Status type_cast_status(Type *from, Type *to) {
return STATUS_WARN;
if (to->kind == TYPE_PTR)
return STATUS_NONE;
- if (to->kind == TYPE_ARR && type_eq(from->ptr, to->arr.of))
- return STATUS_NONE;
if (to->kind == TYPE_FN)
return STATUS_WARN;
return STATUS_ERR;
case TYPE_ARR:
if (to->kind == TYPE_PTR && type_eq(from->arr.of, to->ptr))
return STATUS_NONE;
- if (to->kind == TYPE_ARR && !type_eq(from, to))
- return STATUS_WARN;
return STATUS_ERR;
case TYPE_SLICE:
if (to->kind == TYPE_PTR && type_eq(from->slice, to->ptr))
return STATUS_NONE;
- if (to->kind == TYPE_ARR && type_eq(from->slice, to->arr.of))
- return STATUS_NONE;
return STATUS_ERR;
}
assert(0);
@@ -1171,14 +1165,11 @@ static void typer_create(Typer *tr, Evaluator *ev) {
static bool types_file(Typer *tr, ParsedFile *f) {
bool ret = true;
- if (!block_enter(NULL, f->stmts)) /* enter global scope */
- return false;
arr_foreach(f->stmts, Statement, s) {
if (!types_stmt(tr, s)) {
ret = false;
}
- }
- block_exit(NULL, f->stmts); /* exit global scope */
+ }
return ret;
}
diff --git a/types.h b/types.h
index 182e80d..1c5aaa4 100644
--- a/types.h
+++ b/types.h
@@ -84,6 +84,7 @@ typedef union Value {
} Value;
#define IDECL_FLAG_HAS_VAL 0x01
+#define IDECL_FLAG_CGEN_PTR 0x02 /* is a pointer being used for this identifier? */
typedef struct {
struct Declaration *decl;
struct Block *scope; /* NULL for file scope */