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){
|
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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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){
|
||||||
Ast_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL);
|
if(is_flag_set(it->flags, AST_ANY_VARGS)){
|
||||||
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL, type);
|
if(it->expr)
|
||||||
make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
|
compiler_error(it->pos, "Internal compiler error: Default value for .. multiple arguments should be null");
|
||||||
it->type = type;
|
if(it->typespec)
|
||||||
args.add(type);
|
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(it->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_lambda(lambda, ret, args);
|
return type_lambda(lambda, ret, args);
|
||||||
@@ -890,8 +908,13 @@ 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){
|
||||||
node->value.type = 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);
|
return operand_const_rvalue(node->value);
|
||||||
BREAK();
|
BREAK();
|
||||||
@@ -1131,21 +1154,30 @@ 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);
|
||||||
make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type, TYPE_AND_EXPR_REQUIRED);
|
if(is_flag_set(lambda_arg->flags, AST_ANY_VARGS)){
|
||||||
item->resolved_type = lambda_arg->type;
|
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);
|
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user