Named function args
This commit is contained in:
179
ideas.cpp
179
ideas.cpp
@@ -1,170 +1,33 @@
|
|||||||
Thing :: struct{
|
New_Data_Type::typedef int;
|
||||||
data: (U32) U32; // Function pointer
|
CONST_VAL::const 324;
|
||||||
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*/{
|
Ideas::enum{
|
||||||
if first == 0 {
|
One,
|
||||||
first = last = node;
|
Two,
|
||||||
}
|
Three
|
||||||
else{
|
|
||||||
last = last->next = node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StructInside :: struct { // This is not part of struct
|
Data::struct{
|
||||||
// just in scope
|
first: int;
|
||||||
some_val: U16;
|
second: int;
|
||||||
some_val2: U16;
|
idea: Ideas;
|
||||||
}
|
}
|
||||||
|
|
||||||
insider: StructInside;
|
|
||||||
|
|
||||||
named_union_part_of_struct: union{
|
function_call::(first_param: Data*, second_param: int[32]){
|
||||||
some_val: U16;
|
first_param.first = 10;
|
||||||
some_val2: U32;
|
first_param.second = 10;
|
||||||
|
first_param.idea = Ideas.One;
|
||||||
|
p:= first_param;
|
||||||
|
|
||||||
|
for i in 0...32 {
|
||||||
|
second_param[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
_: union {
|
for i := 0; i < 32; i++ {
|
||||||
// Unamed union
|
second_param[i] = i;
|
||||||
val: U32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope :: scope{
|
|
||||||
Thingy::enum:U32{
|
|
||||||
@str=10 Value = 1,
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Scope.Thingy
|
|
||||||
|
|
||||||
Thing::union{
|
|
||||||
union:{
|
|
||||||
}
|
|
||||||
struct:{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Thing::struct{
|
|
||||||
data: U32;
|
|
||||||
|
|
||||||
inside_call :: (param: U32){
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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{}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1
main.c
1
main.c
@@ -18,4 +18,5 @@
|
|||||||
int main(){
|
int main(){
|
||||||
lex_test();
|
lex_test();
|
||||||
parse_test();
|
parse_test();
|
||||||
|
ast_test();
|
||||||
}
|
}
|
||||||
469
new_ast.c
469
new_ast.c
@@ -1,6 +1,129 @@
|
|||||||
|
|
||||||
typedef struct Expr Expr;
|
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 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{
|
typedef enum Typespec_Kind{
|
||||||
TS_None,
|
TS_None,
|
||||||
TS_Name,
|
TS_Name,
|
||||||
@@ -29,92 +152,127 @@ struct Typespec{
|
|||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Expressions
|
// Declarations
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
typedef enum Expr_Sizeof_Kind{
|
typedef enum Decl_Kind{
|
||||||
SIZEOF_Expr,
|
DECL_None,
|
||||||
SIZEOF_Type,
|
DECL_Struct,
|
||||||
}Expr_Sizeof_Kind;
|
DECL_Union,
|
||||||
|
DECL_Enum,
|
||||||
|
DECL_Variable,
|
||||||
|
DECL_Typedef,
|
||||||
|
DECL_Function,
|
||||||
|
DECL_List,
|
||||||
|
}Decl_Kind;
|
||||||
|
|
||||||
typedef enum Expr_Kind{
|
struct Note{
|
||||||
EK_None,
|
Token *pos;
|
||||||
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 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 *type;
|
|
||||||
Expr* expr;
|
|
||||||
} cast;
|
|
||||||
|
|
||||||
struct{
|
|
||||||
Intern_String name;
|
Intern_String name;
|
||||||
Expr *expr;
|
Expr *expr;
|
||||||
}field;
|
Note *next;
|
||||||
|
Note *first;
|
||||||
|
Note *last;
|
||||||
|
};
|
||||||
|
|
||||||
struct {
|
struct Decl{
|
||||||
Expr *atom;
|
Decl_Kind kind;
|
||||||
Expr *first;
|
Decl *next;
|
||||||
Expr *last;
|
B32 is_incomplete;
|
||||||
} 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;
|
|
||||||
|
|
||||||
struct{
|
Decl *prev; // Doubly linked list?
|
||||||
Expr_Sizeof_Kind kind;
|
Decl *parent; // ?
|
||||||
|
|
||||||
|
Intern_String name;
|
||||||
|
Token *pos;
|
||||||
|
|
||||||
|
Note *first_note;
|
||||||
|
Note *last_note;
|
||||||
union{
|
union{
|
||||||
|
struct{
|
||||||
|
Decl_Enum_Child *first;
|
||||||
|
Decl_Enum_Child *last;
|
||||||
|
Typespec *typespec;
|
||||||
|
}enum_decl;
|
||||||
|
struct{
|
||||||
|
Decl *first;
|
||||||
|
Decl *last;
|
||||||
|
}struct_decl;
|
||||||
|
struct{
|
||||||
Typespec *type;
|
Typespec *type;
|
||||||
Expr *expr;
|
Expr *expr;
|
||||||
|
}var_decl;
|
||||||
|
struct{
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
} size_of;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 *
|
function Expr *
|
||||||
expr_new(Arena *p, Expr_Kind kind, Token *token){
|
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 *
|
function Expr *
|
||||||
expr_cast(Arena *p, Token *token, Typespec *type, Expr *exp){
|
expr_cast(Arena *p, Token *token, Typespec *type, Expr *exp){
|
||||||
Expr *expr = expr_new(p, EK_Cast, token);
|
Expr *expr = expr_new(p, EK_Cast, token);
|
||||||
expr->cast.type = type;
|
expr->cast.typespec = type;
|
||||||
expr->cast.expr = exp;
|
expr->cast.expr = exp;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
expr_sizeof_type(Arena *p, Token *token, Typespec *type){
|
expr_size_type(Arena *p, Token *token, Typespec *type){
|
||||||
Expr *expr = expr_new(p, EK_Sizeof, token);
|
Expr *expr = expr_new(p, EK_SizeType, token);
|
||||||
expr->size_of.kind = SIZEOF_Type;
|
expr->size_type.typespec = type;
|
||||||
expr->size_of.type = type;
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
expr_sizeof_expr(Arena *p, Token *token, Expr *in_expr){
|
expr_sizeof_expr(Arena *p, Token *token, Expr *in_expr){
|
||||||
Expr *expr = expr_new(p, EK_Sizeof, token);
|
Expr *expr = expr_new(p, EK_SizeExpr, token);
|
||||||
expr->size_of.kind = SIZEOF_Expr;
|
expr->size_expr.expr = in_expr;
|
||||||
expr->size_of.expr = in_expr;
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function Expr *
|
||||||
expr_call_push(Expr *list, Expr *expr){
|
expr_compound(Arena *arena, Token *pos, Typespec *typespec){
|
||||||
SLLQueuePush(list->call.first, list->call.last, expr);
|
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_for;
|
||||||
global Intern_String keyword_cast;
|
global Intern_String keyword_cast;
|
||||||
global Intern_String keyword_else;
|
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_typeof;
|
||||||
global Intern_String keyword_while;
|
global Intern_String keyword_while;
|
||||||
global Intern_String keyword_switch;
|
global Intern_String keyword_switch;
|
||||||
@@ -21,7 +22,8 @@ init_default_keywords(Intern_Table *t){
|
|||||||
keyword_cast = intern_string(t, lit("cast"));
|
keyword_cast = intern_string(t, lit("cast"));
|
||||||
keyword_for = intern_string(t, lit("for"));
|
keyword_for = intern_string(t, lit("for"));
|
||||||
keyword_else = intern_string(t, lit("else"));
|
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_typeof = intern_string(t, lit("typeof"));
|
||||||
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"));
|
||||||
@@ -89,6 +91,7 @@ typedef enum Token_Kind{
|
|||||||
|
|
||||||
TK_Colon,
|
TK_Colon,
|
||||||
TK_Assign,
|
TK_Assign,
|
||||||
|
TK_ColonAssign,
|
||||||
TK_DivAssign,
|
TK_DivAssign,
|
||||||
TK_MulAssign,
|
TK_MulAssign,
|
||||||
TK_ModAssign,
|
TK_ModAssign,
|
||||||
@@ -370,6 +373,10 @@ lex__stream(Token_Array *array, Lex_Stream *s){
|
|||||||
lex_advance(s);
|
lex_advance(s);
|
||||||
t.kind = TK_DoubleColon;
|
t.kind = TK_DoubleColon;
|
||||||
}
|
}
|
||||||
|
else if(lexc(s) == '='){
|
||||||
|
lex_advance(s);
|
||||||
|
t.kind = TK_ColonAssign;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
t.kind = TK_Colon;
|
t.kind = TK_Colon;
|
||||||
}
|
}
|
||||||
@@ -496,7 +503,7 @@ lex_test(){
|
|||||||
Arena *scratch = arena_begin_scratch();
|
Arena *scratch = arena_begin_scratch();
|
||||||
String test = lit("18446744073709551616{})(@?&+-;....->,:::/**/\"Thing\"//R\n Thingy"
|
String test = lit("18446744073709551616{})(@?&+-;....->,:::/**/\"Thing\"//R\n Thingy"
|
||||||
"\"Test_Meme\"+=-===42524 4294967295 18446744073709551615"
|
"\"Test_Meme\"+=-===42524 4294967295 18446744073709551615"
|
||||||
"for if while switch");
|
"for if while switch :=");
|
||||||
Token_Array array = lex_stream(scratch, test, lit("Test1"));
|
Token_Array array = lex_stream(scratch, test, lit("Test1"));
|
||||||
|
|
||||||
Token_Kind kind[] = {
|
Token_Kind kind[] = {
|
||||||
@@ -505,7 +512,7 @@ lex_test(){
|
|||||||
TK_ThreeDots, TK_Dot, TK_Arrow, TK_Comma, TK_DoubleColon, TK_Colon,
|
TK_ThreeDots, TK_Dot, TK_Arrow, TK_Comma, TK_DoubleColon, TK_Colon,
|
||||||
TK_StringLit, TK_Identifier, TK_StringLit, TK_AddAssign, TK_SubAssign,
|
TK_StringLit, TK_Identifier, TK_StringLit, TK_AddAssign, TK_SubAssign,
|
||||||
TK_Equals, TK_Int, TK_Int, TK_Int, TK_Keyword, TK_Keyword,
|
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[] = {
|
String strs[] = {
|
||||||
lit("18446744073709551616"),lit("{"),lit("}"),lit(")"),lit("("),
|
lit("18446744073709551616"),lit("{"),lit("}"),lit(")"),lit("("),
|
||||||
@@ -513,7 +520,7 @@ lex_test(){
|
|||||||
lit("..."),lit("."),lit("->"),lit(","),lit("::"),lit(":"),
|
lit("..."),lit("."),lit("->"),lit(","),lit("::"),lit(":"),
|
||||||
lit("Thing"),lit("Thingy"),lit("Test_Meme"), lit("+="),lit("-="),
|
lit("Thing"),lit("Thingy"),lit("Test_Meme"), lit("+="),lit("-="),
|
||||||
lit("=="),lit("42524"),lit("4294967295"),lit("18446744073709551615"),
|
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[] = {
|
U64 vals[] = {
|
||||||
42524, 4294967295, 18446744073709551615llu
|
42524, 4294967295, 18446744073709551615llu
|
||||||
@@ -563,6 +570,7 @@ global const char *token_kind_string[] = {
|
|||||||
[TK_GreaterThen] = ">",
|
[TK_GreaterThen] = ">",
|
||||||
[TK_Colon] = ":",
|
[TK_Colon] = ":",
|
||||||
[TK_Assign] = "=",
|
[TK_Assign] = "=",
|
||||||
|
[TK_ColonAssign] = ":=",
|
||||||
[TK_DivAssign] = "/=",
|
[TK_DivAssign] = "/=",
|
||||||
[TK_MulAssign] = "*=",
|
[TK_MulAssign] = "*=",
|
||||||
[TK_ModAssign] = "%=",
|
[TK_ModAssign] = "%=",
|
||||||
|
|||||||
157
new_parse.c
157
new_parse.c
@@ -110,13 +110,15 @@ atom_expr = Int
|
|||||||
| String
|
| String
|
||||||
| Identifier
|
| Identifier
|
||||||
| 'cast' '(' typespec ',' expr ')'
|
| 'cast' '(' typespec ',' expr ')'
|
||||||
|
| 'size_type' '(' typespec ')'
|
||||||
|
| 'size_expr' '(' 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)*
|
||||||
add_expr = mul_expr (add mul_expr)*
|
add_expr = mul_expr (add mul_expr)*
|
||||||
compare_expr = add_expr (compare add_expr)*
|
logical_expr = add_expr (logical add_expr)*
|
||||||
logical_expr = compare_expr (logical compare_expr)*
|
compare_expr = logical_expr (compare logical_expr)*
|
||||||
ternary_expr = logical_expr ('?' ternary_expr ':' ternary_expr)?
|
ternary_expr = compare_expr ('?' ternary_expr ':' ternary_expr)?
|
||||||
expr = logical_expr
|
expr = logical_expr
|
||||||
*/
|
*/
|
||||||
function Expr *parse_expr(Parser *p);
|
function Expr *parse_expr(Parser *p);
|
||||||
@@ -167,6 +169,51 @@ token_is_postfix(Parser *p){
|
|||||||
return result;
|
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 *
|
function Expr *
|
||||||
parse_expr_postfix(Parser *p){
|
parse_expr_postfix(Parser *p){
|
||||||
Expr *left = parse_expr_atom(p);
|
Expr *left = parse_expr_atom(p);
|
||||||
@@ -180,10 +227,10 @@ parse_expr_postfix(Parser *p){
|
|||||||
else if((token = token_match(p, TK_OpenParen))){
|
else if((token = token_match(p, TK_OpenParen))){
|
||||||
left = expr_call(p->arena, token, left);
|
left = expr_call(p->arena, token, left);
|
||||||
if(!token_is(p, TK_CloseParen)){
|
if(!token_is(p, TK_CloseParen)){
|
||||||
expr_call_push(left, parse_expr(p));
|
do {
|
||||||
while(token_match(p, TK_Comma)){
|
Expr_Compound_Field *field = parse_expr_function_argument(p);
|
||||||
expr_call_push(left, parse_expr(p));
|
expr_call_push(left, field);
|
||||||
}
|
} while(token_match(p, TK_Comma));
|
||||||
}
|
}
|
||||||
token_expect(p, TK_CloseParen);
|
token_expect(p, TK_CloseParen);
|
||||||
}
|
}
|
||||||
@@ -263,24 +310,6 @@ parse_expr_add(Parser *p){
|
|||||||
return left;
|
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
|
function B32
|
||||||
token_is_logical(Parser *p){
|
token_is_logical(Parser *p){
|
||||||
Token *token = token_get(p);
|
Token *token = token_get(p);
|
||||||
@@ -290,10 +319,28 @@ token_is_logical(Parser *p){
|
|||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
parse_expr_logical(Parser *p){
|
parse_expr_logical(Parser *p){
|
||||||
Expr *left = parse_expr_compare(p);
|
Expr *left = parse_expr_add(p);
|
||||||
while(token_is_logical(p)){
|
while(token_is_logical(p)){
|
||||||
Token *op = token_next(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);
|
left = expr_binary(p->arena, op, left, right);
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
@@ -301,7 +348,7 @@ parse_expr_logical(Parser *p){
|
|||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
parse_expr_ternary(Parser *p){
|
parse_expr_ternary(Parser *p){
|
||||||
Expr *cond = parse_expr_logical(p);
|
Expr *cond = parse_expr_compare(p);
|
||||||
Token *token = 0;
|
Token *token = 0;
|
||||||
if((token = token_match(p, TK_Question))){
|
if((token = token_match(p, TK_Question))){
|
||||||
Expr *on_true = parse_expr_ternary(p);
|
Expr *on_true = parse_expr_ternary(p);
|
||||||
@@ -321,11 +368,32 @@ parse_expr(Parser *p){
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Test code
|
// Test code
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
function void expr_print(Expr *expr);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
function void
|
||||||
expr_print(Expr *expr){
|
expr_print(Expr *expr){
|
||||||
switch(expr->kind) {
|
switch(expr->kind) {
|
||||||
@@ -333,15 +401,24 @@ expr_print(Expr *expr){
|
|||||||
token_print(expr->token);
|
token_print(expr->token);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case EK_Sizeof:{
|
case EK_SizeExpr:{
|
||||||
printf("sizeof(");
|
printf("size_expr(");
|
||||||
if(expr->size_of.kind == SIZEOF_Expr){
|
expr_print(expr->size_expr.expr);
|
||||||
expr_print(expr->size_of.expr);
|
printf(")");
|
||||||
}
|
}break;
|
||||||
else{
|
|
||||||
assert(expr->size_of.kind == SIZEOF_Type);
|
case EK_Compound:{
|
||||||
//print_typespec(expr->size_of.type);
|
// 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(")");
|
printf(")");
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
@@ -407,8 +484,8 @@ expr_print(Expr *expr){
|
|||||||
case EK_Call:{
|
case EK_Call:{
|
||||||
expr_print(expr->call.atom);
|
expr_print(expr->call.atom);
|
||||||
printf("(");
|
printf("(");
|
||||||
for(Expr *n = expr->call.first; n; n=n->next){
|
for(Expr_Compound_Field *n = expr->call.first; n; n=n->next){
|
||||||
expr_print(n);
|
expr_compound_print(n);
|
||||||
if(n!=expr->call.last) printf(",");
|
if(n!=expr->call.last) printf(",");
|
||||||
}
|
}
|
||||||
printf(")");
|
printf(")");
|
||||||
@@ -474,13 +551,14 @@ parse_test(){
|
|||||||
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 "
|
||||||
" 5*(4/3)*(2+5) "
|
" 5*(4/3)*(2+5) "
|
||||||
|
" 0&1 == 1&0 "
|
||||||
" 1&&5*3 "
|
" 1&&5*3 "
|
||||||
" 1&&5||0 "
|
" 1&&5||0 "
|
||||||
" 1>5>=5==0 "
|
" 1>5>=5==0 "
|
||||||
" 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(func1, func2, func3)"
|
" 1 + ++Thing[12]++ + ++Thing[12].expr + --Not_Thing[156](Thing) + test_func(asd=func1, af=func2, gg=func3)"
|
||||||
);
|
);
|
||||||
Parser parser = {
|
Parser parser = {
|
||||||
.tokens = lex_stream(scratch, test_case, lit("expr_test")),
|
.tokens = lex_stream(scratch, test_case, lit("expr_test")),
|
||||||
@@ -493,6 +571,7 @@ parse_test(){
|
|||||||
(32+52-242*2/424%5-23),
|
(32+52-242*2/424%5-23),
|
||||||
(((1<<5)>>6)<<2),
|
(((1<<5)>>6)<<2),
|
||||||
5*(4/3)*(2+5),
|
5*(4/3)*(2+5),
|
||||||
|
(0&1) == (1&0),
|
||||||
1&&(t*3),
|
1&&(t*3),
|
||||||
(1&&t)||0,
|
(1&&t)||0,
|
||||||
1>t>=t==0,
|
1>t>=t==0,
|
||||||
|
|||||||
Reference in New Issue
Block a user