diff --git a/builtins/array.h b/builtins/array.h index ff62db3..ae36795 100644 --- a/builtins/array.h +++ b/builtins/array.h @@ -7,6 +7,15 @@ #include "functions.h" #include "types.h" +// Convert negative indices to back-indexed without branching: index0 = index + (index < 0)*(len+1)) - 1 +#define $index(x, i) _Generic(x, array_t: ({ __typeof(x) $obj; int64_t $offset = i; $offset += ($offset < 0) * ($obj.length + 1) - 1; assert($offset >= 0 && offset < $obj.length); $obj.data + $obj.stride * $offset;})) +#define $safe_index(x, i) _Generic(x, array_t: ({ __typeof(x) $obj; int64_t $offset = i - 1; $obj.data + $obj.stride * $offset;})) +#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], \ + .data=memcpy(GC_MALLOC(sizeof($items)), $items, sizeof($items)), \ + .copy_on_write=1}; }) + void Array__insert(array_t *arr, const void *item, int64_t index, const TypeInfo *type); void Array__insert_all(array_t *arr, array_t to_insert, int64_t index, const TypeInfo *type); void Array__remove(array_t *arr, int64_t index, int64_t count, const TypeInfo *type); diff --git a/builtins/pointer.h b/builtins/pointer.h index b8583b7..c355472 100644 --- a/builtins/pointer.h +++ b/builtins/pointer.h @@ -10,6 +10,7 @@ int32_t Pointer__compare(const void *x, const void *y, const TypeInfo *type); bool Pointer__equal(const void *x, const void *y, const TypeInfo *type); uint32_t Pointer__hash(const void *x, const TypeInfo *type); +#define $Null(t) (t*)NULL #define POINTER_TYPE(_sigil, _pointed) (&(TypeInfo){\ .size=sizeof(void*), .align=alignof(void*), .tag=PointerInfo, .PointerInfo.sigil=_sigil, .PointerInfo.pointed=_pointed}) diff --git a/compile.c b/compile.c index 1070186..133cff0 100644 --- a/compile.c +++ b/compile.c @@ -10,7 +10,7 @@ #include "typecheck.h" #include "util.h" -CORD compile_type(env_t *env, type_ast_t *t) +CORD compile_type_ast(env_t *env, type_ast_t *t) { (void)env; switch (t->tag) { @@ -31,8 +31,9 @@ CORD compile_statement(env_t *env, ast_t *ast) stmt = CORD_asprintf("(void)%r;", compile(env, ast)); break; } - int64_t line = get_line_number(ast->file, ast->start); - return stmt ? CORD_asprintf("#line %ld\n%r", line, stmt) : stmt; + // int64_t line = get_line_number(ast->file, ast->start); + // return stmt ? CORD_asprintf("#line %ld\n%r", line, stmt) : stmt; + return stmt; } CORD expr_as_string(env_t *env, CORD expr, type_t *t, CORD color) @@ -63,7 +64,7 @@ CORD compile_string(env_t *env, ast_t *ast, CORD color) CORD compile(env_t *env, ast_t *ast) { switch (ast->tag) { - case Nil: return CORD_asprintf("(%r)NULL", compile_type(env, Match(ast, Nil)->type)); + case Nil: return CORD_asprintf("$Null(%r)", compile_type_ast(env, Match(ast, Nil)->type)); case Bool: return Match(ast, Bool)->b ? "yes" : "no"; case Var: return Match(ast, Var)->name; case Int: return CORD_asprintf("I%ld(%ld)", Match(ast, Int)->bits, Match(ast, Int)->i); @@ -300,6 +301,7 @@ CORD compile(env_t *env, ast_t *ast) case Declare: { auto decl = Match(ast, Declare); return CORD_asprintf("$var(%r, %r);", compile(env, decl->var), compile(env, decl->value)); + // return CORD_asprintf("auto %r = %r;", compile(env, decl->var), compile(env, decl->value)); } case Assign: { auto assign = Match(ast, Assign); @@ -339,20 +341,20 @@ CORD compile(env_t *env, ast_t *ast) case FunctionDef: { auto fndef = Match(ast, FunctionDef); CORD name = compile(env, fndef->name); - CORD_appendf(&env->code->staticdefs, "static %r %r_(", fndef->ret_type ? compile_type(env, fndef->ret_type) : "void", name); + CORD_appendf(&env->code->staticdefs, "static %r %r_(", fndef->ret_type ? compile_type_ast(env, fndef->ret_type) : "void", name); for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) { - CORD_appendf(&env->code->staticdefs, "%r %s", compile_type(env, arg->type), arg->name); + CORD_appendf(&env->code->staticdefs, "%r %s", compile_type_ast(env, arg->type), arg->name); if (arg->next) env->code->staticdefs = CORD_cat(env->code->staticdefs, ", "); } env->code->staticdefs = CORD_cat(env->code->staticdefs, ");\n"); CORD kwargs = CORD_asprintf("#define %r(...) ({ struct {", name); CORD passed_args = CORD_EMPTY; - CORD_appendf(&env->code->funcs, "%r %r_(", fndef->ret_type ? compile_type(env, fndef->ret_type) : "void", name); + CORD_appendf(&env->code->funcs, "%r %r_(", fndef->ret_type ? compile_type_ast(env, fndef->ret_type) : "void", name); env_t *body_scope = fresh_scope(env); body_scope->locals->fallback = env->globals; for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) { - CORD arg_type = compile_type(env, arg->type); + CORD arg_type = compile_type_ast(env, arg->type); CORD_appendf(&env->code->funcs, "%r %s", arg_type, arg->name); if (arg->next) env->code->funcs = CORD_cat(env->code->funcs, ", "); CORD_appendf(&kwargs, "%r %s; ", arg_type, arg->name); @@ -401,7 +403,7 @@ CORD compile(env_t *env, ast_t *ast) CORD index = for_->index ? compile(env, for_->index) : "$i"; return CORD_asprintf("{\n" "$var($iter, %r);\n" - "for (int64_t %r = 1, $len = $length($iter); %r <= $len; ++%r) {\n" + "for (int64_t %r = 1, $len = ($iter).length; %r <= $len; ++%r) {\n" "$var(%r, $safe_index($iter, %s));\n" "%r\n" "}\n}", @@ -433,7 +435,7 @@ CORD compile(env_t *env, ast_t *ast) CORD_appendf(&env->code->typecode, "struct %s_s {\n", def->name); for (arg_ast_t *field = def->fields; field; field = field->next) { - CORD type = compile_type(env, field->type); + CORD type = compile_type_ast(env, field->type); CORD_appendf(&env->code->typecode, "%r %s%s;\n", type, field->name, CORD_cmp(type, "Bool_t") ? "" : ":1"); } @@ -484,7 +486,7 @@ CORD compile(env_t *env, ast_t *ast) for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { env->code->typecode = CORD_cat(env->code->typecode, "struct {\n"); for (arg_ast_t *field = tag->fields; field; field = field->next) { - CORD type = compile_type(env, field->type); + CORD type = compile_type_ast(env, field->type); CORD_appendf(&env->code->typecode, "%r %s%s;\n", type, field->name, CORD_cmp(type, "Bool_t") ? "" : ":1"); } @@ -500,9 +502,9 @@ CORD compile(env_t *env, ast_t *ast) if (test->expr->tag == Declare) { auto decl = Match(test->expr, Declare); return CORD_asprintf( - "$var(%r, %r);\n" + "%r\n" "__doctest(&%r, %r, %r, %r, %ld, %ld);", - compile(env, decl->var), compile(env, decl->value), + compile(env, test->expr), compile(env, decl->var), compile_type_info(env, get_type(env, decl->value)), compile(env, WrapAST(test->expr, StringLiteral, .cord=test->output)), diff --git a/compile.h b/compile.h index 060ee40..83753e5 100644 --- a/compile.h +++ b/compile.h @@ -7,7 +7,7 @@ #include "util.h" #include "environment.h" -CORD compile_type(env_t *env, type_ast_t *t); +CORD compile_type_ast(env_t *env, type_ast_t *t); CORD compile(env_t *env, ast_t *ast); CORD compile_statement(env_t *env, ast_t *ast); CORD compile_type_info(env_t *env, type_t *t); diff --git a/nextlang.c b/nextlang.c index 8b34463..9634dad 100644 --- a/nextlang.c +++ b/nextlang.c @@ -56,9 +56,8 @@ int main(int argc, char *argv[]) bind_statement(env, stmt->ast); } - CORD fileinfo = CORD_asprintf("#line 0 %r\n", Str__quoted(f->filename, false)); CORD program = CORD_all( - fileinfo, + // CORD_asprintf("#line 0 %r\n", Str__quoted(f->filename, false)), "// Generated code:\n", env->code->imports, "\n", env->code->typedefs, "\n", diff --git a/nextlang.h b/nextlang.h index a7e4593..d81fe2e 100644 --- a/nextlang.h +++ b/nextlang.h @@ -40,15 +40,6 @@ CORD as_cord(void *x, bool use_color, const char *fmt, ...); default: "???") #define $heap(x) (__typeof(x)*)memcpy(GC_MALLOC(sizeof(x)), (__typeof(x)[1]){x}, sizeof(x)) #define $stack(x) (__typeof(x)*)((__typeof(x)[1]){x}) -#define $length(x) _Generic(x, default: (x).length) -// Convert negative indices to back-indexed without branching: index0 = index + (index < 0)*(len+1)) - 1 -#define $index(x, i) _Generic(x, array_t: ({ __typeof(x) $obj; int64_t $offset = i; $offset += ($offset < 0) * ($obj.length + 1) - 1; assert($offset >= 0 && offset < $obj.length); $obj.data + $obj.stride * $offset;})) -#define $safe_index(x, i) _Generic(x, array_t: ({ __typeof(x) $obj; int64_t $offset = i - 1; $obj.data + $obj.stride * $offset;})) -#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], \ - .data=memcpy(GC_MALLOC(sizeof($items)), $items, sizeof($items)), \ - .copy_on_write=1}; }) #define not(x) _Generic(x, bool: (bool)!(x), default: ~(x)) #define and(x, y) _Generic(x, bool: (bool)((x) && (y)), default: ((x) & (y)))