F32 is default float, operator overloads turn literals into default types

This commit is contained in:
Krzosa Karol
2022-10-09 14:51:27 +02:00
parent 21ac6662c4
commit 54426fdd69
10 changed files with 64 additions and 64 deletions

View File

@@ -114,7 +114,7 @@ Dot :: (a: Vec3, b: Vec3): F32 ;; return a.x*b.x + a.y*b.y + a.z*b.z
- [ ] Polymorphism - [ ] Polymorphism
- [x] C like void type - [x] C like void type
- [x] Any with it's dynamic typing - [x] Dynamic typing using Any and operator overloading
- [ ] Generics aka compile time polymorphism aka parametric polymorphism - [ ] Generics aka compile time polymorphism aka parametric polymorphism
- [ ] Something akin to inheritence - [ ] Something akin to inheritence
- [ ] Something akin to C unions or Rust's enums - [ ] Something akin to C unions or Rust's enums

View File

@@ -2,5 +2,5 @@
pushd %~dp0 pushd %~dp0
rem cl main.cpp -I.. user32.lib rem cl main.cpp -I.. user32.lib
clang core_main.cpp -O2 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib clang core_main.cpp -O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib
popd popd

View File

@@ -56,7 +56,6 @@ enum{
AST_STRICT = bit_flag(3), AST_STRICT = bit_flag(3),
AST_AGGREGATE = bit_flag(4), AST_AGGREGATE = bit_flag(4),
AST_AGGREGATE_CHILD = bit_flag(5), AST_AGGREGATE_CHILD = bit_flag(5),
AST_ANY_VARGS = bit_flag(6),
AST_ATOM = bit_flag(7), AST_ATOM = bit_flag(7),
AST_FOREIGN = bit_flag(8), AST_FOREIGN = bit_flag(8),
AST_DECL = bit_flag(9), AST_DECL = bit_flag(9),

View File

@@ -796,12 +796,8 @@ compile_to_c_code(){
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#ifndef Panic
#define Panic(...) (*(volatile int *)0 = 0)
#endif
#ifndef Assert #ifndef Assert
#define Assert(x) do{if(!(x))Panic();}while(0) #define Assert(x) do{if(!(x))(*(volatile int *)0 = 0);}while(0)
#endif #endif
#ifndef AssertMessage #ifndef AssertMessage

View File

@@ -444,15 +444,9 @@ parse_lambda(Token *token){
Ast_Decl *param = ast_new(Ast_Decl, AST_VAR, name, AST_DECL); Ast_Decl *param = ast_new(Ast_Decl, AST_VAR, name, AST_DECL);
param->name = name->intern_val; param->name = name->intern_val;
if(token_match(TK_TwoDots)){
set_flag(param->flags, AST_ANY_VARGS);
}
else{
param->typespec = parse_expr(); param->typespec = parse_expr();
if(token_match(TK_Assign)) if(token_match(TK_Assign))
param->expr = parse_expr(); param->expr = parse_expr();
}
params.add(param); params.add(param);
} }

View File

@@ -91,7 +91,7 @@ get_default_type_from_untyped(Ast_Type *type){
case TYPE_UNTYPED_INT: return type_s64; break; case TYPE_UNTYPED_INT: return type_s64; break;
case TYPE_UNTYPED_BOOL: return type_bool; break; case TYPE_UNTYPED_BOOL: return type_bool; break;
case TYPE_UNTYPED_STRING: return type_string; break; case TYPE_UNTYPED_STRING: return type_string; break;
case TYPE_UNTYPED_FLOAT: return type_f64; break; case TYPE_UNTYPED_FLOAT: return type_f32; break;
default: invalid_codepath; default: invalid_codepath;
} }
return 0; return 0;
@@ -891,24 +891,12 @@ resolve_lambda_type(Ast_Lambda *lambda){
} }
For(lambda->args){ For(lambda->args){
if(is_flag_set(it->flags, AST_ANY_VARGS)){
if(it->expr)
compiler_error(it->pos, "Internal compiler error: Default value for .. multiple arguments should be null");
if(it->typespec)
compiler_error(it->pos, "Internal compiler error: Typespec for .. multiple arguments should be null");
it->type = type_slice(type_any, it);
}
else {
Ast_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL); Ast_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL);
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL, type, 0); Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL, type, 0);
make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL); make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
it->type = type; it->type = type;
try_propagating_resolved_type_to_untyped_literals(it->expr, it->type); try_propagating_resolved_type_to_untyped_literals(it->expr, it->type);
}
args.add(it->type); args.add(it->type);
} }
@@ -1290,16 +1278,27 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
// Try finding a operator overload // Try finding a operator overload
if(!is_const){ if(!is_const){
U64 hash = calculate_hash_for_arguments(left.type, right.type); Value left_copy = left.value;
Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, left.type, right.type, node->pos, node->op, hash); Value right_copy = right.value;
try_converting_untyped_to_default_type(&left_copy);
try_converting_untyped_to_default_type(&right_copy);
U64 hash = calculate_hash_for_arguments(left_copy.type, right_copy.type);
Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, left_copy.type, right_copy.type, node->pos, node->op, hash);
if(operator_overload){ if(operator_overload){
proceed_to_default_operator_handler = false; proceed_to_default_operator_handler = false;
if(operator_overload->lambda->ret.len != 1){ if(operator_overload->lambda->ret.len != 1){
compiler_error(operator_overload->pos, "Operator overload is required to have exactly 1 return value"); compiler_error(operator_overload->pos, "Operator overload is required to have exactly 1 return value");
} }
left.value = left_copy;
right.value = right_copy;
node->resolved_type = operator_overload->type->func.ret; node->resolved_type = operator_overload->type->func.ret;
node->resolved_operator_overload = operator_overload; node->resolved_operator_overload = operator_overload;
// We opt out early because we convert all literals to default type
// We don't need to propagate resolved type
return operand_rvalue(node->resolved_type);
} }
} }
@@ -1529,15 +1528,9 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
if(item){ if(item){
set_flag(item->call_flags, CALL_INCLUDED); set_flag(item->call_flags, CALL_INCLUDED);
Operand expr = resolve_expr(item->item, AST_CANT_BE_NULL, lambda_arg->type, field_access_scope); Operand expr = resolve_expr(item->item, AST_CANT_BE_NULL, lambda_arg->type, field_access_scope);
if(is_flag_set(lambda_arg->flags, AST_ANY_VARGS)){
make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type->base, TYPE_AND_EXPR_REQUIRED);
item->resolved_type = expr.type;
}
else{
make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type, TYPE_AND_EXPR_REQUIRED); make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type, TYPE_AND_EXPR_REQUIRED);
item->resolved_type = lambda_arg->type; item->resolved_type = lambda_arg->type;
}
try_propagating_resolved_type_to_untyped_literals(item->item, item->resolved_type); try_propagating_resolved_type_to_untyped_literals(item->item, item->resolved_type);
item->resolved_index = lambda->args.get_index(&lambda_arg); item->resolved_index = lambda->args.get_index(&lambda_arg);

