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

@@ -108,7 +108,7 @@ gen_expr(Ast_Expr *ast){
else gen("."); else gen(".");
gen_expr(node->right); gen_expr(node->right);
} }
else if(node->op == TK_Colon){ // @todo: I think this needs to be a stmt else if(node->op == TK_ColonAssign){ // @todo: I think this needs to be a stmt
Sym *sym = resolved_get(node); Sym *sym = resolved_get(node);
Ast_Atom *atom = (Ast_Atom *)node->left; Ast_Atom *atom = (Ast_Atom *)node->left;
assert(is_atom(atom)); assert(is_atom(atom));
@@ -274,6 +274,12 @@ gen_ast(Ast *ast){
BREAK(); BREAK();
} }
CASE(BINARY,Binary){
gen_expr(node);
gen(";");
BREAK();
}
CASE(FOR, For){ CASE(FOR, For){
gen("for("); gen("for(");
if(node->init) gen_expr(node->init); if(node->init) gen_expr(node->init);
@@ -391,10 +397,16 @@ compile_string(String filecontent, String filename = "default_name"_s){
ctx.init(scratch, &heap); ctx.init(scratch, &heap);
pctx = &ctx; pctx = &ctx;
F64 tokenize_begin = os_time();
lex_restream(&ctx, filecontent, filename); lex_restream(&ctx, filecontent, filename);
F64 tokenize_end = os_time();
F64 parse_begin = os_time();
Ast_Package *result = parse_file(); Ast_Package *result = parse_file();
sym_insert_builtins(); sym_insert_builtins();
pctx->resolving_package = result; pctx->resolving_package = result;
F64 parse_end = os_time();
gen(R"==( gen(R"==(
//------------------------------- //-------------------------------
@@ -403,12 +415,28 @@ compile_string(String filecontent, String filename = "default_name"_s){
//------------------------------- //-------------------------------
)=="); )==");
F64 resolve_begin = os_time();
resolve_package(result); resolve_package(result);
// eval_decl(result); F64 resolve_end = os_time();
F64 codegen_begin = os_time();
gen_ast(result); gen_ast(result);
F64 codegen_end = os_time();
exp_destroy(&heap); exp_destroy(&heap);
F64 flattening_begin = os_time();
String string_result = string_flatten(scratch, &pctx->gen); String string_result = string_flatten(scratch, &pctx->gen);
F64 flattening_end = os_time();
printf("\n//-------------------------------");
printf("\n// Tokenization: %f", tokenize_end - tokenize_begin);
printf("\n// Parsing : %f", parse_end - parse_begin);
printf("\n// Resolving : %f", resolve_end - resolve_begin);
printf("\n// Codegen : %f", codegen_end - codegen_begin);
printf("\n// Flattening : %f", flattening_end - flattening_begin);
printf("\n//-------------------------------");
return string_result; return string_result;
} }

View File

@@ -32,9 +32,9 @@ For now I don't thing it should be overloadable.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@todo @todo
[ ] - Init statements [ ] - Init statements, different kinds [+=] [-=] etc.
[ ] - More operators
[ ] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression [ ] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression
[ ] - More operators
[ ] - More for loop variations [ ] - More for loop variations
[ ] - Fixing access to constants, in C we cant have constants inside of structs / functions so we need to rewrite the tree [ ] - Fixing access to constants, in C we cant have constants inside of structs / functions so we need to rewrite the tree
[ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative [ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative

View File

@@ -132,7 +132,8 @@ struct Lexer{
S64 token_iter; S64 token_iter;
}; };
force_inline B32 token_is_assign(Token *token){return token->kind >= TK_FirstAssign && token->kind <= TK_LastAssign;} force_inline B32 token_is_assign(Token_Kind token){return token >= TK_FirstAssign && token <= TK_LastAssign;}
force_inline B32 token_is_assign(Token *token){return token_is_assign(token->kind);}
function U8 function U8
lexc(Lex_Stream *s){ lexc(Lex_Stream *s){
@@ -353,6 +354,7 @@ lex__stream(Intern_Table *table, Array<Token> *array, Lex_Stream *s){
lex_advance(s); lex_advance(s);
} }
} }
else goto indent_loop_break;
} break; } break;
// @todo: add [;;] operator which adds new scope // @todo: add [;;] operator which adds new scope

View File

