Added almost all expr operators
This commit is contained in:
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
rem clang generate.c -fdiagnostics-absolute-paths -std=c99 -g -o generate.exe -Wl,user32.lib
|
rem clang generate.c -fdiagnostics-absolute-paths -std=c99 -g -o generate.exe -Wl,user32.lib
|
||||||
rem generate.exe
|
rem generate.exe
|
||||||
clang main.c -fdiagnostics-absolute-paths -std=c99 -g -o main.exe -Wl,user32.lib
|
clang main.c -Wall -Wno-unused-function -fdiagnostics-absolute-paths -std=c99 -g -o main.exe -Wl,user32.lib
|
||||||
rem cl main.c -std:c17
|
rem cl main.c -std:c17
|
||||||
|
|||||||
1
main.c
1
main.c
@@ -17,6 +17,5 @@
|
|||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
lex_test();
|
lex_test();
|
||||||
test_ast();
|
|
||||||
parse_test();
|
parse_test();
|
||||||
}
|
}
|
||||||
153
new_ast.c
153
new_ast.c
@@ -41,11 +41,13 @@ typedef enum Expr_Kind{
|
|||||||
EK_Int,
|
EK_Int,
|
||||||
EK_String,
|
EK_String,
|
||||||
EK_Identifier,
|
EK_Identifier,
|
||||||
|
EK_Paren,
|
||||||
|
EK_PostfixUnary,
|
||||||
EK_Unary,
|
EK_Unary,
|
||||||
EK_Binary,
|
EK_Binary,
|
||||||
EK_Ternary,
|
EK_Ternary,
|
||||||
EK_Cast,
|
EK_Cast,
|
||||||
EK_List,
|
EK_Field,
|
||||||
EK_Call,
|
EK_Call,
|
||||||
EK_Index,
|
EK_Index,
|
||||||
EK_Sizeof,
|
EK_Sizeof,
|
||||||
@@ -59,18 +61,24 @@ struct Expr {
|
|||||||
U64 int_val;
|
U64 int_val;
|
||||||
Intern_String intern_val;
|
Intern_String intern_val;
|
||||||
double float_val;
|
double float_val;
|
||||||
|
struct {
|
||||||
|
Expr *expr;
|
||||||
|
} paren;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Typespec *type;
|
Typespec *type;
|
||||||
Expr* expr;
|
Expr* expr;
|
||||||
} cast;
|
} cast;
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
Expr *first;
|
Intern_String name;
|
||||||
Expr *last;
|
Expr *expr;
|
||||||
} list;
|
}field;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Expr *atom;
|
Expr *atom;
|
||||||
Expr *list;
|
Expr *first;
|
||||||
|
Expr *last;
|
||||||
} call;
|
} call;
|
||||||
struct {
|
struct {
|
||||||
Expr *atom;
|
Expr *atom;
|
||||||
@@ -80,6 +88,10 @@ struct Expr {
|
|||||||
Token_Kind op;
|
Token_Kind op;
|
||||||
Expr* expr;
|
Expr* expr;
|
||||||
} unary;
|
} unary;
|
||||||
|
struct {
|
||||||
|
Token_Kind op;
|
||||||
|
Expr *expr;
|
||||||
|
} postfix_unary;
|
||||||
struct {
|
struct {
|
||||||
Token_Kind op;
|
Token_Kind op;
|
||||||
Expr* left;
|
Expr* left;
|
||||||
@@ -90,6 +102,7 @@ struct Expr {
|
|||||||
Expr* on_true;
|
Expr* on_true;
|
||||||
Expr* on_false;
|
Expr* on_false;
|
||||||
} ternary;
|
} ternary;
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
Expr_Sizeof_Kind kind;
|
Expr_Sizeof_Kind kind;
|
||||||
union{
|
union{
|
||||||
@@ -128,13 +141,37 @@ expr_str(Arena *p, Token *token){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
expr_name(Arena *p, Token *token){
|
expr_identifier(Arena *p, Token *token){
|
||||||
assert(token->kind == TK_Identifier);
|
assert(token->kind == TK_Identifier);
|
||||||
Expr *expr = expr_new(p, EK_Identifier, token);
|
Expr *expr = expr_new(p, EK_Identifier, token);
|
||||||
expr->intern_val = token->intern_val;
|
expr->intern_val = token->intern_val;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Expr *
|
||||||
|
expr_field(Arena *p, Token *token, Expr *inexpr){
|
||||||
|
assert(token->kind == TK_Identifier);
|
||||||
|
Expr *expr = expr_new(p, EK_Field, token);
|
||||||
|
expr->field.expr = inexpr;
|
||||||
|
expr->field.name = token->intern_val;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Expr *
|
||||||
|
expr_paren(Arena *p, Token *token, Expr *inexpr){
|
||||||
|
Expr *expr = expr_new(p, EK_Paren, token);
|
||||||
|
expr->paren.expr = inexpr;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Expr *
|
||||||
|
expr_postfix_unary(Arena *p, Token *op, Expr *exp){
|
||||||
|
Expr *expr = expr_new(p, EK_PostfixUnary, op);
|
||||||
|
expr->unary.op = op->kind;
|
||||||
|
expr->unary.expr = exp;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
expr_unary(Arena *p, Token *op, Expr *exp){
|
expr_unary(Arena *p, Token *op, Expr *exp){
|
||||||
Expr *expr = expr_new(p, EK_Unary, op);
|
Expr *expr = expr_new(p, EK_Unary, op);
|
||||||
@@ -162,10 +199,9 @@ expr_ternary(Arena *p, Token *op, Expr *cond, Expr *on_true, Expr *on_false){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
expr_call(Arena *p, Token *token, Expr *atom, Expr *list){
|
expr_call(Arena *p, Token *token, Expr *atom){
|
||||||
Expr *expr = expr_new(p, EK_Call, token);
|
Expr *expr = expr_new(p, EK_Call, token);
|
||||||
expr->call.atom = atom;
|
expr->call.atom = atom;
|
||||||
expr->call.list = list;
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,104 +237,7 @@ expr_sizeof_expr(Arena *p, Token *token, Expr *in_expr){
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Expr *
|
|
||||||
expr_list(Arena *p, Token *token){
|
|
||||||
Expr *expr = expr_new(p, EK_List, token);
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
function void
|
||||||
expr_list_push(Expr *list, Expr *expr){
|
expr_call_push(Expr *list, Expr *expr){
|
||||||
SLLQueuePush(list->list.first, list->list.last, expr);
|
SLLQueuePush(list->call.first, list->call.last, expr);
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
function void
|
|
||||||
token_print(Token *token){
|
|
||||||
printf("%.*s", (S32)token->len, token->str);
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
expr_print(Expr *expr){
|
|
||||||
switch(expr->kind) {
|
|
||||||
case EK_Int:
|
|
||||||
case EK_String: {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
printf(")");
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case EK_Binary:{
|
|
||||||
printf("(");
|
|
||||||
expr_print(expr->binary.left);
|
|
||||||
token_print(expr->token);
|
|
||||||
expr_print(expr->binary.right);
|
|
||||||
printf(")");
|
|
||||||
} break;
|
|
||||||
case EK_Unary:{
|
|
||||||
printf("(");
|
|
||||||
token_print(expr->token);
|
|
||||||
expr_print(expr->unary.expr);
|
|
||||||
printf(")");
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case EK_Ternary:{
|
|
||||||
printf("(");
|
|
||||||
expr_print(expr->ternary.cond);
|
|
||||||
printf("?");
|
|
||||||
expr_print(expr->ternary.on_true);
|
|
||||||
printf(":");
|
|
||||||
expr_print(expr->ternary.on_false);
|
|
||||||
printf(")");
|
|
||||||
} break;
|
|
||||||
case EK_List:{
|
|
||||||
printf("(");
|
|
||||||
for(Expr *n = expr->list.first; n; n=n->next){
|
|
||||||
expr_print(n);
|
|
||||||
if(n!=expr->list.last) printf(",");
|
|
||||||
}
|
|
||||||
printf(")");
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case EK_Cast:{
|
|
||||||
printf("(");
|
|
||||||
printf("(");
|
|
||||||
//print_typespec(expr->cast.type);
|
|
||||||
printf(")");
|
|
||||||
expr_print(expr->cast.expr);
|
|
||||||
printf(")");
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case EK_Index:{
|
|
||||||
expr_print(expr->index.atom);
|
|
||||||
printf("[");
|
|
||||||
expr_print(expr->index.index);
|
|
||||||
printf("]");
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case EK_Call:{
|
|
||||||
expr_print(expr->call.atom);
|
|
||||||
printf("(");
|
|
||||||
expr_print(expr->call.list);
|
|
||||||
printf(")");
|
|
||||||
}break;
|
|
||||||
default: {invalid_codepath;} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
test_ast(){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
222
new_parse.c
222
new_parse.c
@@ -39,7 +39,9 @@ parser_push_error(Parser *p, Token *token, char *str, ...){
|
|||||||
__debugbreak();
|
__debugbreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Parsing helpers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
function Token *
|
function Token *
|
||||||
token_get(Parser *p){
|
token_get(Parser *p){
|
||||||
Token *result = token_array_iter_peek(&p->tokens, 0);
|
Token *result = token_array_iter_peek(&p->tokens, 0);
|
||||||
@@ -93,25 +95,31 @@ token_expect(Parser *p, Token_Kind kind){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Expression parsing
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
/*
|
/*
|
||||||
|
|
||||||
add = [+-]
|
add = [+-]
|
||||||
mul = [/%*]
|
mul = [/%*]
|
||||||
compare = == | != | >= | > | <= | <
|
compare = == | != | >= | > | <= | <
|
||||||
logical = [&|^] | && | ||
|
logical = [&|^] | && | ||
|
||||||
|
unary = [&*-!~+] | ++ | --
|
||||||
|
|
||||||
expr_atom = Int
|
atom_expr = Int
|
||||||
| Float
|
| Float
|
||||||
| String
|
| String
|
||||||
| Identifier
|
| Identifier
|
||||||
| 'cast' '(' typespec ',' expr ')'
|
| 'cast' '(' typespec ',' expr ')'
|
||||||
mul_expr = expr_atom (mul expr_atom)*
|
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)*
|
add_expr = mul_expr (add mul_expr)*
|
||||||
compare_expr = add_expr (compare add_expr)*
|
compare_expr = add_expr (compare add_expr)*
|
||||||
logical_expr = compare_expr (logical compare_expr)*
|
logical_expr = compare_expr (logical compare_expr)*
|
||||||
ternary_expr = logical_expr ('?' ternary_expr ':' ternary_expr)?
|
ternary_expr = logical_expr ('?' ternary_expr ':' ternary_expr)?
|
||||||
expr = logical_expr
|
expr = logical_expr
|
||||||
*/
|
*/
|
||||||
|
function Expr *parse_expr(Parser *p);
|
||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
parse_expr_atom(Parser *p){
|
parse_expr_atom(Parser *p){
|
||||||
@@ -120,10 +128,20 @@ parse_expr_atom(Parser *p){
|
|||||||
Expr *result = expr_str(p->arena, token);
|
Expr *result = expr_str(p->arena, token);
|
||||||
return result;
|
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))){
|
else if((token = token_match(p, TK_Int))){
|
||||||
Expr *result = expr_int(p->arena, token);
|
Expr *result = expr_int(p->arena, token);
|
||||||
return result;
|
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))){
|
else if((token = token_match_keyword(p, keyword_cast))){
|
||||||
token_expect(p, TK_OpenParen);
|
token_expect(p, TK_OpenParen);
|
||||||
token_expect(p, TK_Identifier);
|
token_expect(p, TK_Identifier);
|
||||||
@@ -138,6 +156,77 @@ parse_expr_atom(Parser *p){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 *
|
||||||
|
parse_expr_postfix(Parser *p){
|
||||||
|
Expr *left = parse_expr_atom(p);
|
||||||
|
while(token_is_postfix(p)){
|
||||||
|
Token *token = 0;
|
||||||
|
if((token = token_match(p, TK_OpenBracket))){
|
||||||
|
Expr *size = parse_expr(p);
|
||||||
|
token_expect(p, TK_CloseBracket);
|
||||||
|
left = expr_index(p->arena, token, left, size);
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token_expect(p, TK_CloseParen);
|
||||||
|
}
|
||||||
|
else if(token_match(p, TK_Dot)){
|
||||||
|
token = token_expect(p, TK_Identifier);
|
||||||
|
left = expr_field(p->arena, token, left);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
token = token_next(p);
|
||||||
|
assert(token->kind == TK_Increment || token->kind == TK_Decrement);
|
||||||
|
left = expr_postfix_unary(p->arena, token, left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
function B32
|
||||||
|
token_is_unary(Parser *p){
|
||||||
|
Token *token = token_get(p);
|
||||||
|
B32 result = token->kind == TK_Add
|
||||||
|
|| token->kind == TK_Increment
|
||||||
|
|| token->kind == TK_Decrement
|
||||||
|
|| token->kind == TK_Sub
|
||||||
|
|| token->kind == TK_Mul
|
||||||
|
|| token->kind == TK_BitAnd
|
||||||
|
|| token->kind == TK_Neg
|
||||||
|
|| token->kind == TK_Not;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Expr *
|
||||||
|
parse_expr_unary(Parser *p){
|
||||||
|
if(token_is_unary(p)){
|
||||||
|
Token *op = token_next(p);
|
||||||
|
Expr *right = parse_expr_unary(p);
|
||||||
|
Expr *result = expr_unary(p->arena, op, right);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return parse_expr_postfix(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function B32
|
function B32
|
||||||
token_is_mul(Parser *p){
|
token_is_mul(Parser *p){
|
||||||
Token *token = token_get(p);
|
Token *token = token_get(p);
|
||||||
@@ -147,10 +236,10 @@ token_is_mul(Parser *p){
|
|||||||
|
|
||||||
function Expr *
|
function Expr *
|
||||||
parse_expr_mul(Parser *p){
|
parse_expr_mul(Parser *p){
|
||||||
Expr *left = parse_expr_atom(p);
|
Expr *left = parse_expr_unary(p);
|
||||||
while(token_is_mul(p)){
|
while(token_is_mul(p)){
|
||||||
Token *op = token_next(p);
|
Token *op = token_next(p);
|
||||||
Expr *right = parse_expr_atom(p);
|
Expr *right = parse_expr_unary(p);
|
||||||
left = expr_binary(p->arena, op, left, right);
|
left = expr_binary(p->arena, op, left, right);
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
@@ -229,15 +318,126 @@ parse_expr(Parser *p){
|
|||||||
return parse_expr_ternary(p);
|
return parse_expr_ternary(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Test code
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
function void
|
||||||
|
token_print(Token *token){
|
||||||
|
printf("%.*s", (S32)token->len, token->str);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
expr_print(Expr *expr){
|
||||||
|
switch(expr->kind) {
|
||||||
|
case EK_Int:case EK_String:case EK_Identifier: {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
printf(")");
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case EK_Paren:{
|
||||||
|
printf("(");
|
||||||
|
expr_print(expr->paren.expr);
|
||||||
|
printf(")");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case EK_Field:{
|
||||||
|
expr_print(expr->field.expr);
|
||||||
|
printf(".%s", expr->field.name.s.str);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case EK_Binary:{
|
||||||
|
printf("(");
|
||||||
|
expr_print(expr->binary.left);
|
||||||
|
token_print(expr->token);
|
||||||
|
expr_print(expr->binary.right);
|
||||||
|
printf(")");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case EK_PostfixUnary:{
|
||||||
|
printf("(");
|
||||||
|
expr_print(expr->unary.expr);
|
||||||
|
token_print(expr->token);
|
||||||
|
printf(")");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case EK_Unary:{
|
||||||
|
printf("(");
|
||||||
|
token_print(expr->token);
|
||||||
|
expr_print(expr->unary.expr);
|
||||||
|
printf(")");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case EK_Ternary:{
|
||||||
|
printf("(");
|
||||||
|
expr_print(expr->ternary.cond);
|
||||||
|
printf("?");
|
||||||
|
expr_print(expr->ternary.on_true);
|
||||||
|
printf(":");
|
||||||
|
expr_print(expr->ternary.on_false);
|
||||||
|
printf(")");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case EK_Cast:{
|
||||||
|
printf("(");
|
||||||
|
printf("(");
|
||||||
|
//print_typespec(expr->cast.type);
|
||||||
|
printf(")");
|
||||||
|
expr_print(expr->cast.expr);
|
||||||
|
printf(")");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case EK_Index:{
|
||||||
|
expr_print(expr->index.atom);
|
||||||
|
printf("[");
|
||||||
|
expr_print(expr->index.index);
|
||||||
|
printf("]");
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case EK_Call:{
|
||||||
|
expr_print(expr->call.atom);
|
||||||
|
printf("(");
|
||||||
|
for(Expr *n = expr->call.first; n; n=n->next){
|
||||||
|
expr_print(n);
|
||||||
|
if(n!=expr->call.last) printf(",");
|
||||||
|
}
|
||||||
|
printf(")");
|
||||||
|
}break;
|
||||||
|
default: {invalid_codepath;} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function S64
|
function S64
|
||||||
eval_expr(Expr *expr){
|
eval_expr(Expr *expr){
|
||||||
switch(expr->kind){
|
switch(expr->kind){
|
||||||
case EK_Int: return expr->int_val; break;
|
case EK_Int: return expr->int_val; break;
|
||||||
|
case EK_Unary:{
|
||||||
|
S64 left = eval_expr(expr->unary.expr);
|
||||||
|
switch(expr->unary.op){
|
||||||
|
case TK_Not: return !left; break;
|
||||||
|
case TK_Neg: return ~left; break;
|
||||||
|
case TK_Sub: return -left; break;
|
||||||
|
case TK_Add: return +left; break;
|
||||||
|
default: invalid_codepath;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case EK_Ternary:{
|
case EK_Ternary:{
|
||||||
S64 cond = eval_expr(expr->ternary.cond);
|
S64 cond = eval_expr(expr->ternary.cond);
|
||||||
if(cond) return eval_expr(expr->ternary.on_true);
|
if(cond) return eval_expr(expr->ternary.on_true);
|
||||||
else return eval_expr(expr->ternary.on_false);
|
else return eval_expr(expr->ternary.on_false);
|
||||||
} break;
|
} break;
|
||||||
|
case EK_Paren: return eval_expr(expr->paren.expr); break;
|
||||||
case EK_Binary: {
|
case EK_Binary: {
|
||||||
S64 left = eval_expr(expr->binary.left);
|
S64 left = eval_expr(expr->binary.left);
|
||||||
S64 right = eval_expr(expr->binary.right);
|
S64 right = eval_expr(expr->binary.right);
|
||||||
@@ -273,10 +473,14 @@ parse_test(){
|
|||||||
Arena *scratch = arena_begin_scratch();
|
Arena *scratch = arena_begin_scratch();
|
||||||
String test_case = lit("32+52-242*2/424%5-23"
|
String test_case = lit("32+52-242*2/424%5-23"
|
||||||
" 1<<5>>6<<2 "
|
" 1<<5>>6<<2 "
|
||||||
|
" 5*(4/3)*(2+5) "
|
||||||
" 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 + -!2 "
|
||||||
|
" 1 + ++Thing[12]++ + ++Thing[12].expr + --Not_Thing[156](Thing) + test_func(func1, func2, func3)"
|
||||||
);
|
);
|
||||||
Parser parser = {
|
Parser parser = {
|
||||||
.tokens = lex_stream(scratch, test_case, lit("expr_test")),
|
.tokens = lex_stream(scratch, test_case, lit("expr_test")),
|
||||||
@@ -288,10 +492,13 @@ parse_test(){
|
|||||||
S64 test_val[] = {
|
S64 test_val[] = {
|
||||||
(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),
|
||||||
1&&(t*3),
|
1&&(t*3),
|
||||||
(1&&t)||0,
|
(1&&t)||0,
|
||||||
1>t>=t==0,
|
1>t>=t==0,
|
||||||
1>t ? 1 : 2,
|
1>t ? 1 : 2,
|
||||||
|
!!!!!1,
|
||||||
|
~~1 + -!2,
|
||||||
};
|
};
|
||||||
for(int i = 0; i < buff_cap(test_val); i++){
|
for(int i = 0; i < buff_cap(test_val); i++){
|
||||||
Expr *expr = parse_expr(p);
|
Expr *expr = parse_expr(p);
|
||||||
@@ -299,6 +506,9 @@ parse_test(){
|
|||||||
assert(val == test_val[i]);
|
assert(val == test_val[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expr *expr = parse_expr(p);
|
||||||
|
expr_print(expr);
|
||||||
|
|
||||||
arena_end_scratch();
|
arena_end_scratch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ os_read_file(Arena *arena, String name){
|
|||||||
assert(f);
|
assert(f);
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
result.len = ftell(f);
|
result.len = ftell(f);
|
||||||
fseek(f, 0, SEEK_SET); /* same as rewind(f); */
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
result.str = arena_push_size(arena, result.len + 1);
|
result.str = arena_push_size(arena, result.len + 1);
|
||||||
fread(result.str, result.len, 1, f);
|
fread(result.str, result.len, 1, f);
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ token_array_iter_peek(Token_Array *array, S64 i){
|
|||||||
Token *result = array->iter_bucket->data + over;
|
Token *result = array->iter_bucket->data + over;
|
||||||
array->iter_len = save_len;
|
array->iter_len = save_len;
|
||||||
array->iter_bucket = save_bucket;
|
array->iter_bucket = save_bucket;
|
||||||
|
array->iter_block = save_block;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user