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

34
ast.c Normal file
View File

@@ -0,0 +1,34 @@
typedef AST_Node AST_Node_List;
function B32
ast_is_named(AST_Node *n){
B32 result = n && n->name.s.str;
return result;
}
function AST_Node *
ast_node_new(Parser *p, AST_Kind kind, Token *token, Intern_String name){
AST_Node *node = arena_push_struct(&p->main_arena, AST_Node);
node->pos = token;
node->name = name;
node->kind = kind;
return node;
}
function AST_Node *
ast_enum(Parser *p, Token *token, Intern_String name){
AST_Node *node = ast_node_new(p, AK_Enum, token, name);
return node;
}
function AST_Node *
ast_enum_child(Parser *p, Token *token, Intern_String name, Expr *expr){
AST_Node *node = ast_node_new(p, AK_EnumChild, token, name);
node->expr = expr;
return node;
}
function void
ast_node_push_child(AST_Node *node, AST_Node *child){
SLLQueuePush(node->first_child, node->last_child, child);
}

51
ast.h Normal file
View File

@@ -0,0 +1,51 @@
typedef struct AST_Node AST_Node;
typedef struct Expr Expr;
typedef enum AST_Kind{
AK_None,
AK_Undefined,
AK_BaseType,
AK_Typedef,
AK_Enum,
AK_Struct,
AK_Union,
AK_Note,
AK_List,
AK_Pointer,
AK_Array,
AK_Function,
AK_Variable,
AK_EnumChild,
}AST_Kind;
struct AST_Node{
AST_Kind kind;
Token *pos;
Expr *expr;
Intern_String name;
AST_Node *next;
AST_Node *scope_next;
AST_Node *first_note;
AST_Node *last_note;
AST_Node *first_child;
AST_Node *last_child;
union{
AST_Node *pointer;
SizeU base_type_size;
AST_Node *typedef_type;
AST_Node *func_return_type;
};
};
function B32
ast_is_type(AST_Node *n){
B32 result = n->kind >= AK_BaseType && n->kind <= AK_Union;
return result;
}

70
decl.c
View File

