summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c103
-rw-r--r--main.c3
-rw-r--r--parse.c2
-rw-r--r--test.toc20
4 files changed, 76 insertions, 52 deletions
diff --git a/cgen.c b/cgen.c
index 31d9467..ed9a836 100644
--- a/cgen.c
+++ b/cgen.c
@@ -231,7 +231,7 @@ static inline char *cgen_ident_to_str(Identifier i) {
}
static inline void cgen_ident_id(CGenerator *g, IdentID id) {
- cgen_write(g, "a%lu_", (unsigned long)id);
+ cgen_write(g, "_a%lu", (unsigned long)id);
}
/* used for fields */
static inline void cgen_ident_simple(CGenerator *g, Identifier i) {
@@ -252,7 +252,7 @@ static void cgen_ident(CGenerator *g, Identifier i) {
}
if (i == g->main_ident && i->decl_kind == IDECL_DECL && ident_scope(i) == NULL) {
/* don't conflict with C's main! */
- cgen_write(g, "main__");
+ cgen_write(g, "_main");
} else {
cgen_ident_simple(g, i);
}
@@ -262,7 +262,7 @@ static void cgen_ident(CGenerator *g, Identifier i) {
#define CGEN_IDENT_ID_STR_SIZE 32
/* buffer should be at least CGEN_IDENT_ID_STR_SIZE bytes */
static inline void cgen_ident_id_to_str(char *buffer, IdentID id) {
- snprintf(buffer, CGEN_IDENT_ID_STR_SIZE, "a%lu_", (unsigned long)id);
+ snprintf(buffer, CGEN_IDENT_ID_STR_SIZE, "_a%lu", (unsigned long)id);
}
static char *cgen_nms_prefix(CGenerator *g, Namespace *n) {
@@ -392,7 +392,7 @@ static bool cgen_type_pre(CGenerator *g, Type *t, Location where) {
cgen_write(g, " (*");
break;
case TYPE_SLICE:
- cgen_write(g, "slice_");
+ cgen_write(g, "_slice");
break;
case TYPE_VOID: cgen_write(g, "void"); break;
case TYPE_UNKNOWN:
@@ -548,7 +548,7 @@ static bool cgen_fn_args(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_c
if (any_params || i > 0)
cgen_write(g, ", ");
if (!cgen_type_pre(g, x, f->where)) return false;
- cgen_write(g, "(*ret%lu_)", (unsigned long)i);
+ cgen_write(g, "(*_ret%lu)", (unsigned long)i);
if (!cgen_type_post(g, x, f->where)) return false;
}
} else {
@@ -556,7 +556,7 @@ static bool cgen_fn_args(CGenerator *g, FnExpr *f, U64 instance, U64 which_are_c
cgen_write(g, ", ");
if (!cgen_type_pre(g, &f->ret_type, f->where))
return false;
- cgen_write(g, " (*ret_)");
+ cgen_write(g, " (*_ret)");
if (!cgen_type_post(g, &f->ret_type, f->where))
return false;
}
@@ -721,7 +721,7 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
else if (exprs)
e = &exprs[i];
else {
- snprintf(buf, sizeof buf, "(%s%lu_)", prefix, (unsigned long)i);
+ snprintf(buf, sizeof buf, "(%s%lu)", prefix, (unsigned long)i);
s = buf;
}
if (!cgen_set(g, e, s, &to->tuple[i], NULL)) return false;
@@ -729,8 +729,33 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
}
break;
case EXPR_CALL: {
- Constness *constness = to->call.fn->type.fn.constness;
+ FnType *fn_type = &to->call.fn->type.fn;
+ Type *ret_type = &fn_type->types[0];
+ Constness *constness = fn_type->constness;
int i = 0;
+
+ IdentID *underscore_ids = NULL;
+
+
+ int nout_params = (int)(exprs ? arr_len(exprs) : arr_len(idents));
+
+ if (idents) {
+ for (i = 0; i < nout_params; ++i) {
+ if (ident_eq_str(idents[i], "_")) {
+ Type *type = &ret_type->tuple[i];
+ IdentID id = ++g->ident_counter;
+ if (!cgen_type_pre(g, type, to->call.fn->where))
+ return false;
+ cgen_write(g, " ");
+ cgen_ident_id(g, id);
+ if (!cgen_type_post(g, type, to->call.fn->where))
+ return false;
+ cgen_write(g, "; ");
+ *(IdentID *)arr_add(&underscore_ids) = id;
+ }
+ }
+ }
+
/* e.g. a, b = fn_which_returns_tuple(); */
arr_foreach(to->call.arg_exprs, Expression, arg) {
if (!constness || !arg_is_const(arg, constness[i])) {
@@ -738,6 +763,7 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
return false;
}
}
+
if (!cgen_expr_pre(g, to->call.fn)) return false;
if (!cgen_expr(g, to->call.fn)) return false;
@@ -757,9 +783,8 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
++i;
}
/* out params */
- size_t len = exprs ? arr_len(exprs) : arr_len(idents);
-
- for (i = 0; i < (int)len; ++i) {
+ IdentID *u = underscore_ids;
+ for (i = 0; i < (int)nout_params; ++i) {
if (any_args || i > 0)
cgen_write(g, ", ");
if (exprs) {
@@ -768,11 +793,15 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
return false;
} else if (idents) {
cgen_write(g, "&");
- cgen_ident(g, idents[i]);
+ if (ident_eq_str(idents[i], "_"))
+ cgen_ident_id(g, *u++);
+ else
+ cgen_ident(g, idents[i]);
} else {
- cgen_write(g, "&(%s%d_)", prefix, i);
+ cgen_write(g, "&(_%s%d)", prefix, i);
}
}
+ arr_clear(&underscore_ids);
cgen_writeln(g, "); ");
} break;
case EXPR_IF:
@@ -793,11 +822,11 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
} else if (idents) {
cgen_ident(g, idents[i]);
} else {
- cgen_write(g, "%s%lu_", prefix, i);
+ cgen_write(g, "%s%lu", prefix, i);
}
cgen_write(g, ") = ");
cgen_ident_id(g, prefix_id);
- cgen_write(g, "%lu_", i);
+ cgen_write(g, "%lu", i);
cgen_write(g, "; ");
}
} break;
@@ -826,7 +855,7 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
static bool cgen_expr_pre(CGenerator *g, Expression *e) {
IdentID id = 0;
- char ret_name[CGEN_IDENT_ID_STR_SIZE];
+ char ret_name[CGEN_IDENT_ID_STR_SIZE+20];
switch (e->kind) {
case EXPR_IF:
case EXPR_WHILE:
@@ -839,7 +868,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) {
if (e->type.kind != TYPE_VOID) {
if (e->type.kind == TYPE_TUPLE) {
for (unsigned long i = 0; i < arr_len(e->type.tuple); ++i) {
- sprintf(p, "%lu_", i);
+ sprintf(p, "%lu", i);
if (!cgen_type_pre(g, &e->type.tuple[i], e->where)) return false;
cgen_write(g, " %s", ret_name);
if (!cgen_type_post(g, &e->type.tuple[i], e->where)) return false;
@@ -1184,15 +1213,15 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) {
return false;
if (s->to && !cgen_expr_pre(g, s->to))
return false;
- cgen_write(g, "slice_ ");
+ cgen_write(g, "_slice ");
cgen_ident_id(g, s_id);
- cgen_write(g, "; { slice_ of__ = ");
+ cgen_write(g, "; { _slice of__ = ");
if (s->of->type.kind == TYPE_SLICE) {
if (!cgen_expr(g, s->of))
return false;
} else {
assert(s->of->type.kind == TYPE_ARR);
- cgen_write(g, "mkslice_(");
+ cgen_write(g, "_mkslice(");
if (!cgen_expr(g, s->of))
return false;
cgen_write(g, ", " U64_FMT, s->of->type.arr.n);
@@ -1300,7 +1329,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
break;
case EXPR_LITERAL_STR: {
char *p = e->strl.str;
- cgen_write(g, "mkslice_(\"");
+ cgen_write(g, "_mkslice(\"");
for (size_t i = 0; i < e->strl.len; ++i, ++p) {
if (isprint(*p) && *p != '"')
cgen_write(g, "%c", *p);
@@ -1462,7 +1491,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
case UNARY_NOT:
s = "!"; break;
case UNARY_DEL:
- cgen_write(g, "free_(");
+ cgen_write(g, "_free(");
if (!cgen_expr(g, e->unary.of))
return false;
if (of_type->kind == TYPE_SLICE)
@@ -1502,7 +1531,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
} break;
case EXPR_NEW: {
if (e->new.n) {
- cgen_write(g, "mkslice_(e__calloc(");
+ cgen_write(g, "_mkslice(_ecalloc(");
if (!cgen_expr(g, e->new.n)) return false;
cgen_write(g, ", (i64)sizeof(");
if (!cgen_type_pre(g, &e->new.type, e->where)) return false;
@@ -1517,7 +1546,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
return false;
if (!cgen_type_post(g, &e->type, e->where))
return false;
- cgen_write(g, ")e__calloc(1, sizeof(");
+ cgen_write(g, ")_ecalloc(1, sizeof(");
if (!cgen_type_pre(g, t, e->where))
return false;
if (!cgen_type_post(g, t, e->where))
@@ -1926,6 +1955,7 @@ static bool cgen_decl(CGenerator *g, Declaration *d) {
int nidents = (int)arr_len(d->idents);
for (int idx = 0; idx < nidents; ++idx) {
Identifier i = d->idents[idx];
+ if (ident_eq_str(i, "_")) continue;
Type *type = decl_type_at_index(d, idx);
if (!cgen_type_pre(g, type, d->where)) return false;
cgen_write(g, " ");
@@ -1949,10 +1979,10 @@ static bool cgen_decl(CGenerator *g, Declaration *d) {
cgen_write(g, "{");
cgen_nl(g);
if (!cgen_type_pre(g, &d->type, d->expr.where)) return false;
- cgen_write(g, " expr__");
+ cgen_write(g, " _expr");
if (!cgen_type_post(g, &d->type, d->expr.where)) return false;
cgen_write(g, "; ");
- if (!cgen_set(g, NULL, "expr__", &d->expr, NULL))
+ if (!cgen_set(g, NULL, "_expr", &d->expr, NULL))
return false;
arr_foreach(d->idents, Identifier, i) {
@@ -1961,7 +1991,7 @@ static bool cgen_decl(CGenerator *g, Declaration *d) {
e.kind = EXPR_IDENT;
e.type = d->type;
e.ident = *i;
- if (!cgen_set(g, &e, NULL, NULL, "expr__"))
+ if (!cgen_set(g, &e, NULL, NULL, "_expr"))
return false;
}
cgen_write(g, "}");
@@ -1987,7 +2017,6 @@ static bool cgen_ret(CGenerator *g, Expression *ret) {
if (f->ret_decls) {
assert(!ret);
if (f->ret_type.kind == TYPE_TUPLE) {
- /* TODO TODO */
Expression ret_expr = {0};
ret_expr.flags = EXPR_FOUND_TYPE;
ret_expr.type = f->ret_type;
@@ -2005,7 +2034,7 @@ static bool cgen_ret(CGenerator *g, Expression *ret) {
++idx;
}
}
- bool success = cgen_set_tuple(g, NULL, NULL, "*ret", &ret_expr);
+ bool success = cgen_set_tuple(g, NULL, NULL, "*_ret", &ret_expr);
arr_clear(&ret_expr.tuple);
if (!success)
return false;
@@ -2015,7 +2044,7 @@ static bool cgen_ret(CGenerator *g, Expression *ret) {
ret_expr.type = f->ret_type;
ret_expr.kind = EXPR_IDENT;
ret_expr.ident = f->ret_decls[0].idents[0];
- if (!cgen_set(g, NULL, "*ret_", &ret_expr, NULL)) {
+ if (!cgen_set(g, NULL, "*_ret", &ret_expr, NULL)) {
return false;
}
cgen_writeln(g, ";");
@@ -2036,10 +2065,10 @@ static bool cgen_ret(CGenerator *g, Expression *ret) {
cgen_write(g, "return");
} else if (cgen_uses_ptr(&f->ret_type)) {
if (f->ret_type.kind == TYPE_TUPLE) {
- if (!cgen_set_tuple(g, NULL, NULL, "*ret", ret))
+ if (!cgen_set_tuple(g, NULL, NULL, "*_ret", ret))
return false;
} else {
- if (!cgen_set(g, NULL, "*ret_", ret, NULL)) return false;
+ if (!cgen_set(g, NULL, "*_ret", ret, NULL)) return false;
}
cgen_write(g, " return");
} else {
@@ -2194,19 +2223,19 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) {
"typedef float f32;\n"
"typedef double f64;\n"
"typedef u8 bool;\n"
- "typedef struct { void *data; i64 n; } slice_;\n"
+ "typedef struct { void *data; i64 n; } _slice;\n"
"#define false ((bool)0)\n"
"#define true ((bool)1)\n"
- "static slice_ mkslice_(void *data, i64 n) { slice_ ret; ret.data = data; ret.n = n; return ret; }\n"
- "static void free_(void *data) { extern void free(void *data); free(data); }\n" /* don't introduce free to global namespace */
- "static void *e__calloc(size_t n, size_t sz) { extern void *calloc(size_t n, size_t size); extern void abort(void); extern int printf(const char *fmt, ...); void *ret = calloc(n, sz); if (n && sz && !ret) { printf(\"Out of memory.\\n\"); abort(); } return ret; }\n\n\n");
+ "static _slice _mkslice(void *data, i64 n) { _slice ret; ret.data = data; ret.n = n; return ret; }\n"
+ "static void _free(void *data) { extern void free(void *data); free(data); }\n" /* don't introduce free to global namespace */
+ "static void *_ecalloc(size_t n, size_t sz) { extern void *calloc(size_t n, size_t size); extern void abort(void); extern int printf(const char *fmt, ...); void *ret = calloc(n, sz); if (n && sz && !ret) { printf(\"Out of memory.\\n\"); abort(); } return ret; }\n\n\n");
if (!cgen_sdecls_file(g, f))
return false;
if (!cgen_decls_file(g, f))
return false;
cgen_write(g, "/* code */\n");
- cgen_write(g, "int main() {\n\tmain__();\n\treturn 0;\n}\n\n");
+ cgen_write(g, "int main() {\n\t_main();\n\treturn 0;\n}\n\n");
arr_foreach(f->stmts, Statement, s) {
if (!cgen_defs_stmt(g, s))
return false;
diff --git a/main.c b/main.c
index cead9b5..262f6c4 100644
--- a/main.c
+++ b/main.c
@@ -18,7 +18,8 @@
/*
TODO:
-foo, _ := bar();
+make sure we're checking for redecls with #include
+
nice syntax for #including something into a namespace
run stuff at compile time without assigning it to a constant
the problem of #foreign stuff currently requiring that source and target have the same sizeof(int), etc. -- we may need #C_int, etc.
diff --git a/parse.c b/parse.c
index a521ae1..8a23ac0 100644
--- a/parse.c
+++ b/parse.c
@@ -1948,7 +1948,7 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla
goto ret_false;
}
*ident = parser_ident_insert(p, t->token->ident);
- {
+ if (!ident_eq_str(*ident, "_")) {
Identifier i = *ident;
if (!check_ident_redecl(p, i))
goto ret_false;
diff --git a/test.toc b/test.toc
index 88b4e63..8eed5b7 100644
--- a/test.toc
+++ b/test.toc
@@ -1,19 +1,13 @@
-// io ::= nms {
-// #include "std/io.toc";
-// };
-
-FOO ::= fn(t::Type) Type {
- &ll(int)
+io ::= nms {
+#include "std/io.toc";
};
-ll ::= struct(t::Type) {
- head: t;
- tail: FOO(t);
+foo ::= fn() <int, int> {
+ 3, 5
};
main ::= fn() {
- l:ll(int);
- m:ll(i16);
- x::=#alignof(l);
- y::=#alignof(m);
+ _, x := foo();
+ y, _ := foo();
+ io.puti(x); io.puti(y);
}; \ No newline at end of file