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] 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
|
||||
- [x] Compounds with named fields and numbered fields
|
||||
- [x] Functions calls with named arguments
|
||||
- [x] All the standard binary, unary expressions
|
||||
- [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
|
||||
|
||||
- [x] Runtime reflection
|
||||
|
||||
@@ -5,7 +5,7 @@ global S32 global_indent;
|
||||
global S32 is_inside_struct;
|
||||
|
||||
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
|
||||
gen_indent(){
|
||||
@@ -271,9 +271,14 @@ gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
||||
gen_simple_decl(lambda->resolved_type->func.ret, name);
|
||||
gen("(");
|
||||
For(lambda->args){
|
||||
gen_var(it, DONT_EMIT_VALUE, true);
|
||||
if(&it != (lambda->args.end() - 1))
|
||||
gen(", ");
|
||||
if(is_flag_set(it->flags, AST_ANY_VARGS)){
|
||||
gen("...");
|
||||
}
|
||||
else{
|
||||
gen_var(it, DONT_EMIT_VALUE, true);
|
||||
if(&it != (lambda->args.end() - 1))
|
||||
gen(", ");
|
||||
}
|
||||
}
|
||||
gen(")");
|
||||
|
||||
@@ -284,21 +289,27 @@ gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){
|
||||
}
|
||||
|
||||
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){
|
||||
CASE(IDENT, Atom){
|
||||
if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE)
|
||||
return false;
|
||||
|
||||
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("%Q}", node->intern_val);
|
||||
}
|
||||
|
||||
else if(type_of_var && !is_any(ast->resolved_type) && is_any(type_of_var)){
|
||||
gen("(Any){&");
|
||||
gen_expr(ast);
|
||||
gen(", %d}", ast->resolved_type->type_id);
|
||||
if(is_vargs){
|
||||
gen_expr(ast, 0, is_vargs);
|
||||
}
|
||||
else {
|
||||
gen("(Any){&");
|
||||
gen_expr(ast);
|
||||
gen(", %d}", ast->resolved_type->type_id);
|
||||
}
|
||||
}
|
||||
|
||||
else if(node->resolved_decl->kind == AST_LAMBDA){
|
||||
@@ -315,9 +326,14 @@ 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->pos, node->value); gen("}");
|
||||
gen(", %d}", node->type->type_id);
|
||||
if(is_vargs){
|
||||
gen("(Any){&");
|
||||
gen("("); gen_simple_decl(node->type); gen("){"); gen_value(node->pos, node->value); gen("}");
|
||||
gen(", %d}", node->type->type_id);
|
||||
}
|
||||
else{
|
||||
gen_value(node->pos, node->value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -335,7 +351,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
||||
|
||||
CASE(INDEX, Index){
|
||||
gen("(");
|
||||
gen_expr(node->expr);
|
||||
gen_expr(node->expr, 0, is_vargs);
|
||||
if(node->index_original_type == type_string){
|
||||
gen(".str");
|
||||
}
|
||||
@@ -356,11 +372,11 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
||||
|
||||
CASE(BINARY, Binary){
|
||||
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("->");
|
||||
else gen(".");
|
||||
}
|
||||
gen_expr(node->right);
|
||||
gen_expr(node->right, 0, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -428,7 +444,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
||||
CASE(CALL, Call){
|
||||
gen("%Q(", node->resolved_decl->unique_name);
|
||||
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(", ");
|
||||
}
|
||||
gen(")");
|
||||
@@ -436,6 +452,15 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
||||
}
|
||||
|
||||
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_simple_decl(node->resolved_type);
|
||||
gen(")");
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
/*
|
||||
|
||||
First doable version:
|
||||
|
||||
- [ ] Any stuff working well
|
||||
- [ ] Var args working
|
||||
|
||||
In the future
|
||||
|
||||
- [ ] Cleanup
|
||||
- [ ] 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
|
||||
- [ ] Detecting if return was called
|
||||
|
||||
- [ ] Builtin data structures
|
||||
- [ ] Strings probably should have len() instead of string.len
|
||||
- [ ] Slices
|
||||
- [ ] Some way to take slice of data
|
||||
- [ ] Tuples
|
||||
- [ ] Dynamic arrays
|
||||
- [ ] Hash tables
|
||||
|
||||
- [ ] C Codegen
|
||||
|
||||
- [ ] Programming constructs
|
||||
- [ ] Defer statement
|
||||
- [ ] Using language construct
|
||||
- [ ] Function polimorphism
|
||||
- [ ] Operator Overloading
|
||||
- [ ] Named loops and breaking out of them
|
||||
|
||||
- [ ] Bytecode interpreter
|
||||
@@ -35,7 +39,6 @@
|
||||
|
||||
- [ ] Any
|
||||
- [ ] 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
|
||||
|
||||
Maybe later
|
||||
@@ -145,6 +148,8 @@ For modules it's a bit different cause they should be distributed as valid.
|
||||
|
||||
## 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] 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
|
||||
|
||||
@@ -456,7 +456,7 @@ parse_lambda(Token *token){
|
||||
|
||||
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))
|
||||
break;
|
||||
|
||||
@@ -1694,6 +1694,9 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_
|
||||
else if(is_struct(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);
|
||||
|
||||
@@ -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)){
|
||||
make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type->base, TYPE_AND_EXPR_REQUIRED);
|
||||
item->resolved_type = expr.type;
|
||||
set_flag(item->flags, AST_ANY_VARGS);
|
||||
}
|
||||
|
||||
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
|
||||
a := 10
|
||||
b := 20
|
||||
values := []Any{a, b}
|
||||
|
||||
printf("Test %d", {a})
|
||||
|
||||
for values
|
||||
Assert(it.type == S64)
|
||||
AnyArguments({a,b})
|
||||
VariadicArguments("Test", args = {a+b,b})
|
||||
|
||||
Assert(*(values[0].data->*S64) == 10)
|
||||
Assert(*(values[1].data->*S64) == 20)
|
||||
|
||||
Reference in New Issue
Block a user