From 4b8cc1b6132f179caa25d808808e63f014131f13 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sat, 21 Mar 2020 13:39:05 -0400 Subject: fixed casting to #C type at runtime --- cgen.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- decls_cgen.c | 45 --------------------------------------------- main.c | 2 +- parse.c | 4 ++-- std/mem.toc | 6 +++--- test-build.sh | 2 +- test.toc | 28 +++------------------------- tests/mem.toc | 6 +++--- types.h | 1 + 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 { -- cgit v1.2.3