This commit is contained in:
Krzosa Karol
2022-05-07 15:48:53 +02:00
parent d3ede16bab
commit 042127239e
11 changed files with 629 additions and 266 deletions

View File

@@ -31,7 +31,7 @@ parser_push_error(Parser *p, Token *token, char *str, ...){
// @Note(Krzosa): Print nice error message
{
printf("Error: %s %s:%d\n", string.str, token->file.str, (S32)token->line);
printf("\nError: %s %s:%d\n", string.str, token->file.str, (S32)token->line);
// @Note(Krzosa): Print error line
{
@@ -171,7 +171,6 @@ Compound literals
- { }
*/
function Expr_Compound_Field *
parse_expr_compound_field(Parser *p){
Token *token = token_get(p);
@@ -554,7 +553,6 @@ name::const = 4254;
// data: [24]U32;
// }
// }
*/
function void
parse_note_list(Parser *p, Note *parent) {
@@ -602,34 +600,37 @@ parse_assign_expr(Parser *p){
}
function Typespec *
parse_optional_type(Parser *p){
parse_optional_type(Parser *p, Intern_String type){
Typespec *result = 0;
if(token_match(p, TK_Colon)){
result = parse_typespec(p);
}
else{
result = typespec_name(p->arena, token_get(p), intern_int);
result = typespec_name(p->arena, token_get(p), type);
}
return result;
}
function Decl *
parse_enum(Parser *p, Token *name){
Typespec *typespec = parse_optional_type(p);
Typespec *typespec = parse_optional_type(p, intern_int);
Decl *result = decl_enum(p->arena, name, name->intern_val, typespec);
token_expect(p, TK_OpenBrace);
do{
do {
Note notes = parse_notes(p);
Token *val = token_expect(p, TK_Identifier);
Expr *expr = parse_assign_expr(p);
decl_enum_push(p->arena, result, val, val->intern_val, expr, &notes);
} while(token_match(p, TK_Comma));
if(!token_match(p, TK_Comma)){
break;
}
}while(!token_is(p, TK_CloseBrace));
token_expect(p, TK_CloseBrace);
return result;
}
function void
parse_var_decl(Parser *p, Decl *parent, Token *name){
parse_var_decl(Parser *p, Decl *parent, Token *name, Note *notes){
Token *name_stack[64];
S64 name_stack_len = 0;
name_stack[name_stack_len++] = name;
@@ -640,6 +641,7 @@ parse_var_decl(Parser *p, Decl *parent, Token *name){
token_expect(p, TK_Semicolon);
for(S64 i = 0; i < name_stack_len; i++){
Decl *decl = decl_variable(p->arena, name_stack[i], name_stack[i]->intern_val, typespec, 0);
decl_pass_notes(decl, notes);
decl_struct_push(parent, decl);
}
}
@@ -651,35 +653,38 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){
Decl *result = decl_struct(p->arena, struct_kind, token, intern_name);
token_expect(p, TK_OpenBrace);
do {
Note notes = parse_notes(p);
Token *token = token_get(p);
if(token_match_keyword(p, keyword_union)){
Decl *decl = parse_struct(p, 0, DECL_SubUnion);
decl_pass_notes(decl, &notes);
decl_struct_push(result, decl);
}
else if(token_match_keyword(p, keyword_struct)){
Decl *decl = parse_struct(p, 0, DECL_SubStruct);
decl_pass_notes(decl, &notes);
decl_struct_push(result, decl);
}
else if(token_match(p, TK_Identifier)){
if(token_is(p, TK_Colon)){
if(token_peek_is_keyword(p, keyword_union, 1)){
token_next(p);
token_next(p);
token_next(p); token_next(p);
Decl *decl = parse_struct(p, token, DECL_SubUnion);
decl_pass_notes(decl, &notes);
decl_struct_push(result, decl);
}
else if(token_peek_is_keyword(p, keyword_struct, 1)){
token_next(p);
token_next(p);
token_next(p); token_next(p);
Decl *decl = parse_struct(p, token, DECL_SubStruct);
decl_pass_notes(decl, &notes);
decl_struct_push(result, decl);
}
else{
parse_var_decl(p, result, token);
parse_var_decl(p, result, token, &notes);
}
}
else{
parse_var_decl(p, result, token);
parse_var_decl(p, result, token, &notes);
}
}
else{
@@ -690,9 +695,47 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){
}
function Decl *
parse_decl(Parser *p){
Decl *result = 0;
parse_typedef(Parser *p, Token *name){
token_expect(p, TK_Assign);
Typespec *typespec = parse_typespec(p);
token_expect(p, TK_Semicolon);
Decl *result = decl_typedef(p->arena, name, name->intern_val, typespec);
return result;
}
function Decl *
parse_const(Parser *p, Token *name){
Typespec *typespec = 0;
if(token_match(p, TK_Colon))
typespec = parse_typespec(p);
token_expect(p, TK_Assign);
Expr *expr = parse_expr(p);
token_expect(p, TK_Semicolon);
Decl *result = decl_const(p->arena, name, name->intern_val, expr, typespec);
return result;
}
function Decl *
parse_function(Parser *p, Token *name){
Decl *result = decl_function(p->arena, name, name->intern_val, 0);
if(!token_is(p, TK_CloseParen)){
do{
name = token_expect(p, TK_Identifier);
token_expect(p, TK_Colon);
Typespec *typespec = parse_typespec(p);
decl_func_push(p->arena, result, name, name->intern_val, typespec);
} while(token_match(p, TK_Comma));
}
token_expect(p, TK_CloseParen);
result->func_decl.ret = parse_optional_type(p, intern_void);
token_expect(p, TK_Semicolon);
return result;
}
function B32
parse_decl(Parser *p, Decl *parent){
Token *name = 0;
Decl *result = 0;
Note note = parse_notes(p);
if((name = token_match(p, TK_Identifier))){
if(token_match(p, TK_DoubleColon)){
@@ -706,31 +749,91 @@ parse_decl(Parser *p){
else if((token = token_match_keyword(p, keyword_struct))){
result = parse_struct(p, name, DECL_Struct);
}
else if((token = token_match_keyword(p, keyword_typedef))){
result = parse_typedef(p, name);
}
else if((token = token_match_keyword(p, keyword_const))){
// Const value
result = parse_const(p, name);
}
else if((token = token_match(p, TK_OpenParen))){
// Function
result = parse_function(p, name);
}
else{
parser_push_error(p, token_get(p), "Expected token of kind todo:decl_tokens");
token = token_get(p);
parser_push_error(p, token, "Expected a declaration keyword. Got instead: %s", token_kind_string[token->kind]);
}
}
else{
parser_push_error(p, token_get(p), "Expected token of kind '::'");
Token *token = token_get(p);
parser_push_error(p, token, "Expected a declaration which starts with token '::' got instead"
"token '%s'", token_kind_string[token->kind]);
}
}
if(result){
decl_pass_notes(result, &note);
decl_list_push(parent, result);
return true;
}
return false;
}
function Decl
parse_decls(Parser *p){
Decl decl_list = {.kind=DECL_List};
while(!token_is(p, TK_End)){
B32 success = parse_decl(p, &decl_list);
if(!success){
parser_push_error(p, token_get(p), "Failed to parse decls, unexpected token!");
}
}
return decl_list;
}
//-----------------------------------------------------------------------------
// Statement parsing
//-----------------------------------------------------------------------------
/*
stmt_list = '{' stmt* '}'
stmt =
| stmt_list
| 'return' expr ';'
| 'if' expr stmt_list
| 'for' simple_stmt_list ';' expr ';' simple_stmt_list stmt_list
| 'for' expr stmt_list
| expr assign? ';'
//| 'while' expr stmt_or_stmt_list
*/
function Stmt *
parse_stmt(Parser *p){
Note notes = parse_notes(p);
Stmt *result = 0;
if(token_match_keyword(p, keyword_if)){
}
else if(token_match_keyword(p, keyword_for)){
}
else if(token_match_keyword(p, keyword_while)){
}
else if(token_match_keyword(p, keyword_return)){
}
else if(token_match(p, TK_OpenBrace)){
// Scope
}
else{
// Expr
}
return result;
}
//-----------------------------------------------------------------------------
// Test code
//-----------------------------------------------------------------------------
function S64
eval_expr(Expr *expr){
switch(expr->kind){
@@ -875,15 +978,27 @@ parse_test_decls(){
};
for(SizeU i = 0; i < buff_cap(decls); i++){
parser_restream(&p, decls[i], lit("Decl_Test"));
Decl *decl = parse_decl(&p);
assert(decl);
decl_print(decl);
Decl decl = parse_decls(&p);
assert(decl.list_decl.first);
decl_print(decl.list_decl.first);
}
arena_end_scratch();
}
function void
parse_test_from_file(){
const String FILENAME = lit("test.cc");
Arena *scratch = arena_begin_scratch();
String file = os_read_file(scratch, FILENAME);
Parser p = parser_make_stream(scratch, file, FILENAME);
Decl d = parse_decls(&p);
decl_print(&d);
arena_end_scratch();
}
function void
parse_test(){
parse_test_expr();
parse_test_decls();
parse_test_from_file();
}