diff --git a/new_parse.cpp b/new_parse.cpp index 8428fe6..e0976f4 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -145,7 +145,7 @@ parse_init_stmt(Ast_Expr *expr){ result->flags = set_flag(result->flags, AST_STMT); return result; } - return 0; + return expr; } function Ast_Call * @@ -215,7 +215,6 @@ parse_block(){ else if(token_match_keyword(keyword_for)){ Ast_Expr *expr_first = parse_expr(); Ast_Expr *init = parse_init_stmt(expr_first); - Ast_Expr *actual_init = init ? init : expr_first; Ast_Expr *cond = 0; Ast_Expr *iter = 0; @@ -223,18 +222,19 @@ parse_block(){ cond = parse_expr(); if(token_match(TK_Comma)){ iter = parse_expr(); + iter = parse_init_stmt(iter); } } Ast_Block *for_block = parse_block(); - stmts.add(ast_for(token, actual_init, cond, iter, for_block)); + stmts.add(ast_for(token, init, cond, iter, for_block)); } else if(token_match_keyword(keyword_if)){ Array if_nodes = {scratch}; Ast_Expr *expr = parse_expr(); Ast_Expr *init_val = parse_init_stmt(expr); - if(init_val){ + if(init_val != expr){ if(token_match(TK_Comma)) expr = parse_expr(); else expr = 0; } diff --git a/typecheck.cpp b/typecheck.cpp index 7fb4f46..aee5add 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -85,10 +85,10 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ CASE(FOR, For){ // @todo: I think we need to bring back the Ast_Init, it was not an expression - resolve_stmt(node->init, ret); + resolve_expr(node->init, ret); Operand cond = resolve_expr(node->cond); // @todo: typechecking - Operand iter = resolve_expr(node->iter); - unused(cond); unused(iter); + resolve_expr(node->iter, ret); + unused(cond); resolve_stmt_block(node->block, ret); BREAK(); } @@ -430,100 +430,110 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res CASE(BINARY, Binary){ Operand result = {}; - if(node->op == TK_Dot){ - B32 required_to_be_const = false; - // @note: resolve first chunk which involves querying global map - // second part requires searching through a struct - // resolve.x.y - Operand resolved_ident = resolve_expr(node->left); - Ast_Resolved_Type *type = resolved_ident.type; - if(type == type_type){ - type = resolved_ident.type_val; - required_to_be_const = true; - } - // @copy_paste - if(is_pointer(type)) type = type->base; - type_complete(type); - if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); - sym_new_resolved(SYM_VAR, {}, resolved_ident.type, {}, node->left); - - // This happens only on binary nodes which further chain with dots and require lookups - // This part cant happen on enums - // x.resolve.y - Ast_Binary *binary = (Ast_Binary *)node->right; - for(;!is_ident(binary); binary=(Ast_Binary *)binary->right){ - assert(is_ident(binary->left)); - Ast_Atom *ident = (Ast_Atom *)binary->left; - assert(is_binary(binary)); - - Ast_Struct *agg = (Ast_Struct *)type->ast; - Ast *query = query_struct(agg, ident->intern_val); - if(query){ - Sym *sym = resolved_get(query); - if(required_to_be_const && sym->kind != SYM_CONST) parsing_error(ident->pos, "Required to be constant"); - type = sym->type; + switch(node->op){ + case TK_ColonAssign:{ + assert(is_flag_set(node->flags, AST_STMT)); + // Operand left = resolve_expr(node->left); // needs to be lvalue + Operand right = resolve_expr(node->right); + assert(node->left->kind == AST_IDENT); + Ast_Atom *atom = (Ast_Atom *)node->left; // @todo use left operand + Sym *sym = sym_new_resolved(SYM_VAR, atom->intern_val, right.type, right.value, node); + sym_insert(sym); + }break; + case TK_Dot: { + B32 required_to_be_const = false; + // @note: resolve first chunk which involves querying global map + // second part requires searching through a struct + // resolve.x.y + Operand resolved_ident = resolve_expr(node->left); + Ast_Resolved_Type *type = resolved_ident.type; + if(type == type_type){ + type = resolved_ident.type_val; + required_to_be_const = true; + } // @copy_paste - if(type == type_type){ - required_to_be_const = true; - type = sym->type_val; - } - if(is_pointer(type)) type = type->base; - type_complete(type); - if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); - sym_associate(ident, sym); + if(is_pointer(type)) type = type->base; + type_complete(type); + if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); + sym_new_resolved(SYM_VAR, {}, resolved_ident.type, {}, node->left); - } else parsing_error(ident->pos, "No such member in struct"); - } + // This happens only on binary nodes which further chain with dots and require lookups + // This part cant happen on enums + // x.resolve.y + Ast_Binary *binary = (Ast_Binary *)node->right; + for(;!is_ident(binary); binary=(Ast_Binary *)binary->right){ + assert(is_ident(binary->left)); + Ast_Atom *ident = (Ast_Atom *)binary->left; + assert(is_binary(binary)); - // Here we can resolve the last part, this doesnt need to be a struct - // x.y.resolve - // @copy_paste - Ast_Atom *ident = (Ast_Atom *)binary; - if(is_enum(type)){ - Ast_Enum *enu = (Ast_Enum *)type->ast; - Ast_Enum_Member *query = query_enum(enu, ident->intern_val); - if(query){ - Sym *resolved = resolved_get(query); - assert(resolved); - rewrite_into_const(node, Ast_Binary, resolved); - result = operand(resolved); + Ast_Struct *agg = (Ast_Struct *)type->ast; + Ast *query = query_struct(agg, ident->intern_val); + if(query){ + Sym *sym = resolved_get(query); + if(required_to_be_const && sym->kind != SYM_CONST) parsing_error(ident->pos, "Required to be constant"); + type = sym->type; + // @copy_paste + if(type == type_type){ + required_to_be_const = true; + type = sym->type_val; + } + if(is_pointer(type)) type = type->base; + type_complete(type); + if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); + sym_associate(ident, sym); + + } else parsing_error(ident->pos, "No such member in struct"); } - } - else if(is_struct(type)){ - Ast_Struct *agg = (Ast_Struct *)type->ast; - Ast *query = query_struct(agg, ident->intern_val); - if(query){ - Sym *sym = resolved_get(query); - result = operand(sym); - assert(sym); - if(sym->kind == SYM_CONST) rewrite_into_const(node, Ast_Binary, sym); - else sym_associate(ident, sym); - } else parsing_error(ident->pos, "No such member in struct"); - } - else parsing_error(ident->pos, "Trying to [.] access a value that is not [Enum] or [Struct]"); - - if(result.is_const == false && required_to_be_const){ - invalid_codepath; - } - - } - else{ - Operand left = resolve_expr(node->left); - Operand right = resolve_expr(node->right); - result.type = resolve_type_pair(node->pos, left.type, right.type); - if(left.is_const && right.is_const){ - result.is_const = true; - if(result.type == type_int){ - switch(node->op){ - case TK_Add: result.int_val = left.int_val + right.int_val; break; - case TK_Sub: result.int_val = left.int_val - right.int_val; break; - case TK_Mul: result.int_val = left.int_val * right.int_val; break; - case TK_Div: result.int_val = left.int_val / right.int_val; break; - invalid_default_case; + // Here we can resolve the last part, this doesnt need to be a struct + // x.y.resolve + // @copy_paste + Ast_Atom *ident = (Ast_Atom *)binary; + if(is_enum(type)){ + Ast_Enum *enu = (Ast_Enum *)type->ast; + Ast_Enum_Member *query = query_enum(enu, ident->intern_val); + if(query){ + Sym *resolved = resolved_get(query); + assert(resolved); + rewrite_into_const(node, Ast_Binary, resolved); + result = operand(resolved); } } - else parsing_error(node->pos, "Arithmetic on type [%s] is not supported", type_names[result.type->kind]); + else if(is_struct(type)){ + Ast_Struct *agg = (Ast_Struct *)type->ast; + Ast *query = query_struct(agg, ident->intern_val); + if(query){ + Sym *sym = resolved_get(query); + result = operand(sym); + assert(sym); + if(sym->kind == SYM_CONST) rewrite_into_const(node, Ast_Binary, sym); + else sym_associate(ident, sym); + + } else parsing_error(ident->pos, "No such member in struct"); + } + else parsing_error(ident->pos, "Trying to [.] access a value that is not [Enum] or [Struct]"); + + if(result.is_const == false && required_to_be_const){ + invalid_codepath; + } + } break; + default: { + Operand left = resolve_expr(node->left); + Operand right = resolve_expr(node->right); + result.type = resolve_type_pair(node->pos, left.type, right.type); + if(left.is_const && right.is_const){ + result.is_const = true; + if(result.type == type_int){ + switch(node->op){ + case TK_Add: result.int_val = left.int_val + right.int_val; break; + case TK_Sub: result.int_val = left.int_val - right.int_val; break; + case TK_Mul: result.int_val = left.int_val * right.int_val; break; + case TK_Div: result.int_val = left.int_val / right.int_val; break; + invalid_default_case; + } + } + else parsing_error(node->pos, "Arithmetic on type [%s] is not supported", type_names[result.type->kind]); + }break; } }