diff --git a/ccodegen.cpp b/ccodegen.cpp index e8b8fb9..ccb998f 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -59,8 +59,8 @@ gen_simple_decl(Ast_Resolved_Type *ast, Intern_String name){ gen_simple_decl_prefix(ast->func.ret); gen("(*%s)(", name.str); For(ast->func.args){ - gen_simple_decl_prefix(it[0]); - if(it != ast->func.args.end() - 1) gen(", "); + gen_simple_decl_prefix(it); + if(&it != ast->func.args.end() - 1) gen(", "); } gen(")"); } @@ -143,7 +143,7 @@ gen_expr(Ast_Expr *ast){ gen("{"); For(node->exprs){ - auto comp = it[0]; + auto comp = it; if(comp->name){ gen("["); gen_expr(comp->name); @@ -157,7 +157,7 @@ gen_expr(Ast_Expr *ast){ assert(comp->item); gen_expr(comp->item); - if(!node->exprs.is_last(it)) gen(", "); + if(!node->exprs.is_last(&it)) gen(", "); } gen("}"); } @@ -165,8 +165,8 @@ gen_expr(Ast_Expr *ast){ gen_expr(node->name); gen("("); For(node->exprs){ - gen_expr(it[0]->item); - if(!node->exprs.is_last(it)) gen(", "); + gen_expr(it->item); + if(!node->exprs.is_last(&it)) gen(", "); } gen(")"); } @@ -186,7 +186,7 @@ gen_block(Ast_Block *block){ global_indent++; For(block->stmts) { genln(""); - gen_ast(it[0]); + gen_ast(it); } global_indent--; genln("}"); @@ -199,7 +199,7 @@ gen_ast(Ast *ast){ CASE(PACKAGE, Package){ For(node->ordered) { genln(""); - gen_ast(*it); + gen_ast(it); } BREAK(); } @@ -238,21 +238,21 @@ gen_ast(Ast *ast){ CASE(IF, If){ For(node->ifs){ - if(it[0]->init) gen_ast(it[0]->init); - if(node->ifs.is_first(it)){ + if(it->init) gen_ast(it->init); + if(node->ifs.is_first(&it)){ genln("if("); - gen_expr(it[0]->expr); + gen_expr(it->expr); gen(")"); - gen_block(it[0]->block); + gen_block(it->block); } else{ genln("else"); - if(it[0]->expr){ + if(it->expr){ gen(" if("); - gen_expr(it[0]->expr); + gen_expr(it->expr); gen(")"); } - gen_block(it[0]->block); + gen_block(it->block); } } BREAK(); @@ -269,10 +269,10 @@ gen_ast(Ast *ast){ gen_simple_decl(ret, node->name); gen("("); For(lambda->args){ - assert(it[0]->kind == AST_LAMBDA_ARG); - Ast_Resolved_Type *type = resolved_type_get(it[0]->typespec); - gen_simple_decl(type, it[0]->name); - if(it != (lambda->args.end() - 1)) gen(", "); + assert(it->kind == AST_LAMBDA_ARG); + Ast_Resolved_Type *type = resolved_type_get(it->typespec); + gen_simple_decl(type, it->name); + if(&it != (lambda->args.end() - 1)) gen(", "); } gen(")"); @@ -302,7 +302,7 @@ gen_ast(Ast *ast){ global_indent++; For(agg->members){ genln(""); - gen_ast(it[0]); + gen_ast(it); } global_indent--; genln("};"); diff --git a/main.cpp b/main.cpp index 31052da..e0fa2da 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,7 @@ #include "new_lex.cpp" #include "new_ast.cpp" #include "new_parse.cpp" -#include "new_resolve.cpp" +#include "typechecking.cpp" #include "ccodegen.cpp" // 2022.05.28 - On lambda expressions diff --git a/new_ast.cpp b/new_ast.cpp index 82e94ea..24fe91c 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -291,7 +291,7 @@ ast_call(Token *pos, Ast_Expr *name, Array exprs){ result->name = name; result->exprs = exprs.tight_copy(pctx->perm); if(result->name) result->name->parent = result; - For(result->exprs) it[0]->parent = result; + For(result->exprs) it->parent = result; return result; } @@ -350,7 +350,7 @@ ast_lambda(Token *pos, Array params, Ast_Expr *ret, Ast_Block if(result->block) result->block->parent = result; result->ret->parent = result; - For(result->args) it[0]->parent = result; + For(result->args) it->parent = result; return result; } @@ -370,7 +370,7 @@ function Ast_Block * ast_block(Token *pos, Array stmts){ AST_NEW(Block, BLOCK, pos, AST_STMT); result->stmts = stmts.tight_copy(pctx->perm); - For(result->stmts) it[0]->parent = result; + For(result->stmts) it->parent = result; return result; } @@ -378,7 +378,7 @@ function Ast_If * ast_if(Token *pos, Array ifs){ AST_NEW(If, IF, pos, AST_STMT); result->ifs = ifs.tight_copy(pctx->perm); - For(result->ifs) it[0]->parent = result; + For(result->ifs) it->parent = result; return result; } @@ -430,9 +430,9 @@ ast_struct(Token *pos, Array members){ AST_NEW(Struct, STRUCT, pos, AST_AGGREGATE); result->members = members.tight_copy(pctx->perm); For(result->members) { - assert(is_flag_set(it[0]->flags, AST_BINDING)); - assert(it[0]->kind == AST_VAR || it[0]->kind == AST_CONST); - it[0]->parent = result; + assert(is_flag_set(it->flags, AST_BINDING)); + assert(it->kind == AST_VAR || it->kind == AST_CONST); + it->parent = result; } return result; } @@ -468,7 +468,7 @@ ast_package(Token *pos, String name, Array decls){ result->decls = decls.tight_copy(pctx->perm); result->ordered = array_make(pctx->perm, decls.len); result->name = intern_string(&pctx->interns, name); - For(result->decls) it[0]->parent = result; + For(result->decls) it->parent = result; return result; } diff --git a/new_lex.cpp b/new_lex.cpp index 85fc3cb..7f241a5 100644 --- a/new_lex.cpp +++ b/new_lex.cpp @@ -180,8 +180,8 @@ function void lex_set_keywords(Lexer *lexer, Array keywords){ Intern_String keyword = {}; For(keywords){ - keyword = intern_string(&lexer->interns, *it); - if(it == keywords.begin()) + keyword = intern_string(&lexer->interns, it); + if(&it == keywords.begin()) lexer->interns.first_keyword = keyword.str; } lexer->interns.last_keyword = keyword.str; @@ -674,10 +674,10 @@ lex_test(){ int ui = 0; S32 i = 0; For(arr){ - assert(it->kind == kind[i]); - assert(string_compare(it->string, strs[i])); - if(it->kind == TK_Integer){ - assert(it->int_val == vals[ui++]); + assert(it.kind == kind[i]); + assert(string_compare(it.string, strs[i])); + if(it.kind == TK_Integer){ + assert(it.int_val == vals[ui++]); } i++; } diff --git a/new_type.cpp b/new_type.cpp index 1fd9db5..8ab3fbd 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -132,7 +132,7 @@ type_array(Ast_Resolved_Type *base, SizeU size){ function Ast_Resolved_Type * type_lambda(Ast *ast, Ast_Resolved_Type *ret, Array args){ U64 hash = hash_ptr(ret); - For(args) hash = hash_mix(hash, hash_ptr(*it)); + For(args) hash = hash_mix(hash, hash_ptr(it)); Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, hash); if(result){ @@ -175,9 +175,9 @@ type_complete(Ast_Resolved_Type *type){ Scratch scratch; Array members = {scratch}; For(node->members){ - Operand op = resolve_binding(it[0]); - Intern_String name = ast_get_name(it[0]); - sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]); + Operand op = resolve_binding(it); + Intern_String name = ast_get_name(it); + sym_new_resolved(SYM_VAR, name, op.type, {}, it); members.add({op.type, name}); } type->agg.members = members.tight_copy(pctx->perm); diff --git a/new_resolve.cpp b/typechecking.cpp similarity index 88% rename from new_resolve.cpp rename to typechecking.cpp index 0c67642..34f4cf2 100644 --- a/new_resolve.cpp +++ b/typechecking.cpp @@ -42,6 +42,12 @@ enum{ AST_CAN_BE_NULL = 1 }; +struct Typecheck_Ctx{ + Ast_Resolved_Type *required_type; + Sym *const_sym; + B32 expr_can_be_null; +}; + function Sym *resolve_name(Token *pos, Intern_String name); function Operand resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *compound_required_type = 0, Sym *const_sym = 0); function Operand resolve_binding(Ast *ast, Sym *sym = 0); @@ -225,11 +231,11 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ CASE(IF, If){ For(node->ifs){ - if(it[0]->init) resolve_stmt(it[0]->init, ret); - if(it[0]->expr) resolve_expr(it[0]->expr); + if(it->init) resolve_stmt(it->init, ret); + if(it->expr) resolve_expr(it->expr); S64 scope_index = scope_open(); - For_It(it[0]->block->stmts, jt){ - resolve_stmt(jt[0], ret); + For_It(it->block->stmts, jt){ + resolve_stmt(jt, ret); } scope_close(scope_index); } @@ -302,10 +308,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ Ast_Resolved_Type *ret_type = resolve_typespec(node->ret); Array args = {scratch}; For(node->args){ - Operand type = resolve_expr(it[0]->typespec); - if(type.type != type_type) parsing_error(it[0]->pos, "Required expression of kind [type]"); - Operand default_value = resolve_expr(it[0]->default_value, type.type_val); - if(default_value.type && default_value.type != type.type_val) parsing_error(it[0]->pos, "Default value type and type declaration differ"); + Operand type = resolve_expr(it->typespec); + if(type.type != type_type) parsing_error(it->pos, "Required expression of kind [type]"); + Operand default_value = resolve_expr(it->default_value, type.type_val); + if(default_value.type && default_value.type != type.type_val) parsing_error(it->pos, "Default value type and type declaration differ"); args.add(type.type_val); } lambda_type = type_lambda(node, ret_type, args); @@ -327,14 +333,14 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ if(node->block){ S64 scope_index = scope_open(); For(node->args){ - S64 i = node->args.get_index(it); + S64 i = node->args.get_index(&it); Ast_Resolved_Type *type = args[i]; - Sym *arg_sym = sym_new_resolved(SYM_VAR, it[0]->name, type, {}, it[0]); + Sym *arg_sym = sym_new_resolved(SYM_VAR, it->name, type, {}, it); sym_insert(arg_sym); } For(node->block->stmts){ - resolve_stmt(it[0], ret_type); + resolve_stmt(it, ret_type); } scope_close(scope_index); result.type = lambda_type; @@ -368,7 +374,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ Ast_Resolved_Type *item_type = type->arr.base; For(node->exprs){ - Ast_Call_Item *i = (Ast_Call_Item *)it[0]; + Ast_Call_Item *i = (Ast_Call_Item *)it; assert(i->kind == AST_CALL_ITEM); if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]); if(i->index){ @@ -386,18 +392,18 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ S64 default_iter = 0; For_It(node->exprs, expr){ - if(expr[0]->index) parsing_error(expr[0]->index->pos, "Function call indexing is illegal"); - Ast_Atom *name = expr[0]->name; - S64 expr_index = node->exprs.get_index(expr); + if(expr->index) parsing_error(expr->index->pos, "Function call indexing is illegal"); + Ast_Atom *name = expr->name; + S64 expr_index = node->exprs.get_index(&expr); Ast_Named *found = 0; Ast_Resolved_Member *found_type = 0; if(name){ assert(name->kind == AST_IDENT); For_It(agg->members, member){ - if(member[0]->name.str == name->intern_val.str){ - found = member[0]; - found_type = &type->agg.members[agg->members.get_index(member)]; + if(member->name.str == name->intern_val.str){ + found = member; + found_type = &type->agg.members[agg->members.get_index(&member)]; break; } } @@ -406,21 +412,21 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ S64 i = default_iter++; found = agg->members[i]; found_type = &type->agg.members[i]; - if(i >= agg->members.len) parsing_error(expr[0]->pos, "Too many arguments in compound constructor"); + if(i >= agg->members.len) parsing_error(expr->pos, "Too many arguments in compound constructor"); } - else parsing_error(expr[0]->pos, "Positional argument after named or indexed argument"); + else parsing_error(expr->pos, "Positional argument after named or indexed argument"); - if(!found) parsing_error(expr[0]->pos, "Invalid argument in compound constructor"); + if(!found) parsing_error(expr->pos, "Invalid argument in compound constructor"); if(is_flag_set(found->flags, AST_ITEM_INCLUDED)) parsing_error(found->pos, "Item included multiple times in compound constructor"); found->flags = set_flag(found->flags, AST_ITEM_INCLUDED); - Operand op = resolve_expr(expr[0]->item, found_type->type); - if(found_type->type != op.type) parsing_error(expr[0]->pos, "Invalid type of compound constructor item"); + Operand op = resolve_expr(expr->item, found_type->type); + if(found_type->type != op.type) parsing_error(expr->pos, "Invalid type of compound constructor item"); } // @note: cleanup, required? For(agg->members){ - it[0]->flags = unset_flag(it[0]->flags, AST_ITEM_INCLUDED); + it->flags = unset_flag(it->flags, AST_ITEM_INCLUDED); } } else if(type->kind == TYPE_LAMBDA){ @@ -430,26 +436,26 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ S64 default_iter = 0; auto lambda = (Ast_Lambda *)type->ast; For(lambda->args){ - S64 i = lambda->args.get_index(it); + S64 i = lambda->args.get_index(&it); Ast_Resolved_Type *resolved = type->func.args[i]; - Ast_Lambda_Arg *arg = it[0]; + Ast_Lambda_Arg *arg = it; // @note: match any in list of call items, if none matched then we have a problem // there are three kinds of possible matches: indexed, named, default Ast_Call_Item *item = 0; For_It(node->exprs, expr){ - if(expr[0]->index) parsing_error(expr[0]->index->pos, "Function call indexing is illegal"); - Ast_Atom *name = expr[0]->name; + if(expr->index) parsing_error(expr->index->pos, "Function call indexing is illegal"); + Ast_Atom *name = expr->name; if(name){ assert(name->kind == AST_IDENT); - if(name->intern_val.str == arg->name.str) item = expr[0]; + if(name->intern_val.str == arg->name.str) item = expr; } - else if(node->exprs.get_index(expr) == default_iter){ + else if(node->exprs.get_index(&expr) == default_iter){ default_iter++; - item = expr[0]; + item = expr; } - else if(node->exprs.get_index(expr) > default_iter) parsing_error(expr[0]->pos, "Positional argument after named argument"); + else if(node->exprs.get_index(&expr) > default_iter) parsing_error(expr->pos, "Positional argument after named argument"); if(item) break; } @@ -472,8 +478,8 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ // @note: check if all arguments are included and cleanup For(node->exprs){ - if(!is_flag_set(it[0]->flags, AST_ITEM_INCLUDED)) parsing_error(it[0]->pos, "Invalid argument to function call"); - else it[0]->flags = unset_flag(it[0]->flags, AST_ITEM_INCLUDED); + if(!is_flag_set(it->flags, AST_ITEM_INCLUDED)) parsing_error(it->pos, "Invalid argument to function call"); + else it->flags = unset_flag(it->flags, AST_ITEM_INCLUDED); } node->exprs = items.tight_copy(pctx->perm); @@ -567,15 +573,15 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ Scratch scratch; Array members = {scratch}; For(node->members){ - Operand op = resolve_binding(it[0]); + Operand op = resolve_binding(it); Intern_String name = {}; - if(is_flag_set(it[0]->flags, AST_BINDING)){ - Ast_Named *named = (Ast_Named *)it[0]; + if(is_flag_set(it->flags, AST_BINDING)){ + Ast_Named *named = (Ast_Named *)it; name = named->name; } - sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]); + sym_new_resolved(SYM_VAR, name, op.type, {}, it); members.add({op.type, name}); } Ast_Resolved_Type *resolved = type_struct(node, members); @@ -647,9 +653,9 @@ resolve_name(Token *pos, Intern_String name){ function void resolve_package(Ast_Package *package){ For(package->decls){ - resolve_name(it[0]->pos, it[0]->name); - if(ast_is_struct(it[0])){ - type_complete(const_get_struct(it[0])->type); + resolve_name(it->pos, it->name); + if(ast_is_struct(it)){ + type_complete(const_get_struct(it)->type); } } }