Complete rework, adding packages
This commit is contained in:
68
parsing.cpp
68
parsing.cpp
@@ -1,6 +1,7 @@
|
||||
function Ast_Decl *parse_decl(B32 is_global);
|
||||
|
||||
function void
|
||||
parsing_error(Token *token, const char *str, ...){
|
||||
compiler_error(Token *token, const char *str, ...){
|
||||
Scratch scratch;
|
||||
STRING_FMT(scratch, str, string);
|
||||
|
||||
@@ -109,7 +110,7 @@ function Token *
|
||||
token_expect(Token_Kind kind){
|
||||
Token *token = token_get();
|
||||
if(token->kind == kind) return token_next();
|
||||
parsing_error(token, "Expected token of kind: [%s], got instead token of kind: [%s]", name(kind), name(token->kind));
|
||||
compiler_error(token, "Expected token of kind: [%s], got instead token of kind: [%s]", name(kind), name(token->kind));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,7 +120,7 @@ function Ast_Expr *
|
||||
parse_init_stmt(Ast_Expr *expr){
|
||||
Token *token = token_get();
|
||||
if(token->kind == TK_ColonAssign && expr->kind != AST_IDENT)
|
||||
parsing_error(expr->pos, "Binding with [:=] to something that is not an identifier");
|
||||
compiler_error(expr->pos, "Binding with [:=] to something that is not an identifier");
|
||||
|
||||
if(token_is_assign(token)){
|
||||
token_next();
|
||||
@@ -175,7 +176,6 @@ parse_optional_type(){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Named *parse_named(B32);
|
||||
function Ast_Block *
|
||||
parse_block(){
|
||||
Ast_Block *block = 0;
|
||||
@@ -257,7 +257,7 @@ parse_block(){
|
||||
|
||||
}
|
||||
else{
|
||||
Ast *result = parse_named(false);
|
||||
Ast *result = parse_decl(false);
|
||||
if(!result){
|
||||
result = parse_expr();
|
||||
result = parse_init_stmt((Ast_Expr *)result);
|
||||
@@ -268,7 +268,7 @@ parse_block(){
|
||||
stmts.add(result);
|
||||
}
|
||||
else {
|
||||
parsing_error(token, "Unexpected token [%s] while parsing statement", name(token->kind));
|
||||
compiler_error(token, "Unexpected token [%s] while parsing statement", name(token->kind));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -304,7 +304,7 @@ parse_lambda(Token *token){
|
||||
has_var_args = true;
|
||||
break;
|
||||
}
|
||||
else parsing_error(name, "Expected [Identifier] or [...] when parsing lambda arguments");
|
||||
else compiler_error(name, "Expected [Identifier] or [...] when parsing lambda arguments");
|
||||
|
||||
if(!token_match(TK_Comma))
|
||||
break;
|
||||
@@ -412,7 +412,7 @@ parse_expr(S64 min_bp){
|
||||
Ast_Expr *expr = 0;
|
||||
if(!token_is(TK_CloseBracket))
|
||||
expr = parse_expr(0);
|
||||
|
||||
|
||||
Ast_Array *result = ast_array(token, expr);
|
||||
token_expect(TK_CloseBracket);
|
||||
result->base = parse_expr(prefix_bp.right);
|
||||
@@ -430,7 +430,7 @@ parse_expr(S64 min_bp){
|
||||
token_expect(TK_CloseParen);
|
||||
left = ast_expr_cast(token, expr, typespec);
|
||||
}
|
||||
else parsing_error(token, "Unexpected keyword: [%s], expected keyword [cast]", token->intern_val.str);
|
||||
else compiler_error(token, "Unexpected keyword: [%s], expected keyword [cast]", token->intern_val.str);
|
||||
}break;
|
||||
|
||||
case TK_OpenParen: {
|
||||
@@ -441,7 +441,7 @@ parse_expr(S64 min_bp){
|
||||
token_expect(TK_CloseParen);
|
||||
}
|
||||
}break;
|
||||
default: parsing_error(token, "Unexpected token of kind: [%s] in expression", name(token->kind)); return 0;
|
||||
default: compiler_error(token, "Unexpected token of kind: [%s] in expression", name(token->kind)); return 0;
|
||||
}
|
||||
|
||||
for(;;){
|
||||
@@ -497,51 +497,45 @@ parse_assign_expr(){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Struct *
|
||||
function Ast_Decl *
|
||||
parse_struct(Token *pos){
|
||||
Scratch scratch;
|
||||
Array<Ast_Var *> members = {scratch};
|
||||
Array<Ast_Const *> members_const = {scratch};
|
||||
Array<Ast_Decl *> members = {scratch};
|
||||
|
||||
token_match(OPEN_SCOPE);
|
||||
do{
|
||||
Token *token = token_get();
|
||||
|
||||
Ast_Named *named = parse_named(false);
|
||||
if(!named) parsing_error(token, "Failed to parse struct member");
|
||||
named->flags = set_flag(named->flags, AST_AGGREGATE_CHILD);
|
||||
Ast_Decl *decl = parse_decl(false);
|
||||
if(!decl) compiler_error(token, "Failed to parse struct member");
|
||||
|
||||
if(named->kind == AST_CONST){
|
||||
members_const.add((Ast_Const *)named);
|
||||
}
|
||||
else {
|
||||
assert(named->kind == AST_VAR);
|
||||
members.add((Ast_Var *)named);
|
||||
}
|
||||
decl->flags = set_flag(decl->flags, AST_AGGREGATE_CHILD);
|
||||
members.add(decl);
|
||||
|
||||
}while(token_match(SAME_SCOPE));
|
||||
token_expect(CLOSE_SCOPE);
|
||||
|
||||
Ast_Struct *result = ast_struct(pos, members, members_const);
|
||||
Ast_Decl *result = ast_struct(pos, members);
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Enum *
|
||||
function Ast_Decl *
|
||||
parse_enum(Token *pos){
|
||||
Scratch scratch;
|
||||
Array<Ast_Enum_Member *> members = {scratch};
|
||||
Array<Ast_Decl *> members = {scratch};
|
||||
Ast_Expr *typespec = parse_optional_type();
|
||||
|
||||
token_match(OPEN_SCOPE);
|
||||
do{
|
||||
Token *name = token_expect(TK_Identifier);
|
||||
Ast_Expr *value = parse_assign_expr();
|
||||
Ast_Enum_Member *member = ast_enum_member(name, name->intern_val, value);
|
||||
Ast_Decl *member = ast_const(name, name->intern_val, value);
|
||||
member->flags = set_flag(member->flags, AST_AGGREGATE_CHILD);
|
||||
members.add(member);
|
||||
}while(token_match(SAME_SCOPE));
|
||||
token_expect(CLOSE_SCOPE);
|
||||
|
||||
Ast_Enum *result = ast_enum(pos, typespec, members);
|
||||
Ast_Decl *result = ast_enum(pos, typespec, members);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -550,13 +544,13 @@ 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;
|
||||
function Ast_Decl *
|
||||
parse_decl(B32 is_global){
|
||||
Ast_Decl *result = 0;
|
||||
if(is_global) {
|
||||
token_match(SAME_SCOPE);
|
||||
if(pctx->indent != 0){
|
||||
parsing_error(token_get(), "Top level declarations shouldn't be indented");
|
||||
compiler_error(token_get(), "Top level declarations shouldn't be indented");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,15 +562,12 @@ parse_named(B32 is_global){
|
||||
Token *tname = 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(tname, tname->intern_val, (Ast_Expr *)struct_val);
|
||||
result = parse_struct(tname);
|
||||
}
|
||||
|
||||
else if(token_match_keyword(keyword_enum)){
|
||||
Ast_Enum *enum_val = parse_enum(struct_pos);
|
||||
result = ast_const(tname, tname->intern_val, (Ast_Expr *)enum_val);
|
||||
result = parse_enum(tname);
|
||||
}
|
||||
|
||||
// @note parse constant expression
|
||||
@@ -596,10 +587,11 @@ parse_named(B32 is_global){
|
||||
result = ast_var(tname, 0, tname->intern_val, expr);
|
||||
}
|
||||
else if(is_global && tname->kind != TK_End){
|
||||
parsing_error(tname, "Unexpected token: [%s] when parsing a declaration", name(tname->kind));
|
||||
compiler_error(tname, "Unexpected token: [%s] when parsing a declaration", name(tname->kind));
|
||||
}
|
||||
|
||||
if(result){
|
||||
result->name = tname->intern_val;
|
||||
result->flags = set_flag(result->flags, flags);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user