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(".");
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);
Ast_Atom *atom = (Ast_Atom *)node->left;
assert(is_atom(atom));
@@ -274,6 +274,12 @@ gen_ast(Ast *ast){
BREAK();
}
CASE(BINARY,Binary){
gen_expr(node);
gen(";");
BREAK();
}
CASE(FOR, For){
gen("for(");
if(node->init) gen_expr(node->init);
@@ -391,10 +397,16 @@ compile_string(String filecontent, String filename = "default_name"_s){
ctx.init(scratch, &heap);
pctx = &ctx;
F64 tokenize_begin = os_time();
lex_restream(&ctx, filecontent, filename);
F64 tokenize_end = os_time();
F64 parse_begin = os_time();
Ast_Package *result = parse_file();
sym_insert_builtins();
pctx->resolving_package = result;
F64 parse_end = os_time();
gen(R"==(
//-------------------------------
@@ -403,12 +415,28 @@ compile_string(String filecontent, String filename = "default_name"_s){
//-------------------------------
)==");
F64 resolve_begin = os_time();
resolve_package(result);
// eval_decl(result);
F64 resolve_end = os_time();
F64 codegen_begin = os_time();
gen_ast(result);
F64 codegen_end = os_time();
exp_destroy(&heap);
F64 flattening_begin = os_time();
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;
}

View File

@@ -32,9 +32,9 @@ For now I don't thing it should be overloadable.
-------------------------------------------------------------------------------
@todo
[ ] - Init statements
[ ] - More operators
[ ] - Init statements, different kinds [+=] [-=] etc.
[ ] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression
[ ] - More operators
[ ] - 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
[ ] - 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;
};
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
lexc(Lex_Stream *s){
@@ -353,6 +354,7 @@ lex__stream(Intern_Table *table, Array<Token> *array, Lex_Stream *s){
lex_advance(s);
}
}
else goto indent_loop_break;
} break;
// @todo: add [;;] operator which adds new scope

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,17 +492,24 @@ 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 *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);
@@ -496,36 +521,28 @@ parse_named(B32 is_global){
result = ast_const(name, name->intern_val, (Ast_Expr *)enum_val);
}
// parse constant expression
// @note parse constant expression
else{
Ast_Expr *expr = parse_expr();
result = ast_const(name, name->intern_val, expr);
}
}
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)){
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{
Token *token = token_get();
parsing_error(token, "Unexpected token: [%s] when parsing a declaration", token_kind_string(token->kind).str);
}
}
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_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;
}

View File

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

View File

@@ -64,17 +64,22 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
}
CASE(BINARY, Binary){
switch(node->op){
case TK_ColonAssign:{
if(node->op == TK_ColonAssign){
// 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;
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();
}