Improved any support, removed C Var args
This commit is contained in:
@@ -5,7 +5,7 @@ global S32 global_indent;
|
|||||||
global S32 is_inside_struct;
|
global S32 is_inside_struct;
|
||||||
|
|
||||||
function void gen_ast(Ast *ast);
|
function void gen_ast(Ast *ast);
|
||||||
function bool gen_expr(Ast_Expr *ast, Ast_Type *type_of_var = 0, bool is_vargs = false);
|
function bool gen_expr(Ast_Expr *ast);
|
||||||
|
|
||||||
function void
|
function void
|
||||||
gen_indent(){
|
gen_indent(){
|
||||||
@@ -270,6 +270,35 @@ enum {
|
|||||||
DONT_EMIT_VALUE = 1,
|
DONT_EMIT_VALUE = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function void
|
||||||
|
gen_pointer_to_lvalue(Ast_Expr *expr){
|
||||||
|
gen("&(");
|
||||||
|
gen_simple_decl(expr->resolved_type);
|
||||||
|
gen(")");
|
||||||
|
gen("{");
|
||||||
|
gen_expr(expr);
|
||||||
|
gen("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
gen_try_any_or_slice(Ast_Expr *expr, Ast_Type *decl_type){
|
||||||
|
|
||||||
|
// We want normal values to get boxed as Any pointers
|
||||||
|
// but other then that we shouldn't box other Any values
|
||||||
|
if(expr->kind != AST_COMPOUND && is_any(decl_type) && !is_any(expr->resolved_type)){
|
||||||
|
gen("(Any){");
|
||||||
|
gen_pointer_to_lvalue(expr);
|
||||||
|
gen(", %d}", expr->resolved_type->type_id);
|
||||||
|
}
|
||||||
|
else if(expr->kind == AST_IDENT && is_slice(decl_type)){
|
||||||
|
Ast_Atom *atom = (Ast_Atom *)expr;
|
||||||
|
gen("{%d, ", atom->resolved_type->arr.size);
|
||||||
|
gen_expr(expr);
|
||||||
|
gen("}");
|
||||||
|
}
|
||||||
|
else gen_expr(expr);
|
||||||
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names){
|
gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names){
|
||||||
if(is_flag_set(decl->flags, AST_FOREIGN)) gen("extern ");
|
if(is_flag_set(decl->flags, AST_FOREIGN)) gen("extern ");
|
||||||
@@ -282,7 +311,7 @@ gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names){
|
|||||||
|
|
||||||
if(decl->expr){
|
if(decl->expr){
|
||||||
gen(" = ");
|
gen(" = ");
|
||||||
gen_expr(decl->expr, decl->type);
|
gen_try_any_or_slice(decl->expr, decl->type);
|
||||||
} else { // Default zero
|
} else { // Default zero
|
||||||
if(is_numeric(decl->type)){
|
if(is_numeric(decl->type)){
|
||||||
gen(" = 0");
|
gen(" = 0");
|
||||||
@@ -297,15 +326,10 @@ gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
|||||||
gen_simple_decl(lambda->resolved_type->func.ret, name);
|
gen_simple_decl(lambda->resolved_type->func.ret, name);
|
||||||
gen("(");
|
gen("(");
|
||||||
For(lambda->args){
|
For(lambda->args){
|
||||||
if(is_flag_set(it->flags, AST_ANY_VARGS)){
|
|
||||||
gen("...");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
gen_var(it, DONT_EMIT_VALUE, true);
|
gen_var(it, DONT_EMIT_VALUE, true);
|
||||||
if(&it != (lambda->args.end() - 1))
|
if(&it != (lambda->args.end() - 1))
|
||||||
gen(", ");
|
gen(", ");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
gen(")");
|
gen(")");
|
||||||
|
|
||||||
if(generate_block && lambda->scope){
|
if(generate_block && lambda->scope){
|
||||||
@@ -315,30 +339,25 @@ gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function bool
|
function bool
|
||||||
gen_expr(Ast_Expr *ast, Ast_Type *type_of_var, bool is_vargs){
|
gen_expr(Ast_Expr *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
CASE(IDENT, Atom){
|
CASE(IDENT, Atom){
|
||||||
if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE)
|
if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(type_of_var && is_slice(type_of_var) && is_array(node->resolved_decl->type)){
|
/// @edit
|
||||||
assert(!is_vargs);
|
// if(type_of_var && is_slice(type_of_var) && is_array(node->resolved_decl->type)){
|
||||||
gen("{%d, ", (int)node->resolved_decl->type->arr.size);
|
// gen("{%d, ", (int)node->resolved_decl->type->arr.size);
|
||||||
gen("%Q}", node->intern_val);
|
// gen("%Q}", node->intern_val);
|
||||||
}
|
// }
|
||||||
|
|
||||||
else if(type_of_var && !is_any(ast->resolved_type) && is_any(type_of_var)){
|
// else if(type_of_var && !is_any(ast->resolved_type) && is_any(type_of_var)){
|
||||||
if(is_vargs){
|
// gen("(Any){&");
|
||||||
gen_expr(ast, 0, is_vargs);
|
// gen_expr(ast);
|
||||||
}
|
// gen(", %d}", ast->resolved_type->type_id);
|
||||||
else {
|
// }
|
||||||
gen("(Any){&");
|
|
||||||
gen_expr(ast);
|
|
||||||
gen(", %d}", ast->resolved_type->type_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(node->resolved_decl->kind == AST_LAMBDA){
|
if(node->resolved_decl->kind == AST_LAMBDA){
|
||||||
gen("%Q", node->resolved_decl->unique_name);
|
gen("%Q", node->resolved_decl->unique_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,17 +370,13 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var, bool is_vargs){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(VALUE, Atom){
|
CASE(VALUE, Atom){
|
||||||
if(is_any(type_of_var)){
|
// @edit
|
||||||
if(is_vargs){
|
// if(is_any(type_of_var)){
|
||||||
gen("(Any){&");
|
// gen("(Any){&");
|
||||||
gen("("); gen_simple_decl(node->type); gen("){"); gen_value(node->pos, node->value); gen("}");
|
// gen("("); gen_simple_decl(node->type); gen("){"); gen_value(node->pos, node->value); gen("}");
|
||||||
gen(", %d}", node->type->type_id);
|
// gen(", %d}", node->type->type_id);
|
||||||
}
|
// return true;
|
||||||
else{
|
// }
|
||||||
gen_value(node->pos, node->value);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
B32 written = gen_value(node->pos, node->value);
|
B32 written = gen_value(node->pos, node->value);
|
||||||
if(!written) {
|
if(!written) {
|
||||||
@@ -377,7 +392,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var, bool is_vargs){
|
|||||||
|
|
||||||
CASE(INDEX, Index){
|
CASE(INDEX, Index){
|
||||||
gen("(");
|
gen("(");
|
||||||
gen_expr(node->expr, 0, is_vargs);
|
gen_expr(node->expr);
|
||||||
if(node->index_original_type == type_string){
|
if(node->index_original_type == type_string){
|
||||||
gen(".str");
|
gen(".str");
|
||||||
}
|
}
|
||||||
@@ -398,11 +413,11 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var, bool is_vargs){
|
|||||||
|
|
||||||
CASE(BINARY, Binary){
|
CASE(BINARY, Binary){
|
||||||
if(node->op == TK_Dot){
|
if(node->op == TK_Dot){
|
||||||
if(gen_expr(node->left, 0, 0)){
|
if(gen_expr(node->left)){
|
||||||
if(node->dot_access_step_resolution && node->dot_access_step_resolution->kind == TYPE_POINTER) gen("->");
|
if(node->dot_access_step_resolution && node->dot_access_step_resolution->kind == TYPE_POINTER) gen("->");
|
||||||
else gen(".");
|
else gen(".");
|
||||||
}
|
}
|
||||||
gen_expr(node->right, 0, 0);
|
gen_expr(node->right);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,7 +485,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var, bool is_vargs){
|
|||||||
CASE(CALL, Call){
|
CASE(CALL, Call){
|
||||||
gen("%Q(", node->resolved_decl->unique_name);
|
gen("%Q(", node->resolved_decl->unique_name);
|
||||||
For(node->exprs){
|
For(node->exprs){
|
||||||
gen_expr(it->item, it->resolved_type, is_flag_set(it->flags, AST_ANY_VARGS));
|
gen_try_any_or_slice(it->item, it->resolved_type);
|
||||||
if(!node->exprs.is_last(&it)) gen(", ");
|
if(!node->exprs.is_last(&it)) gen(", ");
|
||||||
}
|
}
|
||||||
gen(")");
|
gen(")");
|
||||||
@@ -478,20 +493,13 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var, bool is_vargs){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(COMPOUND, Call){
|
CASE(COMPOUND, Call){
|
||||||
if(is_vargs){
|
|
||||||
For(node->exprs){
|
|
||||||
gen_expr(it->item, it->resolved_type, true);
|
|
||||||
|
|
||||||
if(!node->exprs.is_last(&it)) gen(", ");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
gen("(");
|
gen("(");
|
||||||
gen_simple_decl(node->resolved_type);
|
gen_simple_decl(node->resolved_type);
|
||||||
gen(")");
|
gen(")");
|
||||||
gen("{");
|
gen("{");
|
||||||
|
|
||||||
|
// We need to double wrap it because Any is a pointer
|
||||||
|
// We need to pass it a compound array
|
||||||
if(is_slice(node->resolved_type)) {
|
if(is_slice(node->resolved_type)) {
|
||||||
gen(".len = %d, ", node->exprs.len);
|
gen(".len = %d, ", node->exprs.len);
|
||||||
gen(".data = (");
|
gen(".data = (");
|
||||||
@@ -506,7 +514,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var, bool is_vargs){
|
|||||||
gen(".%Q = ", it->resolved_name);
|
gen(".%Q = ", it->resolved_name);
|
||||||
else if(is_array(node->resolved_type))
|
else if(is_array(node->resolved_type))
|
||||||
gen("[%d] = ", (int)it->resolved_index);
|
gen("[%d] = ", (int)it->resolved_index);
|
||||||
gen_expr(it->item, it->resolved_type);
|
gen_try_any_or_slice(it->item, it->resolved_type);
|
||||||
|
|
||||||
if(!node->exprs.is_last(&it)) gen(", ");
|
if(!node->exprs.is_last(&it)) gen(", ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1495,7 +1495,6 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_
|
|||||||
if(is_flag_set(lambda_arg->flags, AST_ANY_VARGS)){
|
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);
|
make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type->base, TYPE_AND_EXPR_REQUIRED);
|
||||||
item->resolved_type = expr.type;
|
item->resolved_type = expr.type;
|
||||||
set_flag(item->flags, AST_ANY_VARGS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
VariadicArguments :: (string: *char, args: ..)
|
VariadicArguments :: (string: *char, args: ..): Any
|
||||||
pass
|
return args[0]
|
||||||
|
|
||||||
AnyArguments :: (values: []Any)
|
AnyArguments :: (values: []Any)
|
||||||
for values
|
for values
|
||||||
@@ -20,7 +20,11 @@ main :: (): int
|
|||||||
for values
|
for values
|
||||||
Assert(it.type == S64)
|
Assert(it.type == S64)
|
||||||
AnyArguments({a,b})
|
AnyArguments({a,b})
|
||||||
VariadicArguments("Test", args = {a+b,b})
|
c := VariadicArguments("Test", args = {a+b,b})
|
||||||
|
Assert(*(c.data->*S64) == 30)
|
||||||
|
d := VariadicArguments("Test", {b,a})
|
||||||
|
Assert(*(d.data->*S64) == b)
|
||||||
|
e := VariadicArguments("Test", {b,a})
|
||||||
|
|
||||||
Assert(*(values[0].data->*S64) == 10)
|
Assert(*(values[0].data->*S64) == 10)
|
||||||
Assert(*(values[1].data->*S64) == 20)
|
Assert(*(values[1].data->*S64) == 20)
|
||||||
|
|||||||
@@ -35,15 +35,14 @@ main :: (): int
|
|||||||
any_value: Any = value_to_be_wrapped
|
any_value: Any = value_to_be_wrapped
|
||||||
|
|
||||||
if any_value.type == S64
|
if any_value.type == S64
|
||||||
// Void pointers get implicitly cast
|
*(any_value.data->*S64) = 20
|
||||||
value: *S64 = any_value.data
|
|
||||||
*value = 20
|
|
||||||
elif any_value.type == int
|
elif any_value.type == int
|
||||||
|
// Void pointers get implicitly cast
|
||||||
value: *int = any_value.data
|
value: *int = any_value.data
|
||||||
*value = 30
|
*value = 30
|
||||||
elif any_value.type == char;; Assert(false, "No bueno")
|
elif any_value.type == char;; Assert(false, "No bueno")
|
||||||
|
|
||||||
Assert(value_to_be_wrapped == 20)
|
Assert(*(any_value.data->*S64) == 20)
|
||||||
|
|
||||||
letter := GetFirstLetterOfType(value_to_be_wrapped)
|
letter := GetFirstLetterOfType(value_to_be_wrapped)
|
||||||
Assert(letter == 'I')
|
Assert(letter == 'I')
|
||||||
|
|||||||
Reference in New Issue
Block a user