For loop iterate through arrays and slices
This commit is contained in:
8
ast.cpp
8
ast.cpp
@@ -163,6 +163,10 @@ struct Ast_For: Ast{
|
|||||||
Ast_Expr *cond;
|
Ast_Expr *cond;
|
||||||
Ast_Expr *iter;
|
Ast_Expr *iter;
|
||||||
Ast_Scope *scope;
|
Ast_Scope *scope;
|
||||||
|
|
||||||
|
Ast_Decl *array_traversal_var;
|
||||||
|
bool is_array_traversal;
|
||||||
|
bool is_also_slice_traversal;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Lambda : Ast_Expr {
|
struct Ast_Lambda : Ast_Expr {
|
||||||
@@ -266,9 +270,9 @@ struct Ast_Decl: Ast{
|
|||||||
result->pos = ipos; \
|
result->pos = ipos; \
|
||||||
result->di = ++pctx->unique_ids
|
result->di = ++pctx->unique_ids
|
||||||
|
|
||||||
#define MAKE_AST(T,kind,pos,flags) (T *)ast_new(sizeof(T), kind, pos, flags)
|
#define new_ast(T,kind,pos,flags) (T *)_new_ast(sizeof(T), kind, pos, flags)
|
||||||
function Ast *
|
function Ast *
|
||||||
ast_new(SizeU size, Ast_Kind kind, Token *pos, Ast_Flag flags = 0){
|
_new_ast(SizeU size, Ast_Kind kind, Token *pos, Ast_Flag flags = 0){
|
||||||
Ast *result = (Ast *)exp_alloc(pctx->perm, size, AF_ZeroMemory);
|
Ast *result = (Ast *)exp_alloc(pctx->perm, size, AF_ZeroMemory);
|
||||||
result->flags = flags;
|
result->flags = flags;
|
||||||
result->kind = kind;
|
result->kind = kind;
|
||||||
|
|||||||
27
ccodegen.cpp
27
ccodegen.cpp
@@ -500,6 +500,31 @@ gen_ast(Ast *ast){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(FOR, For){
|
CASE(FOR, For){
|
||||||
|
|
||||||
|
// Array iter
|
||||||
|
if(node->is_array_traversal){
|
||||||
|
gen("for(S64 _i%d = 0; _i%d < ", node->pos->line, node->pos->line);
|
||||||
|
gen_expr(node->cond);
|
||||||
|
gen(".len; _i%d+=1)", node->pos->line);
|
||||||
|
gen("{");
|
||||||
|
global_indent++;
|
||||||
|
genln("");
|
||||||
|
gen_simple_decl(node->array_traversal_var->type, node->array_traversal_var->name);
|
||||||
|
gen(" = ");
|
||||||
|
gen_expr(node->cond);
|
||||||
|
if(node->is_also_slice_traversal) gen(".data");
|
||||||
|
gen(" + _i%d;", node->pos->line);
|
||||||
|
For(node->scope->stmts) {
|
||||||
|
gen_line(it);
|
||||||
|
genln("");
|
||||||
|
gen_ast(it);
|
||||||
|
}
|
||||||
|
global_indent--;
|
||||||
|
genln("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal for loop
|
||||||
|
else{
|
||||||
gen("for(");
|
gen("for(");
|
||||||
if(node->init) gen_expr(node->init);
|
if(node->init) gen_expr(node->init);
|
||||||
gen(";");
|
gen(";");
|
||||||
@@ -508,6 +533,8 @@ gen_ast(Ast *ast){
|
|||||||
if(node->iter) gen_expr(node->iter);
|
if(node->iter) gen_expr(node->iter);
|
||||||
gen(")");
|
gen(")");
|
||||||
gen_stmt_scope(node->scope);
|
gen_stmt_scope(node->scope);
|
||||||
|
}
|
||||||
|
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ Intern_String keyword_enum;
|
|||||||
|
|
||||||
Intern_String intern_void;
|
Intern_String intern_void;
|
||||||
Intern_String intern_foreign;
|
Intern_String intern_foreign;
|
||||||
|
Intern_String intern_it;
|
||||||
Intern_String intern_strict;
|
Intern_String intern_strict;
|
||||||
Intern_String intern_flag;
|
Intern_String intern_flag;
|
||||||
|
|
||||||
@@ -240,6 +241,7 @@ lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l){
|
|||||||
intern_strict = intern_string(&l->interns, "strict"_s);
|
intern_strict = intern_string(&l->interns, "strict"_s);
|
||||||
intern_void = intern_string(&l->interns, "void"_s);
|
intern_void = intern_string(&l->interns, "void"_s);
|
||||||
intern_flag = intern_string(&l->interns, "flag"_s);
|
intern_flag = intern_string(&l->interns, "flag"_s);
|
||||||
|
intern_it = intern_string(&l->interns, "it"_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0){
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if(token_match_keyword(keyword_switch)){
|
else if(token_match_keyword(keyword_switch)){
|
||||||
Ast_Switch *result = MAKE_AST(Ast_Switch, AST_SWITCH, token, AST_STMT);
|
Ast_Switch *result = new_ast(Ast_Switch, AST_SWITCH, token, AST_STMT);
|
||||||
result->value = parse_expr();
|
result->value = parse_expr();
|
||||||
result->cases = {scratch};
|
result->cases = {scratch};
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0){
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Switch_Case *switch_case = MAKE_AST(Ast_Switch_Case, AST_SWITCH_CASE, token_get(), AST_STMT);
|
Ast_Switch_Case *switch_case = new_ast(Ast_Switch_Case, AST_SWITCH_CASE, token_get(), AST_STMT);
|
||||||
if(token_match_pound(pctx->intern("fallthrough"_s)))
|
if(token_match_pound(pctx->intern("fallthrough"_s)))
|
||||||
switch_case->fallthrough = true;
|
switch_case->fallthrough = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
main :: (argc: int, argv: **char): int
|
main :: (argc: int, argv: **char): int
|
||||||
test_arrays()
|
test_arrays()
|
||||||
test_any()
|
test_any()
|
||||||
@@ -14,6 +13,11 @@ test_arrays :: ()
|
|||||||
assert(i+1 == array1[i])
|
assert(i+1 == array1[i])
|
||||||
array6: []*S64 = {&array1[0]}
|
array6: []*S64 = {&array1[0]}
|
||||||
|
|
||||||
|
for array1
|
||||||
|
*it = 0
|
||||||
|
for i := 0, i < length_of(array1), i+=1
|
||||||
|
assert(0 == array1[i])
|
||||||
|
|
||||||
test_any :: ()
|
test_any :: ()
|
||||||
some_int_value := 10
|
some_int_value := 10
|
||||||
thing: Any = some_int_value
|
thing: Any = some_int_value
|
||||||
|
|||||||
@@ -566,7 +566,23 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolve_expr(node->init, AST_CAN_BE_NULL);
|
resolve_expr(node->init, AST_CAN_BE_NULL);
|
||||||
resolve_and_require_bool("Conditional in a for loop condition", node->cond, AST_CAN_BE_NULL);
|
Operand op = resolve_expr(node->cond, AST_CAN_BE_NULL);
|
||||||
|
if(node->cond){
|
||||||
|
if((!node->init && !node->iter) && (is_array(op.type) || is_slice(op.type))){
|
||||||
|
node->is_array_traversal = true;
|
||||||
|
if(is_slice(op.type)) node->is_also_slice_traversal = true;
|
||||||
|
Ast_Decl *var = new_ast(Ast_Decl, AST_VAR, node->cond->pos, AST_DECL);
|
||||||
|
var->state = DECL_RESOLVED;
|
||||||
|
var->type = type_pointer(op.type->base);
|
||||||
|
var->name = intern_it;
|
||||||
|
insert_into_scope(node->parent_scope, var);
|
||||||
|
node->array_traversal_var = var;
|
||||||
|
}
|
||||||
|
else if(!is_bool(op.type)){
|
||||||
|
compiler_error(node->pos, "Invalid type of for loop condition %Q, required [Bool]", typestring(op.type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resolve_expr(node->iter, AST_CAN_BE_NULL);
|
resolve_expr(node->iter, AST_CAN_BE_NULL);
|
||||||
For(node->scope->stmts) resolve_stmt(it, ret);
|
For(node->scope->stmts) resolve_stmt(it, ret);
|
||||||
BREAK();
|
BREAK();
|
||||||
|
|||||||
Reference in New Issue
Block a user