diff options
| -rw-r--r-- | builtins/array.h | 6 | ||||
| -rw-r--r-- | compile.c | 7 | ||||
| -rw-r--r-- | environment.c | 53 | ||||
| -rw-r--r-- | environment.h | 1 | ||||
| -rw-r--r-- | typecheck.c | 6 | ||||
| -rw-r--r-- | typecheck.h | 1 |
6 files changed, 55 insertions, 19 deletions
diff --git a/builtins/array.h b/builtins/array.h index 86e57169..76ab29fd 100644 --- a/builtins/array.h +++ b/builtins/array.h @@ -18,6 +18,12 @@ int64_t $off = $index + ($index < 0) * ($arr.length + 1) - 1; \ (type*)($arr.data + $arr.stride * $off);}) #define $is_atomic(x) _Generic(x, bool: true, int8_t: true, int16_t: true, int32_t: true, int64_t: true, float: true, double: true, default: false) +#define $TypedArray(t, ...) ({ t $items[] = {__VA_ARGS__}; \ + (array_t){.length=sizeof($items)/sizeof($items[0]), \ + .stride=(int64_t)&$items[1] - (int64_t)&$items[0], \ + .data=memcpy(GC_MALLOC(sizeof($items)), $items, sizeof($items)), \ + .atomic=0, \ + .data_refcount=1}; }) #define $Array(x, ...) ({ __typeof(x) $items[] = {x, __VA_ARGS__}; \ (array_t){.length=sizeof($items)/sizeof($items[0]), \ .stride=(int64_t)&$items[1] - (int64_t)&$items[0], \ @@ -146,7 +146,12 @@ CORD compile(env_t *env, ast_t *ast) switch (ast->tag) { case Nil: return CORD_asprintf("$Null(%r)", compile_type_ast(Match(ast, Nil)->type)); case Bool: return Match(ast, Bool)->b ? "yes" : "no"; - case Var: return Match(ast, Var)->name; + case Var: { + binding_t *b = get_binding(env, Match(ast, Var)->name); + if (b) + return b->code ? b->code : Match(ast, Var)->name; + code_err(ast, "I don't know of any variable by this name"); + } case Int: return CORD_asprintf("I%ld(%ld)", Match(ast, Int)->bits, Match(ast, Int)->i); case Num: { // HACK: since the cord library doesn't support the '%a' specifier, this workaround diff --git a/environment.c b/environment.c index 0f0e18d2..87fe8a1e 100644 --- a/environment.c +++ b/environment.c @@ -5,6 +5,7 @@ #include "environment.h" #include "builtins/table.h" #include "builtins/string.h" +#include "typecheck.h" #include "util.h" typedef struct { @@ -12,22 +13,23 @@ typedef struct { binding_t binding; } ns_entry_t; -static type_t *namespace_type(const char *name, table_t *ns) -{ - arg_t *fields = NULL; - for (int64_t i = Table_length(ns); i >= 1; i--) { - struct {const char *name; binding_t *binding; } *entry = Table_entry(ns, i); - fields = new(arg_t, .next=fields, .name=entry->name, .type=entry->binding->type); - } - name = heap_strf("%s_namespace", name); - return Type(StructType, .name=name, .fields=fields); -} +// static type_t *namespace_type(const char *name, table_t *ns) +// { +// arg_t *fields = NULL; +// for (int64_t i = Table_length(ns); i >= 1; i--) { +// struct {const char *name; binding_t *binding; } *entry = Table_entry(ns, i); +// fields = new(arg_t, .next=fields, .name=entry->name, .type=entry->binding->type); +// } +// name = heap_strf("%s_namespace", name); +// return Type(StructType, .name=name, .fields=fields); +// } env_t *new_compilation_unit(void) { env_t *env = new(env_t); env->code = new(compilation_unit_t); env->types = new(table_t); + env->type_namespaces = new(table_t); env->globals = new(table_t); env->locals = new(table_t, .fallback=env->globals); @@ -46,31 +48,46 @@ env_t *new_compilation_unit(void) Table_str_set(env->globals, global_vars[i].name, b); } + typedef struct { + const char *name, *code, *type_str; + } ns_entry_t; + struct { const char *name; type_t *type; CORD typename; CORD struct_val; - table_t namespace; + array_t namespace; } global_types[] = { {"Bool", Type(BoolType), "Bool_t", "Bool", {}}, {"Int", Type(IntType, .bits=64), "Int_t", "Int", {}}, - {"Int32", Type(IntType, .bits=32), "Int32_t", "Int", {}}, - {"Int16", Type(IntType, .bits=16), "Int16_t", "Int", {}}, - {"Int8", Type(IntType, .bits=8), "Int8_t", "Int", {}}, + {"Int32", Type(IntType, .bits=32), "Int32_t", "Int32", {}}, + {"Int16", Type(IntType, .bits=16), "Int16_t", "Int16", {}}, + {"Int8", Type(IntType, .bits=8), "Int8_t", "Int8", {}}, {"Num", Type(NumType, .bits=64), "Num_t", "Num", {}}, {"Num32", Type(NumType, .bits=32), "Num32_t", "Num32", {}}, - {"Str", Type(StringType), "Str_t", "Str", {}}, + {"Str", Type(StringType), "Str_t", "Str", $TypedArray(ns_entry_t, + {"quoted", "Str__quoted", "func(s:Str, color=no)->Str"} + )}, }; for (size_t i = 0; i < sizeof(global_types)/sizeof(global_types[0]); i++) { - table_t *ns = new(table_t); - *ns = global_types[i].namespace; - binding_t *binding = new(binding_t, .type=namespace_type(global_types[i].name, ns)); + binding_t *binding = new(binding_t, .type=Type(TypeInfoType)); Table_str_set(env->globals, global_types[i].name, binding); Table_str_set(env->types, global_types[i].name, global_types[i].type); } + for (size_t i = 0; i < sizeof(global_types)/sizeof(global_types[0]); i++) { + table_t *namespace = new(table_t); + $ARRAY_FOREACH(global_types[i].namespace, j, ns_entry_t, entry, { + type_t *type = parse_type_string(env, entry.type_str); + binding_t *b = new(binding_t, .code=entry.code, .type=type); + Table_str_set(namespace, entry.name, b); + // printf("Bound %s:%s -> %T\n", global_types[i].name, entry.name, b->type); + }, {}) + Table_str_set(env->type_namespaces, global_types[i].name, namespace); + } + return env; } diff --git a/environment.h b/environment.h index 2f5c84dd..5c2e9641 100644 --- a/environment.h +++ b/environment.h @@ -17,6 +17,7 @@ typedef struct { typedef struct { table_t *types, *globals, *locals; + table_t *type_namespaces; // Map of type name -> namespace table compilation_unit_t *code; } env_t; diff --git a/typecheck.c b/typecheck.c index 3d408857..1f79d308 100644 --- a/typecheck.c +++ b/typecheck.c @@ -749,4 +749,10 @@ bool can_be_mutated(env_t *env, ast_t *ast) } } +type_t *parse_type_string(env_t *env, const char *str) +{ + type_ast_t *ast = parse_type_str(str); + return ast ? parse_type_ast(env, ast) : NULL; +} + // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/typecheck.h b/typecheck.h index bb6ed397..4df9a8a0 100644 --- a/typecheck.h +++ b/typecheck.h @@ -18,5 +18,6 @@ type_t *get_function_def_type(env_t *env, ast_t *ast); type_t *get_arg_type(env_t *env, arg_t *arg); type_t *get_arg_ast_type(env_t *env, arg_ast_t *arg); bool can_be_mutated(env_t *env, ast_t *ast); +type_t *parse_type_string(env_t *env, const char *str); // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 |