View File

@@ -1,5 +1,5 @@
VariadicArguments :: (string: *char, args: ..): Any VariadicArguments :: (string: *char, args: []Any): Any
return args[0] return args[0]
AnyArguments :: (values: []Any) AnyArguments :: (values: []Any)
@@ -39,8 +39,6 @@ IntegerToString :: (value: S64, result: *U8, base: S64): *U8
*ptr1++ = tmp_char *ptr1++ = tmp_char
return result return result
StringToDouble :: (s: String): F64 StringToDouble :: (s: String): F64
sign: F64 = 1.0 sign: F64 = 1.0
i := 0 i := 0
@@ -56,7 +54,7 @@ StringToDouble :: (s: String): F64
return 0 return 0
FormatString :: (buffer: *U8, buffer_len: U64, string: String, args: ..) FormatString :: (buffer: *U8, buffer_len: U64, string: String, args: []Any)
// @todo(krzosa): Add consideration of buffer SIZE! Add some function to handle this OutStr or something // @todo(krzosa): Add consideration of buffer SIZE! Add some function to handle this OutStr or something
arg_counter := 0 arg_counter := 0
out_buffer_len := 0 out_buffer_len := 0

View File

@@ -8,9 +8,29 @@ len : S64
*(result.data->*S64) = *(a.data->*S64) + *(b.data->*S64) *(result.data->*S64) = *(a.data->*S64) + *(b.data->*S64)
return result return result
"+" :: (a: Any, b: S64): Any
result: Any = storage[len++]
if a.type == S64
*(result.data->*S64) = *(a.data->*S64) + b
return result
"==" :: (a: Any, b: S64): Bool
result := false
if a.type == S64
result = *(a.data->*S64) == b
return result
"==" :: (a: Any, b: Any): Bool
result := false
if a.type == S64 && b.type == S64
result = *(a.data->*S64) == *(b.data->*S64)
return result
main :: (): int main :: (): int
a: Any = 10 a: Any = 10
b: Any = 20 b: Any = 20
c := a + b c := a + b
Assert(c.type == S64 && *(c.data->*S64) == 30) Assert(c.type == S64 && c == 30)
Assert(a+b+a==c+(5+5))
return 0 return 0