@@ -79,6 +79,17 @@ token_match(Token_Kind kind){
return 0; 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 * function Token *
token_match_keyword(Intern_String string){ token_match_keyword(Intern_String string){
Token *token = token_get(); Token *token = token_get();
@@ -145,6 +156,7 @@ parse_init_stmt(Ast_Expr *expr){
result->flags = set_flag(result->flags, AST_STMT); result->flags = set_flag(result->flags, AST_STMT);
return result; return result;
} }
return expr; return expr;
} }
@@ -264,9 +276,15 @@ parse_block(){
} }
else{ 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); if(result) stmts.add(result);
else parsing_error(token, "Unexpected token [%s] while parsing statement", token_kind_string(token->kind).str); else parsing_error(token, "Unexpected token [%s] while parsing statement", token_kind_string(token->kind).str);
} }
} while(token_match(SAME_SCOPE)); } while(token_match(SAME_SCOPE));
token_expect(CLOSE_SCOPE); token_expect(CLOSE_SCOPE);
@@ -474,17 +492,24 @@ parse_enum(Token *pos){
return result; 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 * function Ast_Named *
parse_named(B32 is_global){ parse_named(B32 is_global){
Ast_Named *result = 0; Ast_Named *result = 0;
if(is_global) token_match(SAME_SCOPE); if(is_global) {
if(token_is(TK_Identifier)){ token_match(SAME_SCOPE);
if(is_global && pctx->indent != 0) parsing_error(token_get(), "Top level declarations shouldn't be indented"); if(pctx->indent != 0){
Token *name = token_next(); parsing_error(token_get(), "Top level declarations shouldn't be indented");
}
}
// @note: parse constant Token *name = token_get();
if(token_match(TK_DoubleColon)){ if(token_match(TK_Identifier, TK_DoubleColon)){
// parse struct binding // @note parse struct binding
Token *struct_pos = token_get(); Token *struct_pos = token_get();
if(token_match_keyword(keyword_struct)){ if(token_match_keyword(keyword_struct)){
Ast_Struct *struct_val = parse_struct(struct_pos); Ast_Struct *struct_val = parse_struct(struct_pos);
@@ -496,36 +521,28 @@ parse_named(B32 is_global){
result = ast_const(name, name->intern_val, (Ast_Expr *)enum_val); result = ast_const(name, name->intern_val, (Ast_Expr *)enum_val);
} }
// parse constant expression // @note parse constant expression
else{ else{
Ast_Expr *expr = parse_expr(); Ast_Expr *expr = parse_expr();
result = ast_const(name, name->intern_val, expr); result = ast_const(name, name->intern_val, expr);
} }
} }
else if(token_match(TK_Identifier, TK_Colon)){
else if(token_match(TK_ColonAssign)){
Ast_Expr *expr = parse_expr();
result = ast_var(name, 0, name->intern_val, expr);
}
// @note: parse variable
else if(token_match(TK_Colon)){
Ast_Expr *typespec = typespec = parse_expr(); Ast_Expr *typespec = typespec = parse_expr();
Ast_Expr *expr = parse_assign_expr(); Ast_Expr *expr = parse_assign_expr();
result = ast_var(name, typespec, name->intern_val, expr); result = ast_var(name, typespec, name->intern_val, expr);
} }
else{
Token *token = token_get(); else if(token_match(TK_Identifier, TK_ColonAssign)){
parsing_error(token, "Unexpected token: [%s] when parsing a declaration", token_kind_string(token->kind).str); Ast_Expr *expr = parse_expr();
} result = ast_var(name, 0, 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(is_global && name->kind != TK_End){
parsing_error(name, "Unexpected token: [%s] when parsing a declaration", token_kind_string(name->kind).str);
} }
return result; return result;
} }

View File

@@ -43,6 +43,15 @@ pointer := &with_type
deref := *pointer deref := *pointer
test_stmts :: ()
i := 0
i += 4
i -= 1
i *= 2
i /= 2
i %= 2
/* /*
for for
pass pass

View File

@@ -64,17 +64,22 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
} }
CASE(BINARY, Binary){ CASE(BINARY, Binary){
switch(node->op){ if(node->op == TK_ColonAssign){
case TK_ColonAssign:{
// Operand left = resolve_expr(node->left); // needs to be lvalue // Operand left = resolve_expr(node->left); // needs to be lvalue
Operand right = resolve_expr(node->right); Operand right = resolve_expr(node->right);
assert(node->left->kind == AST_IDENT); assert(node->left->kind == AST_IDENT);
Ast_Atom *atom = (Ast_Atom *)node->left; // @todo use left operand 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 *sym = sym_new_resolved(SYM_VAR, atom->intern_val, right.type, right.value, node);
sym_insert(sym); sym_insert(sym);
}break;
invalid_default_case;
} }
else if(token_is_assign(node->op)){
// @todo: assign value to constant
// @todo: lvalue concept, passing down syms to change (constants)
Operand left = resolve_expr(node->left);
Operand right = resolve_expr(node->right);
if(left.type != right.type) parsing_error(node->pos, "Different types");
}
else invalid_codepath;
BREAK(); BREAK();
} }