Add if statements
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
pushd %~dp0
|
pushd %~dp0
|
||||||
rem @todo fix msvc
|
rem cl main.cpp -I.. user32.lib
|
||||||
cl main.cpp -I.. user32.lib
|
clang main.cpp -O0 -I.. -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib
|
||||||
rem clang main.cpp -O0 -I.. -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib
|
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -161,6 +161,20 @@ gen_expr(Ast_Expr *ast){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
gen_ast(Ast *ast);
|
||||||
|
function void
|
||||||
|
gen_block(Ast_Block *block){
|
||||||
|
gen("{");
|
||||||
|
global_indent++;
|
||||||
|
For(block->stmts) {
|
||||||
|
genln("");
|
||||||
|
gen_ast(it[0]);
|
||||||
|
}
|
||||||
|
global_indent--;
|
||||||
|
genln("}");
|
||||||
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
gen_ast(Ast *ast){
|
gen_ast(Ast *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
@@ -194,6 +208,27 @@ gen_ast(Ast *ast){
|
|||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ast_Begin(AST_IF, Ast_If){
|
||||||
|
For(node->ifs){
|
||||||
|
if(node->ifs.is_first(it)){
|
||||||
|
genln("if(");
|
||||||
|
gen_expr(it[0]->expr);
|
||||||
|
gen(")");
|
||||||
|
gen_block(it[0]->block);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
genln("else");
|
||||||
|
if(it[0]->expr){
|
||||||
|
gen(" if(");
|
||||||
|
gen_expr(it[0]->expr);
|
||||||
|
gen(")");
|
||||||
|
}
|
||||||
|
gen_block(it[0]->block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ast_End();
|
||||||
|
}
|
||||||
|
|
||||||
Ast_Begin(AST_CONST, Ast_Decl){
|
Ast_Begin(AST_CONST, Ast_Decl){
|
||||||
Sym *sym = resolved_get(node);
|
Sym *sym = resolved_get(node);
|
||||||
|
|
||||||
@@ -211,14 +246,7 @@ gen_ast(Ast *ast){
|
|||||||
gen(")");
|
gen(")");
|
||||||
|
|
||||||
if(lambda->block) {
|
if(lambda->block) {
|
||||||
gen("{");
|
gen_block(lambda->block);
|
||||||
global_indent++;
|
|
||||||
For(lambda->block->stmts) {
|
|
||||||
genln("");
|
|
||||||
gen_ast(it[0]);
|
|
||||||
}
|
|
||||||
global_indent--;
|
|
||||||
genln("}");
|
|
||||||
}
|
}
|
||||||
else gen(";");
|
else gen(";");
|
||||||
}
|
}
|
||||||
|
|||||||
14
lambdas.kl
14
lambdas.kl
@@ -1,5 +1,18 @@
|
|||||||
|
|
||||||
|
if_stmt :: (cond: int): int
|
||||||
|
CONSTANT :: 10
|
||||||
|
|
||||||
|
if cond + CONSTANT
|
||||||
|
return cond + CONSTANT
|
||||||
|
else if cond - CONSTANT
|
||||||
|
return cond - CONSTANT
|
||||||
|
else
|
||||||
|
return CONSTANT
|
||||||
|
|
||||||
|
|
||||||
add_10 :: (size: int): int
|
add_10 :: (size: int): int
|
||||||
|
// @todo: before the generation c pass, each stage should have it's own
|
||||||
|
// tree transformation phase, where it yanks functions etc.
|
||||||
add_20 :: (new_size: int): int
|
add_20 :: (new_size: int): int
|
||||||
return 20
|
return 20
|
||||||
|
|
||||||
@@ -13,3 +26,4 @@ return_constant :: (): int
|
|||||||
returning_void :: (insert: int)
|
returning_void :: (insert: int)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
32
new_ast.cpp
32
new_ast.cpp
@@ -89,6 +89,8 @@ enum Ast_Kind{
|
|||||||
AST_COMPOUND_ITEM,
|
AST_COMPOUND_ITEM,
|
||||||
AST_COMPOUND,
|
AST_COMPOUND,
|
||||||
|
|
||||||
|
AST_IF,
|
||||||
|
AST_IF_NODE,
|
||||||
AST_RETURN,
|
AST_RETURN,
|
||||||
AST_BLOCK,
|
AST_BLOCK,
|
||||||
AST_LAMBDA,
|
AST_LAMBDA,
|
||||||
@@ -104,8 +106,12 @@ enum Ast_Kind{
|
|||||||
|
|
||||||
struct Ast{
|
struct Ast{
|
||||||
U64 id;
|
U64 id;
|
||||||
Ast_Kind kind;
|
|
||||||
Token *pos;
|
Token *pos;
|
||||||
|
|
||||||
|
Ast_Kind kind;
|
||||||
|
bool is_stmt: 1;
|
||||||
|
bool is_expr: 1;
|
||||||
|
bool is_decl: 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Resolved_Type;
|
struct Ast_Resolved_Type;
|
||||||
@@ -161,6 +167,15 @@ struct Ast_Return: Ast{
|
|||||||
Ast_Expr *expr;
|
Ast_Expr *expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Ast_If_Node: Ast{
|
||||||
|
Ast_Expr *expr ;
|
||||||
|
Ast_Block *block;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ast_If: Ast{
|
||||||
|
Array<Ast_If_Node *> ifs;
|
||||||
|
};
|
||||||
|
|
||||||
struct Ast_Lambda_Arg: Ast_Expr{
|
struct Ast_Lambda_Arg: Ast_Expr{
|
||||||
Intern_String name;
|
Intern_String name;
|
||||||
Ast_Typespec *typespec;
|
Ast_Typespec *typespec;
|
||||||
@@ -315,6 +330,21 @@ ast_block(Token *pos, Array<Ast *> stmts){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ast_If *
|
||||||
|
ast_if(Token *pos, Array<Ast_If_Node *> ifs){
|
||||||
|
AST_NEW(If, AST_IF, pos);
|
||||||
|
result->ifs = ifs.tight_copy(pctx->perm);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ast_If_Node *
|
||||||
|
ast_if_node(Token *pos, Ast_Expr *expr, Ast_Block *block){
|
||||||
|
AST_NEW(If_Node, AST_IF_NODE, pos);
|
||||||
|
result->block = block;
|
||||||
|
result->expr = expr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Typespecs
|
// Typespecs
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -668,12 +668,14 @@ lex_test(){
|
|||||||
};
|
};
|
||||||
|
|
||||||
int ui = 0;
|
int ui = 0;
|
||||||
|
S32 i = 0;
|
||||||
For(arr){
|
For(arr){
|
||||||
assert(it->kind == kind[i]);
|
assert(it->kind == kind[i]);
|
||||||
assert(string_compare(it->string, strs[i]));
|
assert(string_compare(it->string, strs[i]));
|
||||||
if(it->kind == TK_Integer){
|
if(it->kind == TK_Integer){
|
||||||
assert(it->int_val == vals[ui++]);
|
assert(it->int_val == vals[ui++]);
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,17 @@ token_is(Token_Kind kind, S64 lookahead = 0){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Token *
|
||||||
|
token_is_keyword(Intern_String keyword, S64 lookahead = 0){
|
||||||
|
Token *token = token_get(lookahead);
|
||||||
|
if(token->kind == TK_Keyword){
|
||||||
|
if(keyword.str == token->intern_val.str){
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
function Token *
|
function Token *
|
||||||
token_match(Token_Kind kind){
|
token_match(Token_Kind kind){
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
@@ -182,10 +193,37 @@ parse_block(){
|
|||||||
if(!token_is_scope()) result->expr = parse_expr();
|
if(!token_is_scope()) result->expr = parse_expr();
|
||||||
stmts.add(result);
|
stmts.add(result);
|
||||||
}
|
}
|
||||||
|
else if(token_match_keyword(keyword_if)){
|
||||||
|
Array<Ast_If_Node *> if_nodes = {scratch};
|
||||||
|
Ast_Expr *expr = parse_expr();
|
||||||
|
Ast_Block *block = parse_block();
|
||||||
|
Ast_If_Node *if_node = ast_if_node(token, expr, block);
|
||||||
|
if_nodes.add(if_node);
|
||||||
|
|
||||||
|
while(token_is(SAME_SCOPE) && token_is_keyword(keyword_else, 1)){
|
||||||
|
token_next();
|
||||||
|
token = token_next();
|
||||||
|
if(token_match_keyword(keyword_if)){
|
||||||
|
Ast_Expr *expr = parse_expr();
|
||||||
|
Ast_Block *block = parse_block();
|
||||||
|
Ast_If_Node *if_node = ast_if_node(token, expr, block);
|
||||||
|
if_nodes.add(if_node);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Ast_Block *block = parse_block();
|
||||||
|
Ast_If_Node *if_node = ast_if_node(token, 0, block);
|
||||||
|
if_nodes.add(if_node);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ast_If *result_if = ast_if(token, if_nodes);
|
||||||
|
stmts.add(result_if);
|
||||||
|
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
Ast_Decl *result = parse_decl(false);
|
Ast_Decl *result = parse_decl(false);
|
||||||
if(result) stmts.add(result);
|
if(result) stmts.add(result);
|
||||||
else parsing_error(token, "Unexpected token while parsing statement");
|
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);
|
||||||
|
|||||||
@@ -192,7 +192,6 @@ resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){
|
|||||||
function void eval_decl(Ast *ast);
|
function void eval_decl(Ast *ast);
|
||||||
function void
|
function void
|
||||||
eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
||||||
|
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
Ast_Begin(AST_RETURN, Ast_Return){ // @todo: need to check if all paths return a value
|
Ast_Begin(AST_RETURN, Ast_Return){ // @todo: need to check if all paths return a value
|
||||||
Operand op = {};
|
Operand op = {};
|
||||||
@@ -213,6 +212,15 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
|||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ast_Begin(AST_IF, Ast_If){
|
||||||
|
For(node->ifs){
|
||||||
|
if(it[0]->expr) eval_expr(it[0]->expr);
|
||||||
|
For_It(it[0]->block->stmts, jt){
|
||||||
|
eval_stmt(jt[0], ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ast_End();
|
||||||
|
}
|
||||||
|
|
||||||
invalid_default_case;
|
invalid_default_case;
|
||||||
}
|
}
|
||||||
@@ -409,7 +417,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){
|
|||||||
invalid_default_case;
|
invalid_default_case;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else parsing_error(node->pos, "Arithmetic on type [TODO] is not supported");
|
else parsing_error(node->pos, "Arithmetic on type [%s] is not supported", type_names[result.type->kind]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user