diff --git a/README.md b/README.md index 83c6f46..077f5cb 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,10 @@ Stuff that helped me a lot programming the compiler. Hopefully they also will be - [ ] Generics / Parametric polymorphism +- [ ] Platforms + - [x] Windows + - [ ] Unix based + - [ ] Language constructs - [x] If - [x] For loops diff --git a/core_ast.cpp b/core_ast.cpp index 067906c..83b98f2 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -81,6 +81,7 @@ struct Ast_Expr:Ast{ union{ Ast_Type *index_original_type; Ast_Type *cast_after_type; + Ast_Type *dot_access_step_resolution; }; }; diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index efd656c..8bc1ce1 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -323,7 +323,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){ CASE(BINARY, Binary){ if(node->op == TK_Dot){ if(gen_expr(node->left)){ - if(node->resolved_type && node->resolved_type->kind == TYPE_POINTER) gen("->"); + if(node->dot_access_step_resolution && node->dot_access_step_resolution->kind == TYPE_POINTER) gen("->"); else gen("."); } gen_expr(node->right); diff --git a/core_main.cpp b/core_main.cpp index 72509ee..ac2e3b4 100644 --- a/core_main.cpp +++ b/core_main.cpp @@ -237,17 +237,20 @@ int main(int argument_count, char **arguments){ test_intern_table(); emit_line_directives = true; - String program_name = "examples/types_as_first_class_values.kl"_s; if(argument_count > 1){ - program_name = string_from_cstring(arguments[1]); + String program_name = string_from_cstring(arguments[1]); + compile_file(program_name, COMPILE_AND_RUN); + } - Scratch scratch; - Array examples = os_list_dir(scratch, "examples"_s); - // compile_file("examples/language_basics.kl"_s, COMPILE_AND_RUN); - For(examples){ - if(it.is_directory) continue; - compile_file(it.absolute_path, COMPILE_AND_RUN); + else { + Scratch scratch; + Array examples = os_list_dir(scratch, "examples"_s); + // compile_file("examples/language_basics.kl"_s, COMPILE_AND_RUN); + For(examples){ + if(it.is_directory) continue; + compile_file(it.absolute_path, COMPILE_AND_RUN); + } } __debugbreak(); diff --git a/core_parsing.cpp b/core_parsing.cpp index b92c7b7..f6c1879 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -379,6 +379,9 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0){ } else{ Ast *result = parse_decl(false); + if(result && result->kind != AST_VAR && result->kind != AST_CONST){ + compiler_error(token, "Invalid statement construct"); + } if(!result){ result = parse_expr(); result = parse_init_stmt((Ast_Expr *)result); @@ -831,7 +834,6 @@ parse_decl(B32 is_global){ result->kind = AST_LAMBDA; } } - } } else if(token_match(TK_Identifier, TK_Colon)){ diff --git a/core_typechecking.cpp b/core_typechecking.cpp index faf6d66..7f8cad9 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -972,7 +972,7 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){ Ast_Type *type = decl->type; if(type == type_type && decl->type_val && (is_enum(decl->type_val) || is_struct(decl->type_val))) type = decl->type_val; - if(current) current->resolved_type = type; + if(current) current->dot_access_step_resolution = type; if(is_pointer(type)) type = type->base; type_complete(type); @@ -1106,6 +1106,8 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ } else if(node->op == TK_Dot){ Operand op = resolve_field_access(node, 0); + node->resolved_type = op.type; + if(op.is_const){ rewrite_into_const(node, Ast_Binary, op.value); } diff --git a/examples/language_basics.kl b/examples/language_basics.kl index 4badb0b..f7c750f 100644 --- a/examples/language_basics.kl +++ b/examples/language_basics.kl @@ -21,11 +21,6 @@ main :: (): int string_val: String = "String type" cstring_val: *char = "CString type" - Assert(s64val == 0 && s32val == 0 && s16val == 0 && s8val == 0 && intval == 0 && u64val == 0 && u32val == 0 && u16val == 0 && u8val == 0 && f64val == 0 && f32val == 0) - // @todo: Fix error here !! - // Assert(string_val[0] == 'S) //' - Assert(cstring_val[0] == 'C') - // This is how we can assign variables // There is no need for prefixes, compiler figures // out the format by itself @@ -58,9 +53,35 @@ main :: (): int // To do this we need a cast combining_types := this_is_s64_by_default->F64 + this_is_f64_by_default - + Assert(s64val == 0 && s32val == 0 && s16val == 0 && s8val == 0 && intval == 0 && u64val == 0 && u32val == 0 && u16val == 0 && u8val == 0 && f64val == 0 && f32val == 0) + Assert(string_val[0] == 'S') + Assert(cstring_val[0] == 'C') Assert(signed_variable == 10 && unsigned_variable == 10) Assert(INT_VALUE == 10) Assert(FLOAT_VALUE == 124.125) Assert(this_is_f64_by_default == 15.1255) Assert(combining_types == 15.1255 + 20) + + // Compound statements + data1 := Data{ + a = 1, + d = 2 + } + data2: Data = { + a = 4, + b = 2, + } + Assert(data1.a == 1) + Assert(data1.b == 0) + Assert(data1.c == 0) + Assert(data1.d == 2) + Assert(data2.a == 4) + Assert(data2.b == 2) + Assert(data2.c == 0) + Assert(data2.d == 0) + +Data :: struct + a: S64 + b: S32 + c: S32 + d: S32 diff --git a/examples/runtime_type_information.kl b/examples/runtime_type_information.kl index b77fef5..e6c4186 100644 --- a/examples/runtime_type_information.kl +++ b/examples/runtime_type_information.kl @@ -6,7 +6,7 @@ main :: (): int // about this type. For example this information allows us to walk // the type tree, pretty print all values in that type, along with their sizes. // Other use cases allow us to do a type safe printf - type_info: *Type_Info = get_type_info(some_type) + type_info: *Type_Info = GetTypeInfo(some_type) // It can be null, requiring the type information would be a bit unwise // this is a lot of data @@ -45,11 +45,11 @@ main :: (): int Assert(value_to_be_wrapped == 20) - letter := get_first_letter_of_type(value_to_be_wrapped) + letter := GetFirstLetterOfType(value_to_be_wrapped) Assert(letter == 'I') -get_first_letter_of_type :: (a: Any): U8 - type_info := get_type_info(a.type) +GetFirstLetterOfType :: (a: Any): U8 + type_info := GetTypeInfo(a.type) if !type_info return '-' diff --git a/modules/base.kl b/modules/base.kl index 738f6e4..c0b90d6 100644 --- a/modules/base.kl +++ b/modules/base.kl @@ -94,7 +94,7 @@ StringToString16 :: (arena: *Arena, in: String): String16 result.str[result.len] = 0 return result -test_unicode :: (arena: *Arena) +TestUnicode :: (arena: *Arena) string := " 豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ..." string_result := StringToString16(arena, string) print(string_result) diff --git a/modules/language.kl b/modules/language.kl index 50adef1..a3bf020 100644 --- a/modules/language.kl +++ b/modules/language.kl @@ -68,7 +68,7 @@ Type_Info :: struct type_infos_len: S64 #foreign type_infos : *Type_Info #foreign -get_type_info :: (type: Type): *Type_Info +GetTypeInfo :: (type: Type): *Type_Info id := type->S64 if id >= type_infos_len return 0