Working on Any arrays and vargs

This commit is contained in:
Krzosa Karol
2022-06-20 10:02:23 +02:00
parent 4e288dcfab
commit 99b0ba2673
3 changed files with 73 additions and 29 deletions

View File

@@ -273,6 +273,13 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
} }
CASE(VALUE, Atom){ CASE(VALUE, Atom){
if(is_any(type_of_var)){
gen("(Any){&");
gen("("); gen_simple_decl(node->type); gen("){"); gen_value(node->value); gen("}");
gen(", %d}", node->type->type_id);
return true;
}
B32 written = gen_value(node->value); B32 written = gen_value(node->value);
if(!written) { if(!written) {
gen("%Q", node->value.intern_val); gen("%Q", node->value.intern_val);

View File

@@ -1,9 +1,23 @@
main :: (argc: int, argv: **char): int main :: (argc: int, argv: **char): int
test_arrays()
test_any() test_any()
test_arrays()
test_type() test_type()
test_array_any :: (any: Any, array_of_any: ..)
for array_of_any
pass
test_any :: ()
some_int_value := 10
thing: Any = some_int_value
other_any: Any = thing
imp_any := thing
assert(thing.type != Any)
any_array := []Any{some_int_value, thing}
for any_array
assert(it.type == S64)
test_arrays :: () test_arrays :: ()
array1 := []S64{1,2,3,4,5} array1 := []S64{1,2,3,4,5}
array2: []S64 = {0,9,8} array2: []S64 = {0,9,8}
@@ -17,16 +31,7 @@ test_arrays :: ()
for array2;; *it = 0 for array2;; *it = 0
for i := 0, i < length_of(array1), i+=1;; assert(0 == array1[i]) for i := 0, i < length_of(array1), i+=1;; assert(0 == array1[i])
test_any :: () test_array_any(10, 20, 30)
some_int_value := 10
thing: Any = some_int_value
other_any: Any = thing
imp_any := thing
assert(thing.type != Any)
any_array := []Any{some_int_value, thing}
for any_array
assert(it.type == S64)
Some_Struct :: struct Some_Struct :: struct
thing: int thing: int

View File

@@ -326,7 +326,7 @@ eval_unary(Token *pos, Token_Kind op, Operand *operand){
} }
function void function void
try_converting_untyped_to_typed(Operand *op){ try_converting_untyped_to_typed(Value *op){
if(is_untyped(op->type)){ if(is_untyped(op->type)){
switch(op->type->kind){ switch(op->type->kind){
case TYPE_UNTYPED_INT: op->type = type_s64; break; case TYPE_UNTYPED_INT: op->type = type_s64; break;
@@ -338,6 +338,11 @@ try_converting_untyped_to_typed(Operand *op){
} }
} }
function void
try_converting_untyped_to_typed(Operand *op){
try_converting_untyped_to_typed(&op->value);
}
FLAG32(Typecheck_Flag){ FLAG32(Typecheck_Flag){
TYPE_AND_EXPR_REQUIRED = 0, TYPE_AND_EXPR_REQUIRED = 0,
TYPE_CAN_BE_NULL = 1, TYPE_CAN_BE_NULL = 1,
@@ -653,11 +658,24 @@ 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); Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL, type);
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;
args.add(type); }
args.add(it->type);
} }
return type_lambda(lambda, ret, args); return type_lambda(lambda, ret, args);
@@ -890,9 +908,14 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
CASE(VALUE, Atom){ CASE(VALUE, Atom){
// @todo: More propagation of const char to sub values // @todo: More propagation of const char to sub values
if(compound_context && is_string(node->value.type) && is_string(compound_context)){ if(compound_context){
if(is_string(node->value.type) && is_string(compound_context)){
node->value.type = compound_context; node->value.type = compound_context;
} }
if(is_any(compound_context)){
try_converting_untyped_to_typed(&node->value);
}
}
return operand_const_rvalue(node->value); return operand_const_rvalue(node->value);
BREAK(); BREAK();
} }
@@ -1131,22 +1154,31 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
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); Operand expr = resolve_expr(item->item, AST_CANT_BE_NULL, lambda_arg->type);
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;
}
item->resolved_index = lambda->args.get_index(&lambda_arg); item->resolved_index = lambda->args.get_index(&lambda_arg);
items.add(item); items.add(item);
} }
else{ else{
if(!lambda_arg->expr)
compiler_error(lambda_arg->pos, "Required value: %Q in lambda call was not passed", lambda_arg->name);
// @note: default values are typechecked when they get resolved // @note: default values are typechecked when they get resolved
if(lambda_arg->expr){
Ast_Call_Item *call_item = ast_call_item(lambda_arg->expr->pos, 0, 0, lambda_arg->expr); Ast_Call_Item *call_item = ast_call_item(lambda_arg->expr->pos, 0, 0, lambda_arg->expr);
call_item->resolved_type = lambda_arg->expr->resolved_type; call_item->resolved_type = lambda_arg->expr->resolved_type;
call_item->resolved_index = lambda->args.get_index(&lambda_arg); call_item->resolved_index = lambda->args.get_index(&lambda_arg);
set_flag(call_item->call_flags, CALL_INCLUDED); set_flag(call_item->call_flags, CALL_INCLUDED);
items.add(call_item); items.add(call_item);
} }
else compiler_error(lambda_arg->pos, "Required value in lambda call was not passed");
}
} }