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;
|
||||
|
||||
struct Intern_String{
|
||||
String s;
|
||||
String s;
|
||||
};
|
||||
|
||||
typedef enum Token_Kind{
|
||||
TK_End,
|
||||
TK_Mul,
|
||||
TK_Div,
|
||||
TK_Add,
|
||||
TK_Sub,
|
||||
TK_Mod,
|
||||
TK_BitAnd,
|
||||
TK_BitOr,
|
||||
TK_BitXor,
|
||||
TK_Neg,
|
||||
TK_Not,
|
||||
TK_OpenParen,
|
||||
TK_CloseParen,
|
||||
TK_OpenBrace,
|
||||
TK_CloseBrace,
|
||||
TK_OpenBracket,
|
||||
TK_CloseBracket,
|
||||
TK_Comma,
|
||||
TK_Pound,
|
||||
TK_Question,
|
||||
TK_ThreeDots,
|
||||
TK_Semicolon,
|
||||
TK_Dot,
|
||||
TK_LesserThen,
|
||||
TK_GreaterThen,
|
||||
TK_Colon,
|
||||
TK_Assign,
|
||||
TK_DivAssign,
|
||||
TK_MulAssign,
|
||||
TK_ModAssign,
|
||||
TK_SubAssign,
|
||||
TK_AddAssign,
|
||||
TK_AndAssign,
|
||||
TK_OrAssign,
|
||||
TK_XorAssign,
|
||||
TK_LeftShiftAssign,
|
||||
TK_RightShiftAssign,
|
||||
TK_DoubleColon,
|
||||
TK_At,
|
||||
TK_Decrement,
|
||||
TK_Increment,
|
||||
TK_PostDecrement,
|
||||
TK_PostIncrement,
|
||||
TK_LesserThenOrEqual,
|
||||
TK_GreaterThenOrEqual,
|
||||
TK_Equals,
|
||||
TK_And,
|
||||
TK_Or,
|
||||
TK_NotEquals,
|
||||
TK_LeftShift,
|
||||
TK_RightShift,
|
||||
TK_Arrow,
|
||||
TK_ExprSizeof,
|
||||
TK_DocComment,
|
||||
TK_Comment,
|
||||
TK_Identifier,
|
||||
TK_StringLit,
|
||||
TK_U8Lit,
|
||||
TK_Character,
|
||||
TK_Error,
|
||||
TK_Float,
|
||||
TK_Int,
|
||||
TK_Keyword,
|
||||
TK_End,
|
||||
TK_Mul,
|
||||
TK_Div,
|
||||
TK_Add,
|
||||
TK_Sub,
|
||||
TK_Mod,
|
||||
TK_BitAnd,
|
||||
TK_BitOr,
|
||||
TK_BitXor,
|
||||
TK_Neg,
|
||||
TK_Not,
|
||||
TK_OpenParen,
|
||||
TK_CloseParen,
|
||||
TK_OpenBrace,
|
||||
TK_CloseBrace,
|
||||
TK_OpenBracket,
|
||||
TK_CloseBracket,
|
||||
TK_Comma,
|
||||
TK_Pound,
|
||||
TK_Question,
|
||||
TK_ThreeDots,
|
||||
TK_Semicolon,
|
||||
TK_Dot,
|
||||
TK_LesserThen,
|
||||
TK_GreaterThen,
|
||||
TK_Colon,
|
||||
TK_Assign,
|
||||
TK_DivAssign,
|
||||
TK_MulAssign,
|
||||
TK_ModAssign,
|
||||
TK_SubAssign,
|
||||
TK_AddAssign,
|
||||
TK_AndAssign,
|
||||
TK_OrAssign,
|
||||
TK_XorAssign,
|
||||
TK_LeftShiftAssign,
|
||||
TK_RightShiftAssign,
|
||||
TK_DoubleColon,
|
||||
TK_At,
|
||||
TK_Decrement,
|
||||
TK_Increment,
|
||||
TK_PostDecrement,
|
||||
TK_PostIncrement,
|
||||
TK_LesserThenOrEqual,
|
||||
TK_GreaterThenOrEqual,
|
||||
TK_Equals,
|
||||
TK_And,
|
||||
TK_Or,
|
||||
TK_NotEquals,
|
||||
TK_LeftShift,
|
||||
TK_RightShift,
|
||||
TK_Arrow,
|
||||
TK_ExprSizeof,
|
||||
TK_DocComment,
|
||||
TK_Comment,
|
||||
TK_Identifier,
|
||||
TK_StringLit,
|
||||
TK_U8Lit,
|
||||
TK_Character,
|
||||
TK_Error,
|
||||
TK_Float,
|
||||
TK_Int,
|
||||
TK_Keyword,
|
||||
}Token_Kind;
|
||||
|
||||
struct Token{
|
||||
Token_Kind kind;
|
||||
union{
|
||||
struct{
|
||||
U8 (*str);
|
||||
S64 len;
|
||||
};
|
||||
String string;
|
||||
};
|
||||
union{
|
||||
S64 int_val;
|
||||
String error_val;
|
||||
Intern_String intern_val;
|
||||
};
|
||||
String file;
|
||||
S64 line;
|
||||
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;
|
||||
Token_Kind kind;
|
||||
union{
|
||||
struct{
|
||||
U8 (*str);
|
||||
S64 len;
|
||||
};
|
||||
String string;
|
||||
};
|
||||
union{
|
||||
S64 int_val;
|
||||
String error_val;
|
||||
Intern_String intern_val;
|
||||
};
|
||||
String file;
|
||||
S64 line;
|
||||
U8 (*line_begin);
|
||||
};
|
||||
|
||||
|
||||
179
new_ast.c
179
new_ast.c
@@ -4,6 +4,7 @@ typedef struct Decl Decl;
|
||||
typedef struct Stmt Stmt;
|
||||
typedef struct Stmt_If Stmt_If;
|
||||
typedef struct Typespec Typespec;
|
||||
typedef struct Typespec_Function_Arg Typespec_Function_Arg;
|
||||
typedef struct Decl_Enum_Child Decl_Enum_Child;
|
||||
typedef struct Decl_Function_Arg Decl_Function_Arg;
|
||||
typedef struct Expr_Compound_Field Expr_Compound_Field;
|
||||
@@ -130,15 +131,20 @@ typedef enum Typespec_Kind{
|
||||
TS_Pointer,
|
||||
TS_Array,
|
||||
TS_Function,
|
||||
TS_NamedArgument,
|
||||
}Typespec_Kind;
|
||||
|
||||
struct Typespec{
|
||||
Typespec_Kind kind;
|
||||
Typespec *next;
|
||||
Typespec_Kind kind;
|
||||
Token *pos;
|
||||
union{
|
||||
Intern_String name;
|
||||
Typespec *base;
|
||||
Intern_String name;
|
||||
struct{
|
||||
Intern_String name;
|
||||
Typespec *base;
|
||||
}named;
|
||||
struct{
|
||||
Typespec *first;
|
||||
Typespec *last;
|
||||
@@ -165,15 +171,6 @@ typedef enum Decl_Kind{
|
||||
DECL_List,
|
||||
}Decl_Kind;
|
||||
|
||||
struct Note{
|
||||
Token *pos;
|
||||
Intern_String name;
|
||||
Expr *expr;
|
||||
Note *next;
|
||||
Note *first;
|
||||
Note *last;
|
||||
};
|
||||
|
||||
struct Decl{
|
||||
Decl_Kind kind;
|
||||
Decl *next;
|
||||
@@ -208,7 +205,7 @@ struct Decl{
|
||||
Decl_Function_Arg *first;
|
||||
Decl_Function_Arg *last;
|
||||
Typespec *ret;
|
||||
//Stmt *body;
|
||||
Stmt *body;
|
||||
}func_decl;
|
||||
struct{
|
||||
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{
|
||||
Decl_Function_Arg *next;
|
||||
Token *pos;
|
||||
@@ -439,11 +445,148 @@ expr_compound_push(Expr *list, Expr_Compound_Field *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
|
||||
//-----------------------------------------------------------------------------
|
||||
function void
|
||||
decl_list_push(Decl *l, Decl *node){
|
||||
decl_dll_list_push(Decl *l, Decl *node){
|
||||
if(l->list_decl.first == 0){
|
||||
l->list_decl.first = l->list_decl.last = node;
|
||||
node->prev = 0;
|
||||
@@ -459,7 +602,7 @@ decl_list_push(Decl *l, Decl *node){
|
||||
}
|
||||
|
||||
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){
|
||||
l->list_decl.first = l->list_decl.last = node;
|
||||
node->prev = 0;
|
||||
@@ -523,10 +666,10 @@ ast_test(){
|
||||
decls[2].kind = 2;
|
||||
decls[3].kind = 3;
|
||||
decls[4].kind = 4;
|
||||
decl_list_push(decls, decls+1);
|
||||
decl_list_push(decls, decls+2);
|
||||
decl_list_push(decls, decls+3);
|
||||
decl_list_push_front(decls, decls+4);
|
||||
decl_dll_list_push(decls, decls+1);
|
||||
decl_dll_list_push(decls, decls+2);
|
||||
decl_dll_list_push(decls, decls+3);
|
||||
decl_dll_list_push_front(decls, decls+4);
|
||||
|
||||
//list_print(decls);
|
||||
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_size_type;
|
||||
global Intern_String keyword_size_expr;
|
||||
global Intern_String keyword_const;
|
||||
global Intern_String keyword_typeof;
|
||||
global Intern_String keyword_while;
|
||||
global Intern_String keyword_switch;
|
||||
@@ -14,6 +15,9 @@ global Intern_String keyword_union;
|
||||
global U8 *first_keyword;
|
||||
global U8 *last_keyword;
|
||||
|
||||
global Intern_String intern_void;
|
||||
global Intern_String intern_int;
|
||||
|
||||
function void
|
||||
init_default_keywords(Intern_Table *t){
|
||||
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_expr = intern_string(t, lit("size_expr"));
|
||||
keyword_typeof = intern_string(t, lit("typeof"));
|
||||
keyword_const = intern_string(t, lit("const"));
|
||||
keyword_while = intern_string(t, lit("while"));
|
||||
keyword_switch = intern_string(t, lit("switch"));
|
||||
keyword_case = intern_string(t, lit("case"));
|
||||
@@ -33,6 +38,9 @@ init_default_keywords(Intern_Table *t){
|
||||
|
||||
keyword_union = intern_string(t, lit("union"));
|
||||
last_keyword = keyword_union.s.str;
|
||||
|
||||
intern_void = intern_string(t, lit("void"));
|
||||
intern_int = intern_string(t, lit("int"));
|
||||
}
|
||||
|
||||
function B32
|
||||
@@ -489,15 +497,32 @@ lex__stream(Token_Array *array, Lex_Stream *s){
|
||||
}
|
||||
}
|
||||
|
||||
function Token_Array
|
||||
lex_stream(Arena *arena, String stream, String file){
|
||||
function void
|
||||
lex_add_stream(Token_Array *array, String stream, String file){
|
||||
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);
|
||||
init_default_keywords(&array.interns);
|
||||
lex__stream(&array, &s);
|
||||
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
|
||||
lex_test(){
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
error->message = string;
|
||||
error->next = 0;
|
||||
@@ -48,6 +64,20 @@ token_get(Parser *p){
|
||||
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 *
|
||||
token_is(Parser *p, Token_Kind kind){
|
||||
Token *result = token_get(p);
|
||||
@@ -95,6 +125,8 @@ token_expect(Parser *p, Token_Kind kind){
|
||||
return 0;
|
||||
}
|
||||
|
||||
function Typespec *parse_typespec(Parser *p);
|
||||
function Expr *parse_expr(Parser *p);
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expression parsing
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -112,6 +144,9 @@ atom_expr = Int
|
||||
| 'cast' '(' typespec ',' expr ')'
|
||||
| 'size_type' '(' typespec ')'
|
||||
| 'size_expr' '(' expr ')'
|
||||
| '{' compound_expr '}'
|
||||
| '(' expr ')'
|
||||
| '(' ':' typespec ')' '{' compound_expr '}'
|
||||
postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')*
|
||||
unary_expr = unary ? unary_expr : 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)*
|
||||
ternary_expr = compare_expr ('?' ternary_expr ':' ternary_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 *
|
||||
parse_expr_compound(Parser *p){
|
||||
parse_expr_compound_field(Parser *p){
|
||||
Token *token = token_get(p);
|
||||
Expr_Compound_Field *result = 0;
|
||||
if(token_match(p, TK_OpenBracket)){
|
||||
@@ -196,6 +190,81 @@ parse_expr_compound(Parser *p){
|
||||
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 *
|
||||
parse_expr_function_argument(Parser *p){
|
||||
Token *token = token_get(p);
|
||||
@@ -365,10 +434,171 @@ parse_expr(Parser *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
|
||||
//-----------------------------------------------------------------------------
|
||||
function void expr_print(Expr *expr);
|
||||
function B32 typespec_print(Typespec *spec);
|
||||
function void
|
||||
token_print(Token *token){
|
||||
printf("%.*s", (S32)token->len, token->str);
|
||||
@@ -408,7 +638,11 @@ expr_print(Expr *expr){
|
||||
}break;
|
||||
|
||||
case EK_Compound:{
|
||||
// typespec_print(p);
|
||||
if(expr->compound.typespec){
|
||||
printf("(");
|
||||
typespec_print(expr->compound.typespec);
|
||||
printf(")");
|
||||
}
|
||||
printf("{");
|
||||
for(Expr_Compound_Field *n = expr->compound.first; n; n=n->next){
|
||||
expr_compound_print(n);
|
||||
@@ -468,7 +702,7 @@ expr_print(Expr *expr){
|
||||
case EK_Cast:{
|
||||
printf("(");
|
||||
printf("(");
|
||||
//print_typespec(expr->cast.type);
|
||||
typespec_print(expr->cast.typespec);
|
||||
printf(")");
|
||||
expr_print(expr->cast.expr);
|
||||
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
|
||||
eval_expr(Expr *expr){
|
||||
@@ -545,8 +819,34 @@ eval_expr(Expr *expr){
|
||||
return 0;
|
||||
}
|
||||
|
||||
function Parser
|
||||
parser_make(Arena *arena){
|
||||
Parser result = {
|
||||
.tokens = lex_make_token_array(arena),
|
||||
.arena = arena,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
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();
|
||||
String test_case = lit("32+52-242*2/424%5-23"
|
||||
" 1<<5>>6<<2 "
|
||||
@@ -558,12 +858,9 @@ parse_test(){
|
||||
" 1>5 ? 1 : 2 "
|
||||
" !!!!!1 "
|
||||
" ~~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 = {
|
||||
.tokens = lex_stream(scratch, test_case, lit("expr_test")),
|
||||
.arena = scratch,
|
||||
};
|
||||
Parser parser = parser_make_stream(scratch, test_case, lit("Big_Expr"));
|
||||
Parser *p = &parser;
|
||||
|
||||
S64 t = 5;
|
||||
@@ -585,10 +882,33 @@ parse_test(){
|
||||
assert(val == test_val[i]);
|
||||
}
|
||||
|
||||
Expr *expr = parse_expr(p);
|
||||
expr_print(expr);
|
||||
String exprs[] = {
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 *
|
||||
token_array_iter_begin(Token_Array *array){
|
||||
array->iter_len = 0;
|
||||
|
||||
Reference in New Issue
Block a user