Various fixes, including for Null values
This commit is contained in:
parent
2345c8c5c9
commit
fbf39cd7e9
@ -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);
|
||||
|
@ -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})
|
||||
|
||||
|
28
compile.c
28
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)),
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
@ -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)))
|
||||
|
Loading…
Reference in New Issue
Block a user