219 lines
5.5 KiB
C
219 lines
5.5 KiB
C
function Decl *parse_decl_variable(Parser *p);
|
|
|
|
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);
|
|
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;
|
|
|
|
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, token, "Expected type when parsing global variable");
|
|
}
|
|
|
|
Expr *expr = 0;
|
|
if(token_match(p, TK_Assign)){
|
|
expr = parse_expr(p);
|
|
}
|
|
|
|
if(name){
|
|
result = decl_variable(p, name, type, expr);
|
|
}
|
|
|
|
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;
|
|
|
|
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));
|
|
|
|
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)){
|
|
|
|
}
|
|
return result;
|
|
}
|