View File

@@ -29,13 +29,13 @@ main :: (): int
// We can also tell the compiler to infer the type // We can also tell the compiler to infer the type
this_is_s64_by_default := 10 this_is_s64_by_default := 10
this_is_f64_by_default := 10.1251 this_is_f32_by_default := 10.1251
this_is_string_by_default := "Thing" this_is_string_by_default := "Thing"
// Reassigning values is exactly like in other languages // Reassigning values is exactly like in other languages
this_is_s64_by_default = 20 this_is_s64_by_default = 20
this_is_string_by_default = "Other_Thing" this_is_string_by_default = "Other_Thing"
this_is_f64_by_default = 15.1255 this_is_f32_by_default = 15.1255
// @todo: Add type_of operator!!! // @todo: Add type_of operator!!!
// Assert(type_of(this_is_string_by_default) == String) // Assert(type_of(this_is_string_by_default) == String)
@@ -51,7 +51,7 @@ main :: (): int
// When it comes to runtime variables it's a bit different // When it comes to runtime variables it's a bit different
// To do this we need a cast // To do this we need a cast
combining_types := this_is_s64_by_default->F64 + this_is_f64_by_default combining_types := this_is_s64_by_default->F32 + this_is_f32_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(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(string_val[0] == 'S')
@@ -59,7 +59,7 @@ main :: (): int
Assert(signed_variable == 10 && unsigned_variable == 10) Assert(signed_variable == 10 && unsigned_variable == 10)
Assert(INT_VALUE == 10) Assert(INT_VALUE == 10)
Assert(FLOAT_VALUE == 124.125) Assert(FLOAT_VALUE == 124.125)
Assert(this_is_f64_by_default == 15.1255) Assert(this_is_f32_by_default == 15.1255)
Assert(combining_types == 15.1255 + 20) Assert(combining_types == 15.1255 + 20)
// Compound statements // Compound statements

View File

@@ -141,7 +141,7 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
window_dc := GetDC(window) window_dc := GetDC(window)
bitmap := CreateBitmap(screen_size) bitmap := CreateBitmap(screen_size)
requested_time_per_frame := 1.0 / 60.0 requested_time_per_frame: F64 = 1.0 / 60.0
frame_start_time := Time() frame_start_time := Time()
frame_number: S64 frame_number: S64
for AppIsRunning for AppIsRunning