diff --git a/ideas.cpp b/ideas.cpp index 6359bc1..919990b 100644 --- a/ideas.cpp +++ b/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{} - - - - diff --git a/main.c b/main.c index b346c70..7d4b77b 100644 --- a/main.c +++ b/main.c @@ -18,4 +18,5 @@ int main(){ lex_test(); parse_test(); + ast_test(); } \ No newline at end of file diff --git a/new_ast.c b/new_ast.c index 4900fc3..e2cae2e 100644 --- a/new_ast.c +++ b/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 { +struct Decl{ + Decl_Kind kind; + Decl *next; + B32 is_incomplete; + + 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); +} + + diff --git a/new_lex.c b/new_lex.c index dde0d70..84a9e42 100644 --- a/new_lex.c +++ b/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] = "%=", diff --git a/new_parse.c b/new_parse.c index ce6531c..a4142e0 100644 --- a/new_parse.c +++ b/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,