Named function args
This commit is contained in:
179
ideas.cpp
179
ideas.cpp
@@ -1,170 +1,33 @@
|
||||
Thing :: struct{
|
||||
data: (U32) U32; // Function pointer
|
||||
data: (U32) U32 @ [32]; // Array of function pointers
|
||||
data: (U32) U32* @ [32]; // Array of function pointers, they return a pointer
|
||||
|
||||
actual_function :: (first: Thing*, last: Thing*, node: Thing*)/*no type == void*/{
|
||||
if first == 0 {
|
||||
first = last = node;
|
||||
}
|
||||
else{
|
||||
last = last->next = node;
|
||||
}
|
||||
}
|
||||
|
||||
StructInside :: struct { // This is not part of struct
|
||||
// just in scope
|
||||
some_val: U16;
|
||||
some_val2: U16;
|
||||
}
|
||||
|
||||
insider: StructInside;
|
||||
|
||||
named_union_part_of_struct: union{
|
||||
some_val: U16;
|
||||
some_val2: U32;
|
||||
}
|
||||
|
||||
_: union {
|
||||
// Unamed union
|
||||
val: U32;
|
||||
}
|
||||
New_Data_Type::typedef int;
|
||||
CONST_VAL::const 324;
|
||||
|
||||
Ideas::enum{
|
||||
One,
|
||||
Two,
|
||||
Three
|
||||
}
|
||||
|
||||
Scope :: scope{
|
||||
Thingy::enum:U32{
|
||||
@str=10 Value = 1,
|
||||
|
||||
}
|
||||
Data::struct{
|
||||
first: int;
|
||||
second: int;
|
||||
idea: Ideas;
|
||||
}
|
||||
|
||||
//Scope.Thingy
|
||||
|
||||
Thing::union{
|
||||
union:{
|
||||
}
|
||||
struct:{
|
||||
function_call::(first_param: Data*, second_param: int[32]){
|
||||
first_param.first = 10;
|
||||
first_param.second = 10;
|
||||
first_param.idea = Ideas.One;
|
||||
p:= first_param;
|
||||
|
||||
for i in 0...32 {
|
||||
second_param[i] = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Thing::struct{
|
||||
data: U32;
|
||||
|
||||
inside_call :: (param: U32){
|
||||
for i := 0; i < 32; i++ {
|
||||
second_param[i] = i;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
call :: (param:U32) U32{
|
||||
inner_call :: (param2:U32){
|
||||
size_of_s64 = sizeof(:S64);
|
||||
size_of_val = sizeof(param);
|
||||
|
||||
|
||||
param2 + 10;
|
||||
return;
|
||||
}
|
||||
|
||||
inner_call();
|
||||
}
|
||||
|
||||
@stringify
|
||||
Enumeration:enum{
|
||||
None,
|
||||
Thing = 1 << 10,
|
||||
Thing2,
|
||||
Thing3,
|
||||
}
|
||||
|
||||
@sllqueue()
|
||||
@sllqueue(prefix=thing_scope, next=next_scope)
|
||||
Thing::struct{
|
||||
Inner_Struct :: {
|
||||
test_val : U32;
|
||||
}
|
||||
thing:Inner_Struct;
|
||||
next: Thing*;
|
||||
first: Thing*;
|
||||
last: Thing*;
|
||||
next_scope: Thing*;
|
||||
|
||||
val: U32[16];
|
||||
str: String;
|
||||
embed: struct{
|
||||
thing: S32;
|
||||
}
|
||||
}
|
||||
|
||||
@register(sllqueue, first, last, next)
|
||||
sllqueue_push:(base:T1, child:T2) void {
|
||||
if(base.first == 0){
|
||||
base.first = base.last = child;
|
||||
}
|
||||
else{
|
||||
base.last = base.last.next = child;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
function void
|
||||
thing_sllqueue_push(){
|
||||
|
||||
}
|
||||
|
||||
function void
|
||||
thing_scope_sllqueue_push(){
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
Builtin types:
|
||||
B8,B16,B32,B64
|
||||
S8,S16,S32,S64
|
||||
U8,U16,U32,U64
|
||||
SizeI, SizeU
|
||||
F32, F64
|
||||
|
||||
Decls:
|
||||
S32 *var;
|
||||
S32 (*func)();
|
||||
S32 *var[expr][expr];
|
||||
S32 **var;
|
||||
|
||||
Global scope:
|
||||
function S32
|
||||
do_thing(S32 a, U32 b){
|
||||
stmt_list
|
||||
}
|
||||
|
||||
function S32
|
||||
do_thing(S32 a, S32 b);
|
||||
|
||||
typedef struct Thing Thing;
|
||||
struct Thing{};
|
||||
typedef struct Thing{} Thing;
|
||||
|
||||
typedef enum Thingy Thingy;
|
||||
enum Thingy{};
|
||||
typedef enum Thingy{} Thingy;
|
||||
|
||||
global S32 variable = expr | compound;
|
||||
|
||||
// typedef S32 NewName;
|
||||
// typedef S32 BaseFunctionType(S32 thing);
|
||||
// typedef S32 (*FunctionPointer)(S32 thing);
|
||||
|
||||
Local scope-(stmts):
|
||||
S32 variable = expr;
|
||||
variable = expr;
|
||||
variable++;
|
||||
return 0;
|
||||
if(a){}elseif(b){}else{}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
475
new_ast.c
475
new_ast.c
@@ -1,6 +1,129 @@
|
||||
|
||||
typedef struct Expr Expr;
|
||||
typedef struct Note Note;
|
||||
typedef struct Decl Decl;
|
||||
typedef struct Stmt Stmt;
|
||||
typedef struct Stmt_If Stmt_If;
|
||||
typedef struct Typespec Typespec;
|
||||
typedef struct Decl_Enum_Child Decl_Enum_Child;
|
||||
typedef struct Decl_Function_Arg Decl_Function_Arg;
|
||||
typedef struct Expr_Compound_Field Expr_Compound_Field;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expressions
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef enum Expr_Sizeof_Kind{
|
||||
SIZEOF_Expr,
|
||||
SIZEOF_Type,
|
||||
}Expr_Sizeof_Kind;
|
||||
|
||||
typedef enum Expr_Kind{
|
||||
EK_None,
|
||||
EK_Int,
|
||||
EK_String,
|
||||
EK_Identifier,
|
||||
EK_Compound,
|
||||
EK_Paren,
|
||||
EK_PostfixUnary,
|
||||
EK_Unary,
|
||||
EK_Binary,
|
||||
EK_Ternary,
|
||||
EK_Cast,
|
||||
EK_Field,
|
||||
EK_Call,
|
||||
EK_Index,
|
||||
EK_SizeType,
|
||||
EK_SizeExpr,
|
||||
} Expr_Kind;
|
||||
|
||||
typedef enum Expr_Compound_Kind{
|
||||
COMPOUND_None,
|
||||
COMPOUND_Default,
|
||||
COMPOUND_Named,
|
||||
COMPOUND_Index,
|
||||
}Expr_Compound_Kind;
|
||||
|
||||
struct Expr_Compound_Field{
|
||||
Expr_Compound_Field *next;
|
||||
Expr_Compound_Kind kind;
|
||||
Token *pos;
|
||||
Expr *init;
|
||||
union{
|
||||
Expr *index;
|
||||
Intern_String name;
|
||||
};
|
||||
};
|
||||
|
||||
struct Expr {
|
||||
Expr_Kind kind;
|
||||
Token *token;
|
||||
Expr *next;
|
||||
union {
|
||||
U64 int_val;
|
||||
Intern_String intern_val;
|
||||
double float_val;
|
||||
struct {
|
||||
Expr *expr;
|
||||
} paren;
|
||||
struct {
|
||||
Typespec *typespec;
|
||||
Expr* expr;
|
||||
} cast;
|
||||
struct{
|
||||
Intern_String name;
|
||||
Expr *expr;
|
||||
}field;
|
||||
|
||||
struct{
|
||||
Typespec *typespec;
|
||||
Expr_Compound_Field *first;
|
||||
Expr_Compound_Field *last;
|
||||
}compound;
|
||||
|
||||
struct {
|
||||
Expr *atom;
|
||||
Expr_Compound_Field *first;
|
||||
Expr_Compound_Field *last;
|
||||
} call;
|
||||
struct{
|
||||
|
||||
}arg;
|
||||
struct {
|
||||
Expr *atom;
|
||||
Expr *index;
|
||||
} index;
|
||||
|
||||
struct {
|
||||
Token_Kind op;
|
||||
Expr* expr;
|
||||
} unary;
|
||||
struct {
|
||||
Token_Kind op;
|
||||
Expr *expr;
|
||||
} postfix_unary;
|
||||
struct {
|
||||
Token_Kind op;
|
||||
Expr* left;
|
||||
Expr* right;
|
||||
} binary;
|
||||
struct {
|
||||
Expr* cond;
|
||||
Expr* on_true;
|
||||
Expr* on_false;
|
||||
} ternary;
|
||||
|
||||
struct{
|
||||
Typespec *typespec;
|
||||
} size_type;
|
||||
|
||||
struct{
|
||||
Expr *expr;
|
||||
} size_expr;
|
||||
};
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Type specifiers
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef enum Typespec_Kind{
|
||||
TS_None,
|
||||
TS_Name,
|
||||
@@ -29,92 +152,127 @@ struct Typespec{
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expressions
|
||||
// Declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef enum Expr_Sizeof_Kind{
|
||||
SIZEOF_Expr,
|
||||
SIZEOF_Type,
|
||||
}Expr_Sizeof_Kind;
|
||||
typedef enum Decl_Kind{
|
||||
DECL_None,
|
||||
DECL_Struct,
|
||||
DECL_Union,
|
||||
DECL_Enum,
|
||||
DECL_Variable,
|
||||
DECL_Typedef,
|
||||
DECL_Function,
|
||||
DECL_List,
|
||||
}Decl_Kind;
|
||||
|
||||
typedef enum Expr_Kind{
|
||||
EK_None,
|
||||
EK_Int,
|
||||
EK_String,
|
||||
EK_Identifier,
|
||||
EK_Paren,
|
||||
EK_PostfixUnary,
|
||||
EK_Unary,
|
||||
EK_Binary,
|
||||
EK_Ternary,
|
||||
EK_Cast,
|
||||
EK_Field,
|
||||
EK_Call,
|
||||
EK_Index,
|
||||
EK_Sizeof,
|
||||
} Expr_Kind;
|
||||
struct Note{
|
||||
Token *pos;
|
||||
Intern_String name;
|
||||
Expr *expr;
|
||||
Note *next;
|
||||
Note *first;
|
||||
Note *last;
|
||||
};
|
||||
|
||||
struct Expr {
|
||||
Expr_Kind kind;
|
||||
Token *token;
|
||||
Expr *next;
|
||||
union {
|
||||
U64 int_val;
|
||||
Intern_String intern_val;
|
||||
double float_val;
|
||||
struct {
|
||||
Expr *expr;
|
||||
} paren;
|
||||
struct Decl{
|
||||
Decl_Kind kind;
|
||||
Decl *next;
|
||||
B32 is_incomplete;
|
||||
|
||||
struct {
|
||||
Decl *prev; // Doubly linked list?
|
||||
Decl *parent; // ?
|
||||
|
||||
Intern_String name;
|
||||
Token *pos;
|
||||
|
||||
Note *first_note;
|
||||
Note *last_note;
|
||||
union{
|
||||
struct{
|
||||
Decl_Enum_Child *first;
|
||||
Decl_Enum_Child *last;
|
||||
Typespec *typespec;
|
||||
}enum_decl;
|
||||
struct{
|
||||
Decl *first;
|
||||
Decl *last;
|
||||
}struct_decl;
|
||||
struct{
|
||||
Typespec *type;
|
||||
Expr* expr;
|
||||
} cast;
|
||||
|
||||
struct{
|
||||
Intern_String name;
|
||||
Expr *expr;
|
||||
}field;
|
||||
|
||||
struct {
|
||||
Expr *atom;
|
||||
Expr *first;
|
||||
Expr *last;
|
||||
} call;
|
||||
struct {
|
||||
Expr *atom;
|
||||
Expr *index;
|
||||
} index;
|
||||
struct {
|
||||
Token_Kind op;
|
||||
Expr* expr;
|
||||
} unary;
|
||||
struct {
|
||||
Token_Kind op;
|
||||
Expr *expr;
|
||||
} postfix_unary;
|
||||
struct {
|
||||
Token_Kind op;
|
||||
Expr* left;
|
||||
Expr* right;
|
||||
} binary;
|
||||
struct {
|
||||
Expr* cond;
|
||||
Expr* on_true;
|
||||
Expr* on_false;
|
||||
} ternary;
|
||||
|
||||
}var_decl;
|
||||
struct{
|
||||
Expr_Sizeof_Kind kind;
|
||||
union{
|
||||
Typespec *type;
|
||||
Expr *expr;
|
||||
};
|
||||
} size_of;
|
||||
Typespec *type;
|
||||
}typedef_decl;
|
||||
struct{
|
||||
Decl_Function_Arg *first;
|
||||
Decl_Function_Arg *last;
|
||||
Typespec *ret;
|
||||
//Stmt *body;
|
||||
}func_decl;
|
||||
struct{
|
||||
Decl *first;
|
||||
Decl *last;
|
||||
}list_decl;
|
||||
};
|
||||
};
|
||||
|
||||
struct Decl_Function_Arg{
|
||||
Decl_Function_Arg *next;
|
||||
Token *pos;
|
||||
Intern_String name;
|
||||
Typespec *typespec;
|
||||
};
|
||||
|
||||
struct Decl_Enum_Child{
|
||||
Decl_Enum_Child *next;
|
||||
Intern_String name;
|
||||
Token *pos;
|
||||
Expr *expr;
|
||||
Note *first_note;
|
||||
Note *last_note;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expr
|
||||
// Statements
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef enum Stmt_Kind{
|
||||
STMT_None,
|
||||
STMT_Decl,
|
||||
STMT_Expr,
|
||||
STMT_List,
|
||||
STMT_Return,
|
||||
STMT_If,
|
||||
STMT_For,
|
||||
}Stmt_Kind;
|
||||
|
||||
struct Stmt_If{
|
||||
Stmt_If *next;
|
||||
Expr *cond;
|
||||
Stmt *body;
|
||||
};
|
||||
|
||||
struct Stmt{
|
||||
Stmt_Kind kind;
|
||||
Stmt *next;
|
||||
Token *pos;
|
||||
union{
|
||||
Stmt_If stmt_if;
|
||||
Decl *decl;
|
||||
Expr *expr;
|
||||
struct{
|
||||
Stmt *first;
|
||||
Stmt *last;
|
||||
}list;
|
||||
struct{
|
||||
Expr *expr;
|
||||
}ret;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expression constructors
|
||||
//-----------------------------------------------------------------------------
|
||||
function Expr *
|
||||
expr_new(Arena *p, Expr_Kind kind, Token *token){
|
||||
@@ -216,28 +374,171 @@ expr_index(Arena *p, Token *token, Expr *atom, Expr *index){
|
||||
function Expr *
|
||||
expr_cast(Arena *p, Token *token, Typespec *type, Expr *exp){
|
||||
Expr *expr = expr_new(p, EK_Cast, token);
|
||||
expr->cast.type = type;
|
||||
expr->cast.typespec = type;
|
||||
expr->cast.expr = exp;
|
||||
return expr;
|
||||
}
|
||||
|
||||
function Expr *
|
||||
expr_sizeof_type(Arena *p, Token *token, Typespec *type){
|
||||
Expr *expr = expr_new(p, EK_Sizeof, token);
|
||||
expr->size_of.kind = SIZEOF_Type;
|
||||
expr->size_of.type = type;
|
||||
expr_size_type(Arena *p, Token *token, Typespec *type){
|
||||
Expr *expr = expr_new(p, EK_SizeType, token);
|
||||
expr->size_type.typespec = type;
|
||||
return expr;
|
||||
}
|
||||
|
||||
function Expr *
|
||||
expr_sizeof_expr(Arena *p, Token *token, Expr *in_expr){
|
||||
Expr *expr = expr_new(p, EK_Sizeof, token);
|
||||
expr->size_of.kind = SIZEOF_Expr;
|
||||
expr->size_of.expr = in_expr;
|
||||
Expr *expr = expr_new(p, EK_SizeExpr, token);
|
||||
expr->size_expr.expr = in_expr;
|
||||
return expr;
|
||||
}
|
||||
|
||||
function void
|
||||
expr_call_push(Expr *list, Expr *expr){
|
||||
SLLQueuePush(list->call.first, list->call.last, expr);
|
||||
function Expr *
|
||||
expr_compound(Arena *arena, Token *pos, Typespec *typespec){
|
||||
Expr *result = expr_new(arena, EK_Compound, pos);
|
||||
result->compound.typespec = typespec;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr_Compound_Field *
|
||||
expr_compound_new(Arena *arena, Expr_Compound_Kind kind, Token *pos, Expr *init){
|
||||
Expr_Compound_Field *result = arena_push_struct(arena, Expr_Compound_Field);
|
||||
result->kind = kind;
|
||||
result->pos = pos;
|
||||
result->init = init;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr_Compound_Field *
|
||||
expr_compound_default(Arena *arena, Token *pos, Expr *init){
|
||||
Expr_Compound_Field *result = expr_compound_new(arena, COMPOUND_Default, pos, init);
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr_Compound_Field *
|
||||
expr_compound_named(Arena *arena, Token *pos, Intern_String name, Expr *init){
|
||||
Expr_Compound_Field *result = expr_compound_new(arena, COMPOUND_Named, pos, init);
|
||||
result->name = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr_Compound_Field *
|
||||
expr_compound_index(Arena *arena, Token *pos, Expr *index, Expr *init){
|
||||
Expr_Compound_Field *result = expr_compound_new(arena, COMPOUND_Index, pos, init);
|
||||
result->index = index;
|
||||
return result;
|
||||
}
|
||||
|
||||
function void
|
||||
expr_call_push(Expr *list, Expr_Compound_Field *field){
|
||||
SLLQueuePush(list->call.first, list->call.last, field);
|
||||
}
|
||||
|
||||
function void
|
||||
expr_compound_push(Expr *list, Expr_Compound_Field *field){
|
||||
SLLQueuePush(list->compound.first, list->compound.last, field);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Double linked list
|
||||
//-----------------------------------------------------------------------------
|
||||
function void
|
||||
decl_list_push(Decl *l, Decl *node){
|
||||
if(l->list_decl.first == 0){
|
||||
l->list_decl.first = l->list_decl.last = node;
|
||||
node->prev = 0;
|
||||
node->next = 0;
|
||||
}
|
||||
else{
|
||||
l->list_decl.last->next = node;
|
||||
node->prev = l->list_decl.last;
|
||||
node->next = 0;
|
||||
l->list_decl.last = node;
|
||||
}
|
||||
node->parent = l;
|
||||
}
|
||||
|
||||
function void
|
||||
decl_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;
|
||||
node->next = 0;
|
||||
}
|
||||
else{
|
||||
node->next = l->list_decl.first;
|
||||
l->list_decl.first->prev = node;
|
||||
node->prev = 0;
|
||||
l->list_decl.first = node;
|
||||
}
|
||||
node->parent = l;
|
||||
}
|
||||
|
||||
function void
|
||||
decl_list_remove(Decl *l, Decl *node){
|
||||
if(l->list_decl.first == l->list_decl.last){
|
||||
assert(node == l->list_decl.last);
|
||||
l->list_decl.first = l->list_decl.last = 0;
|
||||
}
|
||||
else if(l->list_decl.last == node){
|
||||
l->list_decl.last = l->list_decl.last->prev;
|
||||
l->list_decl.last->next = 0;
|
||||
}
|
||||
else if(l->list_decl.first == node){
|
||||
l->list_decl.first = l->list_decl.first->next;
|
||||
l->list_decl.first->prev = 0;
|
||||
}
|
||||
else{
|
||||
node->prev->next = node->next;
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
|
||||
node->parent = 0;
|
||||
node->prev = 0;
|
||||
node->next = 0;
|
||||
}
|
||||
|
||||
function void
|
||||
list_print(Decl *decls){
|
||||
|
||||
printf("next:");
|
||||
for(Decl *n = decls[0].list_decl.first; n; n=n->next){
|
||||
printf("%d", n->kind);
|
||||
}
|
||||
printf("prev:");
|
||||
for(Decl *n = decls[0].list_decl.last; n; n=n->prev){
|
||||
printf("%d", n->kind);
|
||||
}
|
||||
printf("parent:");
|
||||
for(Decl *n = decls[0].list_decl.first; n; n=n->next){
|
||||
printf("%d", n->parent->kind);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
ast_test(){
|
||||
Decl decls[16] = {0};
|
||||
decls[0].kind = 9;
|
||||
decls[1].kind = 1;
|
||||
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);
|
||||
|
||||
//list_print(decls);
|
||||
decl_list_remove(decls, decls+1);
|
||||
//list_print(decls);
|
||||
decl_list_remove(decls, decls+2);
|
||||
//list_print(decls);
|
||||
decl_list_remove(decls, decls+3);
|
||||
//list_print(decls);
|
||||
decl_list_remove(decls, decls+4);
|
||||
//list_print(decls);
|
||||
assert(decls[0].list_decl.first == 0);
|
||||
assert(decls[0].list_decl.last == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
18
new_lex.c
18
new_lex.c
@@ -2,7 +2,8 @@ global Intern_String keyword_if;
|
||||
global Intern_String keyword_for;
|
||||
global Intern_String keyword_cast;
|
||||
global Intern_String keyword_else;
|
||||
global Intern_String keyword_sizeof;
|
||||
global Intern_String keyword_size_type;
|
||||
global Intern_String keyword_size_expr;
|
||||
global Intern_String keyword_typeof;
|
||||
global Intern_String keyword_while;
|
||||
global Intern_String keyword_switch;
|
||||
@@ -21,7 +22,8 @@ init_default_keywords(Intern_Table *t){
|
||||
keyword_cast = intern_string(t, lit("cast"));
|
||||
keyword_for = intern_string(t, lit("for"));
|
||||
keyword_else = intern_string(t, lit("else"));
|
||||
keyword_sizeof = intern_string(t, lit("sizeof"));
|
||||
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_while = intern_string(t, lit("while"));
|
||||
keyword_switch = intern_string(t, lit("switch"));
|
||||
@@ -89,6 +91,7 @@ typedef enum Token_Kind{
|
||||
|
||||
TK_Colon,
|
||||
TK_Assign,
|
||||
TK_ColonAssign,
|
||||
TK_DivAssign,
|
||||
TK_MulAssign,
|
||||
TK_ModAssign,
|
||||
@@ -370,6 +373,10 @@ lex__stream(Token_Array *array, Lex_Stream *s){
|
||||
lex_advance(s);
|
||||
t.kind = TK_DoubleColon;
|
||||
}
|
||||
else if(lexc(s) == '='){
|
||||
lex_advance(s);
|
||||
t.kind = TK_ColonAssign;
|
||||
}
|
||||
else {
|
||||
t.kind = TK_Colon;
|
||||
}
|
||||
@@ -496,7 +503,7 @@ lex_test(){
|
||||
Arena *scratch = arena_begin_scratch();
|
||||
String test = lit("18446744073709551616{})(@?&+-;....->,:::/**/\"Thing\"//R\n Thingy"
|
||||
"\"Test_Meme\"+=-===42524 4294967295 18446744073709551615"
|
||||
"for if while switch");
|
||||
"for if while switch :=");
|
||||
Token_Array array = lex_stream(scratch, test, lit("Test1"));
|
||||
|
||||
Token_Kind kind[] = {
|
||||
@@ -505,7 +512,7 @@ lex_test(){
|
||||
TK_ThreeDots, TK_Dot, TK_Arrow, TK_Comma, TK_DoubleColon, TK_Colon,
|
||||
TK_StringLit, TK_Identifier, TK_StringLit, TK_AddAssign, TK_SubAssign,
|
||||
TK_Equals, TK_Int, TK_Int, TK_Int, TK_Keyword, TK_Keyword,
|
||||
TK_Keyword, TK_Keyword, TK_End
|
||||
TK_Keyword, TK_Keyword, TK_ColonAssign, TK_End
|
||||
};
|
||||
String strs[] = {
|
||||
lit("18446744073709551616"),lit("{"),lit("}"),lit(")"),lit("("),
|
||||
@@ -513,7 +520,7 @@ lex_test(){
|
||||
lit("..."),lit("."),lit("->"),lit(","),lit("::"),lit(":"),
|
||||
lit("Thing"),lit("Thingy"),lit("Test_Meme"), lit("+="),lit("-="),
|
||||
lit("=="),lit("42524"),lit("4294967295"),lit("18446744073709551615"),
|
||||
lit("for"), lit("if"), lit("while"), lit("switch"), lit(""),
|
||||
lit("for"), lit("if"), lit("while"), lit("switch"), lit(":="), lit(""),
|
||||
};
|
||||
U64 vals[] = {
|
||||
42524, 4294967295, 18446744073709551615llu
|
||||
@@ -563,6 +570,7 @@ global const char *token_kind_string[] = {
|
||||
[TK_GreaterThen] = ">",
|
||||
[TK_Colon] = ":",
|
||||
[TK_Assign] = "=",
|
||||
[TK_ColonAssign] = ":=",
|
||||
[TK_DivAssign] = "/=",
|
||||
[TK_MulAssign] = "*=",
|
||||
[TK_ModAssign] = "%=",
|
||||
|
||||
157
new_parse.c
157
new_parse.c
@@ -110,13 +110,15 @@ atom_expr = Int
|
||||
| String
|
||||
| Identifier
|
||||
| 'cast' '(' typespec ',' expr ')'
|
||||
| 'size_type' '(' typespec ')'
|
||||
| 'size_expr' '(' expr ')'
|
||||
postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')*
|
||||
unary_expr = unary ? unary_expr : atom_expr
|
||||
mul_expr = atom_expr (mul atom_expr)*
|
||||
add_expr = mul_expr (add mul_expr)*
|
||||
compare_expr = add_expr (compare add_expr)*
|
||||
logical_expr = compare_expr (logical compare_expr)*
|
||||
ternary_expr = logical_expr ('?' ternary_expr ':' ternary_expr)?
|
||||
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
|
||||
*/
|
||||
function Expr *parse_expr(Parser *p);
|
||||
@@ -167,6 +169,51 @@ token_is_postfix(Parser *p){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr_Compound_Field *
|
||||
parse_expr_compound(Parser *p){
|
||||
Token *token = token_get(p);
|
||||
Expr_Compound_Field *result = 0;
|
||||
if(token_match(p, TK_OpenBracket)){
|
||||
Expr *index = parse_expr(p);
|
||||
token_expect(p, TK_CloseBracket);
|
||||
token_expect(p, TK_Assign);
|
||||
Expr *expr = parse_expr(p);
|
||||
result = expr_compound_index(p->arena, token, index, expr);
|
||||
}
|
||||
else{
|
||||
Expr *expr = parse_expr(p);
|
||||
if((token = token_match(p, TK_Assign))){
|
||||
if(expr->kind != EK_Identifier){
|
||||
parser_push_error(p, token, "Failed to parse compound literal, required identifier as left value");
|
||||
}
|
||||
result = expr_compound_named(p->arena, token, expr->intern_val, parse_expr(p));
|
||||
|
||||
}
|
||||
else{
|
||||
result = expr_compound_default(p->arena, token, expr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr_Compound_Field *
|
||||
parse_expr_function_argument(Parser *p){
|
||||
Token *token = token_get(p);
|
||||
Expr_Compound_Field *result = 0;
|
||||
Expr *expr1 = parse_expr(p);
|
||||
if(token_match(p, TK_Assign)){
|
||||
if(expr1->kind != EK_Identifier){
|
||||
parser_push_error(p, token, "Failed to parse named function argument, required identifier as left value");
|
||||
}
|
||||
Expr *expr2 = parse_expr(p);
|
||||
result = expr_compound_named(p->arena, token, expr1->intern_val, expr2);
|
||||
}
|
||||
else{
|
||||
result = expr_compound_default(p->arena, token, expr1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr *
|
||||
parse_expr_postfix(Parser *p){
|
||||
Expr *left = parse_expr_atom(p);
|
||||
@@ -180,10 +227,10 @@ parse_expr_postfix(Parser *p){
|
||||
else if((token = token_match(p, TK_OpenParen))){
|
||||
left = expr_call(p->arena, token, left);
|
||||
if(!token_is(p, TK_CloseParen)){
|
||||
expr_call_push(left, parse_expr(p));
|
||||
while(token_match(p, TK_Comma)){
|
||||
expr_call_push(left, parse_expr(p));
|
||||
}
|
||||
do {
|
||||
Expr_Compound_Field *field = parse_expr_function_argument(p);
|
||||
expr_call_push(left, field);
|
||||
} while(token_match(p, TK_Comma));
|
||||
}
|
||||
token_expect(p, TK_CloseParen);
|
||||
}
|
||||
@@ -263,24 +310,6 @@ parse_expr_add(Parser *p){
|
||||
return left;
|
||||
}
|
||||
|
||||
function B32
|
||||
token_is_compare(Parser *p){
|
||||
Token *token = token_get(p);
|
||||
B32 result = token->kind >= TK_FirstCompare && token->kind <= TK_LastCompare;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr *
|
||||
parse_expr_compare(Parser *p){
|
||||
Expr *left = parse_expr_add(p);
|
||||
while(token_is_compare(p)){
|
||||
Token *op = token_next(p);
|
||||
Expr *right = parse_expr_add(p);
|
||||
left = expr_binary(p->arena, op, left, right);
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
function B32
|
||||
token_is_logical(Parser *p){
|
||||
Token *token = token_get(p);
|
||||
@@ -290,10 +319,28 @@ token_is_logical(Parser *p){
|
||||
|
||||
function Expr *
|
||||
parse_expr_logical(Parser *p){
|
||||
Expr *left = parse_expr_compare(p);
|
||||
Expr *left = parse_expr_add(p);
|
||||
while(token_is_logical(p)){
|
||||
Token *op = token_next(p);
|
||||
Expr *right = parse_expr_compare(p);
|
||||
Expr *right = parse_expr_add(p);
|
||||
left = expr_binary(p->arena, op, left, right);
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
function B32
|
||||
token_is_compare(Parser *p){
|
||||
Token *token = token_get(p);
|
||||
B32 result = token->kind >= TK_FirstCompare && token->kind <= TK_LastCompare;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Expr *
|
||||
parse_expr_compare(Parser *p){
|
||||
Expr *left = parse_expr_logical(p);
|
||||
while(token_is_compare(p)){
|
||||
Token *op = token_next(p);
|
||||
Expr *right = parse_expr_logical(p);
|
||||
left = expr_binary(p->arena, op, left, right);
|
||||
}
|
||||
return left;
|
||||
@@ -301,7 +348,7 @@ parse_expr_logical(Parser *p){
|
||||
|
||||
function Expr *
|
||||
parse_expr_ternary(Parser *p){
|
||||
Expr *cond = parse_expr_logical(p);
|
||||
Expr *cond = parse_expr_compare(p);
|
||||
Token *token = 0;
|
||||
if((token = token_match(p, TK_Question))){
|
||||
Expr *on_true = parse_expr_ternary(p);
|
||||
@@ -321,11 +368,32 @@ parse_expr(Parser *p){
|
||||
//-----------------------------------------------------------------------------
|
||||
// Test code
|
||||
//-----------------------------------------------------------------------------
|
||||
function void expr_print(Expr *expr);
|
||||
function void
|
||||
token_print(Token *token){
|
||||
printf("%.*s", (S32)token->len, token->str);
|
||||
}
|
||||
|
||||
function void
|
||||
expr_compound_print(Expr_Compound_Field *field){
|
||||
switch(field->kind){
|
||||
case COMPOUND_Default: {
|
||||
expr_print(field->init);
|
||||
}break;
|
||||
case COMPOUND_Named: {
|
||||
printf("[%s] = ", field->name.s.str);
|
||||
expr_print(field->init);
|
||||
}break;
|
||||
case COMPOUND_Index: {
|
||||
printf("[");
|
||||
expr_print(field->index);
|
||||
printf("] = ");
|
||||
expr_print(field->init);
|
||||
}break;
|
||||
default: invalid_codepath;
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
expr_print(Expr *expr){
|
||||
switch(expr->kind) {
|
||||
@@ -333,15 +401,24 @@ expr_print(Expr *expr){
|
||||
token_print(expr->token);
|
||||
} break;
|
||||
|
||||
case EK_Sizeof:{
|
||||
printf("sizeof(");
|
||||
if(expr->size_of.kind == SIZEOF_Expr){
|
||||
expr_print(expr->size_of.expr);
|
||||
}
|
||||
else{
|
||||
assert(expr->size_of.kind == SIZEOF_Type);
|
||||
//print_typespec(expr->size_of.type);
|
||||
case EK_SizeExpr:{
|
||||
printf("size_expr(");
|
||||
expr_print(expr->size_expr.expr);
|
||||
printf(")");
|
||||
}break;
|
||||
|
||||
case EK_Compound:{
|
||||
// typespec_print(p);
|
||||
printf("{");
|
||||
for(Expr_Compound_Field *n = expr->compound.first; n; n=n->next){
|
||||
expr_compound_print(n);
|
||||
if(n!=expr->compound.last) printf(",");
|
||||
}
|
||||
printf("}");
|
||||
} break;
|
||||
|
||||
case EK_SizeType:{
|
||||
printf("size_type(");
|
||||
printf(")");
|
||||
}break;
|
||||
|
||||
@@ -407,8 +484,8 @@ expr_print(Expr *expr){
|
||||
case EK_Call:{
|
||||
expr_print(expr->call.atom);
|
||||
printf("(");
|
||||
for(Expr *n = expr->call.first; n; n=n->next){
|
||||
expr_print(n);
|
||||
for(Expr_Compound_Field *n = expr->call.first; n; n=n->next){
|
||||
expr_compound_print(n);
|
||||
if(n!=expr->call.last) printf(",");
|
||||
}
|
||||
printf(")");
|
||||
@@ -474,13 +551,14 @@ parse_test(){
|
||||
String test_case = lit("32+52-242*2/424%5-23"
|
||||
" 1<<5>>6<<2 "
|
||||
" 5*(4/3)*(2+5) "
|
||||
" 0&1 == 1&0 "
|
||||
" 1&&5*3 "
|
||||
" 1&&5||0 "
|
||||
" 1>5>=5==0 "
|
||||
" 1>5 ? 1 : 2 "
|
||||
" !!!!!1 "
|
||||
" ~~1 + -!2 "
|
||||
" 1 + ++Thing[12]++ + ++Thing[12].expr + --Not_Thing[156](Thing) + test_func(func1, func2, func3)"
|
||||
" 1 + ++Thing[12]++ + ++Thing[12].expr + --Not_Thing[156](Thing) + test_func(asd=func1, af=func2, gg=func3)"
|
||||
);
|
||||
Parser parser = {
|
||||
.tokens = lex_stream(scratch, test_case, lit("expr_test")),
|
||||
@@ -493,6 +571,7 @@ parse_test(){
|
||||
(32+52-242*2/424%5-23),
|
||||
(((1<<5)>>6)<<2),
|
||||
5*(4/3)*(2+5),
|
||||
(0&1) == (1&0),
|
||||
1&&(t*3),
|
||||
(1&&t)||0,
|
||||
1>t>=t==0,
|
||||
|
||||
Reference in New Issue
Block a user