From: Brendan Hansen Date: Mon, 20 Jul 2020 00:39:56 +0000 (-0500) Subject: Added '__heap_start' builtin; more cases for casting X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=1f397ebde4098cd06aa2de4bab9643d96bf719d9;p=onyx.git Added '__heap_start' builtin; more cases for casting --- diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 25791afb..c2fc7c67 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -346,6 +346,16 @@ extern AstBasicType basic_type_f32; extern AstBasicType basic_type_f64; extern AstBasicType basic_type_rawptr; +extern AstNumLit builtin_heap_start; + +typedef struct BuiltinSymbol { + char* sym; + AstNode* node; +} BuiltinSymbol; + +extern const BuiltinSymbol builtin_symbols[]; + + // NOTE: Useful inlined functions static inline b32 is_lval(AstNode* node) { diff --git a/onyx b/onyx index 6bf00b5a..03babad2 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/arrays.onyx b/progs/arrays.onyx index eab2ac03..a7ec6d2d 100644 --- a/progs/arrays.onyx +++ b/progs/arrays.onyx @@ -21,21 +21,15 @@ min :: proc #overloaded { // NOTE: in-place insertion sort sort :: proc (src: ^i32, len: i32) { - i := 0; - while i < len { + for i: 0, len { smallest := i; - j := i + 1; - while j < len { + for j: i + 1, len if src[j] < src[smallest] smallest = j; - j += 1; - } tmp :: src[smallest]; src[smallest] = src[i]; src[i] = tmp; - - i += 1; } } @@ -44,8 +38,8 @@ for_test :: proc { for i: 0, 10 print(i); } -str_test :: proc #export "main" { - hello_str :: "Hello World!"; +str_test :: proc #export { + hello_str :: "Hello World! 123"; // Address of and dereference cancel each other out print(^*hello_str); @@ -58,17 +52,13 @@ str_test :: proc #export "main" { } // Don't need to bind this function to a symbol -proc #export "main2" { - print(min(10.0, 12.0)); +proc #export "main" { + print(__heap_start as i32); - global_arr = 128 as ^i32; + global_arr = __heap_start as ^i32; len :: 10; - i := 0; - while i < len { - global_arr[i] = (len - i) * 10; - i += 1; - } + for i: 0, len global_arr[i] = (len - i) * 10; print(global_arr, len); @@ -76,6 +66,4 @@ proc #export "main2" { print(1234567); print(global_arr, len); - - str_test(); } diff --git a/progs/print_funcs.onyx b/progs/print_funcs.onyx index e232cb25..2cd75ddc 100644 --- a/progs/print_funcs.onyx +++ b/progs/print_funcs.onyx @@ -5,35 +5,19 @@ print_i64 :: proc #foreign "host" "print" (value: i64) --- print_f64 :: proc #foreign "host" "print" (value: f64) --- print_i32arr :: proc (arr: ^i32, len: i32) { - i := 0; - while i < len { - print(arr[i]); - i += 1; - } + for i: 0, len print(arr[i]); } print_i64arr :: proc (arr: ^i64, len: i32) { - i := 0; - while i < len { - print(arr[i]); - i += 1; - } + for i: 0, len print(arr[i]); } print_f32arr :: proc (arr: ^f32, len: i32) { - i := 0; - while i < len { - print(arr[i]); - i += 1; - } + for i: 0, len print(arr[i]); } print_f64arr :: proc (arr: ^f64, len: i32) { - i := 0; - while i < len { - print(arr[i]); - i += 1; - } + for i: 0, len print(arr[i]); } // NOTE: print null-terminated string diff --git a/src/onyxlex.c b/src/onyxlex.c index afc0b6c5..5b2acd12 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -19,6 +19,7 @@ static const char* token_type_names[] = { "proc", "as", "while", + "for", "break", "continue", @@ -157,7 +158,7 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { LITERAL_TOKEN("%=", 0, Token_Type_Percent_Equal); // Symbols - if (char_is_alpha(*tk.text)) { + if (char_is_alpha(*tk.text) || *tokenizer->curr == '_') { u64 len = 0; while (char_is_alphanum(*tokenizer->curr) || charset_contains("_$", *tokenizer->curr)) { len++; diff --git a/src/onyxparser.c b/src/onyxparser.c index 097af9cb..a630e36b 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -8,20 +8,6 @@ static AstNode error_node = { Ast_Kind_Error, 0, NULL, NULL }; -AstBasicType basic_type_void = { { Ast_Kind_Basic_Type, 0, "void" }, &basic_types[Basic_Kind_Void] }; -AstBasicType basic_type_bool = { { Ast_Kind_Basic_Type, 0, "bool" }, &basic_types[Basic_Kind_Bool] }; -AstBasicType basic_type_i8 = { { Ast_Kind_Basic_Type, 0, "i8" }, &basic_types[Basic_Kind_I8] }; -AstBasicType basic_type_u8 = { { Ast_Kind_Basic_Type, 0, "u8" }, &basic_types[Basic_Kind_U8] }; -AstBasicType basic_type_i16 = { { Ast_Kind_Basic_Type, 0, "i16" }, &basic_types[Basic_Kind_I16] }; -AstBasicType basic_type_u16 = { { Ast_Kind_Basic_Type, 0, "u16" }, &basic_types[Basic_Kind_U16] }; -AstBasicType basic_type_i32 = { { Ast_Kind_Basic_Type, 0, "i32" }, &basic_types[Basic_Kind_I32] }; -AstBasicType basic_type_u32 = { { Ast_Kind_Basic_Type, 0, "u32" }, &basic_types[Basic_Kind_U32] }; -AstBasicType basic_type_i64 = { { Ast_Kind_Basic_Type, 0, "i64" }, &basic_types[Basic_Kind_I64] }; -AstBasicType basic_type_u64 = { { Ast_Kind_Basic_Type, 0, "u64" }, &basic_types[Basic_Kind_U64] }; -AstBasicType basic_type_f32 = { { Ast_Kind_Basic_Type, 0, "f32" }, &basic_types[Basic_Kind_F32] }; -AstBasicType basic_type_f64 = { { Ast_Kind_Basic_Type, 0, "f64" }, &basic_types[Basic_Kind_F64] }; -AstBasicType basic_type_rawptr = { { Ast_Kind_Basic_Type, 0, "rawptr" }, &basic_types[Basic_Kind_Rawptr] }; - // NOTE: Forward declarations static void consume_token(OnyxParser* parser); static void unconsume_token(OnyxParser* parser); diff --git a/src/onyxsymres.c b/src/onyxsymres.c index f504daa3..ca3c274f 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -1,9 +1,45 @@ #define BH_DEBUG #include "onyxsempass.h" +AstBasicType basic_type_void = { { Ast_Kind_Basic_Type, 0, "void" }, &basic_types[Basic_Kind_Void] }; +AstBasicType basic_type_bool = { { Ast_Kind_Basic_Type, 0, "bool" }, &basic_types[Basic_Kind_Bool] }; +AstBasicType basic_type_i8 = { { Ast_Kind_Basic_Type, 0, "i8" }, &basic_types[Basic_Kind_I8] }; +AstBasicType basic_type_u8 = { { Ast_Kind_Basic_Type, 0, "u8" }, &basic_types[Basic_Kind_U8] }; +AstBasicType basic_type_i16 = { { Ast_Kind_Basic_Type, 0, "i16" }, &basic_types[Basic_Kind_I16] }; +AstBasicType basic_type_u16 = { { Ast_Kind_Basic_Type, 0, "u16" }, &basic_types[Basic_Kind_U16] }; +AstBasicType basic_type_i32 = { { Ast_Kind_Basic_Type, 0, "i32" }, &basic_types[Basic_Kind_I32] }; +AstBasicType basic_type_u32 = { { Ast_Kind_Basic_Type, 0, "u32" }, &basic_types[Basic_Kind_U32] }; +AstBasicType basic_type_i64 = { { Ast_Kind_Basic_Type, 0, "i64" }, &basic_types[Basic_Kind_I64] }; +AstBasicType basic_type_u64 = { { Ast_Kind_Basic_Type, 0, "u64" }, &basic_types[Basic_Kind_U64] }; +AstBasicType basic_type_f32 = { { Ast_Kind_Basic_Type, 0, "f32" }, &basic_types[Basic_Kind_F32] }; +AstBasicType basic_type_f64 = { { Ast_Kind_Basic_Type, 0, "f64" }, &basic_types[Basic_Kind_F64] }; +AstBasicType basic_type_rawptr = { { Ast_Kind_Basic_Type, 0, "rawptr" }, &basic_types[Basic_Kind_Rawptr] }; + +AstNumLit builtin_heap_start = { Ast_Kind_NumLit, 0, NULL, NULL, (AstType *) &basic_type_rawptr, NULL, 0 }; + +const BuiltinSymbol builtin_symbols[] = { + { "void", (AstNode *) &basic_type_void }, + { "bool", (AstNode *) &basic_type_bool }, + { "i8", (AstNode *) &basic_type_i8 }, + { "u8", (AstNode *) &basic_type_u8 }, + { "i16", (AstNode *) &basic_type_i16 }, + { "u16", (AstNode *) &basic_type_u16 }, + { "i32", (AstNode *) &basic_type_i32 }, + { "u32", (AstNode *) &basic_type_u32 }, + { "i64", (AstNode *) &basic_type_i64 }, + { "u64", (AstNode *) &basic_type_u64 }, + { "f32", (AstNode *) &basic_type_f32 }, + { "f64", (AstNode *) &basic_type_f64 }, + { "rawptr", (AstNode *) &basic_type_rawptr }, + + { "__heap_start", (AstNode *) &builtin_heap_start }, + + { NULL, NULL }, +}; + static b32 symbol_introduce(OnyxToken* tkn, AstNode* symbol); +static void symbol_builtin_introduce(char* sym, AstNode *node); static AstNode* symbol_resolve(OnyxToken* tkn); -static void symbol_basic_type_introduce(AstBasicType* basic_type); static void scope_enter(Scope* new_scope); static void scope_leave(); @@ -42,8 +78,8 @@ static b32 symbol_introduce(OnyxToken* tkn, AstNode* symbol) { return 1; } -static void symbol_basic_type_introduce(AstBasicType* basic_type) { - bh_table_put(AstNode *, semstate.curr_scope->symbols, basic_type->name, (AstNode *) basic_type); +static void symbol_builtin_introduce(char* sym, AstNode *node) { + bh_table_put(AstNode *, semstate.curr_scope->symbols, sym, node); } static AstNode* symbol_resolve(OnyxToken* tkn) { @@ -316,19 +352,11 @@ void onyx_resolve_symbols(ProgramInfo* program) { scope_enter(semstate.global_scope); // NOTE: Add types to global scope - symbol_basic_type_introduce(&basic_type_void); - symbol_basic_type_introduce(&basic_type_bool); - symbol_basic_type_introduce(&basic_type_i8); - symbol_basic_type_introduce(&basic_type_u8); - symbol_basic_type_introduce(&basic_type_i16); - symbol_basic_type_introduce(&basic_type_u16); - symbol_basic_type_introduce(&basic_type_i32); - symbol_basic_type_introduce(&basic_type_u32); - symbol_basic_type_introduce(&basic_type_i64); - symbol_basic_type_introduce(&basic_type_u64); - symbol_basic_type_introduce(&basic_type_f32); - symbol_basic_type_introduce(&basic_type_f64); - symbol_basic_type_introduce(&basic_type_rawptr); + BuiltinSymbol* bsym = (BuiltinSymbol *) &builtin_symbols[0]; + while (bsym->sym != NULL) { + symbol_builtin_introduce(bsym->sym, bsym->node); + bsym++; + } bh_arr_each(AstBinding *, binding, program->bindings) if (!symbol_introduce((*binding)->token, (*binding)->node)) return; diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 972db89f..7e949cc3 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -212,6 +212,7 @@ static WasmType onyx_type_to_wasm_type(Type* type) { if (basic->size <= 4) return WASM_TYPE_INT32; if (basic->size == 8) return WASM_TYPE_INT64; } + if (basic->flags & Basic_Flag_Pointer) return WASM_TYPE_INT32; if (basic->flags & Basic_Flag_Float) { if (basic->size <= 4) return WASM_TYPE_FLOAT32; if (basic->size == 8) return WASM_TYPE_FLOAT64; @@ -848,14 +849,17 @@ COMPILE_FUNC(expression, AstTyped* expr) { *pcode = code; } -static const WasmInstructionType cast_map[][6] = { - // I32 U32 I64 U64 F32 F64 - /* I32 */ { WI_NOP, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_F32_FROM_I32_S, WI_F64_FROM_I32_S }, - /* U32 */ { WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U }, - /* I64 */ { WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_S, WI_F64_FROM_I64_S }, - /* U64 */ { WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_U, WI_F64_FROM_I64_U }, - /* F32 */ { WI_I32_FROM_F32_S, WI_I32_FROM_F32_U, WI_I64_FROM_F32_S, WI_I64_FROM_F32_U, WI_NOP, WI_F64_FROM_F32 }, - /* F64 */ { WI_I32_FROM_F64_S, WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64, WI_NOP, }, +static const WasmInstructionType cast_map[][9] = { + // I8 I16 I32 U32 I64 U64 F32 F64 PTR + /* I8 */ { WI_NOP, WI_I32_EXTEND_8_S, WI_I32_EXTEND_8_S, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, + /* I16 */ { WI_NOP, WI_NOP, WI_I32_EXTEND_16_S, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U, WI_UNREACHABLE }, + /* I32 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_F32_FROM_I32_S, WI_F64_FROM_I32_S, WI_NOP }, + /* U32 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U, WI_NOP }, + /* I64 */ { WI_NOP, WI_NOP, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_S, WI_F64_FROM_I64_S, WI_I32_FROM_I64 }, + /* U64 */ { WI_NOP, WI_NOP, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_U, WI_F64_FROM_I64_U, WI_I32_FROM_I64 }, + /* F32 */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_I32_FROM_F32_S, WI_I32_FROM_F32_U, WI_I64_FROM_F32_S, WI_I64_FROM_F32_U, WI_NOP, WI_F64_FROM_F32, WI_UNREACHABLE }, + /* F64 */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_I32_FROM_F64_S, WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64, WI_NOP, WI_UNREACHABLE }, + /* PTR */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE, WI_UNREACHABLE, WI_NOP }, }; COMPILE_FUNC(cast, AstUnaryOp* cast) { @@ -866,36 +870,57 @@ COMPILE_FUNC(cast, AstUnaryOp* cast) { Type* from = cast->expr->type; Type* to = cast->type; - i32 fromidx = 0, toidx = 0; + i32 fromidx = -1, toidx = -1; if (from->Basic.flags & Basic_Flag_Integer) { b32 unsign = (from->Basic.flags & Basic_Flag_Unsigned) != 0; - if (from->Basic.size == 4 && !unsign) fromidx = 0; - else if (from->Basic.size == 4 && unsign) fromidx = 1; - else if (from->Basic.size == 8 && !unsign) fromidx = 2; - else if (from->Basic.size == 8 && unsign) fromidx = 3; + if (from->Basic.size == 1 && !unsign) fromidx = 0; + else if (from->Basic.size == 1 && unsign) fromidx = -1; + else if (from->Basic.size == 2 && !unsign) fromidx = 1; + else if (from->Basic.size == 2 && unsign) fromidx = -1; + else if (from->Basic.size == 4 && !unsign) fromidx = 2; + else if (from->Basic.size == 4 && unsign) fromidx = 3; + else if (from->Basic.size == 8 && !unsign) fromidx = 4; + else if (from->Basic.size == 8 && unsign) fromidx = 5; } else if (from->Basic.flags & Basic_Flag_Float) { - if (from->Basic.size == 4) fromidx = 4; - else if (from->Basic.size == 8) fromidx = 5; + if (from->Basic.size == 4) fromidx = 6; + else if (from->Basic.size == 8) fromidx = 7; + } + else if (from->Basic.flags & Basic_Flag_Pointer) { + fromidx = 8; } if (to->Basic.flags & Basic_Flag_Integer) { b32 unsign = (to->Basic.flags & Basic_Flag_Unsigned) != 0; - if (to->Basic.size == 4 && !unsign) toidx = 0; - else if (to->Basic.size == 4 && unsign) toidx = 1; - else if (to->Basic.size == 8 && !unsign) toidx = 2; - else if (to->Basic.size == 8 && unsign) toidx = 3; + if (to->Basic.size == 1 && !unsign) toidx = 0; + else if (to->Basic.size == 1 && unsign) toidx = -1; + else if (to->Basic.size == 2 && !unsign) toidx = 1; + else if (to->Basic.size == 2 && unsign) toidx = -1; + else if (to->Basic.size == 4 && !unsign) toidx = 2; + else if (to->Basic.size == 4 && unsign) toidx = 3; + else if (to->Basic.size == 8 && !unsign) toidx = 4; + else if (to->Basic.size == 8 && unsign) toidx = 5; } else if (to->Basic.flags & Basic_Flag_Float) { - if (to->Basic.size == 4) toidx = 4; - else if (to->Basic.size == 8) toidx = 5; + if (to->Basic.size == 4) toidx = 6; + else if (to->Basic.size == 8) toidx = 7; + } + else if (to->Basic.flags & Basic_Flag_Pointer) { + toidx = 8; } - WasmInstructionType cast_op = cast_map[fromidx][toidx]; - if (cast_op != WI_NOP) { - WI(cast_op); + if (fromidx != -1 && toidx != -1) { + WasmInstructionType cast_op = cast_map[fromidx][toidx]; + if (cast_op == WI_UNREACHABLE) { + onyx_message_add(Msg_Type_Literal, + cast->token->pos, + "bad cast"); + } + else if (cast_op != WI_NOP) { + WI(cast_op); + } } *pcode = code; @@ -1216,8 +1241,11 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) { } } - - + // NOTE: Round up to the nearest multiple of 16 + builtin_heap_start.value.i = + (module->next_datum_offset & 15) + ? ((module->next_datum_offset >> 4) + 1) << 4 + : module->next_datum_offset; // NOTE: Then, compile everything bh_arr_each(Entity, entity, program->entities) {