Lambdas, statements, typechecking lambdas
This commit is contained in:
@@ -6,16 +6,13 @@ token_get(S64 i = 0){
|
||||
return &pctx->empty_token;
|
||||
}
|
||||
Token *result = &pctx->tokens[i];
|
||||
if(result->kind == TK_NewLine){
|
||||
pctx->indent = result->indent;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function Token *
|
||||
token_next(){
|
||||
Token *token = token_get();
|
||||
if(token->kind == TK_NewLine) pctx->indent = token->indent;
|
||||
pctx->token_iter++;
|
||||
return token;
|
||||
}
|
||||
@@ -79,14 +76,44 @@ parsing_error(Token *token, const char *str, ...){
|
||||
function Token *
|
||||
token_expect(Token_Kind kind){
|
||||
Token *token = token_get();
|
||||
if(token->kind == kind){
|
||||
token = token_next();
|
||||
return token;
|
||||
}
|
||||
if(token->kind == kind) return token_next();
|
||||
parsing_error(token, "Expected token of kind: [%s], got instead token of kind: [%s]", token_kind_string(kind).str, token_kind_string(token->kind).str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
function Token *
|
||||
token_is_scope(Token_Kind scope){
|
||||
assert(scope == OPEN_SCOPE || scope == CLOSE_SCOPE || scope == SAME_SCOPE);
|
||||
Token *token = token_get();
|
||||
if(token->kind == TK_NewLine){
|
||||
if (scope == OPEN_SCOPE && token->indent > pctx->indent) return token;
|
||||
else if(scope == CLOSE_SCOPE && token->indent < pctx->indent) return token;
|
||||
else if(scope == SAME_SCOPE && token->indent == pctx->indent) return token;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function Token *
|
||||
token_match_scope(Token_Kind scope){
|
||||
Token *token = token_is_scope(scope);
|
||||
if(token) return token_next();
|
||||
return 0;
|
||||
}
|
||||
|
||||
function Token *
|
||||
token_expect_scope(Token_Kind scope){
|
||||
assert(scope == OPEN_SCOPE || scope == CLOSE_SCOPE || scope == SAME_SCOPE);
|
||||
Token *token = token_get();
|
||||
if(token->kind == TK_NewLine){
|
||||
if (scope == OPEN_SCOPE && token->indent > pctx->indent) return token;
|
||||
else if(scope == CLOSE_SCOPE && token->indent < pctx->indent) return token;
|
||||
else if(scope == SAME_SCOPE && token->indent == pctx->indent) return token;
|
||||
else parsing_error(token, "Expected a scope of kind [%s]", token_kind_string(scope));
|
||||
}
|
||||
parsing_error(token, "Expected Scope[%s] got instead: [%s]", token_kind_string(scope).str, token_kind_string(token->kind).str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expression parsing
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -165,10 +192,11 @@ parse_optional_type(){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Decl *parse_decl(B32);
|
||||
function Ast_Block *
|
||||
parse_block(){
|
||||
Ast_Block *block = 0;
|
||||
if(token_match(TK_NewUpScope)){
|
||||
if(token_match_scope(OPEN_SCOPE)){
|
||||
Token *token_block = token_get();
|
||||
|
||||
Scratch scratch;
|
||||
@@ -177,19 +205,16 @@ parse_block(){
|
||||
Token *token = token_get();
|
||||
if(token_match_keyword(keyword_return)){
|
||||
AST_NEW(Return, AST_RETURN, token);
|
||||
result->expr = parse_expr();
|
||||
if(!token_is(TK_NewLine)) result->expr = parse_expr();
|
||||
stmts.add(result);
|
||||
}
|
||||
else{
|
||||
// @todo
|
||||
// Probably want to rewrite parse decls to allow for
|
||||
// calling from other places, dont want to error messages
|
||||
// to suffer though!!!
|
||||
parsing_error(token, "Unexpected token while parsing statement");
|
||||
Ast_Decl *result = parse_decl(false);
|
||||
if(result) stmts.add(result);
|
||||
else parsing_error(token, "Unexpected token while parsing statement");
|
||||
}
|
||||
} while(token_match(TK_NewLine));
|
||||
token_expect(TK_NewDownScope);
|
||||
|
||||
} while(token_match_scope(SAME_SCOPE));
|
||||
token_expect_scope(CLOSE_SCOPE);
|
||||
block = ast_block(token_block, stmts);
|
||||
}
|
||||
return block;
|
||||
@@ -390,10 +415,10 @@ parse_assign_expr(){
|
||||
}
|
||||
|
||||
function Ast_Decl *
|
||||
parse_decl(){
|
||||
parse_decl(B32 is_global){
|
||||
Ast_Decl *result = 0;
|
||||
if(token_is(TK_Identifier)){
|
||||
if(pctx->indent != 0) parsing_error(token_get(), "Top level declarations shouldn't be indented");
|
||||
if(is_global && pctx->indent != 0) parsing_error(token_get(), "Top level declarations shouldn't be indented");
|
||||
Token *name = token_next();
|
||||
if(token_match(TK_DoubleColon)){ // Constant
|
||||
Ast_Expr *expr = parse_expr();
|
||||
@@ -414,8 +439,10 @@ parse_decl(){
|
||||
}
|
||||
}
|
||||
else if(!token_is(TK_End)){
|
||||
Token *token = token_get();
|
||||
parsing_error(token, "Unexpected token: [%s] when parsing a declaration", token_kind_string(token->kind).str);
|
||||
if(is_global){
|
||||
Token *token = token_get();
|
||||
parsing_error(token, "Unexpected token: [%s] when parsing a declaration", token_kind_string(token->kind).str);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -427,7 +454,7 @@ parse_file(){
|
||||
Array<Ast_Decl *>decls = {scratch};
|
||||
while(!token_is(TK_End)){
|
||||
while(token_match(TK_NewLine));
|
||||
Ast_Decl *decl = parse_decl();
|
||||
Ast_Decl *decl = parse_decl(true);
|
||||
if(!decl) break;
|
||||
decls.add(decl);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user