More parsing of expressions
This commit is contained in:
69
generated.c
69
generated.c
@@ -1,69 +0,0 @@
|
|||||||
typedef struct Token_Bucket Token_Bucket;
|
|
||||||
typedef struct Token_Array Token_Array;
|
|
||||||
struct Token_Bucket{
|
|
||||||
Token_Bucket*next;
|
|
||||||
Token data[4096];
|
|
||||||
};
|
|
||||||
struct Token_Array{
|
|
||||||
Intern_Table interns;
|
|
||||||
Token_Bucket first;
|
|
||||||
Token_Bucket*last;
|
|
||||||
S64 len;
|
|
||||||
S64 block;
|
|
||||||
Arena*arena;
|
|
||||||
Token_Bucket*iter_bucket;
|
|
||||||
S64 iter_len;
|
|
||||||
S64 iter_block;
|
|
||||||
};
|
|
||||||
function Token_Array token_array_make(Arena*arena){
|
|
||||||
Token_Array result={
|
|
||||||
.last=&result.first,.arena=arena,.interns=intern_table(arena,4096*4)};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
function void token_array_push(Token_Array*array,Token*p){
|
|
||||||
if(array->len>=buff_cap(array->first.data)){
|
|
||||||
Token_Bucket*bucket=arena_push_struct(array->arena,Token_Bucket);
|
|
||||||
array->last=array->last->next=bucket;
|
|
||||||
array->len=0;
|
|
||||||
array->block+=1;
|
|
||||||
}
|
|
||||||
array->last->data[array->len++]=*p;
|
|
||||||
}
|
|
||||||
function B32 token_array_iter_is_end(Token_Array*array){
|
|
||||||
B32 result=array->iter_len==array->len&&array->iter_block==array->block;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
function Token*token_array_iter_next(Token_Array*array){
|
|
||||||
if(token_array_iter_is_end(array)){
|
|
||||||
return0;
|
|
||||||
}
|
|
||||||
if(array->iter_len>=buff_cap(array->first.data)){
|
|
||||||
array->iter_len=0;
|
|
||||||
array->iter_block+=1;
|
|
||||||
array->iter_bucket=array->iter_bucket->next;
|
|
||||||
}
|
|
||||||
Token*result=array->iter_bucket->data+array->iter_len++;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
function Token*token_array_iter_peek(Token_Array*array,S64 i){
|
|
||||||
S64 save_len=array->iter_len;
|
|
||||||
Token_Bucket*save_bucket=array->iter_bucket;
|
|
||||||
assert(i<buff_cap(array->first.data));
|
|
||||||
S64 over=i;
|
|
||||||
if(array->iter_len+i>=buff_cap(array->first.data)){
|
|
||||||
over=buff_cap(array->first.data)-(array->iter_len+i);
|
|
||||||
array->iter_len=0;
|
|
||||||
array->iter_bucket=array->iter_bucket->next;
|
|
||||||
}
|
|
||||||
Token*result=array->iter_bucket->data+array->iter_len+over;
|
|
||||||
array->iter_len=save_len;
|
|
||||||
array->iter_bucket=save_bucket;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
function Token*token_array_iter_begin(Token_Array*array){
|
|
||||||
array->iter_len=0;
|
|
||||||
array->iter_block=0;
|
|
||||||
array->iter_bucket=&array->first;
|
|
||||||
Token*result=token_array_iter_next(array);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
198
generated_lex.h
198
generated_lex.h
@@ -8,129 +8,91 @@ typedef struct Lex_Stream Lex_Stream;
|
|||||||
typedef struct Tokens Tokens;
|
typedef struct Tokens Tokens;
|
||||||
|
|
||||||
struct Intern_String{
|
struct Intern_String{
|
||||||
String s;
|
String s;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum Token_Kind{
|
typedef enum Token_Kind{
|
||||||
TK_End,
|
TK_End,
|
||||||
TK_Mul,
|
TK_Mul,
|
||||||
TK_Div,
|
TK_Div,
|
||||||
TK_Add,
|
TK_Add,
|
||||||
TK_Sub,
|
TK_Sub,
|
||||||
TK_Mod,
|
TK_Mod,
|
||||||
TK_BitAnd,
|
TK_BitAnd,
|
||||||
TK_BitOr,
|
TK_BitOr,
|
||||||
TK_BitXor,
|
TK_BitXor,
|
||||||
TK_Neg,
|
TK_Neg,
|
||||||
TK_Not,
|
TK_Not,
|
||||||
TK_OpenParen,
|
TK_OpenParen,
|
||||||
TK_CloseParen,
|
TK_CloseParen,
|
||||||
TK_OpenBrace,
|
TK_OpenBrace,
|
||||||
TK_CloseBrace,
|
TK_CloseBrace,
|
||||||
TK_OpenBracket,
|
TK_OpenBracket,
|
||||||
TK_CloseBracket,
|
TK_CloseBracket,
|
||||||
TK_Comma,
|
TK_Comma,
|
||||||
TK_Pound,
|
TK_Pound,
|
||||||
TK_Question,
|
TK_Question,
|
||||||
TK_ThreeDots,
|
TK_ThreeDots,
|
||||||
TK_Semicolon,
|
TK_Semicolon,
|
||||||
TK_Dot,
|
TK_Dot,
|
||||||
TK_LesserThen,
|
TK_LesserThen,
|
||||||
TK_GreaterThen,
|
TK_GreaterThen,
|
||||||
TK_Colon,
|
TK_Colon,
|
||||||
TK_Assign,
|
TK_Assign,
|
||||||
TK_DivAssign,
|
TK_DivAssign,
|
||||||
TK_MulAssign,
|
TK_MulAssign,
|
||||||
TK_ModAssign,
|
TK_ModAssign,
|
||||||
TK_SubAssign,
|
TK_SubAssign,
|
||||||
TK_AddAssign,
|
TK_AddAssign,
|
||||||
TK_AndAssign,
|
TK_AndAssign,
|
||||||
TK_OrAssign,
|
TK_OrAssign,
|
||||||
TK_XorAssign,
|
TK_XorAssign,
|
||||||
TK_LeftShiftAssign,
|
TK_LeftShiftAssign,
|
||||||
TK_RightShiftAssign,
|
TK_RightShiftAssign,
|
||||||
TK_DoubleColon,
|
TK_DoubleColon,
|
||||||
TK_At,
|
TK_At,
|
||||||
TK_Decrement,
|
TK_Decrement,
|
||||||
TK_Increment,
|
TK_Increment,
|
||||||
TK_PostDecrement,
|
TK_PostDecrement,
|
||||||
TK_PostIncrement,
|
TK_PostIncrement,
|
||||||
TK_LesserThenOrEqual,
|
TK_LesserThenOrEqual,
|
||||||
TK_GreaterThenOrEqual,
|
TK_GreaterThenOrEqual,
|
||||||
TK_Equals,
|
TK_Equals,
|
||||||
TK_And,
|
TK_And,
|
||||||
TK_Or,
|
TK_Or,
|
||||||
TK_NotEquals,
|
TK_NotEquals,
|
||||||
TK_LeftShift,
|
TK_LeftShift,
|
||||||
TK_RightShift,
|
TK_RightShift,
|
||||||
TK_Arrow,
|
TK_Arrow,
|
||||||
TK_ExprSizeof,
|
TK_ExprSizeof,
|
||||||
TK_DocComment,
|
TK_DocComment,
|
||||||
TK_Comment,
|
TK_Comment,
|
||||||
TK_Identifier,
|
TK_Identifier,
|
||||||
TK_StringLit,
|
TK_StringLit,
|
||||||
TK_U8Lit,
|
TK_U8Lit,
|
||||||
TK_Character,
|
TK_Character,
|
||||||
TK_Error,
|
TK_Error,
|
||||||
TK_Float,
|
TK_Float,
|
||||||
TK_Int,
|
TK_Int,
|
||||||
TK_Keyword,
|
TK_Keyword,
|
||||||
}Token_Kind;
|
}Token_Kind;
|
||||||
|
|
||||||
struct Token{
|
struct Token{
|
||||||
Token_Kind kind;
|
Token_Kind kind;
|
||||||
union{
|
union{
|
||||||
struct{
|
struct{
|
||||||
U8 (*str);
|
U8 (*str);
|
||||||
S64 len;
|
S64 len;
|
||||||
};
|
};
|
||||||
String string;
|
String string;
|
||||||
};
|
};
|
||||||
union{
|
union{
|
||||||
S64 int_val;
|
S64 int_val;
|
||||||
String error_val;
|
String error_val;
|
||||||
Intern_String intern_val;
|
Intern_String intern_val;
|
||||||
};
|
};
|
||||||
String file;
|
String file;
|
||||||
S64 line;
|
S64 line;
|
||||||
U8 (*line_begin);
|
U8 (*line_begin);
|
||||||
};
|
|
||||||
|
|
||||||
// Generated Array block
|
|
||||||
typedef struct Token_Array Token_Array;
|
|
||||||
typedef struct Token_Array_Block Token_Array_Block;
|
|
||||||
typedef struct Token_Array_Iter Token_Array_Iter;
|
|
||||||
struct Token_Array_Block{
|
|
||||||
Token_Array_Block*next;
|
|
||||||
Token data[4096];
|
|
||||||
};
|
|
||||||
struct Token_Array_Iter{
|
|
||||||
Token_Array_Block*block;
|
|
||||||
U32 iter_len;
|
|
||||||
U32 iter_block;
|
|
||||||
U32 total_len;
|
|
||||||
U32 total_block;
|
|
||||||
};
|
|
||||||
struct Token_Array{
|
|
||||||
Token_Array_Block first;
|
|
||||||
Token_Array_Block*last;
|
|
||||||
Token_Array_Iter it;
|
|
||||||
Arena*arena;
|
|
||||||
S64 block;
|
|
||||||
S64 len;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Lex_Stream{
|
|
||||||
U8 (*stream);
|
|
||||||
U8 (*line_begin);
|
|
||||||
String filename;
|
|
||||||
S64 line;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Tokens{
|
|
||||||
Token (*tokens);
|
|
||||||
S64 len;
|
|
||||||
S64 cap;
|
|
||||||
S64 iter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
179
new_ast.c
179
new_ast.c
@@ -4,6 +4,7 @@ typedef struct Decl Decl;
|
|||||||
typedef struct Stmt Stmt;
|
typedef struct Stmt Stmt;
|
||||||
typedef struct Stmt_If Stmt_If;
|
typedef struct Stmt_If Stmt_If;
|
||||||
typedef struct Typespec Typespec;
|
typedef struct Typespec Typespec;
|
||||||
|
typedef struct Typespec_Function_Arg Typespec_Function_Arg;
|
||||||
typedef struct Decl_Enum_Child Decl_Enum_Child;
|
typedef struct Decl_Enum_Child Decl_Enum_Child;
|
||||||
typedef struct Decl_Function_Arg Decl_Function_Arg;
|
typedef struct Decl_Function_Arg Decl_Function_Arg;
|
||||||
typedef struct Expr_Compound_Field Expr_Compound_Field;
|
typedef struct Expr_Compound_Field Expr_Compound_Field;
|
||||||
@@ -130,15 +131,20 @@ typedef enum Typespec_Kind{
|
|||||||
TS_Pointer,
|
TS_Pointer,
|
||||||
TS_Array,
|
TS_Array,
|
||||||
TS_Function,
|
TS_Function,
|
||||||
|
TS_NamedArgument,
|
||||||
}Typespec_Kind;
|
}Typespec_Kind;
|
||||||
|
|
||||||
struct Typespec{
|
struct Typespec{
|
||||||
Typespec_Kind kind;
|
|
||||||
Typespec *next;
|
Typespec *next;
|
||||||
|
Typespec_Kind kind;
|
||||||
Token *pos;
|
Token *pos;
|
||||||
union{
|
union{
|
||||||
Intern_String name;
|
|
||||||
Typespec *base;
|
Typespec *base;
|
||||||
|
Intern_String name;
|
||||||
|
struct{
|
||||||
|
Intern_String name;
|
||||||
|
Typespec *base;
|
||||||
|
}named;
|
||||||
struct{
|
struct{
|
||||||
Typespec *first;
|
Typespec *first;
|
||||||
Typespec *last;
|
Typespec *last;
|
||||||
@@ -165,15 +171,6 @@ typedef enum Decl_Kind{
|
|||||||
DECL_List,
|
DECL_List,
|
||||||
}Decl_Kind;
|
}Decl_Kind;
|
||||||
|
|
||||||
struct Note{
|
|
||||||
Token *pos;
|
|
||||||
Intern_String name;
|
|
||||||
Expr *expr;
|
|
||||||
Note *next;
|
|
||||||
Note *first;
|
|
||||||
Note *last;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Decl{
|
struct Decl{
|
||||||
Decl_Kind kind;
|
Decl_Kind kind;
|
||||||
Decl *next;
|
Decl *next;
|
||||||
@@ -208,7 +205,7 @@ struct Decl{
|
|||||||
Decl_Function_Arg *first;
|
Decl_Function_Arg *first;
|
||||||
Decl_Function_Arg *last;
|
Decl_Function_Arg *last;
|
||||||
Typespec *ret;
|
Typespec *ret;
|
||||||
//Stmt *body;
|
Stmt *body;
|
||||||
}func_decl;
|
}func_decl;
|
||||||
struct{
|
struct{
|
||||||
Decl *first;
|
Decl *first;
|
||||||
@@ -217,6 +214,15 @@ struct Decl{
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Note{
|
||||||
|
Token *pos;
|
||||||
|
Intern_String name;
|
||||||
|
Expr *expr;
|
||||||
|
Note *next;
|
||||||
|
Note *first;
|
||||||
|
Note *last;
|
||||||
|
};
|
||||||
|
|
||||||
struct Decl_Function_Arg{
|
struct Decl_Function_Arg{
|
||||||
Decl_Function_Arg *next;
|
Decl_Function_Arg *next;
|
||||||
Token *pos;
|
Token *pos;
|
||||||
@@ -439,11 +445,148 @@ expr_compound_push(Expr *list, Expr_Compound_Field *field){
|
|||||||
SLLQueuePush(list->compound.first, list->compound.last, field);
|
SLLQueuePush(list->compound.first, list->compound.last, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Type specifier constructors
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
function Typespec *
|
||||||
|
typespec_new(Arena *p, Typespec_Kind kind, Token *pos){
|
||||||
|
Typespec *result = arena_push_struct(p, Typespec);
|
||||||
|
result->kind = kind;
|
||||||
|
result->pos = pos;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Typespec *
|
||||||
|
typespec_name(Arena *p, Token *pos, Intern_String name){
|
||||||
|
Typespec *result = typespec_new(p, TS_Name, pos);
|
||||||
|
result->name = name;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Typespec *
|
||||||
|
typespec_pointer(Arena *p, Token *pos, Typespec *base){
|
||||||
|
Typespec *result = typespec_new(p, TS_Pointer, pos);
|
||||||
|
result->base = base;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Typespec *
|
||||||
|
typespec_array(Arena *p, Token *pos, Typespec *base, Expr *size){
|
||||||
|
Typespec *result = typespec_new(p, TS_Array, pos);
|
||||||
|
result->arr.base = base;
|
||||||
|
result->arr.size = size;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Typespec *
|
||||||
|
typespec_function(Arena *p, Token *pos, Typespec *ret){
|
||||||
|
Typespec *result = typespec_new(p, TS_Function, pos);
|
||||||
|
result->func.ret = ret;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Typespec *
|
||||||
|
typespec_named_argument(Arena *arena, Token *pos, Typespec *typespec, Intern_String name){
|
||||||
|
Typespec *result = typespec_new(arena, TS_NamedArgument, pos);
|
||||||
|
result->named.base = typespec;
|
||||||
|
result->named.name = name;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
typespec_function_push(Typespec *func, Typespec *arg){
|
||||||
|
SLLQueuePush(func->func.first, func->func.last, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Declarations
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
function Decl *
|
||||||
|
decl_new(Arena *p, Decl_Kind kind, Token *pos, Intern_String name){
|
||||||
|
Decl *result = arena_push_struct(p, Decl);
|
||||||
|
result->kind = kind;
|
||||||
|
result->pos = pos;
|
||||||
|
result->name = name;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
decl_struct(Arena *p, Decl_Kind kind, Token *pos, Intern_String name){
|
||||||
|
assert(kind == DECL_Struct || kind == DECL_Union);
|
||||||
|
Decl *result = decl_new(p, kind, pos, name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
decl_typedef(Arena *p, Token *pos, Intern_String name, Typespec *type){
|
||||||
|
Decl *result = decl_new(p, DECL_Typedef, pos, name);
|
||||||
|
result->typedef_decl.type = type;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
decl_enum(Arena *p, Token *pos, Intern_String name, Typespec *typespec){
|
||||||
|
Decl *result = decl_new(p, DECL_Enum, pos, name);
|
||||||
|
result->enum_decl.typespec = typespec;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
decl_variable(Arena *p, Token *pos, Intern_String name, Typespec *typespec, Expr *expr){
|
||||||
|
Decl *result = decl_new(p, DECL_Variable, pos, name);
|
||||||
|
result->var_decl.type = typespec;
|
||||||
|
result->var_decl.expr = expr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
decl_function(Arena *p, Token *pos, Intern_String name, Typespec *ret){
|
||||||
|
Decl *result = decl_new(p, DECL_Function, pos, name);
|
||||||
|
result->func_decl.ret = ret;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
decl_func_push(Arena *p, Decl *parent, Token *pos, Intern_String name, Typespec *type){
|
||||||
|
assert(parent->kind == DECL_Function);
|
||||||
|
Decl_Function_Arg *result = arena_push_struct(p, Decl_Function_Arg);
|
||||||
|
result->name = name;
|
||||||
|
result->typespec = type;
|
||||||
|
result->pos = pos;
|
||||||
|
SLLQueuePush(parent->func_decl.first, parent->func_decl.last, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
decl_enum_push(Arena *p, Decl *parent, Token *pos, Intern_String name, Expr *expr, Note *notes){
|
||||||
|
assert(parent->kind == DECL_Enum);
|
||||||
|
Decl_Enum_Child *child = arena_push_struct(p, Decl_Enum_Child);
|
||||||
|
child->pos = pos;
|
||||||
|
child->name = name;
|
||||||
|
child->expr = expr;
|
||||||
|
child->first_note = notes->first;
|
||||||
|
child->last_note = notes->last;
|
||||||
|
SLLQueuePush(parent->enum_decl.first, parent->enum_decl.last, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
decl_struct_push(Decl *parent, Decl *child){
|
||||||
|
assert(parent->kind == DECL_Struct || parent->kind == DECL_Union);
|
||||||
|
SLLQueuePush(parent->struct_decl.first, parent->struct_decl.last, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
decl_list_push(Decl *parent, Decl *child){
|
||||||
|
assert(parent->kind == DECL_List);
|
||||||
|
SLLQueuePush(parent->list_decl.first, parent->list_decl.last, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Double linked list
|
// Double linked list
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function void
|
function void
|
||||||
decl_list_push(Decl *l, Decl *node){
|
decl_dll_list_push(Decl *l, Decl *node){
|
||||||
if(l->list_decl.first == 0){
|
if(l->list_decl.first == 0){
|
||||||
l->list_decl.first = l->list_decl.last = node;
|
l->list_decl.first = l->list_decl.last = node;
|
||||||
node->prev = 0;
|
node->prev = 0;
|
||||||
@@ -459,7 +602,7 @@ decl_list_push(Decl *l, Decl *node){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
decl_list_push_front(Decl *l, Decl *node){
|
decl_dll_list_push_front(Decl *l, Decl *node){
|
||||||
if(l->list_decl.first == 0){
|
if(l->list_decl.first == 0){
|
||||||
l->list_decl.first = l->list_decl.last = node;
|
l->list_decl.first = l->list_decl.last = node;
|
||||||
node->prev = 0;
|
node->prev = 0;
|
||||||
@@ -523,10 +666,10 @@ ast_test(){
|
|||||||
decls[2].kind = 2;
|
decls[2].kind = 2;
|
||||||
decls[3].kind = 3;
|
decls[3].kind = 3;
|
||||||
decls[4].kind = 4;
|
decls[4].kind = 4;
|
||||||
decl_list_push(decls, decls+1);
|
decl_dll_list_push(decls, decls+1);
|
||||||
decl_list_push(decls, decls+2);
|
decl_dll_list_push(decls, decls+2);
|
||||||
decl_list_push(decls, decls+3);
|
decl_dll_list_push(decls, decls+3);
|
||||||
decl_list_push_front(decls, decls+4);
|
decl_dll_list_push_front(decls, decls+4);
|
||||||
|
|
||||||
//list_print(decls);
|
//list_print(decls);
|
||||||
decl_list_remove(decls, decls+1);
|
decl_list_remove(decls, decls+1);
|
||||||
|
|||||||
31
new_lex.c
31
new_lex.c
@@ -4,6 +4,7 @@ global Intern_String keyword_cast;
|
|||||||
global Intern_String keyword_else;
|
global Intern_String keyword_else;
|
||||||
global Intern_String keyword_size_type;
|
global Intern_String keyword_size_type;
|
||||||
global Intern_String keyword_size_expr;
|
global Intern_String keyword_size_expr;
|
||||||
|
global Intern_String keyword_const;
|
||||||
global Intern_String keyword_typeof;
|
global Intern_String keyword_typeof;
|
||||||
global Intern_String keyword_while;
|
global Intern_String keyword_while;
|
||||||
global Intern_String keyword_switch;
|
global Intern_String keyword_switch;
|
||||||
@@ -14,6 +15,9 @@ global Intern_String keyword_union;
|
|||||||
global U8 *first_keyword;
|
global U8 *first_keyword;
|
||||||
global U8 *last_keyword;
|
global U8 *last_keyword;
|
||||||
|
|
||||||
|
global Intern_String intern_void;
|
||||||
|
global Intern_String intern_int;
|
||||||
|
|
||||||
function void
|
function void
|
||||||
init_default_keywords(Intern_Table *t){
|
init_default_keywords(Intern_Table *t){
|
||||||
keyword_if = intern_string(t, lit("if"));
|
keyword_if = intern_string(t, lit("if"));
|
||||||
@@ -25,6 +29,7 @@ init_default_keywords(Intern_Table *t){
|
|||||||
keyword_size_type = intern_string(t, lit("size_type"));
|
keyword_size_type = intern_string(t, lit("size_type"));
|
||||||
keyword_size_expr = intern_string(t, lit("size_expr"));
|
keyword_size_expr = intern_string(t, lit("size_expr"));
|
||||||
keyword_typeof = intern_string(t, lit("typeof"));
|
keyword_typeof = intern_string(t, lit("typeof"));
|
||||||
|
keyword_const = intern_string(t, lit("const"));
|
||||||
keyword_while = intern_string(t, lit("while"));
|
keyword_while = intern_string(t, lit("while"));
|
||||||
keyword_switch = intern_string(t, lit("switch"));
|
keyword_switch = intern_string(t, lit("switch"));
|
||||||
keyword_case = intern_string(t, lit("case"));
|
keyword_case = intern_string(t, lit("case"));
|
||||||
@@ -33,6 +38,9 @@ init_default_keywords(Intern_Table *t){
|
|||||||
|
|
||||||
keyword_union = intern_string(t, lit("union"));
|
keyword_union = intern_string(t, lit("union"));
|
||||||
last_keyword = keyword_union.s.str;
|
last_keyword = keyword_union.s.str;
|
||||||
|
|
||||||
|
intern_void = intern_string(t, lit("void"));
|
||||||
|
intern_int = intern_string(t, lit("int"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
function B32
|
||||||
@@ -489,15 +497,32 @@ lex__stream(Token_Array *array, Lex_Stream *s){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Token_Array
|
function void
|
||||||
lex_stream(Arena *arena, String stream, String file){
|
lex_add_stream(Token_Array *array, String stream, String file){
|
||||||
Lex_Stream s = {stream, 0, stream.str, file, 0};
|
Lex_Stream s = {stream, 0, stream.str, file, 0};
|
||||||
|
lex__stream(array, &s);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Token_Array
|
||||||
|
lex_make_token_array(Arena *arena){
|
||||||
Token_Array array = token_array_make(arena);
|
Token_Array array = token_array_make(arena);
|
||||||
init_default_keywords(&array.interns);
|
init_default_keywords(&array.interns);
|
||||||
lex__stream(&array, &s);
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Token_Array
|
||||||
|
lex_stream(Arena *arena, String stream, String file){
|
||||||
|
Token_Array array = lex_make_token_array(arena);
|
||||||
|
lex_add_stream(&array, stream, file);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
lex_restream(Token_Array *array, String stream, String file){
|
||||||
|
token_array_reset(array);
|
||||||
|
lex_add_stream(array, stream, file);
|
||||||
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
lex_test(){
|
lex_test(){
|
||||||
Arena *scratch = arena_begin_scratch();
|
Arena *scratch = arena_begin_scratch();
|
||||||
|
|||||||
438
new_parse.c
438
new_parse.c
@@ -29,7 +29,23 @@ parser_push_error(Parser *p, Token *token, char *str, ...){
|
|||||||
va_end(args1);
|
va_end(args1);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Error: %s %s:%d\n", string.str, token->file.str, (S32)token->line);
|
// @Note(Krzosa): Print nice error message
|
||||||
|
{
|
||||||
|
printf("Error: %s %s:%d\n", string.str, token->file.str, (S32)token->line);
|
||||||
|
|
||||||
|
// @Note(Krzosa): Print error line
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while(token->line_begin[i]!='\n' && token->line_begin[i]!=0) i++;
|
||||||
|
printf("%.*s\n", i, token->line_begin);
|
||||||
|
|
||||||
|
// @Note(Krzosa): Print error marker
|
||||||
|
int token_i = token->str - token->line_begin;
|
||||||
|
for(int i = 0; i < token_i-2; i++) printf(" ");
|
||||||
|
printf("^^^^^^\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Parser_Error *error = arena_push_struct(p->arena, Parser_Error);
|
Parser_Error *error = arena_push_struct(p->arena, Parser_Error);
|
||||||
error->message = string;
|
error->message = string;
|
||||||
error->next = 0;
|
error->next = 0;
|
||||||
@@ -48,6 +64,20 @@ token_get(Parser *p){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Token *
|
||||||
|
token_peek(Parser *p, S64 i){
|
||||||
|
Token *result = token_array_iter_peek(&p->tokens, i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Token *
|
||||||
|
token_peek_is(Parser *p, Token_Kind kind, S64 i){
|
||||||
|
Token *result = token_peek(p, i);
|
||||||
|
if(result->kind == kind)
|
||||||
|
return result;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
function Token *
|
function Token *
|
||||||
token_is(Parser *p, Token_Kind kind){
|
token_is(Parser *p, Token_Kind kind){
|
||||||
Token *result = token_get(p);
|
Token *result = token_get(p);
|
||||||
@@ -95,6 +125,8 @@ token_expect(Parser *p, Token_Kind kind){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Typespec *parse_typespec(Parser *p);
|
||||||
|
function Expr *parse_expr(Parser *p);
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Expression parsing
|
// Expression parsing
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -112,6 +144,9 @@ atom_expr = Int
|
|||||||
| 'cast' '(' typespec ',' expr ')'
|
| 'cast' '(' typespec ',' expr ')'
|
||||||
| 'size_type' '(' typespec ')'
|
| 'size_type' '(' typespec ')'
|
||||||
| 'size_expr' '(' expr ')'
|
| 'size_expr' '(' expr ')'
|
||||||
|
| '{' compound_expr '}'
|
||||||
|
| '(' expr ')'
|
||||||
|
| '(' ':' typespec ')' '{' compound_expr '}'
|
||||||
postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')*
|
postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')*
|
||||||
unary_expr = unary ? unary_expr : atom_expr
|
unary_expr = unary ? unary_expr : atom_expr
|
||||||
mul_expr = atom_expr (mul atom_expr)*
|
mul_expr = atom_expr (mul atom_expr)*
|
||||||
@@ -120,57 +155,16 @@ logical_expr = add_expr (logical add_expr)*
|
|||||||
compare_expr = logical_expr (compare logical_expr)*
|
compare_expr = logical_expr (compare logical_expr)*
|
||||||
ternary_expr = compare_expr ('?' ternary_expr ':' ternary_expr)?
|
ternary_expr = compare_expr ('?' ternary_expr ':' ternary_expr)?
|
||||||
expr = logical_expr
|
expr = logical_expr
|
||||||
|
|
||||||
|
Compound literals
|
||||||
|
- (:[23]*Type){}
|
||||||
|
- Type{}
|
||||||
|
- { }
|
||||||
|
|
||||||
*/
|
*/
|
||||||
function Expr *parse_expr(Parser *p);
|
|
||||||
|
|
||||||
function Expr *
|
|
||||||
parse_expr_atom(Parser *p){
|
|
||||||
Token *token = 0;
|
|
||||||
if((token = token_match(p, TK_StringLit))){
|
|
||||||
Expr *result = expr_str(p->arena, token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else if((token = token_match(p, TK_Identifier))){
|
|
||||||
Expr *result = expr_identifier(p->arena, token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else if((token = token_match(p, TK_Int))){
|
|
||||||
Expr *result = expr_int(p->arena, token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else if((token = token_match(p, TK_OpenParen))){
|
|
||||||
Expr *expr = parse_expr(p);
|
|
||||||
token_expect(p, TK_CloseParen);
|
|
||||||
Expr *result = expr_paren(p->arena, token, expr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else if((token = token_match_keyword(p, keyword_cast))){
|
|
||||||
token_expect(p, TK_OpenParen);
|
|
||||||
token_expect(p, TK_Identifier);
|
|
||||||
token_expect(p, TK_Comma);
|
|
||||||
token_expect(p, TK_Identifier);
|
|
||||||
token_expect(p, TK_CloseParen);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
parser_push_error(p, token_get(p), "Failed to parse expression");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function B32
|
|
||||||
token_is_postfix(Parser *p){
|
|
||||||
Token *token = token_get(p);
|
|
||||||
B32 result = token->kind == TK_OpenBracket
|
|
||||||
|| token->kind == TK_OpenParen
|
|
||||||
|| token->kind == TK_Dot
|
|
||||||
|| token->kind == TK_Increment
|
|
||||||
|| token->kind == TK_Decrement;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Expr_Compound_Field *
|
function Expr_Compound_Field *
|
||||||
parse_expr_compound(Parser *p){
|
parse_expr_compound_field(Parser *p){
|
||||||
Token *token = token_get(p);
|
Token *token = token_get(p);
|
||||||
Expr_Compound_Field *result = 0;
|
Expr_Compound_Field *result = 0;
|
||||||
if(token_match(p, TK_OpenBracket)){
|
if(token_match(p, TK_OpenBracket)){
|
||||||
@@ -196,6 +190,81 @@ parse_expr_compound(Parser *p){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Expr *
|
||||||
|
parse_expr_compound(Parser *p, Typespec *typespec){
|
||||||
|
Token *token = token_expect(p, TK_OpenBrace);
|
||||||
|
Expr *expr = expr_compound(p->arena, token, typespec);
|
||||||
|
while(!token_is(p, TK_CloseBrace)){
|
||||||
|
Expr_Compound_Field *field = parse_expr_compound_field(p);
|
||||||
|
expr_compound_push(expr, field);
|
||||||
|
if(!token_match(p, TK_Comma)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token_expect(p, TK_CloseBrace);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Expr *
|
||||||
|
parse_expr_atom(Parser *p){
|
||||||
|
Expr *result = 0;
|
||||||
|
Token *token = token_get(p);
|
||||||
|
if(token_match(p, TK_StringLit)){
|
||||||
|
result = expr_str(p->arena, token);
|
||||||
|
}
|
||||||
|
else if(token_match(p, TK_Identifier)){
|
||||||
|
if(token_is(p, TK_OpenBrace)){
|
||||||
|
Typespec *typespec = typespec_name(p->arena, token, token->intern_val);
|
||||||
|
result = parse_expr_compound(p, typespec);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
result = expr_identifier(p->arena, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(token_match(p, TK_Int)){
|
||||||
|
result = expr_int(p->arena, token);
|
||||||
|
}
|
||||||
|
else if(token_is(p, TK_OpenBrace)){
|
||||||
|
result = parse_expr_compound(p, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(token_match(p, TK_OpenParen)){
|
||||||
|
if(token_match(p, TK_Colon)){
|
||||||
|
Typespec *typespec = parse_typespec(p);
|
||||||
|
token_expect(p, TK_CloseParen);
|
||||||
|
result = parse_expr_compound(p, typespec);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Expr *expr = parse_expr(p);
|
||||||
|
token_expect(p, TK_CloseParen);
|
||||||
|
result = expr_paren(p->arena, token, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(token_match_keyword(p, keyword_cast)){
|
||||||
|
token_expect(p, TK_OpenParen);
|
||||||
|
Typespec *typespec = parse_typespec(p);
|
||||||
|
token_expect(p, TK_Comma);
|
||||||
|
Expr *expr = parse_expr(p);
|
||||||
|
token_expect(p, TK_CloseParen);
|
||||||
|
result = expr_cast(p->arena, token, typespec, expr);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
parser_push_error(p, token, "Failed to parse expression");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function B32
|
||||||
|
token_is_postfix(Parser *p){
|
||||||
|
Token *token = token_get(p);
|
||||||
|
B32 result = token->kind == TK_OpenBracket
|
||||||
|
|| token->kind == TK_OpenParen
|
||||||
|
|| token->kind == TK_Dot
|
||||||
|
|| token->kind == TK_Increment
|
||||||
|
|| token->kind == TK_Decrement;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function Expr_Compound_Field *
|
function Expr_Compound_Field *
|
||||||
parse_expr_function_argument(Parser *p){
|
parse_expr_function_argument(Parser *p){
|
||||||
Token *token = token_get(p);
|
Token *token = token_get(p);
|
||||||
@@ -365,10 +434,171 @@ parse_expr(Parser *p){
|
|||||||
return parse_expr_ternary(p);
|
return parse_expr_ternary(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Type specifier parsing
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
base_type = NAME
|
||||||
|
| '(' type_list? ')' type?
|
||||||
|
|
||||||
|
type = ('*' | '[' expr ']')* base_type
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
[32]*U32 - Array of 32 pointers to U32
|
||||||
|
**CustomDataType - Pointer to pointer of CustomDataType
|
||||||
|
(*U32, S64) **S64 - Function pointer
|
||||||
|
(CoolType: optional, S32) - Implicit void return value
|
||||||
|
|
||||||
|
*/
|
||||||
|
function Typespec *
|
||||||
|
parse_typespec_function(Parser *p, Token *token){
|
||||||
|
Typespec *result = typespec_function(p->arena, token, 0);
|
||||||
|
if(!token_is(p, TK_CloseParen))
|
||||||
|
for(;;) {
|
||||||
|
|
||||||
|
// Optional name
|
||||||
|
Token *name = 0;
|
||||||
|
if((token = token_is(p, TK_Identifier))){
|
||||||
|
if(token_peek_is(p, TK_Colon, 1)){
|
||||||
|
token_next(p);
|
||||||
|
token_next(p);
|
||||||
|
name = token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse type
|
||||||
|
Typespec *arg = parse_typespec(p);
|
||||||
|
if(name)
|
||||||
|
arg = typespec_named_argument(p->arena, name, arg, name->intern_val);
|
||||||
|
typespec_function_push(result, arg);
|
||||||
|
|
||||||
|
if(!token_match(p, TK_Comma)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token_expect(p, TK_CloseParen);
|
||||||
|
if(token_is(p, TK_Identifier)
|
||||||
|
|| token_is(p, TK_OpenParen)
|
||||||
|
|| token_is(p, TK_Mul)
|
||||||
|
|| token_is(p, TK_OpenBracket))
|
||||||
|
result->func.ret = parse_typespec(p);
|
||||||
|
else
|
||||||
|
result->func.ret = typespec_name(p->arena, token_get(p), intern_void);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [10]*int - Array of 10 pointers to ints
|
||||||
|
function Typespec *
|
||||||
|
parse_typespec_recurse(Parser *p){
|
||||||
|
Token *token = token_get(p);
|
||||||
|
if(token_match(p, TK_Mul)){
|
||||||
|
Typespec *result = parse_typespec_recurse(p);
|
||||||
|
result = typespec_pointer(p->arena, token, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if(token_match(p, TK_OpenBracket)){
|
||||||
|
Expr *expr = parse_expr(p);
|
||||||
|
token_expect(p, TK_CloseBracket);
|
||||||
|
Typespec *result = parse_typespec_recurse(p);
|
||||||
|
result = typespec_array(p->arena, token, result, expr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if(token_match(p, TK_OpenParen)){
|
||||||
|
Typespec *result = parse_typespec_function(p, token);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if(token_match(p, TK_Identifier)){
|
||||||
|
Typespec *result = typespec_name(p->arena, token, token->intern_val);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
parser_push_error(p, token, "Failed to parse type, unexpected token");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Typespec *
|
||||||
|
parse_typespec(Parser *p){
|
||||||
|
Typespec *result = parse_typespec_recurse(p);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Parsing decls
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
name::(param:U32)*U32{}
|
||||||
|
name::struct{}
|
||||||
|
name::union{}
|
||||||
|
name::enum{}
|
||||||
|
|
||||||
|
name::typedef = name2;
|
||||||
|
name::const = 4254;
|
||||||
|
|
||||||
|
*/
|
||||||
|
function Decl *
|
||||||
|
parse_enum(Parser *p, Token *name){
|
||||||
|
Typespec *typespec = 0;
|
||||||
|
if(token_match(p, TK_Colon)){
|
||||||
|
typespec = parse_typespec(p);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
typespec = typespec_name(p->arena, token_get(p), intern_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
Decl *result = decl_enum(p->arena, name, name->intern_val, typespec);
|
||||||
|
token_expect(p, TK_OpenBrace);
|
||||||
|
do{
|
||||||
|
Token *val = token_expect(p, TK_Identifier);
|
||||||
|
Expr *expr = 0;
|
||||||
|
if(token_match(p, TK_Assign)){
|
||||||
|
expr = parse_expr(p);
|
||||||
|
}
|
||||||
|
decl_enum_push(p->arena, result, val, val->intern_val, expr, 0);
|
||||||
|
} while(token_is(p, TK_Comma));
|
||||||
|
token_expect(p, TK_CloseBrace);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
parse_decl(Parser *p){
|
||||||
|
Decl *result = 0;
|
||||||
|
Token *name = 0;
|
||||||
|
if((name = token_match(p, TK_Identifier))){
|
||||||
|
if(token_match(p, TK_DoubleColon)){
|
||||||
|
Token *token = 0;
|
||||||
|
if((token = token_match_keyword(p, keyword_enum))){
|
||||||
|
result = parse_enum(p, name);
|
||||||
|
}
|
||||||
|
else if((token = token_match_keyword(p, keyword_union))){
|
||||||
|
// Union
|
||||||
|
}
|
||||||
|
else if((token = token_match_keyword(p, keyword_struct))){
|
||||||
|
// Struct
|
||||||
|
}
|
||||||
|
else if((token = token_match_keyword(p, keyword_const))){
|
||||||
|
// Const value
|
||||||
|
}
|
||||||
|
else if((token = token_match(p, TK_OpenParen))){
|
||||||
|
// Function
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
parser_push_error(p, token_get(p), "Expected token of kind todo:decl_tokens");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
parser_push_error(p, token_get(p), "Expected token of kind '::'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Test code
|
// Test code
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function void expr_print(Expr *expr);
|
function void expr_print(Expr *expr);
|
||||||
|
function B32 typespec_print(Typespec *spec);
|
||||||
function void
|
function void
|
||||||
token_print(Token *token){
|
token_print(Token *token){
|
||||||
printf("%.*s", (S32)token->len, token->str);
|
printf("%.*s", (S32)token->len, token->str);
|
||||||
@@ -408,7 +638,11 @@ expr_print(Expr *expr){
|
|||||||
}break;
|
}break;
|
||||||
|
|
||||||
case EK_Compound:{
|
case EK_Compound:{
|
||||||
// typespec_print(p);
|
if(expr->compound.typespec){
|
||||||
|
printf("(");
|
||||||
|
typespec_print(expr->compound.typespec);
|
||||||
|
printf(")");
|
||||||
|
}
|
||||||
printf("{");
|
printf("{");
|
||||||
for(Expr_Compound_Field *n = expr->compound.first; n; n=n->next){
|
for(Expr_Compound_Field *n = expr->compound.first; n; n=n->next){
|
||||||
expr_compound_print(n);
|
expr_compound_print(n);
|
||||||
@@ -468,7 +702,7 @@ expr_print(Expr *expr){
|
|||||||
case EK_Cast:{
|
case EK_Cast:{
|
||||||
printf("(");
|
printf("(");
|
||||||
printf("(");
|
printf("(");
|
||||||
//print_typespec(expr->cast.type);
|
typespec_print(expr->cast.typespec);
|
||||||
printf(")");
|
printf(")");
|
||||||
expr_print(expr->cast.expr);
|
expr_print(expr->cast.expr);
|
||||||
printf(")");
|
printf(")");
|
||||||
@@ -494,6 +728,46 @@ expr_print(Expr *expr){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function B32
|
||||||
|
typespec_print(Typespec *spec){
|
||||||
|
switch(spec->kind) {
|
||||||
|
case TS_Name: {
|
||||||
|
printf("%s", spec->name.s.str);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TS_NamedArgument: {
|
||||||
|
printf("%s: ", spec->named.name.s.str);
|
||||||
|
typespec_print(spec->named.base);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case TS_Pointer: {
|
||||||
|
typespec_print(spec->base);
|
||||||
|
printf("*");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TS_Array: {
|
||||||
|
typespec_print(spec->arr.base);
|
||||||
|
printf("[");
|
||||||
|
expr_print(spec->arr.size);
|
||||||
|
printf("]");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TS_Function: {
|
||||||
|
printf("(");
|
||||||
|
for(Typespec *n = spec->func.first; n; n=n->next){
|
||||||
|
typespec_print(n);
|
||||||
|
if(n!=spec->func.last)
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(")");
|
||||||
|
typespec_print(spec->func.ret);
|
||||||
|
} break;
|
||||||
|
default: {invalid_codepath;} break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function S64
|
function S64
|
||||||
eval_expr(Expr *expr){
|
eval_expr(Expr *expr){
|
||||||
@@ -545,8 +819,34 @@ eval_expr(Expr *expr){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Parser
|
||||||
|
parser_make(Arena *arena){
|
||||||
|
Parser result = {
|
||||||
|
.tokens = lex_make_token_array(arena),
|
||||||
|
.arena = arena,
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
parse_test(){
|
parser_restream(Parser *p, String stream, String file){
|
||||||
|
lex_restream(&p->tokens, stream, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Parser
|
||||||
|
parser_make_stream(Arena *arena, String stream, String file){
|
||||||
|
Parser parser = parser_make(arena);
|
||||||
|
lex_restream(&parser.tokens, stream, file);
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
parser_add_stream(Parser *p, String string, String file){
|
||||||
|
lex_add_stream(&p->tokens, string, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
parse_test_expr(){
|
||||||
Arena *scratch = arena_begin_scratch();
|
Arena *scratch = arena_begin_scratch();
|
||||||
String test_case = lit("32+52-242*2/424%5-23"
|
String test_case = lit("32+52-242*2/424%5-23"
|
||||||
" 1<<5>>6<<2 "
|
" 1<<5>>6<<2 "
|
||||||
@@ -558,12 +858,9 @@ parse_test(){
|
|||||||
" 1>5 ? 1 : 2 "
|
" 1>5 ? 1 : 2 "
|
||||||
" !!!!!1 "
|
" !!!!!1 "
|
||||||
" ~~1 + -!2 "
|
" ~~1 + -!2 "
|
||||||
" 1 + ++Thing[12]++ + ++Thing[12].expr + --Not_Thing[156](Thing) + test_func(asd=func1, af=func2, gg=func3)"
|
" 1 + ++Thing[12]++ + ++Thing[12].expr +"
|
||||||
);
|
);
|
||||||
Parser parser = {
|
Parser parser = parser_make_stream(scratch, test_case, lit("Big_Expr"));
|
||||||
.tokens = lex_stream(scratch, test_case, lit("expr_test")),
|
|
||||||
.arena = scratch,
|
|
||||||
};
|
|
||||||
Parser *p = &parser;
|
Parser *p = &parser;
|
||||||
|
|
||||||
S64 t = 5;
|
S64 t = 5;
|
||||||
@@ -585,10 +882,33 @@ parse_test(){
|
|||||||
assert(val == test_val[i]);
|
assert(val == test_val[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr *expr = parse_expr(p);
|
String exprs[] = {
|
||||||
expr_print(expr);
|
lit("cast([12](thing: U32, qwe: *U32) [32]Result, (123+234))"),
|
||||||
|
lit("cast((thing: U32, qwe: *U32), (123+234))"),
|
||||||
|
lit("(:(U32,U32)){Thing=10}"),
|
||||||
|
lit("--Not_Thing[156](Thing) + test_func(asd=func1, af=func2, gg=func3)"),
|
||||||
|
lit("(:[23]*Type){Thing=10}"),
|
||||||
|
lit("cast(**Data,{Thing=10})"),
|
||||||
|
lit("(:[64]S64){1,2,3,4,5}"),
|
||||||
|
lit("Data_Type{1,2,3,4,5}"),
|
||||||
|
};
|
||||||
|
for(SizeU i = 0; i < buff_cap(exprs); i++){
|
||||||
|
parser_restream(p, exprs[i], lit("Test_Exprs"));
|
||||||
|
Expr *expr = parse_expr(p);
|
||||||
|
expr_print(expr);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
arena_end_scratch();
|
arena_end_scratch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
parse_test_decls(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
parse_test(){
|
||||||
|
parse_test_expr();
|
||||||
|
parse_test_decls();
|
||||||
|
}
|
||||||
@@ -96,6 +96,19 @@ token_array_iter_peek(Token_Array *array, S64 i){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
token_array_reset(Token_Array *array){
|
||||||
|
// @Todo(Krzosa): Add free list
|
||||||
|
assert(&array->first == array->last);
|
||||||
|
array->len = 0;
|
||||||
|
array->block = 0;
|
||||||
|
array->last = &array->first;
|
||||||
|
array->last->next = 0;
|
||||||
|
array->iter_bucket = array->last;
|
||||||
|
array->iter_len = 0;
|
||||||
|
array->iter_block = 0;
|
||||||
|
}
|
||||||
|
|
||||||
function Token *
|
function Token *
|
||||||
token_array_iter_begin(Token_Array *array){
|
token_array_iter_begin(Token_Array *array){
|
||||||
array->iter_len = 0;
|
array->iter_len = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user