Backup, Decl,Type parsing enum,structs etc.

This commit is contained in:
Krzosa Karol
2022-04-29 23:28:41 +02:00
parent 9cbbb4d616
commit a5a3acf3ef
12 changed files with 407 additions and 45 deletions

24
decl.c
View File

@@ -2,7 +2,6 @@
function Decl * function Decl *
decl_new(Parser *p, Decl_Kind kind, Token *token, Intern_String name){ decl_new(Parser *p, Decl_Kind kind, Token *token, Intern_String name){
Decl *result = arena_push_struct(&p->main_arena, Decl); Decl *result = arena_push_struct(&p->main_arena, Decl);
memory_zero(result, sizeof(Decl));
result->token = token; result->token = token;
result->kind = kind; result->kind = kind;
@@ -13,12 +12,33 @@ decl_new(Parser *p, Decl_Kind kind, Token *token, Intern_String name){
function Decl_Enum_Child * function Decl_Enum_Child *
decl_enum_child(Parser *p, Token *token, Expr *expr){ decl_enum_child(Parser *p, Token *token, Expr *expr){
Decl_Enum_Child *result = arena_push_struct(&p->main_arena, Decl_Enum_Child); Decl_Enum_Child *result = arena_push_struct(&p->main_arena, Decl_Enum_Child);
memory_zero(result, sizeof(Decl_Enum_Child));
result->expr = expr; result->expr = expr;
result->token = token; result->token = token;
return result; return result;
} }
function Decl *
decl_variable(Parser *p, Token *token, Type *type, Expr *expr){
Decl *result = decl_new(p, DK_Variable, token, token->intern_val);
result->var_val.expr = expr;
result->var_val.type = type;
return result;
}
function Decl *
decl_function(Parser *p, Token *token, Type *return_type){
Decl *result = decl_new(p, DK_Function, token, token->intern_val);
result->func_val.return_type = return_type;
return result;
}
function Decl *
decl_type(Parser *p, Token *token, Type *type, Intern_String name){
Decl *result = decl_new(p, DK_Typedef, token, name);
result->typedef_val.type = type;
return result;
}
function Decl * function Decl *
decl_enum(Parser *p, Token *token, Intern_String name){ decl_enum(Parser *p, Token *token, Intern_String name){
Decl *result = decl_new(p, DK_Enum, token, name); Decl *result = decl_new(p, DK_Enum, token, name);

65
decl.h
View File

@@ -61,3 +61,68 @@ struct Decl{
}; };
}; };
//-----------------------------------------------------------------------------
// Idea
//-----------------------------------------------------------------------------
typedef struct AST_Node AST_Node;
typedef enum AST_Kind{
AK_None,
AK_Undefined,
AK_BaseType,
AK_Typedef,
AK_Pointer,
AK_Struct,
AK_Union,
AK_Array,
AK_Function,
AK_Variable,
AK_EnumChild,
}AST_Kind;
struct AST_Node{
AST_Kind kind;
Intern_String name;
Expr *expr;
Token *pos;
AST_Node *next;
AST_Node *first_note;
AST_Node *last_note;
union{
AST_Node *pointer;
struct{
SizeU size;
}base_type_val;
struct{
AST_Node *type;
}typedef_val;
struct{
AST_Node *return_type;
AST_Node *first;
AST_Node *last;
}func_val;
struct{
AST_Node *first;
AST_Node *last;
}aggregate;
struct{
AST_Node *first;
AST_Node *last;
}enum_val;
};
};
// Then I can yoink the entire idea of a symbol
// cause AST_Node is THE symbol
typedef struct Scope{
Scope *next;
AST_Node *first;
AST_Node *last;
}Scope;
{
Scope *first;
Scope *last;
}
scope_pop(Parser *p)

1
expr.c
View File

@@ -2,7 +2,6 @@
function Expr * function Expr *
expr_new(Parser *p, Expr_Kind kind, Token *token){ expr_new(Parser *p, Expr_Kind kind, Token *token){
Expr *expr = arena_push_struct(&p->main_arena, Expr); Expr *expr = arena_push_struct(&p->main_arena, Expr);
memory_zero(expr, sizeof(Expr));
expr->kind = kind; expr->kind = kind;
expr->token = token; expr->token = token;
return expr; return expr;

7
main.c
View File

@@ -11,6 +11,10 @@
#include "expr.h" #include "expr.h"
#include "decl.h" #include "decl.h"
global FILE *global_output_file;
#define lex_print(...) fprintf(global_output_file, __VA_ARGS__)
#define lex_new_line() lex_print("\n")
#include "common.c" #include "common.c"
#include "memory.c" #include "memory.c"
#include "parser.c" #include "parser.c"
@@ -99,6 +103,9 @@ parser_test(){
String decls[] = { String decls[] = {
lit("enum Thing{ Thing_1, Thing_2 = 2}"), lit("enum Thing{ Thing_1, Thing_2 = 2}"),
lit("global S64 *variable[10] = 10"),
lit("global S64 (*variable)(S64 thing) = 10"),
lit("struct Thing{ S64 a; U64 *b; union A{ S64 thing; }; }"),
}; };
for(S64 i = 0; i < buff_cap(decls); i++){ for(S64 i = 0; i < buff_cap(decls); i++){
parser_lex_stream(&p, decls[i], lit("File")); parser_lex_stream(&p, decls[i], lit("File"));

View File

@@ -35,6 +35,8 @@ arena_push_size(Arena *a, SizeU size){
a->len = align_up(a->len, a->alignment); a->len = align_up(a->len, a->alignment);
void *result = (U8*)a->memory.data + a->len; void *result = (U8*)a->memory.data + a->len;
a->len += size; a->len += size;
memory_zero(result, size);
return result; return result;
} }

View File

@@ -1,3 +1,10 @@
function Decl *parse_decl_variable(Parser *p);
function B32
intern_empty(Intern_String a){
B32 result = (a.s.str == 0);
return result;
}
function Decl * function Decl *
parse_decl_enum(Parser *p){ parse_decl_enum(Parser *p){
@@ -17,6 +24,7 @@ parse_decl_enum(Parser *p){
expr = parse_expr(p); expr = parse_expr(p);
} }
Decl_Enum_Child *child = decl_enum_child(p, token, expr); 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); decl_enum_push(result, child);
} }
else break; else break;
@@ -32,29 +40,179 @@ parse_decl_enum(Parser *p){
} }
} }
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; return result;
} }
function Decl * function Decl *
parse_decl_global(Parser *p){ parse_decl_global(Parser *p){
Decl *result = 0; Decl *result = 0;
if(token_match_keyword(p, keyword_enum)){ 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); result = parse_decl_enum(p);
}
else if(token_match_keyword(p, keyword_typedef)){
} }
else if(token_match_keyword(p, keyword_union)){ else if(token_match_keyword(p, keyword_union)){
result = parse_struct(p, DK_Union);
} }
else if(token_match_keyword(p, keyword_struct)){ else if(token_match_keyword(p, keyword_struct)){
result = parse_struct(p, DK_Struct);
} }
else if(token_match_keyword(p, keyword_global)){ else if(token_match_keyword(p, keyword_global)){
result = parse_decl_variable(p);
} }
else if(token_match_keyword(p, keyword_function)){ else if(token_match_keyword(p, keyword_function)){
} }
return result; return result;
} }

