mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 01:21:38 -07:00
Compound Literals - struct, array, slice, vector
This commit is contained in:
+111
-11
@@ -4,6 +4,7 @@
|
||||
|
||||
declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1)
|
||||
|
||||
%main.Vec2 = type <2 x float>
|
||||
define void @exec(i64 ()* %p) {
|
||||
"entry - 0":
|
||||
%0 = alloca i64 ()*, align 8 ; p
|
||||
@@ -18,21 +19,119 @@ define void @exec(i64 ()* %p) {
|
||||
|
||||
define void @main() {
|
||||
"entry - 0":
|
||||
%0 = alloca i8, align 1 ; a
|
||||
store i8 zeroinitializer, i8* %0
|
||||
store i8 123, i8* %0
|
||||
%1 = load i8, i8* %0
|
||||
%2 = zext i8 %1 to i64
|
||||
call void @print_int(i64 %2)
|
||||
%0 = alloca i64, align 8 ; i
|
||||
store i64 zeroinitializer, i64* %0
|
||||
store i64 123, i64* %0
|
||||
%1 = load i64, i64* %0
|
||||
call void @print_int(i64 %1)
|
||||
call void @print_rune(i32 128149)
|
||||
call void @print_rune(i32 10)
|
||||
call void @exec(i64 ()* @main$cool_beans)
|
||||
%2 = alloca %main.Vec2, align 2 ; v
|
||||
store %main.Vec2 zeroinitializer, %main.Vec2* %2
|
||||
%3 = alloca %main.Vec2, align 2
|
||||
store %main.Vec2 zeroinitializer, %main.Vec2* %3
|
||||
%4 = getelementptr inbounds %main.Vec2, %main.Vec2* %3, i64 0, i32 0
|
||||
store float 0x3ff0000000000000, float* %4
|
||||
%5 = getelementptr inbounds %main.Vec2, %main.Vec2* %3, i64 0, i32 1
|
||||
store float 0x4000000000000000, float* %5
|
||||
%6 = load %main.Vec2, %main.Vec2* %3
|
||||
store %main.Vec2 %6, %main.Vec2* %2
|
||||
%7 = alloca [4 x i64], align 8 ; a
|
||||
store [4 x i64] zeroinitializer, [4 x i64]* %7
|
||||
%8 = alloca [4 x i64], align 8
|
||||
store [4 x i64] zeroinitializer, [4 x i64]* %8
|
||||
%9 = load i64, i64* %0
|
||||
%10 = getelementptr inbounds [4 x i64], [4 x i64]* %8, i64 0, i32 0
|
||||
store i64 %9, i64* %10
|
||||
%11 = getelementptr inbounds [4 x i64], [4 x i64]* %8, i64 0, i32 1
|
||||
store i64 2, i64* %11
|
||||
%12 = getelementptr inbounds [4 x i64], [4 x i64]* %8, i64 0, i32 2
|
||||
store i64 3, i64* %12
|
||||
%13 = getelementptr inbounds [4 x i64], [4 x i64]* %8, i64 0, i32 3
|
||||
store i64 7, i64* %13
|
||||
%14 = load [4 x i64], [4 x i64]* %8
|
||||
store [4 x i64] %14, [4 x i64]* %7
|
||||
%15 = alloca [4 x i64], align 8 ; e
|
||||
store [4 x i64] zeroinitializer, [4 x i64]* %15
|
||||
%16 = alloca [4 x i64], align 8
|
||||
store [4 x i64] zeroinitializer, [4 x i64]* %16
|
||||
%17 = load i64, i64* %0
|
||||
%18 = getelementptr inbounds [4 x i64], [4 x i64]* %16, i64 0, i32 0
|
||||
store i64 %17, i64* %18
|
||||
%19 = getelementptr inbounds [4 x i64], [4 x i64]* %16, i64 0, i32 1
|
||||
store i64 2, i64* %19
|
||||
%20 = getelementptr inbounds [4 x i64], [4 x i64]* %16, i64 0, i32 2
|
||||
store i64 3, i64* %20
|
||||
%21 = getelementptr inbounds [4 x i64], [4 x i64]* %16, i64 0, i32 3
|
||||
store i64 7, i64* %21
|
||||
%22 = load [4 x i64], [4 x i64]* %16
|
||||
store [4 x i64] %22, [4 x i64]* %15
|
||||
%23 = alloca {i64*, i64, i64}, align 8 ; s
|
||||
store {i64*, i64, i64} zeroinitializer, {i64*, i64, i64}* %23
|
||||
%24 = alloca {i64*, i64, i64}, align 8
|
||||
store {i64*, i64, i64} zeroinitializer, {i64*, i64, i64}* %24
|
||||
%25 = alloca [4 x i64], align 8
|
||||
store [4 x i64] zeroinitializer, [4 x i64]* %25
|
||||
%26 = load i64, i64* %0
|
||||
%27 = getelementptr inbounds [4 x i64], [4 x i64]* %25, i64 0, i32 0
|
||||
store i64 %26, i64* %27
|
||||
%28 = getelementptr inbounds [4 x i64], [4 x i64]* %25, i64 0, i32 1
|
||||
store i64 2, i64* %28
|
||||
%29 = getelementptr inbounds [4 x i64], [4 x i64]* %25, i64 0, i32 2
|
||||
store i64 3, i64* %29
|
||||
%30 = getelementptr inbounds [4 x i64], [4 x i64]* %25, i64 0, i32 3
|
||||
store i64 7, i64* %30
|
||||
%31 = getelementptr inbounds [4 x i64], [4 x i64]* %25, i64 0, i32 0
|
||||
%32 = getelementptr inbounds {i64*, i64, i64}, {i64*, i64, i64}* %24, i64 0, i32 0
|
||||
store i64* %31, i64** %32
|
||||
%33 = getelementptr inbounds {i64*, i64, i64}, {i64*, i64, i64}* %24, i64 0, i32 1
|
||||
store i64 4, i64* %33
|
||||
%34 = getelementptr inbounds {i64*, i64, i64}, {i64*, i64, i64}* %24, i64 0, i32 2
|
||||
store i64 4, i64* %34
|
||||
%35 = load {i64*, i64, i64}, {i64*, i64, i64}* %24
|
||||
store {i64*, i64, i64} %35, {i64*, i64, i64}* %23
|
||||
%36 = alloca i64, align 8 ; i
|
||||
store i64 zeroinitializer, i64* %36
|
||||
store i64 0, i64* %36
|
||||
br label %"for.loop - 2"
|
||||
|
||||
"for.body - 1":
|
||||
%37 = getelementptr inbounds [4 x i64], [4 x i64]* %7, i64 0, i64 0
|
||||
%38 = load i64, i64* %36
|
||||
%39 = getelementptr i64, i64* %37, i64 %38
|
||||
%40 = load i64, i64* %39
|
||||
call void @print_int(i64 %40)
|
||||
%41 = getelementptr inbounds [2 x i8], [2 x i8]* @.str0, i64 0, i64 0
|
||||
%42 = alloca %.string, align 8
|
||||
store %.string zeroinitializer, %.string* %42
|
||||
%43 = getelementptr inbounds %.string, %.string* %42, i64 0, i32 0
|
||||
%44 = getelementptr inbounds %.string, %.string* %42, i64 0, i32 1
|
||||
store i8* %41, i8** %43
|
||||
store i64 2, i64* %44
|
||||
%45 = load %.string, %.string* %42
|
||||
call void @print_string(%.string %45)
|
||||
br label %"for.post - 3"
|
||||
|
||||
"for.loop - 2":
|
||||
%46 = load i64, i64* %36
|
||||
%47 = icmp slt i64 %46, 4
|
||||
br i1 %47, label %"for.body - 1", label %"for.done - 4"
|
||||
|
||||
"for.post - 3":
|
||||
%48 = load i64, i64* %36
|
||||
%49 = add i64 %48, 1
|
||||
store i64 %49, i64* %36
|
||||
br label %"for.loop - 2"
|
||||
|
||||
"for.done - 4":
|
||||
call void @print_rune(i32 10)
|
||||
call void @exec(i64 ()* @main$0)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i64 @main$cool_beans() {
|
||||
define i64 @main$0() {
|
||||
"entry - 0":
|
||||
%0 = alloca i64, align 8 ; a
|
||||
%0 = alloca i64, align 8 ; i
|
||||
store i64 zeroinitializer, i64* %0
|
||||
store i64 1337, i64* %0
|
||||
call void @print_rune(i32 128149)
|
||||
@@ -411,7 +510,7 @@ define void @print_int_base(i64 %i, i64 %base) {
|
||||
%16 = getelementptr inbounds [21 x i8], [21 x i8]* %2, i64 0, i64 0
|
||||
%17 = load i64, i64* %3
|
||||
%18 = getelementptr i8, i8* %16, i64 %17
|
||||
%19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str0, i64 0, i64 0
|
||||
%19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str1, i64 0, i64 0
|
||||
%20 = load i64, i64* %1
|
||||
%21 = load i64, i64* %0
|
||||
%22 = srem i64 %21, %20
|
||||
@@ -494,4 +593,5 @@ define void @print_int_base(i64 %i, i64 %base) {
|
||||
ret void
|
||||
}
|
||||
|
||||
@.str0 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$"
|
||||
@.str0 = global [2 x i8] c"\2C\20"
|
||||
@.str1 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$"
|
||||
|
||||
+20
-7
@@ -2,24 +2,37 @@ import "basic"
|
||||
|
||||
TWO_HEARTS :: '💕';
|
||||
|
||||
|
||||
exec :: proc(p : proc() -> int) {
|
||||
print_int(p());
|
||||
print_rune('\n');
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
a : u8 = 123;
|
||||
print_int(cast(int)a);
|
||||
i := 123;
|
||||
print_int(i);
|
||||
print_rune(TWO_HEARTS);
|
||||
print_rune('\n');
|
||||
|
||||
cool_beans :: proc() -> int {
|
||||
a : int = 1337;
|
||||
type Vec2: {2}f32;
|
||||
|
||||
v := Vec2{1, 2};
|
||||
a := [4] int{i, 2, 3, 7};
|
||||
e := [..]int{i, 2, 3, 7};
|
||||
s := [] int{i, 2, 3, 7};
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
print_int(a[i]);
|
||||
print_string(", ");
|
||||
}
|
||||
print_rune('\n');
|
||||
|
||||
exec(proc() -> int {
|
||||
i : int = 1337;
|
||||
print_rune('💕');
|
||||
print_rune('\n');
|
||||
return a;
|
||||
}
|
||||
exec(cool_beans);
|
||||
return i;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+26
-5
@@ -18,10 +18,6 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
|
||||
GB_ASSERT(node->kind == AstNode_StructType);
|
||||
GB_ASSERT(struct_type->kind == Type_Structure);
|
||||
ast_node(st, StructType, node);
|
||||
if (st->field_count == 0) {
|
||||
error(&c->error_collector, ast_node_token(node), "Empty struct{} definition");
|
||||
return;
|
||||
}
|
||||
|
||||
Map<Entity *> entity_map = {};
|
||||
map_init(&entity_map, gb_heap_allocator());
|
||||
@@ -1759,8 +1755,21 @@ ExpressionKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *typ
|
||||
|
||||
case_ast_node(cl, CompoundLit, node);
|
||||
Type *type = type_hint;
|
||||
b32 ellipsis_array = false;
|
||||
if (cl->type != NULL) {
|
||||
type = check_type(c, cl->type);
|
||||
type = NULL;
|
||||
|
||||
// [..]Type
|
||||
if (cl->type->kind == AstNode_ArrayType && cl->type->ArrayType.count != NULL) {
|
||||
if (cl->type->ArrayType.count->kind == AstNode_Ellipsis) {
|
||||
type = make_type_array(c->allocator, check_type(c, cl->type->ArrayType.elem), -1);
|
||||
ellipsis_array = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == NULL) {
|
||||
type = check_type(c, cl->type);
|
||||
}
|
||||
}
|
||||
|
||||
if (type == NULL) {
|
||||
@@ -1798,12 +1807,16 @@ ExpressionKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *typ
|
||||
|
||||
case Type_Slice:
|
||||
case Type_Array:
|
||||
case Type_Vector:
|
||||
{
|
||||
Type *elem_type = NULL;
|
||||
String context_name = {};
|
||||
if (t->kind == Type_Slice) {
|
||||
elem_type = t->slice.elem;
|
||||
context_name = make_string("slice literal");
|
||||
} else if (t->kind == Type_Vector) {
|
||||
elem_type = t->vector.elem;
|
||||
context_name = make_string("vector literal");
|
||||
} else {
|
||||
elem_type = t->array.elem;
|
||||
context_name = make_string("array literal");
|
||||
@@ -1826,6 +1839,10 @@ ExpressionKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *typ
|
||||
}
|
||||
if (max < index)
|
||||
max = index;
|
||||
|
||||
if (t->kind == Type_Array && ellipsis_array) {
|
||||
t->array.count = max;
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
@@ -2277,6 +2294,10 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
||||
str = write_expr_to_string(str, ce->expr);
|
||||
case_end;
|
||||
|
||||
case_ast_node(e, Ellipsis, node);
|
||||
str = gb_string_appendc(str, "..");
|
||||
case_end;
|
||||
|
||||
case_ast_node(pt, PointerType, node);
|
||||
str = gb_string_appendc(str, "^");
|
||||
str = write_expr_to_string(str, pt->type);
|
||||
|
||||
@@ -60,7 +60,8 @@ void ssa_gen_code(ssaGen *s) {
|
||||
|
||||
switch (e->kind) {
|
||||
case Entity_TypeName: {
|
||||
ssaValue *t = ssa_make_value_type_name(a, e);
|
||||
ssaValue *t = ssa_make_value_type_name(a, e->token.string, e->type);
|
||||
map_set(&m->values, hash_pointer(e), t);
|
||||
map_set(&m->members, hash_string(name), t);
|
||||
} break;
|
||||
|
||||
|
||||
@@ -184,6 +184,12 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
|
||||
}
|
||||
|
||||
void ssa_print_exact_value(gbFile *f, ssaModule *m, ExactValue value, Type *type) {
|
||||
if (is_type_float(type)) {
|
||||
value = exact_value_to_float(value);
|
||||
} else if (is_type_integer(type)) {
|
||||
value = exact_value_to_integer(value);
|
||||
}
|
||||
|
||||
switch (value.kind) {
|
||||
case ExactValue_Bool:
|
||||
ssa_fprintf(f, (value.value_bool ? "true" : "false"));
|
||||
@@ -238,7 +244,7 @@ void ssa_print_value(gbFile *f, ssaModule *m, ssaValue *value, Type *type_hint)
|
||||
ssa_print_exact_value(f, m, value->constant.value, type_hint);
|
||||
break;
|
||||
case ssaValue_TypeName:
|
||||
ssa_print_encoded_local(f, value->type_name.entity->token.string);
|
||||
ssa_print_encoded_local(f, value->type_name.name);
|
||||
break;
|
||||
case ssaValue_Global:
|
||||
ssa_print_encoded_global(f, value->global.entity->token.string);
|
||||
@@ -592,16 +598,21 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) {
|
||||
ssa_fprintf(f, "}\n\n");
|
||||
}
|
||||
|
||||
gb_for_array(i, proc->anon_procs) {
|
||||
ssa_print_proc(f, m, proc->anon_procs[i]);
|
||||
}
|
||||
gb_for_array(i, proc->nested_procs) {
|
||||
ssa_print_proc(f, m, proc->nested_procs[i]);
|
||||
gb_for_array(i, proc->children) {
|
||||
ssa_print_proc(f, m, proc->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ssa_print_type_name(gbFile *f, ssaModule *m, ssaValue *v) {
|
||||
GB_ASSERT(v->kind == ssaValue_TypeName);
|
||||
ssa_print_encoded_local(f, v->type_name.name);
|
||||
ssa_fprintf(f, " = type ");
|
||||
ssa_print_type(f, m->sizes, get_base_type(v->type_name.type));
|
||||
ssa_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
void ssa_print_llvm_ir(gbFile *f, ssaModule *m) {
|
||||
if (m->layout.len > 0) {
|
||||
if (m->layout.len > 0) {
|
||||
ssa_fprintf(f, "target datalayout = %.*s\n", LIT(m->layout));
|
||||
}
|
||||
|
||||
@@ -618,12 +629,17 @@ if (m->layout.len > 0) {
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, ", i32, i1)\n\n");
|
||||
|
||||
gb_for_array(i, m->nested_type_names) {
|
||||
ssaValue *v = m->nested_type_names[i];
|
||||
ssa_print_type_name(f, m, v);
|
||||
}
|
||||
|
||||
gb_for_array(member_index, m->members.entries) {
|
||||
auto *entry = &m->members.entries[member_index];
|
||||
ssaValue *v = entry->value;
|
||||
switch (v->kind) {
|
||||
case ssaValue_TypeName: {
|
||||
ssa_print_encoded_local(f, v->type_name.entity->token.string);
|
||||
ssa_print_encoded_local(f, v->type_name.name);
|
||||
ssa_fprintf(f, " = type ");
|
||||
ssa_print_type(f, m->sizes, get_base_type(v->type_name.type));
|
||||
ssa_fprintf(f, "\n");
|
||||
|
||||
+138
-28
@@ -14,6 +14,7 @@ struct ssaModule {
|
||||
|
||||
Map<ssaValue *> values; // Key: Entity *
|
||||
Map<ssaValue *> members; // Key: String
|
||||
gbArray(ssaValue *) nested_type_names; // ssaValue_TypeName
|
||||
i32 global_string_index;
|
||||
};
|
||||
|
||||
@@ -38,6 +39,8 @@ struct ssaTargetList {
|
||||
|
||||
struct ssaProcedure {
|
||||
ssaProcedure *parent;
|
||||
gbArray(ssaProcedure *) children;
|
||||
|
||||
ssaModule * module;
|
||||
String name;
|
||||
Type * type;
|
||||
@@ -47,9 +50,6 @@ struct ssaProcedure {
|
||||
gbArray(ssaBlock *) blocks;
|
||||
ssaBlock * curr_block;
|
||||
ssaTargetList * target_list;
|
||||
|
||||
gbArray(ssaProcedure *) anon_procs;
|
||||
gbArray(ssaProcedure *) nested_procs;
|
||||
};
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ struct ssaValue {
|
||||
ExactValue value;
|
||||
} constant;
|
||||
struct {
|
||||
Entity *entity;
|
||||
String name;
|
||||
Type * type;
|
||||
} type_name;
|
||||
struct {
|
||||
@@ -276,11 +276,13 @@ void ssa_module_init(ssaModule *m, Checker *c) {
|
||||
|
||||
map_init(&m->values, m->allocator);
|
||||
map_init(&m->members, m->allocator);
|
||||
gb_array_init(m->nested_type_names, m->allocator);
|
||||
}
|
||||
|
||||
void ssa_module_destroy(ssaModule *m) {
|
||||
map_destroy(&m->values);
|
||||
map_destroy(&m->members);
|
||||
gb_array_free(m->nested_type_names);
|
||||
gb_arena_free(&m->arena);
|
||||
}
|
||||
|
||||
@@ -416,10 +418,10 @@ ssaValue *ssa_alloc_instr(gbAllocator a, ssaInstrKind kind) {
|
||||
return v;
|
||||
}
|
||||
|
||||
ssaValue *ssa_make_value_type_name(gbAllocator a, Entity *e) {
|
||||
ssaValue *ssa_make_value_type_name(gbAllocator a, String name, Type *type) {
|
||||
ssaValue *v = ssa_alloc_value(a, ssaValue_TypeName);
|
||||
v->type_name.entity = e;
|
||||
v->type_name.type = e->type;
|
||||
v->type_name.name = name;
|
||||
v->type_name.type = type;
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -1146,8 +1148,17 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
|
||||
return value;
|
||||
|
||||
if (value->kind == ssaValue_Constant) {
|
||||
if (dst->kind == Type_Basic)
|
||||
return ssa_make_value_constant(proc->module->allocator, t, value->constant.value);
|
||||
if (dst->kind == Type_Basic) {
|
||||
ExactValue ev = value->constant.value;
|
||||
if (is_type_float(dst)) {
|
||||
ev = exact_value_to_float(ev);
|
||||
} else if (is_type_string(dst)) {
|
||||
//
|
||||
} else if (is_type_integer(dst)) {
|
||||
ev = exact_value_to_integer(ev);
|
||||
}
|
||||
return ssa_make_value_constant(proc->module->allocator, t, ev);
|
||||
}
|
||||
}
|
||||
|
||||
// integer -> integer
|
||||
@@ -1337,34 +1348,113 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
case_end;
|
||||
|
||||
case_ast_node(pl, ProcLit, expr);
|
||||
if (proc->anon_procs == NULL) {
|
||||
// TODO(bill): Cleanup
|
||||
gb_array_init(proc->anon_procs, gb_heap_allocator());
|
||||
if (proc->children == NULL) {
|
||||
gb_array_init(proc->children, gb_heap_allocator());
|
||||
}
|
||||
// NOTE(bill): Generate a new name
|
||||
// parent$count
|
||||
isize name_len = proc->name.len + 1 + 8 + 1;
|
||||
u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
|
||||
name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%d", LIT(proc->name), cast(i32)gb_array_count(proc->anon_procs));
|
||||
name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%d", LIT(proc->name), cast(i32)gb_array_count(proc->children));
|
||||
String name = make_string(name_text, name_len-1);
|
||||
|
||||
|
||||
// auto **found = map_get(&proc->module->info->definitions,
|
||||
// hash_pointer(expr))
|
||||
Type *type = type_of_expr(proc->module->info, expr);
|
||||
ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
|
||||
proc->module, type, pl->type, pl->body, name);
|
||||
ssaProcedure *np = &value->proc;
|
||||
|
||||
gb_array_append(proc->anon_procs, np);
|
||||
gb_array_append(proc->children, &value->proc);
|
||||
ssa_build_proc(value, proc);
|
||||
|
||||
return value; // TODO(bill): Is this correct?
|
||||
return value;
|
||||
case_end;
|
||||
|
||||
|
||||
case_ast_node(pl, CompoundLit, expr);
|
||||
GB_PANIC("TODO(bill): ssa_build_single_expr CompoundLit");
|
||||
case_ast_node(cl, CompoundLit, expr);
|
||||
Type *type = type_of_expr(proc->module->info, expr);
|
||||
Type *base_type = get_base_type(type);
|
||||
ssaValue *v = ssa_add_local_generated(proc, type);
|
||||
|
||||
Type *et = NULL;
|
||||
switch (base_type->kind) {
|
||||
case Type_Vector: et = base_type->vector.elem; break;
|
||||
case Type_Array: et = base_type->array.elem; break;
|
||||
case Type_Slice: et = base_type->slice.elem; break;
|
||||
}
|
||||
|
||||
switch (base_type->kind) {
|
||||
default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break;
|
||||
case Type_Structure: {
|
||||
auto *st = &base_type->structure;
|
||||
isize index = 0;
|
||||
for (AstNode *elem = cl->elem_list;
|
||||
elem != NULL;
|
||||
elem = elem->next) {
|
||||
ssaValue *field_expr = ssa_build_expr(proc, elem);
|
||||
Type *t = ssa_value_type(field_expr);
|
||||
if (t->kind != Type_Tuple) {
|
||||
Entity *field = st->fields[index];
|
||||
Type *ft = field->type;
|
||||
ssaValue *fv = ssa_emit_conv(proc, field_expr, ft);
|
||||
ssaValue *gep = ssa_emit_struct_gep(proc, v, index, ft);
|
||||
ssa_emit_store(proc, gep, fv);
|
||||
index++;
|
||||
} else {
|
||||
GB_PANIC("TODO(bill): tuples in struct literals");
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case Type_Vector:
|
||||
case Type_Array: {
|
||||
isize index = 0;
|
||||
for (AstNode *elem = cl->elem_list;
|
||||
elem != NULL;
|
||||
elem = elem->next) {
|
||||
ssaValue *field_expr = ssa_build_expr(proc, elem);
|
||||
Type *t = ssa_value_type(field_expr);
|
||||
if (t->kind != Type_Tuple) {
|
||||
ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
|
||||
ssaValue *gep = ssa_emit_struct_gep(proc, v, index, et);
|
||||
ssa_emit_store(proc, gep, ev);
|
||||
index++;
|
||||
} else {
|
||||
GB_PANIC("TODO(bill): tuples in array literals");
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case Type_Slice: {
|
||||
i64 count = cl->elem_count;
|
||||
ssaValue *array = ssa_add_local_generated(proc, make_type_array(proc->module->allocator, et, count));
|
||||
isize index = 0;
|
||||
for (AstNode *elem = cl->elem_list;
|
||||
elem != NULL;
|
||||
elem = elem->next) {
|
||||
ssaValue *field_expr = ssa_build_expr(proc, elem);
|
||||
Type *t = ssa_value_type(field_expr);
|
||||
if (t->kind != Type_Tuple) {
|
||||
ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
|
||||
ssaValue *gep = ssa_emit_struct_gep(proc, array, index, et);
|
||||
ssa_emit_store(proc, gep, ev);
|
||||
index++;
|
||||
} else {
|
||||
GB_PANIC("TODO(bill): tuples in array literals");
|
||||
}
|
||||
}
|
||||
|
||||
ssaValue *elem = ssa_emit_struct_gep(proc, array, v_zero32,
|
||||
make_type_pointer(proc->module->allocator, et));
|
||||
ssaValue *len = ssa_array_len(proc, array);
|
||||
ssaValue *gep = NULL;
|
||||
gep = ssa_emit_struct_gep(proc, v, v_zero32, ssa_value_type(elem));
|
||||
ssa_emit_store(proc, gep, elem);
|
||||
gep = ssa_emit_struct_gep(proc, v, v_one32, t_int);
|
||||
ssa_emit_store(proc, gep, len);
|
||||
gep = ssa_emit_struct_gep(proc, v, v_two32, t_int);
|
||||
ssa_emit_store(proc, gep, len);
|
||||
} break;
|
||||
}
|
||||
|
||||
return ssa_emit_load(proc, v);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ce, CastExpr, expr);
|
||||
@@ -1768,9 +1858,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(pd, ProcDecl, node);
|
||||
if (proc->nested_procs == NULL) {
|
||||
// TODO(bill): Cleanup
|
||||
gb_array_init(proc->nested_procs, gb_heap_allocator());
|
||||
if (proc->children == NULL) {
|
||||
gb_array_init(proc->children, gb_heap_allocator());
|
||||
}
|
||||
// NOTE(bill): Generate a new name
|
||||
// parent$name
|
||||
@@ -1780,15 +1869,36 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
||||
name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%.*s", LIT(proc->name), LIT(pd_name));
|
||||
String name = make_string(name_text, name_len-1);
|
||||
|
||||
Entity *e = *map_get(&proc->module->info->definitions, hash_pointer(pd->name));
|
||||
Entity **found = map_get(&proc->module->info->definitions, hash_pointer(pd->name));
|
||||
GB_ASSERT(found != NULL);
|
||||
Entity *e = *found;
|
||||
ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
|
||||
proc->module, e->type, pd->type, pd->body, name);
|
||||
ssaProcedure *np = &value->proc;
|
||||
gb_array_append(proc->nested_procs, np);
|
||||
|
||||
ssa_module_add_value(proc->module, e, value);
|
||||
gb_array_append(proc->children, &value->proc);
|
||||
ssa_build_proc(value, proc);
|
||||
case_end;
|
||||
|
||||
map_set(&proc->module->values, hash_pointer(e), value);
|
||||
case_ast_node(td, TypeDecl, node);
|
||||
|
||||
// NOTE(bill): Generate a new name
|
||||
// parent_proc.name
|
||||
String td_name = td->name->Ident.token.string;
|
||||
isize name_len = proc->name.len + 1 + td_name.len + 1;
|
||||
u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
|
||||
name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s.%.*s", LIT(proc->name), LIT(td_name));
|
||||
String name = make_string(name_text, name_len-1);
|
||||
|
||||
Entity **found = map_get(&proc->module->info->definitions, hash_pointer(td->name));
|
||||
GB_ASSERT(found != NULL);
|
||||
Entity *e = *found;
|
||||
ssaValue *value = ssa_make_value_type_name(proc->module->allocator,
|
||||
name, e->type);
|
||||
// HACK(bill): Override name of type so printer prints it correctly
|
||||
e->type->named.name = name;
|
||||
ssa_module_add_value(proc->module, e, value);
|
||||
gb_array_append(proc->module->nested_type_names, value);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ids, IncDecStmt, node);
|
||||
|
||||
+32
-18
@@ -2,7 +2,6 @@ struct AstNode;
|
||||
struct Type;
|
||||
struct AstScope;
|
||||
|
||||
|
||||
enum ParseFileError {
|
||||
ParseFile_None,
|
||||
|
||||
@@ -110,6 +109,7 @@ AST_NODE_KIND(_ExprBegin, struct{}) \
|
||||
AstNode *low, *high, *max; \
|
||||
b32 triple_indexed; \
|
||||
}) \
|
||||
AST_NODE_KIND(Ellipsis, struct { Token token; }) \
|
||||
AST_NODE_KIND(_ExprEnd, struct{}) \
|
||||
AST_NODE_KIND(_StmtBegin, struct{}) \
|
||||
AST_NODE_KIND(BadStmt, struct { Token begin, end; }) \
|
||||
@@ -164,7 +164,6 @@ AST_NODE_KIND(_DeclBegin, struct{}) \
|
||||
isize name_count, value_count; \
|
||||
}) \
|
||||
AST_NODE_KIND(ProcDecl, struct { \
|
||||
DeclKind kind; \
|
||||
AstNode *name; \
|
||||
AstNode *type; \
|
||||
AstNode *body; \
|
||||
@@ -295,6 +294,8 @@ Token ast_node_token(AstNode *node) {
|
||||
return node->IndexExpr.open;
|
||||
case AstNode_SliceExpr:
|
||||
return node->SliceExpr.open;
|
||||
case AstNode_Ellipsis:
|
||||
return node->Ellipsis.token;
|
||||
case AstNode_CastExpr:
|
||||
return node->CastExpr.token;
|
||||
case AstNode_DerefExpr:
|
||||
@@ -553,6 +554,11 @@ gb_inline AstNode *make_deref_expr(AstFile *f, AstNode *expr, Token op) {
|
||||
}
|
||||
|
||||
|
||||
gb_inline AstNode *make_ellipsis(AstFile *f, Token token) {
|
||||
AstNode *result = make_node(f, AstNode_Ellipsis);
|
||||
result->Ellipsis.token = token;
|
||||
return result;
|
||||
}
|
||||
gb_inline AstNode *make_basic_lit(AstFile *f, Token basic_lit) {
|
||||
AstNode *result = make_node(f, AstNode_BasicLit);
|
||||
result->BasicLit = basic_lit;
|
||||
@@ -678,7 +684,7 @@ gb_inline AstNode *make_bad_decl(AstFile *f, Token begin, Token end) {
|
||||
return result;
|
||||
}
|
||||
|
||||
gb_inline AstNode *make_variable_decl(AstFile *f, DeclKind kind, AstNode *name_list, isize name_count, AstNode *type, AstNode *value_list, isize value_count) {
|
||||
gb_inline AstNode *make_var_decl(AstFile *f, DeclKind kind, AstNode *name_list, isize name_count, AstNode *type, AstNode *value_list, isize value_count) {
|
||||
AstNode *result = make_node(f, AstNode_VarDecl);
|
||||
result->VarDecl.kind = kind;
|
||||
result->VarDecl.name_list = name_list;
|
||||
@@ -707,9 +713,8 @@ gb_inline AstNode *make_proc_type(AstFile *f, Token token, AstNode *param_list,
|
||||
return result;
|
||||
}
|
||||
|
||||
gb_inline AstNode *make_procedure_decl(AstFile *f, DeclKind kind, AstNode *name, AstNode *proc_type, AstNode *body, AstNode *tag_list, isize tag_count) {
|
||||
gb_inline AstNode *make_proc_decl(AstFile *f, AstNode *name, AstNode *proc_type, AstNode *body, AstNode *tag_list, isize tag_count) {
|
||||
AstNode *result = make_node(f, AstNode_ProcDecl);
|
||||
result->ProcDecl.kind = kind;
|
||||
result->ProcDecl.name = name;
|
||||
result->ProcDecl.type = proc_type;
|
||||
result->ProcDecl.body = body;
|
||||
@@ -1169,7 +1174,6 @@ AstNode *parse_atom_expr(AstFile *f, b32 lhs) {
|
||||
|
||||
case Token_OpenBrace: {
|
||||
if (is_literal_type(operand) && f->expr_level >= 0) {
|
||||
gb_printf_err("here\n");
|
||||
if (lhs) {
|
||||
// TODO(bill): Handle this
|
||||
}
|
||||
@@ -1474,8 +1478,12 @@ AstNode *parse_identifier_or_type(AstFile *f) {
|
||||
Token token = expect_token(f, Token_OpenBracket);
|
||||
AstNode *count_expr = NULL;
|
||||
|
||||
if (f->cursor[0].kind != Token_CloseBracket)
|
||||
if (f->cursor[0].kind == Token_Ellipsis) {
|
||||
count_expr = make_ellipsis(f, f->cursor[0]);
|
||||
next_token(f);
|
||||
} else if (f->cursor[0].kind != Token_CloseBracket) {
|
||||
count_expr = parse_expr(f, false);
|
||||
}
|
||||
expect_token(f, Token_CloseBracket);
|
||||
f->expr_level--;
|
||||
return make_array_type(f, token, count_expr, parse_type(f));
|
||||
@@ -1596,7 +1604,7 @@ AstNode *parse_body(AstFile *f, AstScope *scope) {
|
||||
return make_block_stmt(f, statement_list, statement_list_count, open, close);
|
||||
}
|
||||
|
||||
AstNode *parse_procedure_decl(AstFile *f, Token proc_token, AstNode *name, DeclKind kind) {
|
||||
AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) {
|
||||
AstNode *param_list = NULL;
|
||||
AstNode *result_list = NULL;
|
||||
isize param_count = 0;
|
||||
@@ -1621,7 +1629,7 @@ AstNode *parse_procedure_decl(AstFile *f, Token proc_token, AstNode *name, DeclK
|
||||
close_ast_scope(f);
|
||||
|
||||
AstNode *proc_type = make_proc_type(f, proc_token, param_list, param_count, result_list, result_count);
|
||||
return make_procedure_decl(f, kind, name, proc_type, body, tag_list, tag_count);
|
||||
return make_proc_decl(f, name, proc_type, body, tag_list, tag_count);
|
||||
}
|
||||
|
||||
AstNode *parse_decl(AstFile *f, AstNode *name_list, isize name_count) {
|
||||
@@ -1642,7 +1650,9 @@ AstNode *parse_decl(AstFile *f, AstNode *name_list, isize name_count) {
|
||||
declaration_kind = Declaration_Immutable;
|
||||
next_token(f);
|
||||
|
||||
if (f->cursor[0].kind == Token_proc) { // NOTE(bill): Procedure declarations
|
||||
if (f->cursor[0].kind == Token_proc &&
|
||||
declaration_kind == Declaration_Immutable) {
|
||||
// NOTE(bill): Procedure declarations
|
||||
Token proc_token = f->cursor[0];
|
||||
AstNode *name = name_list;
|
||||
if (name_count != 1) {
|
||||
@@ -1650,9 +1660,9 @@ AstNode *parse_decl(AstFile *f, AstNode *name_list, isize name_count) {
|
||||
return make_bad_decl(f, name->Ident.token, proc_token);
|
||||
}
|
||||
|
||||
AstNode *procedure_decl = parse_procedure_decl(f, proc_token, name, declaration_kind);
|
||||
add_ast_entity(f, f->curr_scope, procedure_decl, name_list);
|
||||
return procedure_decl;
|
||||
AstNode *proc_decl = parse_proc_decl(f, proc_token, name);
|
||||
add_ast_entity(f, f->curr_scope, proc_decl, name_list);
|
||||
return proc_decl;
|
||||
|
||||
} else {
|
||||
value_list = parse_rhs_expr_list(f, &value_count);
|
||||
@@ -1684,9 +1694,9 @@ AstNode *parse_decl(AstFile *f, AstNode *name_list, isize name_count) {
|
||||
return make_bad_decl(f, begin, f->cursor[0]);
|
||||
}
|
||||
|
||||
AstNode *variable_decl = make_variable_decl(f, declaration_kind, name_list, name_count, type, value_list, value_count);
|
||||
add_ast_entity(f, f->curr_scope, variable_decl, name_list);
|
||||
return variable_decl;
|
||||
AstNode *var_decl = make_var_decl(f, declaration_kind, name_list, name_count, type, value_list, value_count);
|
||||
add_ast_entity(f, f->curr_scope, var_decl, name_list);
|
||||
return var_decl;
|
||||
}
|
||||
|
||||
|
||||
@@ -1761,7 +1771,8 @@ AstNode *parse_return_stmt(AstFile *f) {
|
||||
isize result_count = 0;
|
||||
if (f->cursor[0].kind != Token_Semicolon)
|
||||
result = parse_rhs_expr_list(f, &result_count);
|
||||
expect_token(f, Token_Semicolon);
|
||||
if (f->cursor[0].kind != Token_CloseBrace)
|
||||
expect_token(f, Token_Semicolon);
|
||||
|
||||
return make_return_stmt(f, token, result, result_count);
|
||||
}
|
||||
@@ -1899,7 +1910,10 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
case Token_Xor:
|
||||
case Token_Not:
|
||||
s = parse_simple_stmt(f);
|
||||
if (s->kind != AstNode_ProcDecl && !allow_token(f, Token_Semicolon)) {
|
||||
if (s->kind != AstNode_ProcDecl &&
|
||||
!allow_token(f, Token_Semicolon) &&
|
||||
f->cursor[0].kind == Token_CloseBrace) {
|
||||
// TODO(bill): Cleanup semicolon handling in parser
|
||||
ast_file_err(f, f->cursor[0],
|
||||
"Expected `;` after statement, got `%.*s`",
|
||||
LIT(token_strings[f->cursor[0].kind]));
|
||||
|
||||
+1
-4
@@ -146,10 +146,7 @@ void print_ast(AstNode *node, isize indent) {
|
||||
break;
|
||||
case AstNode_ProcDecl:
|
||||
print_indent(indent);
|
||||
if (node->ProcDecl.kind == Declaration_Mutable)
|
||||
gb_printf("(decl:proc,mutable)\n");
|
||||
else if (node->ProcDecl.kind == Declaration_Immutable)
|
||||
gb_printf("(decl:proc,immutable)\n");
|
||||
gb_printf("(decl:proc)\n");
|
||||
print_ast(node->ProcDecl.type, indent+1);
|
||||
print_ast(node->ProcDecl.body, indent+1);
|
||||
print_ast(node->ProcDecl.tag_list, indent+1);
|
||||
|
||||
+2
-5
@@ -95,7 +95,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
|
||||
TOKEN_KIND(Token_Semicolon, ";"), \
|
||||
TOKEN_KIND(Token_Period, "."), \
|
||||
TOKEN_KIND(Token_Comma, ","), \
|
||||
TOKEN_KIND(Token_Ellipsis, "..."), \
|
||||
TOKEN_KIND(Token_Ellipsis, ".."), \
|
||||
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
|
||||
\
|
||||
TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
@@ -741,10 +741,7 @@ Token tokenizer_get_token(Tokenizer *t) {
|
||||
token = scan_number_to_token(t, true);
|
||||
} else if (t->curr_rune == '.') { // Could be an ellipsis
|
||||
advance_to_next_rune(t);
|
||||
if (t->curr_rune == '.') {
|
||||
advance_to_next_rune(t);
|
||||
token.kind = Token_Ellipsis;
|
||||
}
|
||||
token.kind = Token_Ellipsis;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user