Var args sort of working, but I feel like all this stuff will need to get yanked out
or tested and refactored
This commit is contained in:
@@ -126,13 +126,14 @@ Utf8ToUtf32 :: (c: *U8, max_advance: S64): U32, S64
|
|||||||
- [x] Order independent declarations - The ordering of functions in code files or modules does not matter, compiler figures all that stuff out for you. "main" can be wherever you want it to be and all functions should be available without problems
|
- [x] Order independent declarations - The ordering of functions in code files or modules does not matter, compiler figures all that stuff out for you. "main" can be wherever you want it to be and all functions should be available without problems
|
||||||
|
|
||||||
- [x] Synchronize generated C code with original source using line directives so that debuggers work
|
- [x] Synchronize generated C code with original source using line directives so that debuggers work
|
||||||
|
- [x] Fix overshoots when debugger goes to brace in c code
|
||||||
|
|
||||||
- [ ] Expressions
|
- [ ] Expressions
|
||||||
- [x] Compounds with named fields and numbered fields
|
- [x] Compounds with named fields and numbered fields
|
||||||
- [x] Functions calls with named arguments
|
- [x] Functions calls with named arguments
|
||||||
- [x] All the standard binary, unary expressions
|
- [x] All the standard binary, unary expressions
|
||||||
- [x] Pointer arithmetic and pointer as array
|
- [x] Pointer arithmetic and pointer as array
|
||||||
- [ ] Dot access expression needs a redesign because it doesn't handle expressions after the dot it requires names instead
|
- [x] Dot access expression needs a redesign because it doesn't handle expressions after the dot, requires identifiers
|
||||||
- [ ] Casting might need a redesign not sure
|
- [ ] Casting might need a redesign not sure
|
||||||
|
|
||||||
- [x] Runtime reflection
|
- [x] Runtime reflection
|
||||||
|
|||||||
@@ -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);
|
function bool gen_expr(Ast_Expr *ast, Ast_Type *type_of_var = 0, bool is_vargs = false);
|
||||||
|
|
||||||
function void
|
function void
|
||||||
gen_indent(){
|
gen_indent(){
|
||||||
@@ -271,10 +271,15 @@ 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){
|
||||||
@@ -284,22 +289,28 @@ 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){
|
gen_expr(Ast_Expr *ast, Ast_Type *type_of_var, bool is_vargs){
|
||||||
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)){
|
if(type_of_var && is_slice(type_of_var) && is_array(node->resolved_decl->type)){
|
||||||
|
assert(!is_vargs);
|
||||||
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_expr(ast, 0, is_vargs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
gen("(Any){&");
|
gen("(Any){&");
|
||||||
gen_expr(ast);
|
gen_expr(ast);
|
||||||
gen(", %d}", ast->resolved_type->type_id);
|
gen(", %d}", ast->resolved_type->type_id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if(node->resolved_decl->kind == AST_LAMBDA){
|
else if(node->resolved_decl->kind == AST_LAMBDA){
|
||||||
gen("%Q", node->resolved_decl->unique_name);
|
gen("%Q", node->resolved_decl->unique_name);
|
||||||
@@ -315,9 +326,14 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
|
|
||||||
CASE(VALUE, Atom){
|
CASE(VALUE, Atom){
|
||||||
if(is_any(type_of_var)){
|
if(is_any(type_of_var)){
|
||||||
|
if(is_vargs){
|
||||||
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);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
gen_value(node->pos, node->value);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +351,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
|
|
||||||
CASE(INDEX, Index){
|
CASE(INDEX, Index){
|
||||||
gen("(");
|
gen("(");
|
||||||
gen_expr(node->expr);
|
gen_expr(node->expr, 0, is_vargs);
|
||||||
if(node->index_original_type == type_string){
|
if(node->index_original_type == type_string){
|
||||||
gen(".str");
|
gen(".str");
|
||||||
}
|
}
|
||||||
@@ -356,11 +372,11 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
|
|
||||||
CASE(BINARY, Binary){
|
CASE(BINARY, Binary){
|
||||||
if(node->op == TK_Dot){
|
if(node->op == TK_Dot){
|
||||||
if(gen_expr(node->left)){
|
if(gen_expr(node->left, 0, 0)){
|
||||||
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);
|
gen_expr(node->right, 0, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,7 +444,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
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);
|
gen_expr(it->item, it->resolved_type, is_flag_set(it->flags, AST_ANY_VARGS));
|
||||||
if(!node->exprs.is_last(&it)) gen(", ");
|
if(!node->exprs.is_last(&it)) gen(", ");
|
||||||
}
|
}
|
||||||
gen(")");
|
gen(")");
|
||||||
@@ -436,6 +452,15 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
}
|
}
|
||||||
|
|
||||||
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(")");
|
||||||
|
|||||||
@@ -1,27 +1,31 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
|
First doable version:
|
||||||
|
|
||||||
|
- [ ] Any stuff working well
|
||||||
|
- [ ] Var args working
|
||||||
|
|
||||||
|
In the future
|
||||||
|
|
||||||
- [ ] Cleanup
|
- [ ] Cleanup
|
||||||
- [ ] Remove tuple stuff or cleanup, in the future might replace it with a better implementation
|
- [ ] Remove tuple stuff or cleanup, in the future might replace it with a better implementation
|
||||||
- [ ] '.' Operator doesn't handle expressions inside the dot chain, no good, so casts don't work
|
|
||||||
|
- [ ] Conditional compilation
|
||||||
|
- [ ] Expand macros
|
||||||
|
- [ ] Defer
|
||||||
|
|
||||||
- [ ] Basic
|
- [ ] Basic
|
||||||
- [ ] Detecting if return was called
|
- [ ] Detecting if return was called
|
||||||
|
|
||||||
- [ ] Builtin data structures
|
- [ ] Builtin data structures
|
||||||
- [ ] Strings probably should have len() instead of string.len
|
|
||||||
- [ ] Slices
|
- [ ] Slices
|
||||||
- [ ] Some way to take slice of data
|
- [ ] Some way to take slice of data
|
||||||
- [ ] Tuples
|
- [ ] Tuples
|
||||||
- [ ] Dynamic arrays
|
- [ ] Dynamic arrays
|
||||||
- [ ] Hash tables
|
- [ ] Hash tables
|
||||||
|
|
||||||
- [ ] C Codegen
|
|
||||||
|
|
||||||
- [ ] Programming constructs
|
- [ ] Programming constructs
|
||||||
- [ ] Defer statement
|
|
||||||
- [ ] Using language construct
|
- [ ] Using language construct
|
||||||
- [ ] Function polimorphism
|
|
||||||
- [ ] Operator Overloading
|
|
||||||
- [ ] Named loops and breaking out of them
|
- [ ] Named loops and breaking out of them
|
||||||
|
|
||||||
- [ ] Bytecode interpreter
|
- [ ] Bytecode interpreter
|
||||||
@@ -35,7 +39,6 @@
|
|||||||
|
|
||||||
- [ ] Any
|
- [ ] Any
|
||||||
- [ ] Assigning to any values like ints etc. should work perhaps? But what type they should have?
|
- [ ] Assigning to any values like ints etc. should work perhaps? But what type they should have?
|
||||||
- [ ] Var args using any
|
|
||||||
- [ ] Slice of Any should work well
|
- [ ] Slice of Any should work well
|
||||||
|
|
||||||
Maybe later
|
Maybe later
|
||||||
@@ -145,6 +148,8 @@ For modules it's a bit different cause they should be distributed as valid.
|
|||||||
|
|
||||||
## Done
|
## Done
|
||||||
|
|
||||||
|
- [x] Operator Overloading
|
||||||
|
- [x] '.' Operator doesn't handle expressions inside the dot chain, no good, so casts don't work
|
||||||
- [x] Introduce List to reduce heap allocations and make it more arena friendly, can we get rid of heap completly?
|
- [x] Introduce List to reduce heap allocations and make it more arena friendly, can we get rid of heap completly?
|
||||||
- [x] Function renaming to prevent colissions, we can't really touch other stuff cause I want it to be easily debuggable
|
- [x] Function renaming to prevent colissions, we can't really touch other stuff cause I want it to be easily debuggable
|
||||||
- [x] Fix Length etc. they should be function calls not operators
|
- [x] Fix Length etc. they should be function calls not operators
|
||||||
|
|||||||
@@ -456,7 +456,7 @@ parse_lambda(Token *token){
|
|||||||
|
|
||||||
params.add(param);
|
params.add(param);
|
||||||
}
|
}
|
||||||
else compiler_error(name, "Expected [Identifier] or [...] when parsing lambda arguments");
|
else compiler_error(name, "Expected [Identifier] or [..] when parsing lambda arguments");
|
||||||
|
|
||||||
if(!token_match(TK_Comma))
|
if(!token_match(TK_Comma))
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1694,6 +1694,9 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_
|
|||||||
else if(is_struct(type)){
|
else if(is_struct(type)){
|
||||||
resolve_compound_struct(node, type);
|
resolve_compound_struct(node, type);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
compiler_error(node->pos, "Internal compiler error: Invalid type was passed to the compound expression, should have been an array, struct or slice");
|
||||||
|
}
|
||||||
|
|
||||||
return operand_lvalue(type);
|
return operand_lvalue(type);
|
||||||
|
|
||||||
@@ -1815,6 +1818,7 @@ 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,11 +1,26 @@
|
|||||||
|
|
||||||
|
VariadicArguments :: (string: *char, args: ..)
|
||||||
|
pass
|
||||||
|
|
||||||
|
AnyArguments :: (values: []Any)
|
||||||
|
for values
|
||||||
|
Assert(it.type == S64)
|
||||||
|
Assert(*(values[0].data->*S64) == 10)
|
||||||
|
Assert(*(values[1].data->*S64) == 20)
|
||||||
|
|
||||||
|
printf :: #foreign (string: *char, args: ..): int
|
||||||
|
|
||||||
main :: (): int
|
main :: (): int
|
||||||
a := 10
|
a := 10
|
||||||
b := 20
|
b := 20
|
||||||
values := []Any{a, b}
|
values := []Any{a, b}
|
||||||
|
|
||||||
|
printf("Test %d", {a})
|
||||||
|
|
||||||
for values
|
for values
|
||||||
Assert(it.type == S64)
|
Assert(it.type == S64)
|
||||||
|
AnyArguments({a,b})
|
||||||
|
VariadicArguments("Test", args = {a+b,b})
|
||||||
|
|
||||||
Assert(*(values[0].data->*S64) == 10)
|
Assert(*(values[0].data->*S64) == 10)
|
||||||
Assert(*(values[1].data->*S64) == 20)
|
Assert(*(values[1].data->*S64) == 20)
|
||||||
|
|||||||
Reference in New Issue
Block a user