From 9dc97819d38b1a63935a4909b246c88f960e0899 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 3 Mar 2020 21:09:09 -0500 Subject: seem to have fully fixed bug --- cgen.c | 2 +- eval.c | 4 ++-- main.c | 1 + test.toc | 68 +++------------------------------------------------------------- types.c | 23 +++++++++++----------- types.h | 1 - 6 files changed, 18 insertions(+), 81 deletions(-) diff --git a/cgen.c b/cgen.c index 0897a52..33fc840 100644 --- a/cgen.c +++ b/cgen.c @@ -1317,7 +1317,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { assert(type_is_builtin(struct_type, BUILTIN_NMS)); char *prefix = e->binary.lhs->val.nms->c.prefix; cgen_write(g, "%s", prefix); - cgen_ident_simple(g, e->binary.dot.translated_ident); + cgen_ident_simple(g, e->binary.rhs->ident); } handled = true; } break; diff --git a/eval.c b/eval.c index 31c0472..df6f469 100644 --- a/eval.c +++ b/eval.c @@ -703,9 +703,9 @@ static Status eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr, void *p = (char *)struc_data + dot_expr->binary.dot.field->offset; } else { void *ptr; + Identifier ident = dot_expr->binary.rhs->ident; assert(type_is_builtin(struct_type, BUILTIN_NMS)); - Identifier translated = dot_expr->binary.dot.translated_ident; - if (!eval_address_of_ident(translated, dot_expr->where, &dot_expr->type, &ptr)) + if (!eval_address_of_ident(ident, dot_expr->where, &dot_expr->type, &ptr)) return false; *p = ptr; } diff --git a/main.c b/main.c index b3528f2..f53cce2 100644 --- a/main.c +++ b/main.c @@ -17,6 +17,7 @@ switch enums typeof macros +unions --- switch to / add as an alternative: libffi X ::= newtype(int); or something diff --git a/test.toc b/test.toc index f78e1fe..1b02eed 100644 --- a/test.toc +++ b/test.toc @@ -22,73 +22,11 @@ main ::= fn() { io.puti(arr_sum(a)); }; */ -puti ::= fn(x: int) { -//tcc's giving me "incompatible types for redefinition of 'printf'" for some reason (even though the declarations have the exact same type) - #C("#ifndef __TINYC__ -extern int printf(const char *fmt, ...); -#endif -"); - #C("printf(\"%ld\\n\", (long)x);"); -}; -putf ::= fn(x: float) { - #C("#ifndef __TINYC__ -extern int printf(const char *fmt, ...); -#endif -"); - #C("printf(\"%f\\n\", (double)x);"); -}; - -// it would be nice if Arr.data.len == Arr.len (: but this will require some C code... -Arr ::= fn (t :: Type) Type { - struct { - data : []t; - len, cap : int; - } -}; - -arr_add ::= fn(t :: Type, a : &Arr(t), x : t) { - if a.len >= a.cap { - a.cap = a.cap * 2 + 2; - new_data := new(t, a.cap); - for i := 0..a.len-1 { - new_data[i] = a.data[i]; - } - a.data = new_data; - } - a.data[a.len] = x; - a.len += 1; -}; - -square ::= fn(t :: Type, x : t) t { - a : Arr(t); - for i := 1,2..2*x-1 { - arr_add(t, &a, i); - }; - sum := 0 as t; - for i := 0..a.len-1 { - sum += a.data[i]; - }; - sum -}; - - -ArrInt ::= Arr(int); -inc ::= fn(t :: Type, x : t) t { - x + 1 +a ::= nms { + x: int; }; main ::= fn() { - arr : ArrInt; - farr : Arr(float); - for i := 1..100 { - arr_add(int, &arr, inc(int, square(int, i))); - arr_add(float, &farr, inc(float, square(float, i as float))); - } - for i := 0..arr.len - 1 { - puti(arr.data[i]); - } - for i := 0..farr.len - 1 { - putf(farr.data[i]); - } + a.x; }; diff --git a/types.c b/types.c index 128a36f..bd9cc18 100644 --- a/types.c +++ b/types.c @@ -521,6 +521,10 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { goto ret; } if (type_is_compileonly(&f->ret_type)) { + if (type_is_builtin(&f->ret_type, BUILTIN_NMS)) { + err_print(f->where, "Functions cannot return namespaces."); + return false; + } /* a function which returns a compile-only type but has non-constant parameters is weird... but might be useful, so let's warn @@ -2523,9 +2527,8 @@ static Status types_expr(Typer *tr, Expression *e) { if (!eval_expr(tr->evalr, rhs, &member_name)) return false; e->binary.op = BINARY_DOT; e->binary.rhs->kind = EXPR_IDENT; - Identifier ident = e->binary.rhs->ident = e->binary.dot.translated_ident = - ident_get_with_len(&nms->body.idents, member_name.slice.data, (size_t)member_name.slice.n); - if (!type_of_ident(tr, rhs->where, &ident, t)) { + e->binary.rhs->ident = ident_get_with_len(&nms->body.idents, member_name.slice.data, (size_t)member_name.slice.n); + if (!type_of_ident(tr, rhs->where, &e->binary.rhs->ident, t)) { return false; } } break; @@ -2595,17 +2598,13 @@ static Status types_expr(Typer *tr, Expression *e) { Namespace *nms = nms_val.nms; lhs->kind = EXPR_VAL; lhs->val.nms = nms; - Identifier translated = ident_translate(rhs->ident, &nms->body.idents); - if (!translated) { - char *s = ident_to_str(rhs->ident); - err_print(rhs->where, "%s is not a member of this namespace.", s); - return false; - } - assert(translated->decl_kind != IDECL_NONE); - if (!type_of_ident(tr, rhs->where, &translated, t)) { + Block *prev = tr->block; + /* briefly pretend we are in the namespace */ + tr->block = &nms->body; + if (!type_of_ident(tr, rhs->where, &rhs->ident, t)) { return false; } - e->binary.dot.translated_ident = translated; + tr->block = prev; } else { char *s = type_to_str(lhs_type); err_print(e->where, "Operator . applied to type %s, which is not a structure or pointer to structure.", s); diff --git a/types.h b/types.h index 2ac43ec..74b7afc 100644 --- a/types.h +++ b/types.h @@ -806,7 +806,6 @@ typedef struct Expression { struct Expression *rhs; union { Field *field; /* for struct. */ - Identifier translated_ident; /* for nms. */ } dot; } binary; CallExpr call; -- cgit v1.2.3