summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-01 12:21:50 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-01 12:21:50 -0500
commit88e7c92e76ce771e7a1efd4824060e3905194070 (patch)
tree04b36c981e662cb2c4a4db364dc36b3e8dd7164a
parentda748748c0239c21b9d62c77b51e269ad1d7de9f (diff)
casting to #C types
-rw-r--r--cgen.c8
-rw-r--r--decls_cgen.c27
-rw-r--r--parse.c14
-rw-r--r--std/io.toc27
-rw-r--r--test.toc1
-rw-r--r--types.c6
6 files changed, 49 insertions, 34 deletions
diff --git a/cgen.c b/cgen.c
index fb10a0e..9a45984 100644
--- a/cgen.c
+++ b/cgen.c
@@ -78,7 +78,10 @@ static void cgen_defs_decl(CGenerator *g, Declaration *d);
block_f(g, &e->block); \
break; \
case EXPR_NMS: { \
+ Namespace *prev = g->nms; \
+ g->nms = &e->nms; \
block_f(g, &e->nms.body); \
+ g->nms = prev; \
} break; \
case EXPR_IF: \
if (e->if_.cond) \
@@ -1896,10 +1899,11 @@ static void cgen_stmt(CGenerator *g, Statement *s) {
cgen_decl(g, s->decl);
break;
case STMT_EXPR:
- if (g->block != NULL && !type_is_compileonly(&s->expr.type)) {
+ if ((g->block != NULL || s->expr.kind == EXPR_C) && !type_is_compileonly(&s->expr.type)) {
cgen_expr_pre(g, &s->expr);
cgen_expr(g, &s->expr);
- cgen_writeln(g, ";");
+ if (s->expr.kind != EXPR_C)
+ cgen_writeln(g, ";");
}
break;
case STMT_RET: {
diff --git a/decls_cgen.c b/decls_cgen.c
index b5dbec0..e026584 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -136,13 +136,30 @@ static void cgen_fn_decl(CGenerator *g, FnExpr *f, Type *t) {
if (ctypes[0].kind == CTYPE_NONE)
cgen_type_post(g, &fn_types[0], f->where);
cgen_write(g, ";");
- if (!f->c.name || !ident_eq_str(f->c.name, foreign_name)) {
+ if (!f->c.name || !ident_eq_str(f->c.name, foreign_name) || g->nms != NULL) {
cgen_write(g, "static ");
- cgen_type_pre(g, t, f->where);
- cgen_write(g, " const ");
+ if (ctypes[0].kind == CTYPE_NONE) {
+ cgen_type_pre(g, &fn_types[0], f->where);
+ } else {
+ cgen_ctype(g, &ctypes[0]);
+ }
+
+ cgen_write(g, " const (*");
cgen_fn_name(g, f);
- cgen_type_post(g, t, f->where);
- cgen_write(g, " = %s;", foreign_name);
+ cgen_write(g, ")(");
+ for (size_t i = 1; i < arr_len(fn_types); ++i) {
+ if (i > 1)
+ cgen_write(g, ", ");
+ CType *csub = &ctypes[i];
+ if (csub->kind == CTYPE_NONE) {
+ Type *sub = &fn_types[i];
+ cgen_type_pre(g, sub, f->where);
+ cgen_type_post(g, sub, f->where);
+ } else {
+ cgen_ctype(g, csub);
+ }
+ }
+ cgen_write(g, ") = %s;", foreign_name);
}
cgen_nl(g);
return;
diff --git a/parse.c b/parse.c
index f49d9a0..bad5956 100644
--- a/parse.c
+++ b/parse.c
@@ -1714,8 +1714,15 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
if (!parse_expr(p, casted, lowest_precedence_op))
return false;
t->token = lowest_precedence_op + 1;
- if (!parse_type(p, &e->cast.type))
- return false;
+ if (token_is_direct(t->token, DIRECT_C)) {
+ /* cast to #C type */
+ CType unused;
+ if (!parse_c_type(p, &unused, &e->cast.type))
+ return false;
+ } else {
+ if (!parse_type(p, &e->cast.type))
+ return false;
+ }
if (t->token != end) {
tokr_err(t, "Cast expression continues after type");
return false;
@@ -1940,7 +1947,8 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
if (single_arg) {
++t->token;
if (!token_is_kw(t->token, KW_LPAREN)) {
- tokr_err(t, "Expected ( to follow #%s.", directives[t->token->direct]);
+ printf("%d\n",t->token->direct);
+ tokr_err(t, "Expected ( to follow #%s.", directives[t->token[-1].direct]);
return false;
}
++t->token;
diff --git a/std/io.toc b/std/io.toc
index 5a69269..2c1fc8b 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -1,31 +1,14 @@
-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("#include <stdio.h>\n");
-c_putchar ::= #foreign("putchar", "libc.so.6") fn(#C int) #C int;
+putchar ::= #foreign("putchar", "libc.so.6") fn(#C int) #C int;
toc_putchar ::= fn(x: char) {
- c_putchar(x as c_int);
+ putchar(x as #C int);
};
-c_fwrite ::= #foreign("fwrite", "libc.so.6") fn(&u8, #C size_t, #C size_t, &u8) #C size_t;
+fwrite ::= #foreign("fwrite", "libc.so.6") fn(#C &"void", #C size_t, #C size_t, #C &"void") #C size_t;
stdout_fwrite ::= fn(data: &u8, size: u64, nmemb: u64) {
- c_fwrite(data, size as c_size_t, nmemb as c_size_t, #builtin("stdout"));
+ fwrite(data, size as #C size_t, nmemb as #C size_t, #builtin("stdout"));
};
puts ::= fn(x: []char) {
diff --git a/test.toc b/test.toc
index 2a3a68a..1e41663 100644
--- a/test.toc
+++ b/test.toc
@@ -1,5 +1,6 @@
#include "std/io.toc", io;
+
main ::= fn() {
io.puts("Hello!");
io.puti(17);
diff --git a/types.c b/types.c
index 722fbc3..7b323b0 100644
--- a/types.c
+++ b/types.c
@@ -2845,8 +2845,10 @@ static Status types_stmt(Typer *tr, Statement *s) {
}
}
if (tr->block == NULL) {
- if (!eval_stmt(tr->evalr, s))
- return false;
+ if (s->expr.kind != EXPR_C) {
+ if (!eval_stmt(tr->evalr, s))
+ return false;
+ }
}
break;
case STMT_DECL: