This commit is contained in:
Krzosa Karol
2022-04-30 12:28:34 +02:00
parent a5a3acf3ef
commit 3a9b748fed
15 changed files with 296 additions and 746 deletions

View File

@@ -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;
}
}