From 839596962060faea66cfa5e696155c98ff9ff094 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Wed, 5 Oct 2022 20:54:38 +0200 Subject: [PATCH] Typing the untyped values in an array of Any, commenting stuff --- core_ast.cpp | 8 ++++ core_globals.cpp | 2 - core_typechecking.cpp | 51 +++++++++++++--------- examples/any_and_variadic_args.core | 65 ++++++++++++++++++----------- 4 files changed, 81 insertions(+), 45 deletions(-) diff --git a/core_ast.cpp b/core_ast.cpp index 888fb46..dc4a6a5 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -88,6 +88,14 @@ struct Ast_Expr:Ast{ }; struct Ast_Atom: Ast_Expr{ + // We have a field type here + // it has a different purpose from the + // resolved_type of Ast_Expr, it describes + // the inherent type of a value + // + // resolved_type is a solid type that + // can be use during code generation + // it cannot be untyped. (or at least thats the hope :) INLINE_VALUE_FIELDS; }; diff --git a/core_globals.cpp b/core_globals.cpp index c00c580..16b1544 100644 --- a/core_globals.cpp +++ b/core_globals.cpp @@ -4,8 +4,6 @@ global String symbol_prefix = ""_s; global B32 single_header_library_mode = false; global String single_header_library_name = ""_s; - - thread_local Parse_Ctx *pctx; Allocator *bigint_allocator; diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 8b409fc..3b02d89 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -85,6 +85,30 @@ operand_rvalue(Ast_Type *type){ return result; } +function Ast_Type * +get_default_type_from_untyped(Ast_Type *type){ + switch(type->kind){ + case TYPE_UNTYPED_INT: return type_s64; break; + case TYPE_UNTYPED_BOOL: return type_bool; break; + case TYPE_UNTYPED_STRING: return type_string; break; + case TYPE_UNTYPED_FLOAT: return type_f64; break; + default: invalid_codepath; + } + return 0; +} + +function void +try_converting_untyped_to_default_type(Value *op){ + if(is_untyped(op->type)){ + op->type = get_default_type_from_untyped(op->type); + } +} + +function void +try_converting_untyped_to_default_type(Operand *op){ + try_converting_untyped_to_default_type(&op->value); +} + function void check_value_bounds(Token *pos, Value *a){ if(!is_int(a->type)) return; @@ -102,7 +126,9 @@ convert_untyped_to_typed(Token *pos, Value *a, Ast_Type *new_type){ if(a->type == 0) return; if(is_typed(a->type)) return; - if(is_int(a->type) && is_int(new_type)) + if(is_any(new_type)) + new_type = get_default_type_from_untyped(a->type); + else if(is_int(a->type) && is_int(new_type)) assert(a->type == untyped_int); else if(is_int(a->type) && is_enum(new_type)) ; @@ -349,24 +375,6 @@ eval_unary(Token *pos, Token_Kind op, Operand *operand){ } } -function void -try_converting_untyped_to_default_type(Value *op){ - if(is_untyped(op->type)){ - switch(op->type->kind){ - case TYPE_UNTYPED_INT: op->type = type_s64; break; - case TYPE_UNTYPED_BOOL: op->type = type_bool; break; - case TYPE_UNTYPED_STRING: op->type = type_string; break; - case TYPE_UNTYPED_FLOAT: op->type = type_f64; break; - default: invalid_codepath; - } - } -} - -function void -try_converting_untyped_to_default_type(Operand *op){ - try_converting_untyped_to_default_type(&op->value); -} - function void make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *type, Typecheck_Flag debug_flag){ if(type == expr->type){ @@ -599,6 +607,11 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_ auto node = (Ast_Atom *)ast; convert_untyped_to_typed(ast->pos, &node->value, type); + + // This only is required when we have arrays of Any type. + // That is because we are folding all the constants and there + // the resolved_type is set + node->resolved_type = node->value.type; return; } diff --git a/examples/any_and_variadic_args.core b/examples/any_and_variadic_args.core index 4439067..3e666dc 100644 --- a/examples/any_and_variadic_args.core +++ b/examples/any_and_variadic_args.core @@ -14,31 +14,48 @@ AnyArguments :: (values: []Any) * Released under GPLv3. */ IntegerToString :: (value: S64, result: *U8, base: S64): *U8 - // check that the base if valid - if (base < 2) || (base > 36) - *result = 0 // ' - return result - - ptr := result - ptr1 := result - tmp_char: U8 - tmp_value: S64 - - for value != 0 - tmp_value = value - value /= base - *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)] - - // Apply negative sign - if tmp_value < 0 - *ptr++ = '-' - *ptr-- = 0 - for ptr1 < ptr - tmp_char = *ptr - *ptr-- = *ptr1 - *ptr1++ = tmp_char + // check that the base if valid + if (base < 2) || (base > 36) + *result = 0 // ' return result + ptr := result + ptr1 := result + tmp_char: U8 + tmp_value: S64 + + for value != 0 + tmp_value = value + value /= base + *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)] + + // Apply negative sign + if tmp_value < 0 + *ptr++ = '-' + *ptr-- = 0 + for ptr1 < ptr + tmp_char = *ptr + *ptr-- = *ptr1 + *ptr1++ = tmp_char + return result + + + +StringToDouble :: (s: String): F64 + sign: F64 = 1.0 + i := 0 + + if s[i] == '-' + sign = -1 + i += 1 + elif s[i] == '+' + i += 1 + + for , i < Len(s), i+= 1 + pass // BACKUP + + return 0 + FormatString :: (buffer: *U8, buffer_len: U64, string: String, args: ..) // @todo(krzosa): Add consideration of buffer SIZE! Add some function to handle this OutStr or something @@ -78,6 +95,6 @@ main :: (): int Assert(*(values[1].data->*S64) == 20) buf: [128]U8 - FormatString(&buf[0], Len(buf), "Test % %", {32->S64, 156->S64}) + FormatString(&buf[0], Len(buf), "Test % %", {32, 156}) return 0 \ No newline at end of file