Basic variable reassignments

This commit is contained in:
Krzosa Karol
2022-06-01 12:13:02 +02:00
parent 86aec0b1eb
commit 9b18c106b6
6 changed files with 116 additions and 55 deletions

View File

@@ -79,6 +79,17 @@ token_match(Token_Kind kind){
return 0;
}
function Token *
token_match(Token_Kind a, Token_Kind b){
Token *ta = token_get();
Token *tb = token_get(1);
if(ta->kind == a && tb->kind == b){
token_next(); token_next();
return ta;
}
return 0;
}
function Token *
token_match_keyword(Intern_String string){
Token *token = token_get();
@@ -145,6 +156,7 @@ parse_init_stmt(Ast_Expr *expr){
result->flags = set_flag(result->flags, AST_STMT);
return result;
}
return expr;
}
@@ -264,9 +276,15 @@ parse_block(){
}
else{
Ast_Named *result = parse_named(false);
Ast *result = parse_named(false);
if(!result){
result = parse_expr();
result = parse_init_stmt((Ast_Expr *)result);
}
if(result) stmts.add(result);
else parsing_error(token, "Unexpected token [%s] while parsing statement", token_kind_string(token->kind).str);
}
} while(token_match(SAME_SCOPE));
token_expect(CLOSE_SCOPE);
@@ -474,58 +492,57 @@ parse_enum(Token *pos){
return result;
}
/*
Needs peeking only because I didn't want to duplicate code
for parsing statements and it makes code nicer.
Statements can have named syntax i :=
*/
function Ast_Named *
parse_named(B32 is_global){
Ast_Named *result = 0;
if(is_global) token_match(SAME_SCOPE);
if(token_is(TK_Identifier)){
if(is_global && pctx->indent != 0) parsing_error(token_get(), "Top level declarations shouldn't be indented");
Token *name = token_next();
if(is_global) {
token_match(SAME_SCOPE);
if(pctx->indent != 0){
parsing_error(token_get(), "Top level declarations shouldn't be indented");
}
}
// @note: parse constant
if(token_match(TK_DoubleColon)){
// parse struct binding
Token *struct_pos = token_get();
if(token_match_keyword(keyword_struct)){
Ast_Struct *struct_val = parse_struct(struct_pos);
result = ast_const(name, name->intern_val, (Ast_Expr *)struct_val);
}
else if(token_match_keyword(keyword_enum)){
Ast_Enum *enum_val = parse_enum(struct_pos);
result = ast_const(name, name->intern_val, (Ast_Expr *)enum_val);
}
// parse constant expression
else{
Ast_Expr *expr = parse_expr();
result = ast_const(name, name->intern_val, expr);
}
Token *name = token_get();
if(token_match(TK_Identifier, TK_DoubleColon)){
// @note parse struct binding
Token *struct_pos = token_get();
if(token_match_keyword(keyword_struct)){
Ast_Struct *struct_val = parse_struct(struct_pos);
result = ast_const(name, name->intern_val, (Ast_Expr *)struct_val);
}
else if(token_match(TK_ColonAssign)){
Ast_Expr *expr = parse_expr();
result = ast_var(name, 0, name->intern_val, expr);
else if(token_match_keyword(keyword_enum)){
Ast_Enum *enum_val = parse_enum(struct_pos);
result = ast_const(name, name->intern_val, (Ast_Expr *)enum_val);
}
// @note: parse variable
else if(token_match(TK_Colon)){
Ast_Expr *typespec = typespec = parse_expr();
Ast_Expr *expr = parse_assign_expr();
result = ast_var(name, typespec, name->intern_val, expr);
}
// @note parse constant expression
else{
Token *token = token_get();
parsing_error(token, "Unexpected token: [%s] when parsing a declaration", token_kind_string(token->kind).str);
Ast_Expr *expr = parse_expr();
result = ast_const(name, name->intern_val, expr);
}
}
else if(!token_is(TK_End)){
if(is_global){
Token *token = token_get();
parsing_error(token, "Unexpected token: [%s] when parsing a declaration", token_kind_string(token->kind).str);
}
else if(token_match(TK_Identifier, TK_Colon)){
Ast_Expr *typespec = typespec = parse_expr();
Ast_Expr *expr = parse_assign_expr();
result = ast_var(name, typespec, name->intern_val, expr);
}
else if(token_match(TK_Identifier, TK_ColonAssign)){
Ast_Expr *expr = parse_expr();
result = ast_var(name, 0, name->intern_val, expr);
}
else if(is_global && name->kind != TK_End){
parsing_error(name, "Unexpected token: [%s] when parsing a declaration", token_kind_string(name->kind).str);
}
return result;
}