Msg_Type_Function_Param_Mismatch,
Msg_Type_Duplicate_Member,
+ Msg_Type_No_Field,
Msg_Type_Unresolved_Type,
Msg_Type_Unresolved_Symbol,
+ Msg_Type_Failed_Gen_Load,
+ Msg_Type_Failed_Gen_Store,
+
Msg_Type_Count,
} MsgType;
const char* type_get_name(Type* type);
u32 type_get_alignment_log2(Type* type);
-StructMember type_struct_lookup_member(Type* type, char* member);
+b32 type_struct_lookup_member(Type* type, char* member, StructMember* smem);
b32 type_is_pointer(Type* type);
+b32 type_is_array(Type* tyoe);
b32 type_is_struct(Type* type);
b32 type_is_bool(Type* type);
b32 type_results_in_void(Type* type);
use "progs/intrinsics"
use "progs/print_funcs"
-global_arr :: global ^i32;
+global_arr :: global []i32;
min_i32 :: proc (a: i32, b: i32) -> i32 {
least := a;
}
// NOTE: in-place insertion sort
-sort :: proc (src: ^i32, len: i32) {
+sort :: proc (src: []i32, len: i32) {
for i: 0, len {
smallest := i;
// Address of and dereference cancel each other out
print(^*hello_str);
- print(hello_str, 5);
+ print(hello_str as []u8, 5);
for i: 0, 10, 2 print(i);
print(__heap_start as i32);
len :: 10;
- global_arr = alloc((len * 4) as u32) as ^i32;
- other_arr := alloc((len * 4) as u32) as ^i32;
+ global_arr = alloc(sizeof [10]i32) as []i32;
+ other_arr := alloc((len * 4) as u32) as []i32;
print(global_arr as i32);
print(other_arr as i32);
return ((__heap_start as u32) + curr_offset) as rawptr;
}
-alloc_2darr :: proc (rows: u32, cols: u32) -> ^^i32 {
- arr := alloc(rows * 4) as ^^i32;
+alloc_2darr :: proc (rows: u32, cols: u32) -> []^i32 {
+ arr := alloc(rows * 4) as []^i32;
for i: 0, cols arr[i] = alloc(cols * 4) as ^i32;
return arr;
}
return ^fooarr[i];
}
-proc #export "main" {
+proc #export "main3" {
// foo := foo_make();
// other_foo := foo_make();
// other_foo.i = 1234;
return count;
}
-link_test :: proc #export "main2" {
+link_test :: proc #export "main4" {
node_head := alloc(sizeof ^Link) as ^^Link;
*node_head = 0 as ^Link;
// TODO: Make everything below this comment work
-// SOA :: struct {
-// x : [3]i32;
-// y : [3]i32;
-// }
+multi_arr :: proc #export "main2" {
+ arr1 := alloc(sizeof [5][5] i32) as [5][5] i32; // Sizeof 25 * 4
+ arr2 := alloc(sizeof [5]^ i32) as [5]^ i32; // Sizeof 20
-// soa_test :: proc #export "main" {
-// m_arr := alloc(sizeof [5][5]i32) as [5][5]i32;
+ arr2[3][2] = 5; // (arr1 + (3 * 5 * 4) + (2 * 4))
+ print(arr2[3][2]);
+ // arr2[3][2] = 5; // (arr1[3] + 2 * 4)
+}
+
+Vec2 :: struct {
+ x : i32;
+ y : i32;
+}
-// for y: 0, 5 {
-// for x: 0, 5 {
-// m_arr[y][x] = x + y * 5;
-// }
-// }
+SOA :: struct {
+ positions : [10] Vec2;
+ velocities : [10] Vec2;
+ things : [10] ^Vec2;
+}
+
+vec2_set :: proc (v: ^Vec2) {
+ v.x = 1234;
+ v.y = 5678;
+}
-// print(m_arr[2][4]); // 14
+soa_test :: proc #export "main" {
-// print(sizeof SOA);
-// }
\ No newline at end of file
+ // print(sizeof SOA); // 240
+
+ soa := alloc(sizeof SOA + 20 * sizeof Vec2) as ^SOA;
+
+ for i: 0, 10 {
+ soa.things[i] = alloc(sizeof Vec2) as ^Vec2;
+ }
+
+ soa.velocities[2].x = 10;
+ soa.velocities[2].y = 12;
+ soa.positions[5].x = 1;
+ soa.positions[5].y = 2;
+ soa.positions[2].x = 1001;
+ vec2_set(^(soa.positions[6]));
+ vec2_set(soa.things[2]);
+
+ print(soa.positions[5].y);
+ print(soa.velocities[2].x);
+ print(soa.things[2].x);
+ print(soa.things[2].y);
+ print(soa.positions[6].x);
+ print(soa.positions[6].y);
+
+ m_arr := alloc(sizeof [5][5]i32) as [5][5]i32;
+
+ for y: 0, 5 {
+ for x: 0, 5 {
+ m_arr[y][x] = x + y * 5;
+ }
+ }
+
+ for i: 0, 25 print((m_arr as [] i32)[i]);
+}
\ No newline at end of file
if (fornode->step)
if (check_expression(fornode->step)) return 1;
+ if (check_expression((AstTyped *) fornode->var)) return 1;
+
// HACK
if (!types_are_compatible(fornode->start->type, &basic_types[Basic_Kind_I32])) {
onyx_message_add(Msg_Type_Literal,
}
token_toggle_end(field->token);
- StructMember smem = type_struct_lookup_member(field->expr->type, field->token->text);
+ StructMember smem;
+ if (!type_struct_lookup_member(field->expr->type, field->token->text, &smem)) {
+ onyx_message_add(Msg_Type_No_Field,
+ field->token->pos,
+ field->token->text,
+ type_get_name(field->expr->type));
+ token_toggle_end(field->token);
+ return 1;
+ }
+
field->offset = smem.offset;
field->type = smem.type;
- token_toggle_end(field->token);
+ token_toggle_end(field->token);
return 0;
}
"function '%b' expected type '%s' in position '%d', got '%s'",
"duplicate declaration of struct member '%s'",
+ "field '%s' does not exist on '%s'",
"unable to resolve type for symbol '%b'",
"unable to resolve symbol '%b'",
+
+ "failed to generate load instruction for type '%s'",
+ "failed to generate store instruction for type '%s'",
};
void onyx_message_init(bh_allocator allocator, bh_table(bh_file_contents)* files) {
return 2;
}
-StructMember type_struct_lookup_member(Type* type, char* member) {
- if (!type_is_struct(type)) return (StructMember) { 0 };
+b32 type_struct_lookup_member(Type* type, char* member, StructMember* smem) {
+ if (!type_is_struct(type)) return 0;
if (type->kind == Type_Kind_Pointer) type = type->Pointer.elem;
TypeStruct* stype = &type->Struct;
- if (!bh_table_has(StructMember, stype->members, member)) return (StructMember) { 0 };
- StructMember smem = bh_table_get(StructMember, stype->members, member);
- return smem;
+ if (!bh_table_has(StructMember, stype->members, member)) return 0;
+ *smem = bh_table_get(StructMember, stype->members, member);
+ return 1;
}
b32 type_is_pointer(Type* type) {
|| (type->kind == Type_Kind_Array);
}
+b32 type_is_array(Type* type) {
+ return type->kind == Type_Kind_Array;
+}
+
b32 type_is_struct(Type* type) {
if (type->kind == Type_Kind_Struct) return 1;
if (type->kind == Type_Kind_Pointer && type->Pointer.elem->kind == Type_Kind_Struct) return 1;
i32 store_size = type_size_of(type);
i32 is_basic = type->kind == Type_Kind_Basic || type->kind == Type_Kind_Pointer;
- i32 is_integer = is_basic &&
- ((type->Basic.flags & Basic_Flag_Integer)
- || (type->Basic.flags & Basic_Flag_Pointer));
- i32 is_float = is_basic && type->Basic.flags & Basic_Flag_Float;
+ i32 is_pointer = is_basic && (type->Basic.flags & Basic_Flag_Pointer);
+ i32 is_integer = is_basic && (type->Basic.flags & Basic_Flag_Integer);
+ i32 is_float = is_basic && type->Basic.flags & Basic_Flag_Float;
- if (is_integer) {
+ if (is_pointer) {
+ WID(WI_I32_STORE, ((WasmInstructionData) { alignment, offset }));
+ } else if (is_integer) {
if (store_size == 1) WID(WI_I32_STORE_8, ((WasmInstructionData) { alignment, offset }));
else if (store_size == 2) WID(WI_I32_STORE_16, ((WasmInstructionData) { alignment, offset }));
else if (store_size == 4) WID(WI_I32_STORE, ((WasmInstructionData) { alignment, offset }));
if (store_size == 4) WID(WI_F32_STORE, ((WasmInstructionData) { alignment, offset }));
else if (store_size == 8) WID(WI_F64_STORE, ((WasmInstructionData) { alignment, offset }));
} else {
- onyx_message_add(Msg_Type_Literal,
+ onyx_message_add(Msg_Type_Failed_Gen_Store,
(OnyxFilePos) { 0 },
- "failed to generate store instruction");
+ type_get_name(type));
}
*pcode = code;
i32 load_size = type_size_of(type);
i32 is_basic = type->kind == Type_Kind_Basic || type->kind == Type_Kind_Pointer;
- i32 is_integer = is_basic &&
- ((type->Basic.flags & Basic_Flag_Integer)
- || (type->Basic.flags & Basic_Flag_Pointer));
+ i32 is_pointer = is_basic && (type->Basic.flags & Basic_Flag_Pointer);
+ i32 is_integer = is_basic && (type->Basic.flags & Basic_Flag_Integer);
i32 is_float = is_basic && type->Basic.flags & Basic_Flag_Float;
i32 is_unsigned = is_basic && type->Basic.flags & Basic_Flag_Unsigned;
WasmInstructionType instr = WI_NOP;
i32 alignment = type_get_alignment_log2(type);
- if (is_integer) {
+ if (is_pointer) {
+ instr = WI_I32_LOAD;
+ }
+ else if (is_integer) {
if (load_size == 1) instr = WI_I32_LOAD_8_S;
else if (load_size == 2) instr = WI_I32_LOAD_16_S;
else if (load_size == 4) instr = WI_I32_LOAD;
else if (load_size == 8) instr = WI_I64_LOAD;
if (load_size < 4 && is_unsigned) instr += 1;
- } else if (is_float) {
+ }
+ else if (is_float) {
if (load_size == 4) instr = WI_F32_LOAD;
else if (load_size == 8) instr = WI_F64_LOAD;
}
WID(instr, ((WasmInstructionData) { alignment, offset }));
if (instr == WI_NOP) {
- onyx_message_add(Msg_Type_Literal,
+ onyx_message_add(Msg_Type_Failed_Gen_Load,
(OnyxFilePos) { 0 },
- "failed to generate load instruction");
+ type_get_name(type));
}
*pcode = code;
COMPILE_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return) {
bh_arr(WasmInstruction) code = *pcode;
- *offset_return = 0;
-
compile_expression(mod, &code, aa->expr);
if (aa->elem_size != 1) {
WID(WI_I32_CONST, aa->elem_size);
WI(WI_I32_MUL);
}
- compile_expression(mod, &code, aa->addr);
+
+ u64 offset = 0;
+ if (aa->addr->kind == Ast_Kind_Array_Access
+ && aa->addr->type->kind == Type_Kind_Array) {
+ compile_array_access_location(mod, &code, (AstArrayAccess *) aa->addr, &offset);
+ } else if (aa->addr->kind == Ast_Kind_Field_Access
+ && aa->addr->type->kind == Type_Kind_Array) {
+ compile_field_access_location(mod, &code, (AstFieldAccess *) aa->addr, &offset);
+ } else {
+ compile_expression(mod, &code, aa->addr);
+ }
WI(WI_I32_ADD);
+ *offset_return += offset;
+
*pcode = code;
}
source_expr = (AstTyped *) ((AstFieldAccess *) source_expr)->expr;
}
- if (source_expr->kind == Ast_Kind_Array_Access) {
+ if (source_expr->kind == Ast_Kind_Array_Access
+ && source_expr->type->kind != Type_Kind_Pointer) {
u64 o2 = 0;
compile_array_access_location(mod, &code, (AstArrayAccess *) source_expr, &o2);
offset += o2;
module->next_func_idx = program->foreign_func_count;
module->next_global_idx = program->foreign_global_count;
+ WasmExport mem_export = {
+ .kind = WASM_FOREIGN_MEMORY,
+ .idx = 0,
+ };
+ bh_table_put(WasmExport, module->exports, "memory", mem_export);
+ module->export_count++;
+
bh_arr_each(Entity, entity, program->entities) {
switch (entity->type) {
case Entity_Type_Function_Header: {