New AST
This commit is contained in:
270
parse_decl.c
270
parse_decl.c
@@ -1,218 +1,90 @@
|
||||
function Decl *parse_decl_variable(Parser *p);
|
||||
global Intern_String intern_empty;
|
||||
|
||||
function B32
|
||||
intern_empty(Intern_String a){
|
||||
B32 result = (a.s.str == 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
parse_decl_enum(Parser *p){
|
||||
Token *token = token_get(p);
|
||||
Intern_String name = {};
|
||||
if(token_match(p, TK_Identifier)){
|
||||
name = token->intern_val;
|
||||
}
|
||||
|
||||
Decl *result = decl_enum(p, token, name);
|
||||
function AST_Node *
|
||||
parse_enum(Parser *p){
|
||||
AST_Node *result = 0;
|
||||
Token *name = token_match(p, TK_Identifier);
|
||||
if(token_match(p, TK_OpenBrace)){
|
||||
for(;;){
|
||||
Token *token = token_get(p);
|
||||
if(token_match(p, TK_Identifier)){
|
||||
Expr *expr = 0;
|
||||
if(token_match(p, TK_Assign)){
|
||||
expr = parse_expr(p);
|
||||
}
|
||||
Decl_Enum_Child *child = decl_enum_child(p, token, expr);
|
||||
const_val_insert(p, token, type_s64, token->intern_val, expr);
|
||||
decl_enum_push(result, child);
|
||||
}
|
||||
else break;
|
||||
Token *op_close_brace = token_match(p, TK_CloseBrace);
|
||||
|
||||
if(!op_close_brace){
|
||||
|
||||
result = ast_enum(p, name, name->intern_val);
|
||||
do{ // Parse enum members
|
||||
Token *identifier = token_match(p, TK_Identifier);
|
||||
if(identifier){
|
||||
Expr *expr = 0;
|
||||
if(token_match(p, TK_Assign)){
|
||||
expr = parse_expr(p);
|
||||
}
|
||||
AST_Node *child = ast_enum_child(p, identifier, identifier->intern_val, expr);
|
||||
ast_node_push_child(result, child);
|
||||
{
|
||||
// Insert into scope
|
||||
}
|
||||
}
|
||||
else {
|
||||
parser_push_error(p, token_get(p), "invalid syntax of enum member");
|
||||
break;
|
||||
}
|
||||
} while(token_match(p, TK_Comma));
|
||||
token_expect(p, TK_CloseBrace);
|
||||
|
||||
if(!token_match(p, TK_Comma))
|
||||
break;
|
||||
}
|
||||
token_expect(p, TK_CloseBrace);
|
||||
}
|
||||
else {
|
||||
if(name.s.str == 0){
|
||||
parser_push_error(p, token, "Unnamed enum without body is illegal");
|
||||
}
|
||||
}
|
||||
|
||||
if(!intern_empty(name)){
|
||||
Type *type = type_enum(p, result);
|
||||
type_insert(p, type, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function void
|
||||
parse_decl_variable_right(Parser *p, Type **type, Token **name){
|
||||
while(token_match(p, TK_Mul)){
|
||||
*type = type_pointer(p, *type);
|
||||
};
|
||||
*name = token_expect(p, TK_Identifier);
|
||||
while(token_match(p, TK_OpenBracket)){
|
||||
Expr *expr = parse_expr(p);
|
||||
*type = type_array(p, *type, expr);
|
||||
token_expect(p, TK_CloseBracket);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
parse_argument_list(Parser *p, Decl *func){
|
||||
if(!token_is(p, TK_CloseParen)){
|
||||
do{
|
||||
Decl *var = parse_decl_variable(p);
|
||||
decl_function_push(func, var);
|
||||
}while(token_match(p, TK_Comma));
|
||||
}
|
||||
}
|
||||
|
||||
function Decl *
|
||||
parse_decl_variable(Parser *p){
|
||||
Decl *result = 0;
|
||||
Token *name = 0;
|
||||
Type *type = 0;
|
||||
Token *token = token_get(p);
|
||||
if(token_match(p, TK_Identifier) ||
|
||||
token_match(p, TK_Keyword)){
|
||||
type = type_get(p, token->intern_val);
|
||||
if(token_match(p, TK_OpenParen)){
|
||||
token_expect(p, TK_Mul);
|
||||
if((name = token_expect(p, TK_Identifier))){
|
||||
token_expect(p, TK_CloseParen);
|
||||
token_expect(p, TK_OpenParen);
|
||||
Decl *function_p = decl_function(p, name, type);
|
||||
parse_argument_list(p, function_p);
|
||||
token_expect(p, TK_CloseParen);
|
||||
type = type_function_pointer(p, function_p);
|
||||
}
|
||||
}
|
||||
else {
|
||||
parse_decl_variable_right(p, &type, &name);
|
||||
else{
|
||||
parser_push_error(p, op_close_brace, "enum without body");
|
||||
}
|
||||
}
|
||||
else{
|
||||
parser_push_error(p, token, "Expected type when parsing global variable");
|
||||
if(name == 0){
|
||||
parser_push_error(p, token_get(p), "enum without name or body is illegal");
|
||||
}
|
||||
}
|
||||
|
||||
Expr *expr = 0;
|
||||
if(token_match(p, TK_Assign)){
|
||||
expr = parse_expr(p);
|
||||
}
|
||||
|
||||
if(name){
|
||||
result = decl_variable(p, name, type, expr);
|
||||
if(ast_is_named(result)){
|
||||
// Insert into scope
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
parse_decl_and_register_variable(Parser *p){
|
||||
Decl *result = parse_decl_variable(p);
|
||||
if(result){
|
||||
variable_insert(p, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
parse_struct(Parser *p, Decl_Kind kind){
|
||||
Token *token = token_get(p);
|
||||
Token *name = token_match(p, TK_Identifier);
|
||||
Decl *result = decl_struct(p, token, name->intern_val);
|
||||
result->kind = kind;
|
||||
function AST_Node_List *
|
||||
parse(Parser *p){
|
||||
AST_Node_List *result = ast_node_new(p, AK_List, token_get(p), intern_empty);
|
||||
|
||||
if(token_expect(p, TK_OpenBrace)){
|
||||
do{
|
||||
if(token_match_keyword(p, keyword_struct)){
|
||||
Decl *val = parse_struct(p, DK_Struct);
|
||||
decl_aggregate_push(result, val);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_union)){
|
||||
Decl *val = parse_struct(p, DK_Union);
|
||||
decl_aggregate_push(result, val);
|
||||
}
|
||||
else if(token_is(p, TK_Keyword) || token_is(p, TK_Identifier)){
|
||||
Decl *val = parse_decl_variable(p);
|
||||
decl_aggregate_push(result, val);
|
||||
}
|
||||
else if(token_is(p, TK_CloseBrace)){
|
||||
break;
|
||||
}
|
||||
else {
|
||||
parser_push_error(p, token_get(p), "Failed to parse struct, unexpected token");
|
||||
break;
|
||||
}
|
||||
}while(token_match(p, TK_Semicolon));
|
||||
for(;;){
|
||||
AST_Node *node = 0;
|
||||
|
||||
token_expect(p, TK_CloseBrace);
|
||||
}
|
||||
|
||||
if(name){
|
||||
Type *type = type_struct(p, result);
|
||||
type_insert(p, type, name->intern_val);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
parse_decl_typedef(Parser *p){
|
||||
Decl *result = decl_type(p, token_get(p), 0, (Intern_String){});
|
||||
if(token_match_keyword(p, keyword_enum)){
|
||||
Decl *e = parse_decl_enum(p);
|
||||
result->typedef_val.type = type_enum(p, e);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_union)){
|
||||
Decl *e = parse_struct(p, DK_Union);
|
||||
result->typedef_val.type = type_struct(p, e);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_struct)){
|
||||
Decl *e = parse_struct(p, DK_Struct);
|
||||
result->typedef_val.type = type_struct(p, e);
|
||||
}
|
||||
else if(token_is(p, TK_Keyword) || token_is(p, TK_Identifier)){
|
||||
Token *token = token_next(p);
|
||||
result->typedef_val.type = type_get(p, token->intern_val);
|
||||
}
|
||||
else {
|
||||
parser_push_error(p, token_get(p), "Failed to parse typedef, unexpected token");
|
||||
}
|
||||
|
||||
Token *name = token_expect(p, TK_Identifier);
|
||||
if(name){
|
||||
result->name = name->intern_val;
|
||||
type_insert(p, type_typedef(p, result), result->name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
parse_decl_global(Parser *p){
|
||||
Decl *result = 0;
|
||||
if(token_match_keyword(p, keyword_typedef)){
|
||||
result = parse_decl_typedef(p);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_enum)){
|
||||
result = parse_decl_enum(p);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_union)){
|
||||
result = parse_struct(p, DK_Union);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_struct)){
|
||||
result = parse_struct(p, DK_Struct);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_global)){
|
||||
result = parse_decl_variable(p);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_function)){
|
||||
if(token_is(p, TK_End)){
|
||||
break;
|
||||
}
|
||||
else if(token_is(p, TK_Error)){
|
||||
break;
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_struct)){
|
||||
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_union)){
|
||||
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_enum)){
|
||||
node = parse_enum(p);
|
||||
token_expect(p, TK_Semicolon);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_function)){
|
||||
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_typedef)){
|
||||
|
||||
}
|
||||
else {
|
||||
token_next(p);
|
||||
}
|
||||
|
||||
if(node){
|
||||
ast_node_push_child(result, node);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user