From: Michael D. Lowis Date: Wed, 23 Jun 2021 20:55:09 +0000 (-0400) Subject: added very basic AST definition. Considering ditching ssa-like IR for simpler AST... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=5f9c93950538f6120eb6009c421fa6e18956f7ad;p=proto%2Fobnc.git added very basic AST definition. Considering ditching ssa-like IR for simpler AST format --- diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index fa1345f..9b13ab8 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -55,6 +55,7 @@ typedef enum { VAR, WHILE, COUNT, + CALL, ERROR = -2, END_FILE = -1 } TokType; @@ -266,3 +267,84 @@ void ir_binopi(Parser* p, int op, long dest, long arg, long imm); void ir_binopf(Parser* p, int op, long dest, long arg, double imm); void ir_unnopi(Parser* p, int op, long dest, long imm); void ir_unopf(Parser* p, int op, long dest, double imm); + + + +/* Abstract Syntax Tree Definition + *****************************************************************************/ +struct AstNode; + +typedef struct { + int code : 28; + int mode : 4; + struct AstNode* next; + Type* type; +} AstNodeHeader; + +typedef struct AstNode { + AstNodeHeader hdr; + struct AstNode* links[3]; +} AstNode; + +typedef struct { + AstNodeHeader hdr; + union { + long long i; + double f; + char* s; + } val; +} AstValue; + +static AstNode* ast_new(int type, AstNode* l0, AstNode* l1, AstNode* l2) +{ + AstNode* node = calloc(1, sizeof(AstNode)); + node->hdr.code = type; + node->links[0] = l0; + node->links[1] = l1; + node->links[2] = l2; + return node; +} + +static AstNode* ast_int(long long val) +{ + AstValue* node = (AstValue*)ast_new(INT, NULL, NULL, NULL); + node->val.i = val; + return (AstNode*)node; +} + +static AstNode* ast_real(double val) +{ + AstValue* node = (AstValue*)ast_new(REAL, NULL, NULL, NULL); + node->val.i = val; + return (AstNode*)node; +} + +static AstNode* ast_binop(int op, AstNode* left, AstNode* right) +{ + return ast_new(op, left, right, NULL); +} + +static AstNode* ast_unop(int op, AstNode* operand) +{ + return ast_new(op, operand, NULL, NULL); +} + +static AstNode* ast_block(void) +{ + return ast_new(BEGIN, NULL, NULL, NULL); +} + +static AstNode* ast_call(AstNode* func) +{ + return ast_new(CALL, func, NULL, NULL); +} + +static AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2) +{ + return ast_new(IF, cond, br1, br2); +} + +static AstNode* ast_return(AstNode* expr) +{ + return ast_new(RETURN, expr, NULL, NULL); +}