View File

@@ -93,7 +93,7 @@ Expr* parse_unary_expr(Parser* p) {
else if (token_is(p, TK_OpenParen)) { // cast requires lookahead else if (token_is(p, TK_OpenParen)) { // cast requires lookahead
Token *token = token_peek(p, 1); Token *token = token_peek(p, 1);
if (token->kind == TK_Keyword || token->kind == TK_Identifier) { if (token->kind == TK_Keyword || token->kind == TK_Identifier) {
Type *type = type_get(p, token); Type *type = type_get(p, token->intern_val);
if(type != type_undefined){ if(type != type_undefined){
token_next(p); token_next(p);
token_next(p); token_next(p);

View File

@@ -15,11 +15,9 @@ function void
parser_init(Parser *p){ parser_init(Parser *p){
p->interns_count = 4096; p->interns_count = 4096;
p->interns = arena_push_array(&p->intern_table_arena, Intern_String, p->interns_count); p->interns = arena_push_array(&p->intern_table_arena, Intern_String, p->interns_count);
memory_zero(p->interns, sizeof(Intern_String)*p->interns_count);
p->symbols_count = 4096; p->symbols_count = 4096;
p->symbols = arena_push_array(&p->intern_table_arena, Intern_String, p->symbols_count); p->symbols = arena_push_array(&p->intern_table_arena, Intern_String, p->symbols_count);
memory_zero(p->symbols, sizeof(Intern_String)*p->symbols_count);
keyword_s64 = intern_string(p, lit("S64")); keyword_s64 = intern_string(p, lit("S64"));
keyword_u64 = intern_string(p, lit("U64")); keyword_u64 = intern_string(p, lit("U64"));
@@ -50,6 +48,7 @@ intern_is_keyword(Parser *p, Intern_String intern){
function void function void
parser_push_error(Parser *p, Token *token, char *str, ...){ parser_push_error(Parser *p, Token *token, char *str, ...){
String string; String string;
{ {
va_list args1, args2; va_list args1, args2;
@@ -63,6 +62,7 @@ parser_push_error(Parser *p, Token *token, char *str, ...){
va_end(args1); va_end(args1);
} }
lex_print("Error: %s\n", string.str);// @Todo(Krzosa):
Parser_Error *error = arena_push_struct(&p->main_arena, Parser_Error); Parser_Error *error = arena_push_struct(&p->main_arena, Parser_Error);
error->message = string; error->message = string;
error->next = 0; error->next = 0;
@@ -112,6 +112,8 @@ intern_string(Parser *p, String string){
Intern_String *intern = p->interns + index.iter; Intern_String *intern = p->interns + index.iter;
if(intern->s.str == 0){ if(intern->s.str == 0){
result.s = arena_push_string_copy(&p->main_arena, string); result.s = arena_push_string_copy(&p->main_arena, string);
p->interns_in_bytes += string.len;
p->interns_inserted += 1;
*intern = result; *intern = result;
break; break;
} }
@@ -141,26 +143,29 @@ intern_tokens(Parser *p){
} }
} }
function void function Symbol *
symbol_insert(Parser *p, Symbol symbol){ symbol_get_slot(Parser *p, Intern_String intern){
String string = symbol.string.s; String string = intern.s;
Table_Index index = table_index_from_string(string, p->symbols_count); Table_Index index = table_index_from_string(string, p->symbols_count);
for(;;){ for(;;){
Symbol *slot = p->symbols + index.iter; Symbol *slot = p->symbols + index.iter;
if(slot->string.s.str == 0){ if(slot->string.s.str == 0){
*slot = symbol; slot->string = intern;
break; p->symbols_inserted++;
return slot;
} }
else if(slot->string.s.str == string.str){ else if(slot->string.s.str == string.str){
invalid_codepath; return slot;
break;
} }
if (table_index_advance(&index)) if (table_index_advance(&index))
break; break;
} }
parser_push_error(p, token_get(p), "Failed to find a spot for symbol");
return 0;
} }
function Symbol * function Symbol *
@@ -179,31 +184,63 @@ symbol_get(Parser *p, Intern_String string){
return 0; return 0;
} }
function B32
symbol_require_empty(Parser *p, Symbol *symbol){
assert(symbol);
B32 result = symbol->kind == SK_None;
if(!result){
// @Todo(Krzosa): Should send symbol name not token
parser_push_error(p, token_get(p), "This symbol name is already registered");
}
return result;
}
function void
const_val_insert(Parser *p, Token *token, Type *type, Intern_String string, Expr *expr){
Symbol *symbol = symbol_get_slot(p, string);
if(symbol_require_empty(p, symbol)){
symbol->kind = SK_Const;
symbol->token = token;
symbol->const_val.type = type;
symbol->const_val.expr = expr;
}
}
function void
variable_insert(Parser *p, Decl *decl){
Symbol *symbol = symbol_get_slot(p, decl->name);
if(symbol_require_empty(p, symbol)){
symbol->kind = SK_Decl;
symbol->decl = decl;
symbol->string = decl->name;
symbol->token = decl->token;
}
}
function void function void
type_insert(Parser *p, Type *type, Intern_String string){ type_insert(Parser *p, Type *type, Intern_String string){
Symbol symbol = {.kind=SK_Type, .string=string, .type=type}; Symbol *symbol = symbol_get_slot(p, string);
symbol_insert(p, symbol); if(symbol_require_empty(p, symbol)){
symbol->kind = SK_Type;
symbol->type = type;
symbol->string = string;
}
} }
function Type * function Type *
type_get(Parser *p, Token *token){ type_get(Parser *p, Intern_String string){
Type *result = 0; Type *result = 0;
if(token->kind == TK_Identifier || token->kind == TK_Keyword){ Symbol *symbol = symbol_get(p, string);
Symbol *symbol = symbol_get(p, token->intern_val); if(symbol){
if(symbol){ if(symbol->kind == SK_Type){
if(symbol->kind == SK_Type){ result = symbol->type;
result = symbol->type;
}
else {
parser_push_error(p, token, "Symbol is not a type");
}
} }
else{ else {
parser_push_error(p, token, "Undefined type"); parser_push_error(p, token_get(p), "Symbol is not a type");
} }
} }
else { else{
parser_push_error(p, token, "Trying to lookup a type with token of wrong kind"); parser_push_error(p, token_get(p), "Undefined type");
} }
if(!result){ if(!result){

View File

@@ -1,17 +1,27 @@
#pragma once #pragma once
typedef struct Type Type; typedef struct Type Type;
typedef struct Expr Expr;
typedef struct Decl Decl;
typedef struct Parser_Error Parser_Error; typedef struct Parser_Error Parser_Error;
typedef enum Symbol_Kind{ typedef enum Symbol_Kind{
SK_None, SK_None,
SK_Type, SK_Type,
SK_Const,
SK_Decl,
}Symbol_Kind; }Symbol_Kind;
typedef struct Symbol{ typedef struct Symbol{
Symbol_Kind kind; Symbol_Kind kind;
Intern_String string; Intern_String string;
Token *token;
struct{ struct{
Type *type; Type *type;
struct{
Type *type;
Expr *expr;
} const_val;
Decl *decl;
}; };
}Symbol; }Symbol;
@@ -26,9 +36,12 @@ typedef struct Parser{
Arena intern_table_arena; Arena intern_table_arena;
Arena symbol_table_arena; Arena symbol_table_arena;
S64 symbols_inserted;
Symbol *symbols; Symbol *symbols;
S64 symbols_count; S64 symbols_count;
S64 interns_in_bytes;
S64 interns_inserted;
Intern_String *interns; Intern_String *interns;
S64 interns_count; S64 interns_count;
@@ -43,4 +56,4 @@ typedef struct Parser{
function Intern_String intern_string(Parser *p, String string); function Intern_String intern_string(Parser *p, String string);
function void type_insert(Parser *p, Type *type, Intern_String string); function void type_insert(Parser *p, Type *type, Intern_String string);
function Token *token_get(Parser *p);

33
print.c
View File

@@ -1,8 +1,4 @@
global FILE *global_output_file;
#define lex_print(...) fprintf(global_output_file, __VA_ARGS__)
#define lex_new_line() lex_print("\n")
function void function void
tokens_print(Tokens tokens){ tokens_print(Tokens tokens){
lex_print("\n== Token count = %d\n", (S32)tokens.len); lex_print("\n== Token count = %d\n", (S32)tokens.len);
@@ -30,6 +26,14 @@ type_print(Type *type){
type_print(type->pointer); type_print(type->pointer);
lex_print("*"); lex_print("*");
} break; } break;
case TK_Function:{
type_print(type->decl->func_val.return_type);
lex_print("(");
for(Decl *n = type->decl->func_val.first; n; n=n->next){
token_print(n->token); // @Todo(Krzosa):
}
lex_print(")");
} break;
case TK_Array:{ case TK_Array:{
type_print(type->array.pointer); type_print(type->array.pointer);
lex_print("["); lex_print("[");
@@ -110,10 +114,29 @@ expr_print(Expr *expr){
} }
} }
function void function void
decl_print(Decl *decl){ decl_print(Decl *decl){
switch(decl->kind) { switch(decl->kind) {
case DK_Union: lex_print("union");
case DK_Struct:{
lex_print("struct %s{\n", decl->name.s.str);
for(Decl *n = decl->aggregate_val.first; n; n=n->next){
decl_print(n);
lex_print(";\n");
}
lex_print("}\n");
} break;
case DK_Variable:{
type_print(decl->var_val.type);
lex_print(" %s", decl->name.s.str);
if(decl->var_val.expr){
lex_print(" = ");
expr_print(decl->var_val.expr);
}
} break;
case DK_Enum: { case DK_Enum: {
lex_print("enum %s{\n", decl->name.s.str); lex_print("enum %s{\n", decl->name.s.str);
for(Decl_Enum_Child *n = decl->enum_val.first; n; n=n->next){ for(Decl_Enum_Child *n = decl->enum_val.first; n; n=n->next){

38
type.c
View File

@@ -2,8 +2,6 @@
function Type * function Type *
type_new(Parser *p, Type_Kind kind){ type_new(Parser *p, Type_Kind kind){
Type *result = arena_push_struct(&p->main_arena, Type); Type *result = arena_push_struct(&p->main_arena, Type);
memory_zero(result, sizeof(Type));
result->kind = kind; result->kind = kind;
return result; return result;
} }
@@ -22,4 +20,40 @@ type_array(Parser *p, Type *base, Expr *index){
result->array.pointer = base; result->array.pointer = base;
result->array.size = index; result->array.size = index;
return result; return result;
}
function Type *
type_enum(Parser *p, Decl *enum_val){
Type *result = type_new(p, TK_Enum);
result->decl = enum_val;
return result;
}
function Type *
type_struct(Parser *p, Decl *struct_val){
Type *result = type_new(p, TK_Struct);
result->decl = struct_val;
return result;
}
function Type *
type_union(Parser *p, Decl *union_val){
Type *result = type_new(p, TK_Union);
result->decl = union_val;
return result;
}
function Type *
type_function_pointer(Parser *p, Decl *func_val){
Type *result = type_new(p, TK_Function);
result->decl = func_val;
result = type_pointer(p, result);
return result;
}
function Type *
type_typedef(Parser *p, Decl *typedef_val){
Type *result = type_new(p, TK_Typedef);
result->decl = typedef_val;
return result;
} }

4
type.h
View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
typedef struct Type Type; typedef struct Type Type;
typedef struct Expr Expr; typedef struct Expr Expr;
typedef struct Decl Decl;
typedef enum Type_Kind{ typedef enum Type_Kind{
TK_None, TK_None,
@@ -10,8 +11,10 @@ typedef enum Type_Kind{
TK_SizeU, TK_SizeU,
TK_Undefined, TK_Undefined,
TK_Typedef,
TK_Function, TK_Function,
TK_Pointer, TK_Pointer,
TK_Enum,
TK_Array, TK_Array,
TK_Struct, TK_Struct,
TK_Union, TK_Union,
@@ -22,6 +25,7 @@ struct Type{
SizeU size; SizeU size;
union{ union{
Type *pointer; Type *pointer;
Decl *decl;
struct{ struct{
Type *pointer; Type *pointer;
Expr *size; Expr *size;