summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-21 13:39:05 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-21 13:39:05 -0400
commit4b8cc1b6132f179caa25d808808e63f014131f13 (patch)
tree2827ac2445a9fa3feaf8a1a559d31ec38c7b5b98
parent5d4fa960a020f40aa8a5d24225c81e5c467ce197 (diff)
fixed casting to #C type at runtime
-rw-r--r--cgen.c55
-rw-r--r--decls_cgen.c45
-rw-r--r--main.c2
-rw-r--r--parse.c4
-rw-r--r--std/mem.toc6
-rwxr-xr-xtest-build.sh2
-rw-r--r--test.toc28
-rw-r--r--tests/mem.toc6
-rw-r--r--types.h1
9 files changed, 67 insertions, 82 deletions
diff --git a/cgen.c b/cgen.c
index 5b430fc..3554699 100644
--- a/cgen.c
+++ b/cgen.c
@@ -418,6 +418,52 @@ static void cgen_type_post(CGenerator *g, Type *t) {
}
}
+static void cgen_ctype(CGenerator *g, CType *c) {
+ if (c->kind & CTYPE_UNSIGNED) {
+ c->kind &= (CTypeKind)~(CTypeKind)CTYPE_UNSIGNED;
+ cgen_write(g, "unsigned ");
+ }
+ switch (c->kind) {
+ case CTYPE_CHAR:
+ cgen_write(g, "char");
+ break;
+ case CTYPE_SIGNED_CHAR:
+ cgen_write(g, "signed char");
+ break;
+ case CTYPE_SHORT:
+ cgen_write(g, "short");
+ break;
+ case CTYPE_INT:
+ cgen_write(g, "int");
+ break;
+ case CTYPE_LONG:
+ cgen_write(g, "long");
+ break;
+ case CTYPE_LONGLONG:
+ cgen_write(g, "long long");
+ break;
+ case CTYPE_PTR:
+ cgen_write(g, "%s *", c->points_to);
+ break;
+ case CTYPE_FLOAT:
+ cgen_write(g, "float");
+ break;
+ case CTYPE_DOUBLE:
+ cgen_write(g, "double");
+ break;
+ case CTYPE_SIZE_T:
+ cgen_write(g, "size_t");
+ break;
+ case CTYPE_VARARGS:
+ cgen_write(g, "...");
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
+
static inline void cgen_fn_name(CGenerator *g, FnExpr *f) {
if (f->c.name) {
cgen_ident(g, f->c.name);
@@ -1646,9 +1692,14 @@ static void cgen_expr(CGenerator *g, Expression *e) {
/* can't cast to array type */
cgen_expr(g, e->cast.expr);
} else {
+ CType *ctype = &e->cast.ctype;
cgen_write(g, "((");
- cgen_type_pre(g, to);
- cgen_type_post(g, to);
+ if (ctype->kind != CTYPE_NONE) {
+ cgen_ctype(g, ctype);
+ } else {
+ cgen_type_pre(g, to);
+ cgen_type_post(g, to);
+ }
cgen_write(g, ")(");
cgen_expr(g, e->cast.expr);
cgen_write(g, ")");
diff --git a/decls_cgen.c b/decls_cgen.c
index 967294f..c1749a1 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -223,51 +223,6 @@ static void cgen_decls_fn_instances(CGenerator *g, FnExpr *f) {
}
}
-static void cgen_ctype(CGenerator *g, CType *c) {
- if (c->kind & CTYPE_UNSIGNED) {
- c->kind &= (CTypeKind)~(CTypeKind)CTYPE_UNSIGNED;
- cgen_write(g, "unsigned ");
- }
- switch (c->kind) {
- case CTYPE_CHAR:
- cgen_write(g, "char");
- break;
- case CTYPE_SIGNED_CHAR:
- cgen_write(g, "signed char");
- break;
- case CTYPE_SHORT:
- cgen_write(g, "short");
- break;
- case CTYPE_INT:
- cgen_write(g, "int");
- break;
- case CTYPE_LONG:
- cgen_write(g, "long");
- break;
- case CTYPE_LONGLONG:
- cgen_write(g, "long long");
- break;
- case CTYPE_PTR:
- cgen_write(g, "%s *", c->points_to);
- break;
- case CTYPE_FLOAT:
- cgen_write(g, "float");
- break;
- case CTYPE_DOUBLE:
- cgen_write(g, "double");
- break;
- case CTYPE_SIZE_T:
- cgen_write(g, "size_t");
- break;
- case CTYPE_VARARGS:
- cgen_write(g, "...");
- break;
- default:
- assert(0);
- break;
- }
-}
-
static void cgen_fn_decl(CGenerator *g, FnExpr *f, Type *t) {
if (f->flags & FN_EXPR_FOREIGN) {
diff --git a/main.c b/main.c
index e5b493e..134d86e 100644
--- a/main.c
+++ b/main.c
@@ -8,7 +8,7 @@
/*
TODO:
-make casting to #C type work
+simplify eval macros with val_to_u/i64
use
- use with a decl, e.g. use p : Point;
&&, ||
diff --git a/parse.c b/parse.c
index 9a24d26..1e29129 100644
--- a/parse.c
+++ b/parse.c
@@ -1781,10 +1781,10 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
t->token = lowest_precedence_op + 1;
if (token_is_direct(t->token, DIRECT_C)) {
/* cast to #C type */
- CType unused;
- if (!parse_c_type(p, &unused, &e->cast.type))
+ if (!parse_c_type(p, &e->cast.ctype, &e->cast.type))
return false;
} else {
+ e->cast.ctype.kind = CTYPE_NONE;
if (!parse_type(p, &e->cast.type, NULL))
return false;
}
diff --git a/std/mem.toc b/std/mem.toc
index 5e8c5fa..6d16895 100644
--- a/std/mem.toc
+++ b/std/mem.toc
@@ -3,12 +3,12 @@ calloc ::= #foreign("calloc", "libc.so.6") fn(#C size_t, #C size_t) #C &"void";
free ::= #foreign("free", "libc.so.6") fn(#C &"void");
new ::= fn(t :: Type) &t {
- calloc(1, (sizeof t) as u64)
+ calloc(1, (sizeof t) as #C size_t)
}
news ::= fn(t :: Type, n : int) []t {
s: []t;
- s.data = calloc(n as u64, (sizeof t) as u64);
+ s.data = calloc(n as #C size_t, (sizeof t) as #C size_t);
s.len = n;
s
}
@@ -20,4 +20,4 @@ del ::= fn(t::=, x: &t) {
dels ::= fn(t::=, x: []t) {
free(x.data);
-} \ No newline at end of file
+}
diff --git a/test-build.sh b/test-build.sh
index 263c657..ec63972 100755
--- a/test-build.sh
+++ b/test-build.sh
@@ -1,6 +1,6 @@
#!/bin/sh
+echo "tcc -w main.c -o toc" && tcc -w main.c -o toc || exit 1
for CC in tcc gcc clang g++ ; do
-
CC="$CC" CFLAGS='-Werror' ./build.sh || exit 1
CC="$CC" CFLAGS='-Werror' ./build.sh release || exit 1
done
diff --git a/test.toc b/test.toc
index 8372265..d27fae6 100644
--- a/test.toc
+++ b/test.toc
@@ -1,28 +1,6 @@
-#include "std/io.toc", io;
-
-prime_sieve ::= fn(N::=10000) sieve: [N]bool {
- for x, i := &sieve {
- *x = i%2 != 0;
- }
- sieve[1] = false;
- sieve[2] = true;
- i := 3;
- while i*i <= N {
- defer i += 2;
- if !sieve[i] { continue; }
- j := 2*i;
- while j < N {
- sieve[j] = false;
- j += i;
- }
- }
-}
+#include "std/mem.toc";
main ::= fn() {
- sieve := prime_sieve();
- for x, i := sieve {
- if x {
- io.puti(i);
- }
- }
+ thing := new(int);
+ del(thing);
}
diff --git a/tests/mem.toc b/tests/mem.toc
index 5e8c5fa..6d16895 100644
--- a/tests/mem.toc
+++ b/tests/mem.toc
@@ -3,12 +3,12 @@ calloc ::= #foreign("calloc", "libc.so.6") fn(#C size_t, #C size_t) #C &"void";
free ::= #foreign("free", "libc.so.6") fn(#C &"void");
new ::= fn(t :: Type) &t {
- calloc(1, (sizeof t) as u64)
+ calloc(1, (sizeof t) as #C size_t)
}
news ::= fn(t :: Type, n : int) []t {
s: []t;
- s.data = calloc(n as u64, (sizeof t) as u64);
+ s.data = calloc(n as #C size_t, (sizeof t) as #C size_t);
s.len = n;
s
}
@@ -20,4 +20,4 @@ del ::= fn(t::=, x: &t) {
dels ::= fn(t::=, x: []t) {
free(x.data);
-} \ No newline at end of file
+}
diff --git a/types.h b/types.h
index 903e76a..66f68ff 100644
--- a/types.h
+++ b/types.h
@@ -736,6 +736,7 @@ typedef struct Instance {
typedef struct CastExpr {
struct Expression *expr;
Type type;
+ CType ctype;
} CastExpr;
typedef struct NewExpr {