@@ -1,70 +0,0 @@
function Decl *
decl_new(Parser *p, Decl_Kind kind, Token *token, Intern_String name){
Decl *result = arena_push_struct(&p->main_arena, Decl);
result->token = token;
result->kind = kind;
result->name = name;
return result;
}
function Decl_Enum_Child *
decl_enum_child(Parser *p, Token *token, Expr *expr){
Decl_Enum_Child *result = arena_push_struct(&p->main_arena, Decl_Enum_Child);
result->expr = expr;
result->token = token;
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 *
decl_enum(Parser *p, Token *token, Intern_String name){
Decl *result = decl_new(p, DK_Enum, token, name);
return result;
}
function Decl *
decl_struct(Parser *p, Token *token, Intern_String name){
Decl *result = decl_new(p, DK_Struct, token, name);
return result;
}
function Decl *
decl_union(Parser *p, Token *token, Intern_String name){
Decl *result = decl_new(p, DK_Union, token, name);
return result;
}
function void
decl_aggregate_push(Decl *a, Decl *b){
SLLQueuePush(a->aggregate_val.first, a->aggregate_val.last, b);
}
function void
decl_function_push(Decl *a, Decl *b){
SLLQueuePush(a->func_val.first, a->func_val.last, b);
}
function void
decl_enum_push(Decl *a, Decl_Enum_Child *b){
SLLQueuePush(a->enum_val.first, a->enum_val.last, b);
}

128
decl.h
View File

@@ -1,128 +0,0 @@
#pragma once
typedef struct Note Note;
typedef struct Decl Decl;
typedef struct Decl_Enum_Child Decl_Enum_Child;
typedef enum Decl_Kind{
DK_None,
DK_Variable,
DK_Typedef,
DK_Struct,
DK_Union,
DK_Enum,
DK_Function,
}Decl_Kind;
struct Note{
Intern_String string;
Token *token;
Expr *expr;
Note *next;
Note *first;
Note *last;
};
struct Decl_Enum_Child{
Decl_Enum_Child *next;
Token *token; // name
Expr *expr;
};
struct Decl{
Decl_Kind kind;
Decl *next;
Intern_String name;
Token *token;
Note *first_note;
Note *last_note;
union{
struct{
Decl_Enum_Child *first;
Decl_Enum_Child *last;
} enum_val;
struct{
Decl *first;
Decl *last;
} aggregate_val;
struct{
Decl *first;
Decl *last;
Type *return_type;
}func_val;
struct{
Type *type;
Expr *expr;
}var_val;
struct{
Type *type;
}typedef_val;
};
};
//-----------------------------------------------------------------------------
// 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)

2
expr.c
View File

@@ -54,7 +54,7 @@ expr_index(Parser *p, Token *token, Expr *atom, Expr *index){
} }
function Expr * function Expr *
expr_cast(Parser *p, Token *token, Type *type, Expr *exp){ expr_cast(Parser *p, Token *token, AST_Node *type, Expr *exp){
Expr *expr = expr_new(p, EK_Cast, token); Expr *expr = expr_new(p, EK_Cast, token);
expr->cast.type = type; expr->cast.type = type;
expr->cast.expr = exp; expr->cast.expr = exp;

2
expr.h
View File

@@ -19,7 +19,7 @@ struct Expr {
Expr *next; Expr *next;
union { union {
struct { struct {
Type *type; AST_Node *type;
Expr* expr; Expr* expr;
} cast; } cast;
struct { struct {

16
lang.h
View File

@@ -48,4 +48,18 @@ if((f)==0){\
else{\ else{\
(l)=(l)->next=(n);\ (l)=(l)->next=(n);\
} \ } \
}while(0) }while(0)
#define SLLStackPush(l,n) do{\
(n)->next = (l);\
(l) = (n);\
}while(0)
#define SLLStackPop(l,n) do{\
if(l){\
(n) = (l);\
(l) = (l)->next;\
(n)->next = 0;\
}\
}while(0)

22
main.c
View File

@@ -5,11 +5,11 @@
#include "lang.h" #include "lang.h"
#include "os.h" #include "os.h"
#include "memory.h" #include "memory.h"
#include "lex.h" #include "lex.h"
#include "ast.h"
#include "parser.h" #include "parser.h"
#include "type.h"
#include "expr.h" #include "expr.h"
#include "decl.h"
global FILE *global_output_file; global FILE *global_output_file;
#define lex_print(...) fprintf(global_output_file, __VA_ARGS__) #define lex_print(...) fprintf(global_output_file, __VA_ARGS__)
@@ -19,10 +19,10 @@ global FILE *global_output_file;
#include "memory.c" #include "memory.c"
#include "parser.c" #include "parser.c"
#include "os_win32.c" #include "os_win32.c"
#include "lex.c" #include "lex.c"
#include "expr.c" #include "expr.c"
#include "decl.c" #include "ast.c"
#include "type.c"
#include "parse_expr.c" #include "parse_expr.c"
#include "parse_decl.c" #include "parse_decl.c"
#include "print.c" #include "print.c"
@@ -98,21 +98,15 @@ parser_test(){
expr_print(expr); expr_print(expr);
lex_print("\n"); lex_print("\n");
} }
type_test(&p);
lex_new_line();
String decls[] = { String decls[] = {
lit("enum Thing{ Thing_1, Thing_2 = 2}"), lit("enum Thing{ Thing_1 = 10, Thing_2 = 20<<1 };"),
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"));
Decl *decl = parse_decl_global(&p); AST_Node *node = parse(&p);
assert(decl); assert(node);
decl_print(decl);
lex_new_line();
} }
} }

View File

@@ -1,218 +1,90 @@
function Decl *parse_decl_variable(Parser *p); global Intern_String intern_empty;
function B32 function AST_Node *
intern_empty(Intern_String a){ parse_enum(Parser *p){
B32 result = (a.s.str == 0); AST_Node *result = 0;
return result; Token *name = token_match(p, TK_Identifier);
}
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)){ if(token_match(p, TK_OpenBrace)){
for(;;){ Token *op_close_brace = token_match(p, TK_CloseBrace);
Token *token = token_get(p);
if(token_match(p, TK_Identifier)){ if(!op_close_brace){
Expr *expr = 0;
if(token_match(p, TK_Assign)){ result = ast_enum(p, name, name->intern_val);
expr = parse_expr(p); do{ // Parse enum members
} Token *identifier = token_match(p, TK_Identifier);
Decl_Enum_Child *child = decl_enum_child(p, token, expr); if(identifier){
const_val_insert(p, token, type_s64, token->intern_val, expr); Expr *expr = 0;
decl_enum_push(result, child); if(token_match(p, TK_Assign)){
} expr = parse_expr(p);
else break; }
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{
} parser_push_error(p, op_close_brace, "enum without body");
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{ 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(ast_is_named(result)){
if(token_match(p, TK_Assign)){ // Insert into scope
expr = parse_expr(p);
}
if(name){
result = decl_variable(p, name, type, expr);
} }
return result; return result;
} }
function Decl * function AST_Node_List *
parse_decl_and_register_variable(Parser *p){ parse(Parser *p){
Decl *result = parse_decl_variable(p); AST_Node_List *result = ast_node_new(p, AK_List, token_get(p), intern_empty);
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)){ for(;;){
do{ AST_Node *node = 0;
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(token_is(p, TK_End)){
} break;
}
if(name){ else if(token_is(p, TK_Error)){
Type *type = type_struct(p, result); break;
type_insert(p, type, name->intern_val); }
} else if(token_match_keyword(p, keyword_struct)){
return result; }
} else if(token_match_keyword(p, keyword_union)){
function Decl * }
parse_decl_typedef(Parser *p){ else if(token_match_keyword(p, keyword_enum)){
Decl *result = decl_type(p, token_get(p), 0, (Intern_String){}); node = parse_enum(p);
if(token_match_keyword(p, keyword_enum)){ token_expect(p, TK_Semicolon);
Decl *e = parse_decl_enum(p); }
result->typedef_val.type = type_enum(p, e); else if(token_match_keyword(p, keyword_function)){
}
else if(token_match_keyword(p, keyword_union)){ }
Decl *e = parse_struct(p, DK_Union); else if(token_match_keyword(p, keyword_typedef)){
result->typedef_val.type = type_struct(p, e);
} }
else if(token_match_keyword(p, keyword_struct)){ else {
Decl *e = parse_struct(p, DK_Struct); token_next(p);
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(node){
ast_node_push_child(result, node);
}
} }
return result; return result;
} }

View File

@@ -93,8 +93,9 @@ 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->intern_val);
if(type != type_undefined){ AST_Node *type = symbol_lookup_type(p, token->intern_val);
if(type){
token_next(p); token_next(p);
token_next(p); token_next(p);
// @Todo(Krzosa): Parse pointer types // @Todo(Krzosa): Parse pointer types
@@ -105,6 +106,7 @@ Expr* parse_unary_expr(Parser* p) {
else { else {
result = parse_postfix_expr(p); result = parse_postfix_expr(p);
} }
} }
else { else {
result = parse_postfix_expr(p); result = parse_postfix_expr(p);

190
parser.c
View File

@@ -11,13 +11,18 @@ global Intern_String keyword_union;
global Intern_String keyword_function; global Intern_String keyword_function;
global Intern_String keyword_global; global Intern_String keyword_global;
global AST_Node *type_s64;
global AST_Node *type_u64;
global AST_Node *type_void;
global AST_Node *type_sizeu;
function void 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);
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->symbol_table_arena, AST_Node, 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"));
@@ -33,10 +38,12 @@ parser_init(Parser *p){
p->first_keyword = keyword_s64.s.str; p->first_keyword = keyword_s64.s.str;
p->last_keyword = keyword_global.s.str; p->last_keyword = keyword_global.s.str;
type_insert(p, type_s64, keyword_s64); parser_push_scope(p); // Global scope
type_insert(p, type_u64, keyword_u64); type_s64 = symbol_register_basic_type(p, keyword_s64, sizeof(S64));
type_insert(p, type_sizeu, keyword_sizeu); type_u64 = symbol_register_basic_type(p, keyword_u64, sizeof(U64));
type_insert(p, type_void, keyword_void); type_sizeu = symbol_register_basic_type(p, keyword_sizeu, sizeof(SizeU));
type_void = symbol_register_basic_type(p, keyword_void, sizeof(void));
} }
function B32 function B32
@@ -46,6 +53,19 @@ intern_is_keyword(Parser *p, Intern_String intern){
return false; return false;
} }
function void
intern_tokens(Parser *p){
for(S64 i = 0; i < p->tokens.len; i++){
Token *t = p->tokens.tokens + i;
if(t->kind == TK_Identifier){
t->intern_val = intern_string(p, t->string);
if(intern_is_keyword(p, t->intern_val)){
t->kind = TK_Keyword;
}
}
}
}
function void function void
parser_push_error(Parser *p, Token *token, char *str, ...){ parser_push_error(Parser *p, Token *token, char *str, ...){
@@ -130,122 +150,100 @@ intern_string(Parser *p, String string){
return result; return result;
} }
function void //-----------------------------------------------------------------------------
intern_tokens(Parser *p){ // Symbols
for(S64 i = 0; i < p->tokens.len; i++){ //-----------------------------------------------------------------------------
Token *t = p->tokens.tokens + i; function AST_Node *
if(t->kind == TK_Identifier){ symbol_alloc_slot(Parser *p, Intern_String string, B32 is_global){
t->intern_val = intern_string(p, t->string); Table_Index index = table_index_from_string(string.s, p->symbols_count);
if(intern_is_keyword(p, t->intern_val)){
t->kind = TK_Keyword;
}
}
}
}
function Symbol *
symbol_get_slot(Parser *p, Intern_String intern){
String string = intern.s;
Table_Index index = table_index_from_string(string, p->symbols_count);
for(;;){ for(;;){
Symbol *slot = p->symbols + index.iter; AST_Node *symbol = p->symbols + index.iter;
if(slot->string.s.str == 0){
slot->string = intern; if(symbol->name.s.str == 0){
/* @Note(Krzosa): Push on scope */ {
if(is_global){
SLLQueuePush(p->scope_stack->first, p->scope_stack->last, symbol);
}
else{
SLLQueuePush(p->global_scope->first, p->global_scope->last, symbol);
}
}
symbol->name = string;
p->symbols_inserted++; p->symbols_inserted++;
return slot;
return symbol;
} }
else if(slot->string.s.str == string.str){ else if(intern_compare(symbol->name, string)){
return slot; return symbol;
} }
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; return 0;
} }
function Symbol * function AST_Node *
symbol_get(Parser *p, Intern_String string){ symbol_lookup(Parser *p, Intern_String string){
Table_Index index = table_index_from_string(string.s, p->symbols_count); Table_Index index = table_index_from_string(string.s, p->symbols_count);
for(;;){ for(;;){
Symbol *slot = p->symbols + index.iter; AST_Node *symbol = p->symbols + index.iter;
if(slot->string.s.str == string.s.str){
return slot; if(symbol->name.s.str == 0){
return 0;
}
else if(intern_compare(symbol->name, string)){
return symbol;
} }
if (table_index_advance(&index)) if (table_index_advance(&index))
break; return 0;
}
}
function AST_Node *
symbol_register_basic_type(Parser *p, Intern_String string, SizeU size){
AST_Node *node = symbol_alloc_slot(p, string, true);
node->kind = AK_BaseType;
node->base_type_size = size;
return node;
}
function AST_Node *
symbol_lookup_type(Parser *p, Intern_String string){
AST_Node *node = symbol_lookup(p, string);
if(node){
if(ast_is_type(node)){
return node;
}
} }
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 function void
const_val_insert(Parser *p, Token *token, Type *type, Intern_String string, Expr *expr){ parser_push_scope(Parser *p){
Symbol *symbol = symbol_get_slot(p, string); Scope *scope = 0;
if(symbol_require_empty(p, symbol)){ SLLStackPop(p->scope_free_list, scope);
symbol->kind = SK_Const; if(!scope){
symbol->token = token; scope = arena_push_struct(&p->main_arena, Scope);
symbol->const_val.type = type; }
symbol->const_val.expr = expr; SLLStackPush(p->scope_stack, scope);
if(p->global_scope == 0){
p->global_scope = scope;
} }
} }
function void function void
variable_insert(Parser *p, Decl *decl){ parser_pop_scope(Parser *p){
Symbol *symbol = symbol_get_slot(p, decl->name); Scope *scope = 0;
if(symbol_require_empty(p, symbol)){ SLLStackPop(p->scope_stack, scope);
symbol->kind = SK_Decl; assert(scope);
symbol->decl = decl;
symbol->string = decl->name;
symbol->token = decl->token;
}
}
function void
type_insert(Parser *p, Type *type, Intern_String string){
Symbol *symbol = symbol_get_slot(p, string);
if(symbol_require_empty(p, symbol)){
symbol->kind = SK_Type;
symbol->type = type;
symbol->string = string;
}
}
function Type *
type_get(Parser *p, Intern_String string){
Type *result = 0;
Symbol *symbol = symbol_get(p, string);
if(symbol){
if(symbol->kind == SK_Type){
result = symbol->type;
}
else {
parser_push_error(p, token_get(p), "Symbol is not a type");
}
}
else{
parser_push_error(p, token_get(p), "Undefined type");
}
if(!result){ for(AST_Node *s = scope->first; s; s=s->scope_next){
result = type_undefined; memory_zero(s, sizeof(AST_Node));
p->symbols_inserted--;
} }
memory_zero(scope, sizeof(Scope));
return result; SLLStackPush(p->scope_free_list, scope);
} }

View File

@@ -1,43 +1,32 @@
#pragma once #pragma once
typedef struct Type Type;
typedef struct Expr Expr; typedef struct Expr Expr;
typedef struct Decl Decl; typedef struct Scope Scope;
typedef struct AST_Node AST_Node;
typedef struct Parser_Error Parser_Error; typedef struct Parser_Error Parser_Error;
typedef enum Symbol_Kind{
SK_None,
SK_Type,
SK_Const,
SK_Decl,
}Symbol_Kind;
typedef struct Symbol{
Symbol_Kind kind;
Intern_String string;
Token *token;
struct{
Type *type;
struct{
Type *type;
Expr *expr;
} const_val;
Decl *decl;
};
}Symbol;
struct Parser_Error{ struct Parser_Error{
Parser_Error *next; Parser_Error *next;
String message; String message;
Token *token; Token *token;
}; };
struct Scope{
Scope *next;
AST_Node *first;
AST_Node *last;
};
typedef struct Parser{ typedef struct Parser{
Arena main_arena; Arena main_arena;
Arena intern_table_arena; Arena intern_table_arena;
Arena symbol_table_arena; Arena symbol_table_arena;
Scope *scope_free_list;
Scope *scope_stack;
Scope *global_scope;
S64 symbols_inserted; S64 symbols_inserted;
Symbol *symbols; AST_Node *symbols;
S64 symbols_count; S64 symbols_count;
S64 interns_in_bytes; S64 interns_in_bytes;
@@ -55,5 +44,7 @@ typedef struct Parser{
}Parser; }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 Token *token_get(Parser *p); function Token *token_get(Parser *p);
function B32 intern_compare(Intern_String a, Intern_String b);
function void parser_push_scope(Parser *p);
function AST_Node *symbol_register_basic_type(Parser *p, Intern_String string, SizeU size);

82
print.c
View File

@@ -12,45 +12,6 @@ token_print(Token *token){
lex_print("%.*s", (S32)token->len, token->str); lex_print("%.*s", (S32)token->len, token->str);
} }
function Type *type_pointer(Parser *p, Type *base);
function void expr_print(Expr *expr);
function void
type_print(Type *type){
switch(type->kind) {
case TK_S64: case TK_U64:
case TK_SizeU: case TK_Void: {
lex_print("%s", type_kind_string[type->kind].str);
} break;
case TK_Pointer:{
type_print(type->pointer);
lex_print("*");
} 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:{
type_print(type->array.pointer);
lex_print("[");
expr_print(type->array.size);
lex_print("]");
} break;
default: {invalid_codepath;} break;
}
}
function void
type_test(Parser *p){
Type *t = type_pointer(p, type_s64);
t = type_pointer(p, t);
type_print(t);
}
function void function void
expr_print(Expr *expr){ expr_print(Expr *expr){
switch(expr->kind) { switch(expr->kind) {
@@ -93,7 +54,7 @@ expr_print(Expr *expr){
case EK_Cast:{ case EK_Cast:{
lex_print("("); lex_print("(");
lex_print("("); lex_print("(");
type_print(expr->cast.type); //type_print(expr->cast.type);
lex_print(")"); lex_print(")");
expr_print(expr->cast.expr); expr_print(expr->cast.expr);
lex_print(")"); lex_print(")");
@@ -113,44 +74,3 @@ expr_print(Expr *expr){
default: {invalid_codepath;} break; default: {invalid_codepath;} break;
} }
} }
function void
decl_print(Decl *decl){
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: {
lex_print("enum %s{\n", decl->name.s.str);
for(Decl_Enum_Child *n = decl->enum_val.first; n; n=n->next){
lex_print(" ");
token_print(n->token);
if(n->expr){
lex_print(" = ");
expr_print(n->expr);
}
lex_print(",");
lex_new_line();
}
lex_print("};\n");
} break;
default: {invalid_codepath;} break;
}
}

59
type.c
View File

@@ -1,59 +0,0 @@
function Type *
type_new(Parser *p, Type_Kind kind){
Type *result = arena_push_struct(&p->main_arena, Type);
result->kind = kind;
return result;
}
function Type *
type_pointer(Parser *p, Type *base){
Type *result = type_new(p, TK_Pointer);
result->size = sizeof(SizeU);
result->pointer = base;
return result;
}
function Type *
type_array(Parser *p, Type *base, Expr *index){
Type *result = type_new(p, TK_Array);
result->array.pointer = base;
result->array.size = index;
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;
}

69
type.h
View File

@@ -1,69 +0,0 @@
#pragma once
typedef struct Type Type;
typedef struct Expr Expr;
typedef struct Decl Decl;
typedef enum Type_Kind{
TK_None,
TK_Void,
TK_S64,
TK_U64,
TK_SizeU,
TK_Undefined,
TK_Typedef,
TK_Function,
TK_Pointer,
TK_Enum,
TK_Array,
TK_Struct,
TK_Union,
} Type_Kind;
struct Type{
Type_Kind kind;
SizeU size;
union{
Type *pointer;
Decl *decl;
struct{
Type *pointer;
Expr *size;
} array;
};
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
global String type_kind_string[] = {
[TK_None] = lit("None"),
[TK_Void] = lit("void"),
[TK_S64] = lit("S64"),
[TK_U64] = lit("U64"),
[TK_SizeU] = lit("SizeU"),
[TK_Undefined] = lit("Undefined"),
[TK_Pointer] = lit("Pointer"),
[TK_Array] = lit("Array"),
[TK_Struct] = lit("Struct"),
[TK_Union] = lit("Union"),
};
global Type type_table[] = {
[TK_None] = {0},
[TK_Void] = {TK_Void},
[TK_S64] = {TK_S64, sizeof(S64)},
[TK_U64] = {TK_U64, sizeof(U64)},
[TK_SizeU] = {TK_SizeU, sizeof(SizeU)},
[TK_Undefined] = {TK_Undefined},
[TK_Pointer] = {TK_Pointer,sizeof(SizeU)},
[TK_Array] = {TK_Array,sizeof(SizeU)},
[TK_Struct] = {TK_Struct},
[TK_Union] = {TK_Union},
};
global Type *type_void = type_table + 1;
global Type *type_s64 = type_table + 2;
global Type *type_u64 = type_table + 3;
global Type *type_sizeu = type_table + 4;
global Type *type_undefined = type_table + 5;