Working on Any arrays and vargs
This commit is contained in:
@@ -273,6 +273,13 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
||||
}
|
||||
|
||||
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);
|
||||
if(!written) {
|
||||
gen("%Q", node->value.intern_val);
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
|
||||
main :: (argc: int, argv: **char): int
|
||||
test_arrays()
|
||||
test_any()
|
||||
test_arrays()
|
||||
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 :: ()
|
||||
array1 := []S64{1,2,3,4,5}
|
||||
array2: []S64 = {0,9,8}
|
||||
@@ -17,16 +31,7 @@ test_arrays :: ()
|
||||
for array2;; *it = 0
|
||||
for i := 0, i < length_of(array1), i+=1;; assert(0 == array1[i])
|
||||
|
||||
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_array_any(10, 20, 30)
|
||||
|
||||
Some_Struct :: struct
|
||||
thing: int
|
||||
|
||||
@@ -326,7 +326,7 @@ eval_unary(Token *pos, Token_Kind op, Operand *operand){
|
||||
}
|
||||
|
||||
function void
|
||||
try_converting_untyped_to_typed(Operand *op){
|
||||
try_converting_untyped_to_typed(Value *op){
|
||||
if(is_untyped(op->type)){
|
||||
switch(op->type->kind){
|
||||
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){
|
||||
TYPE_AND_EXPR_REQUIRED = 0,
|
||||
TYPE_CAN_BE_NULL = 1,
|
||||
@@ -653,11 +658,24 @@ resolve_lambda_type(Ast_Lambda *lambda){
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
it->type = type;
|
||||
args.add(type);
|
||||
}
|
||||
|
||||
args.add(it->type);
|
||||
}
|
||||
|
||||
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){
|
||||
// @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;
|
||||
}
|
||||
if(is_any(compound_context)){
|
||||
try_converting_untyped_to_typed(&node->value);
|
||||
}
|
||||
}
|
||||
return operand_const_rvalue(node->value);
|
||||
BREAK();
|
||||
}
|
||||
@@ -1131,22 +1154,31 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
if(item){
|
||||
set_flag(item->call_flags, CALL_INCLUDED);
|
||||
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);
|
||||
item->resolved_type = lambda_arg->type;
|
||||
}
|
||||
|
||||
item->resolved_index = lambda->args.get_index(&lambda_arg);
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
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
|
||||
if(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_index = lambda->args.get_index(&lambda_arg);
|
||||
set_flag(call_item->call_flags, CALL_INCLUDED);
|
||||
items.add(call_item);
|
||||
}
|
||||
else compiler_error(lambda_arg->pos, "Required value in lambda call was not passed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user