New AST
This commit is contained in:
34
ast.c
Normal file
34
ast.c
Normal 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
51
ast.h
Normal 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
70
decl.c
@@ -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
128
decl.h
@@ -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
2
expr.c
@@ -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
2
expr.h
@@ -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 {
|
||||||
|
|||||||
14
lang.h
14
lang.h
@@ -49,3 +49,17 @@ 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
22
main.c
@@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
228
parse_decl.c
228
parse_decl.c
@@ -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){
|
||||||
|
|
||||||
|
result = ast_enum(p, name, name->intern_val);
|
||||||
|
do{ // Parse enum members
|
||||||
|
Token *identifier = token_match(p, TK_Identifier);
|
||||||
|
if(identifier){
|
||||||
Expr *expr = 0;
|
Expr *expr = 0;
|
||||||
if(token_match(p, TK_Assign)){
|
if(token_match(p, TK_Assign)){
|
||||||
expr = parse_expr(p);
|
expr = parse_expr(p);
|
||||||
}
|
}
|
||||||
Decl_Enum_Child *child = decl_enum_child(p, token, expr);
|
AST_Node *child = ast_enum_child(p, identifier, identifier->intern_val, expr);
|
||||||
const_val_insert(p, token, type_s64, token->intern_val, expr);
|
ast_node_push_child(result, child);
|
||||||
decl_enum_push(result, child);
|
{
|
||||||
|
// Insert into scope
|
||||||
}
|
}
|
||||||
else break;
|
}
|
||||||
|
else {
|
||||||
if(!token_match(p, TK_Comma))
|
parser_push_error(p, token_get(p), "invalid syntax of enum member");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} while(token_match(p, TK_Comma));
|
||||||
token_expect(p, TK_CloseBrace);
|
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);
|
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
return result;
|
parser_push_error(p, op_close_brace, "enum without body");
|
||||||
}
|
|
||||||
|
|
||||||
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 *
|
for(;;){
|
||||||
parse_struct(Parser *p, Decl_Kind kind){
|
AST_Node *node = 0;
|
||||||
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)){
|
if(token_is(p, TK_End)){
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else if(token_is(p, TK_Error)){
|
||||||
parser_push_error(p, token_get(p), "Failed to parse struct, unexpected token");
|
|
||||||
break;
|
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)){
|
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);
|
|
||||||
}
|
}
|
||||||
|
else if(token_match_keyword(p, keyword_union)){
|
||||||
|
|
||||||
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)){
|
else if(token_match_keyword(p, keyword_enum)){
|
||||||
result = parse_decl_enum(p);
|
node = parse_enum(p);
|
||||||
}
|
token_expect(p, TK_Semicolon);
|
||||||
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)){
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
210
parser.c
210
parser.c
@@ -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);
|
|
||||||
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(;;){
|
|
||||||
Symbol *slot = p->symbols + index.iter;
|
|
||||||
if(slot->string.s.str == 0){
|
|
||||||
slot->string = intern;
|
|
||||||
p->symbols_inserted++;
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
else if(slot->string.s.str == string.str){
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table_index_advance(&index))
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
parser_push_error(p, token_get(p), "Failed to find a spot for symbol");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Symbol *
|
|
||||||
symbol_get(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){
|
||||||
|
/* @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++;
|
||||||
|
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
else if(intern_compare(symbol->name, string)){
|
||||||
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table_index_advance(&index))
|
if (table_index_advance(&index))
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function AST_Node *
|
||||||
|
symbol_lookup(Parser *p, Intern_String string){
|
||||||
|
Table_Index index = table_index_from_string(string.s, p->symbols_count);
|
||||||
|
for(;;){
|
||||||
|
AST_Node *symbol = p->symbols + index.iter;
|
||||||
|
|
||||||
|
if(symbol->name.s.str == 0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(intern_compare(symbol->name, string)){
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table_index_advance(&index))
|
||||||
|
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;
|
for(AST_Node *s = scope->first; s; s=s->scope_next){
|
||||||
symbol->token = decl->token;
|
memory_zero(s, sizeof(AST_Node));
|
||||||
|
p->symbols_inserted--;
|
||||||
}
|
}
|
||||||
}
|
memory_zero(scope, sizeof(Scope));
|
||||||
|
SLLStackPush(p->scope_free_list, scope);
|
||||||
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){
|
|
||||||
result = type_undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|||||||
41
parser.h
41
parser.h
@@ -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
82
print.c
@@ -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
59
type.c
@@ -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
69
type.h
@@ -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;
|
|
||||||
Reference in New Issue
Block a user