From 98519319f1a692db706694964df35902884a7a93 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Thu, 2 Jul 2020 23:30:39 -0500 Subject: [PATCH] Refactored the AST node structure This involved rewriting a lot of the code that was there --- include/onyxlex.h | 10 +- include/onyxparser.h | 390 ++++++++++++++++------------------- include/onyxsempass.h | 6 +- include/onyxutils.h | 2 +- onyx | Bin 223000 -> 213672 bytes src/onyx.c | 26 +-- src/onyxlex.c | 14 +- src/onyxparser.c | 468 +++++++++++++++++++++--------------------- src/onyxsempass.c | 40 ++-- src/onyxsymres.c | 198 +++++++++--------- src/onyxtypecheck.c | 242 +++++++++++----------- src/onyxutils.c | 294 ++++++++++++-------------- src/onyxwasm.c | 228 ++++++++++---------- 13 files changed, 919 insertions(+), 999 deletions(-) diff --git a/include/onyxlex.h b/include/onyxlex.h index 559a2030..ed65258e 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -3,7 +3,7 @@ #include "bh.h" -typedef enum OnyxTokenType { +typedef enum TokenType { TOKEN_TYPE_UNKNOWN, TOKEN_TYPE_END_STREAM, @@ -61,7 +61,7 @@ typedef enum OnyxTokenType { TOKEN_TYPE_LITERAL_BOOL_FALSE, TOKEN_TYPE_COUNT -} OnyxTokenType; +} TokenType; typedef struct OnyxFilePos { const char* filename; @@ -69,7 +69,7 @@ typedef struct OnyxFilePos { } OnyxFilePos; typedef struct OnyxToken { - OnyxTokenType type; + TokenType type; i32 length; char* token; OnyxFilePos pos; @@ -86,8 +86,8 @@ typedef struct OnyxTokenizer { bh_arr(OnyxToken) tokens; } OnyxTokenizer; -const char* onyx_get_token_type_name(OnyxTokenType tkn_type); -void onyx_token_null_toggle(OnyxToken tkn); +const char* onyx_get_token_type_name(TokenType tkn_type); +void onyx_token_null_toggle(OnyxToken* tkn); OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer); OnyxTokenizer onyx_tokenizer_create(bh_allocator allocator, bh_file_contents *fc); void onyx_tokenizer_free(OnyxTokenizer* tokenizer); diff --git a/include/onyxparser.h b/include/onyxparser.h index 1adf8287..095797a4 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -6,21 +6,24 @@ #include "onyxlex.h" #include "onyxmsgs.h" -typedef union OnyxAstNode OnyxAstNode; -typedef struct OnyxAstNodeUnaryOp OnyxAstNodeUnaryOp; -typedef struct OnyxAstNodeBinOp OnyxAstNodeBinOp; -typedef struct OnyxAstNodeNumLit OnyxAstNodeNumLit; -typedef struct OnyxAstNodeLocal OnyxAstNodeLocal; -typedef struct OnyxAstNodeScope OnyxAstNodeScope; -typedef struct OnyxAstNodeBlock OnyxAstNodeBlock; -typedef struct OnyxAstNodeIf OnyxAstNodeIf; -typedef struct OnyxAstNodeWhile OnyxAstNodeWhile; -typedef struct OnyxAstNodeParam OnyxAstNodeParam; -typedef struct OnyxAstNodeFunction OnyxAstNodeFunction; -typedef struct OnyxAstNodeForeign OnyxAstNodeForeign; -typedef struct OnyxAstNodeGlobal OnyxAstNodeGlobal; -typedef struct OnyxAstNodeCall OnyxAstNodeCall; -typedef struct OnyxAstNodeUse OnyxAstNodeUse; +typedef struct AstNode AstNode; +typedef struct AstNodeTyped AstNodeTyped; +typedef struct AstNodeUnaryOp AstNodeUnaryOp; +typedef struct AstNodeBinOp AstNodeBinOp; +typedef struct AstNodeAssign AstNodeAssign; +typedef struct AstNodeNumLit AstNodeNumLit; +typedef struct AstNodeLocal AstNodeLocal; +typedef struct AstNodeScope AstNodeScope; +typedef struct AstNodeReturn AstNodeReturn; +typedef struct AstNodeBlock AstNodeBlock; +typedef struct AstNodeIf AstNodeIf; +typedef struct AstNodeWhile AstNodeWhile; +typedef struct AstNodeFunction AstNodeFunction; +typedef struct AstNodeForeign AstNodeForeign; +typedef struct AstNodeGlobal AstNodeGlobal; +typedef struct AstNodeCall AstNodeCall; +typedef struct AstNodeArgument AstNodeArgument; +typedef struct AstNodeUse AstNodeUse; typedef struct OnyxParser { OnyxTokenizer *tokenizer; // NOTE: not used since all tokens are lexed before parsing starts @@ -29,62 +32,62 @@ typedef struct OnyxParser { // NOTE: Identifiers currently is only used to resolve type names // at parse time, since these are the only symbols we know. - bh_table(OnyxAstNode *) identifiers; + bh_table(AstNode *) identifiers; OnyxMessages *msgs; bh_allocator allocator; } OnyxParser; -typedef enum OnyxAstNodeKind { - ONYX_AST_NODE_KIND_ERROR, - ONYX_AST_NODE_KIND_PROGRAM, - ONYX_AST_NODE_KIND_USE, - - ONYX_AST_NODE_KIND_FUNCTION, - ONYX_AST_NODE_KIND_FOREIGN, - ONYX_AST_NODE_KIND_BLOCK, - ONYX_AST_NODE_KIND_SCOPE, - ONYX_AST_NODE_KIND_LOCAL, - ONYX_AST_NODE_KIND_GLOBAL, - ONYX_AST_NODE_KIND_SYMBOL, - - ONYX_AST_NODE_KIND_UNARY_OP, - ONYX_AST_NODE_KIND_BIN_OP, - - ONYX_AST_NODE_KIND_TYPE, - ONYX_AST_NODE_KIND_LITERAL, - ONYX_AST_NODE_KIND_PARAM, - ONYX_AST_NODE_KIND_ARGUMENT, - ONYX_AST_NODE_KIND_CALL, - ONYX_AST_NODE_KIND_ASSIGNMENT, - ONYX_AST_NODE_KIND_RETURN, - - ONYX_AST_NODE_KIND_IF, - ONYX_AST_NODE_KIND_WHILE, - ONYX_AST_NODE_KIND_BREAK, - ONYX_AST_NODE_KIND_CONTINUE, - - ONYX_AST_NODE_KIND_COUNT -} OnyxAstNodeKind; - -typedef enum OnyxTypeInfoKind { - ONYX_TYPE_INFO_KIND_UNKNOWN, - ONYX_TYPE_INFO_KIND_VOID, - ONYX_TYPE_INFO_KIND_BOOL, - - ONYX_TYPE_INFO_KIND_UINT32, - ONYX_TYPE_INFO_KIND_UINT64, - - ONYX_TYPE_INFO_KIND_INT32, - ONYX_TYPE_INFO_KIND_INT64, - - ONYX_TYPE_INFO_KIND_FLOAT32, - ONYX_TYPE_INFO_KIND_FLOAT64, - ONYX_TYPE_INFO_KIND_SOFT_FLOAT, // 64-bits of data but could be treated as 32-bit -} OnyxTypeInfoKind; - -typedef struct OnyxTypeInfo { - OnyxTypeInfoKind kind; +typedef enum AstNodeKind { + AST_NODE_KIND_ERROR, + AST_NODE_KIND_PROGRAM, + AST_NODE_KIND_USE, + + AST_NODE_KIND_FUNCTION, + AST_NODE_KIND_FOREIGN, + AST_NODE_KIND_BLOCK, + AST_NODE_KIND_SCOPE, + AST_NODE_KIND_LOCAL, + AST_NODE_KIND_GLOBAL, + AST_NODE_KIND_SYMBOL, + + AST_NODE_KIND_UNARY_OP, + AST_NODE_KIND_BIN_OP, + + AST_NODE_KIND_TYPE, + AST_NODE_KIND_LITERAL, + AST_NODE_KIND_PARAM, + AST_NODE_KIND_ARGUMENT, + AST_NODE_KIND_CALL, + AST_NODE_KIND_ASSIGNMENT, + AST_NODE_KIND_RETURN, + + AST_NODE_KIND_IF, + AST_NODE_KIND_WHILE, + AST_NODE_KIND_BREAK, + AST_NODE_KIND_CONTINUE, + + AST_NODE_KIND_COUNT +} AstNodeKind; + +typedef enum TypeInfoKind { + TYPE_INFO_KIND_UNKNOWN, + TYPE_INFO_KIND_VOID, + TYPE_INFO_KIND_BOOL, + + TYPE_INFO_KIND_UINT32, + TYPE_INFO_KIND_UINT64, + + TYPE_INFO_KIND_INT32, + TYPE_INFO_KIND_INT64, + + TYPE_INFO_KIND_FLOAT32, + TYPE_INFO_KIND_FLOAT64, + TYPE_INFO_KIND_SOFT_FLOAT, // 64-bits of data but could be treated as 32-bit +} TypeInfoKind; + +typedef struct TypeInfo { + TypeInfoKind kind; u32 size; // in bytes const char* name; u32 is_int : 1; @@ -92,9 +95,9 @@ typedef struct OnyxTypeInfo { u32 is_float : 1; u32 is_bool : 1; u32 is_known : 1; -} OnyxTypeInfo; +} TypeInfo; -extern OnyxTypeInfo builtin_types[]; +extern TypeInfo builtin_types[]; // NOTE: Some of these flags will overlap since there are // only 32-bits of flags to play with @@ -127,196 +130,147 @@ typedef enum OnyxBinaryOp { ONYX_BINARY_OP_GREATER_EQUAL = 10, } OnyxBinaryOp; -struct OnyxAstNodeBinOp { - OnyxAstNodeKind kind; +// NOTE: AstNode and AstNodeTyped need to be EXACTLY the same for +// all arguments existing in AstNode. I do this to avoid a nested +// "inheiritance" where you would have to say node.base.base.next +// for example +struct AstNode { + AstNodeKind kind; u32 flags; OnyxToken *token; - OnyxTypeInfo *type; - OnyxBinaryOp operation; - OnyxAstNode *next; - OnyxAstNode *left; - OnyxAstNode *right; + AstNode *next; }; -struct OnyxAstNodeUnaryOp { - OnyxAstNodeKind kind; +struct AstNodeTyped { + AstNodeKind kind; u32 flags; OnyxToken *token; - OnyxTypeInfo *type; + AstNode *next; + TypeInfo *type; +}; + +struct AstNodeBinOp { + AstNodeTyped base; + + OnyxBinaryOp operation; + + AstNodeTyped *left, *right; +}; + +struct AstNodeUnaryOp { + AstNodeTyped base; + OnyxUnaryOp operation; - OnyxAstNode *next; - OnyxAstNode *left; + + AstNodeTyped *expr; }; -struct OnyxAstNodeNumLit { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; +struct AstNodeAssign { + AstNode base; + + AstNodeTyped* lval; + AstNodeTyped* expr; +}; + +struct AstNodeNumLit { + AstNodeTyped base; + union { i32 i; i64 l; f32 f; f64 d; } value; }; -struct OnyxAstNodeLocal { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; // NOTE: Unused - OnyxAstNode *next; - OnyxAstNodeLocal *prev_local; +struct AstNodeLocal { + AstNodeTyped base; + + AstNodeLocal *prev_local; }; -struct OnyxAstNodeParam { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: Symbol name i.e. 'a', 'b' - OnyxTypeInfo *type; - u64 data; // NOTE: UNUSED - OnyxAstNodeParam *next; - OnyxAstNodeLocal *prev_local; +struct AstNodeReturn { + AstNode base; + + AstNodeTyped* expr; }; -struct OnyxAstNodeScope { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: UNUSED - OnyxTypeInfo *type; // NOTE: UNUSED - u64 data; // NOTE: UNUSED - OnyxAstNodeScope *prev_scope; - OnyxAstNodeLocal *last_local; +struct AstNodeScope { + AstNode base; + + AstNodeScope *prev_scope; + AstNodeLocal *last_local; }; -struct OnyxAstNodeBlock { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *return_type; - u64 data; // NOTE: UNUSED - OnyxAstNode *next; - OnyxAstNode *body; - OnyxAstNodeScope *scope; +struct AstNodeBlock { + AstNode base; + + AstNode *body; + AstNodeScope *scope; }; -struct OnyxAstNodeIf { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: UNUSED - u64 data; // NOTE: UNUSED - OnyxAstNode *false_block; - OnyxAstNode *next; - OnyxAstNode *cond; - OnyxAstNode *true_block; +struct AstNodeIf { + AstNode base; + + AstNodeTyped *cond; + AstNode *true_block; + AstNode *false_block; }; -struct OnyxAstNodeWhile { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: UNUSED - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; - OnyxAstNode *cond; - OnyxAstNodeBlock *body; +struct AstNodeWhile { + AstNode base; + + AstNodeTyped *cond; + AstNodeBlock *body; }; -struct OnyxAstNodeFunction { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // This will point to the symbol token to identify it - OnyxTypeInfo *return_type; - u64 data; - OnyxAstNode *next; - OnyxAstNodeBlock *body; - OnyxAstNodeParam *params; +struct AstNodeFunction { + AstNodeTyped base; + + AstNodeBlock *body; + AstNodeLocal *params; }; -struct OnyxAstNodeForeign { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *mod_token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; - OnyxToken *name_token; - OnyxAstNode *import; +struct AstNodeForeign { + AstNode base; + + OnyxToken *mod_token, *name_token; + AstNode *import; }; -struct OnyxAstNodeGlobal { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode* next; - OnyxAstNode* initial_value; +struct AstNodeGlobal { + AstNodeTyped base; + + AstNodeTyped *initial_value; }; -struct OnyxAstNodeCall { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; // NOTE: The type that the function returns - u64 data; - OnyxAstNode *next; - OnyxAstNode *callee; // NOTE: Function definition node - OnyxAstNode *arguments; // NOTE: Expressions that form the actual param list - // They will be chained down using the "next" property - // unless this becomes used by something else +struct AstNodeCall { + AstNodeTyped base; + + AstNode *callee; // NOTE: Function definition node + AstNodeArgument *arguments; // NOTE: Expressions that form the actual param list + // They will be chained down using the "next" property + // unless this becomes used by something else }; -struct OnyxAstNodeUse { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; - OnyxToken *filename; +struct AstNodeArgument { + AstNodeTyped base; + + AstNodeTyped *value; }; -union OnyxAstNode { - - // Generic node structure for capturing all binary ops and statements - struct { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - u64 data; - OnyxAstNode *next; - OnyxAstNode *left; - OnyxAstNode *right; - }; - - OnyxAstNodeBlock as_block; - OnyxAstNodeParam as_param; - OnyxAstNodeLocal as_local; - OnyxAstNodeScope as_scope; - OnyxAstNodeCall as_call; - OnyxAstNodeNumLit as_numlit; - OnyxAstNodeBinOp as_binop; - OnyxAstNodeUnaryOp as_unaryop; - OnyxAstNodeIf as_if; - OnyxAstNodeWhile as_while; - OnyxAstNodeUse as_use; - OnyxAstNodeFunction as_function; - OnyxAstNodeGlobal as_global; - OnyxAstNodeForeign as_foreign; +struct AstNodeUse { + AstNode base; + + OnyxToken *filename; }; typedef struct OnyxProgram { - bh_arr(OnyxAstNodeUse *) uses; - bh_arr(OnyxAstNodeGlobal *) globals; - bh_arr(OnyxAstNodeFunction *) functions; - bh_arr(OnyxAstNodeForeign *) foreigns; + bh_arr(AstNodeUse *) uses; + bh_arr(AstNodeGlobal *) globals; + bh_arr(AstNodeFunction *) functions; + bh_arr(AstNodeForeign *) foreigns; } OnyxProgram; -const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind); -void* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind); +const char* onyx_ast_node_kind_string(AstNodeKind kind); +void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstNodeKind kind); OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs); void onyx_parser_free(OnyxParser* parser); -OnyxAstNode* onyx_parse(OnyxParser *parser); +AstNode* onyx_parse(OnyxParser *parser); #endif // #ifndef ONYXPARSER_H diff --git a/include/onyxsempass.h b/include/onyxsempass.h index eec02722..2e4b1d22 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -8,7 +8,7 @@ #include "onyxmsgs.h" typedef struct SemPassSymbol { - OnyxAstNode *node; + AstNode *node; struct SemPassSymbol *shadowed; } SemPassSymbol; @@ -19,10 +19,10 @@ typedef struct OnyxSemPassState { OnyxMessages *msgs; // NOTE: Used in symbol resolution phase - OnyxAstNodeScope* curr_scope; + AstNodeScope* curr_scope; // NOTE: Used in type checking phase - OnyxTypeInfo* expected_return_type; + TypeInfo* expected_return_type; bh_table(SemPassSymbol *) symbols; } OnyxSemPassState; diff --git a/include/onyxutils.h b/include/onyxutils.h index 07fa1e82..fa325d8c 100644 --- a/include/onyxutils.h +++ b/include/onyxutils.h @@ -8,4 +8,4 @@ extern bh_allocator global_scratch_allocator; extern bh_managed_heap global_heap; extern bh_allocator global_heap_allocator; -void onyx_ast_print(OnyxAstNode* program, i32 indent); +void onyx_ast_print(AstNode* program, i32 indent); diff --git a/onyx b/onyx index 2f2f2d9b1e3ac8320f2eb21d76a722a2cce8bee4..ead39f24013624edd5a41908db9705c84703eb31 100755 GIT binary patch literal 213672 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�z3)qqzP2gkaeQr;YM!SQkMgy#A8212H9$?3 zukC6IaC~j=Y5^}Q0m|1VO{IKol%{=cOhkNbdnnC$JhlVo@6rZuL`!>9v|O6wYs-=9 zC|}!A;L*OenOeZR%J9n9CU_iQ8;uz8waudd$JchJ7VweMK>6C(ueGm@3GHiB^-;dI zhbWD4J|6plmbO=^qkL_u?8bk)7=blI6okMd1LTe9Gkrs2UxGg z5f4vQqm3hex`ntfw4aWNh@WmLQV~DhMI_XIx+{^QpKb}D*Wx9FXIVv@BZAjjC*mBR zyjF{dbEwgNx}M0=emXvL>-gz-VQD`d5%km1b>;Z!7}tKfLM&VzKOGM}7zaH9a~Wi6 zKOM(r?Wf}{R{QBFjDEV40ln6{EK?nU*@JlcHC*J+Fui9kLOJ;Rs|0Wfd<+J8)@6p7 z%LF`I^2o{z^Z30YU6Of`VyjSWk0C!xIPGSc9$K2~*zC_+QAzJzh3TR7#S$Hxs^Iim z*CV6Doz$t&^w&2@sp5m%h?*@E;5m~z6`K7WoqB}?`AKXXI4ZK2DYhq+PFcd$HquPv zfG2*1L5bAHt1{~ z?eGf+T4!^(=0B1AKGR>jP%=(pKf<5c(xmx)W}d?@n#^a8WM^mjIlHL;4gN>#B%Amq zyI_9;>>=U5yY3@-|q02i1nWNsf>$mo!8N6j5Z6wWqv67Hz#RN3g&ogSyYXD7=BnA~YDC7+YZ z`y({!RKnyk@%}$oa~b*>Z^=1*nLEY*_B>hq1_@xID|PWxR3E4g2`}T65k%2IxRfyL z09=q~o z`gzvQPp^$HD}m+2zK%5zc^#|oiohM9O;`&VMuK=9YeLlPSbZDa7XU4eUHPty=aVNv zJ_`96LLwuH<6Rui!f_OVt!Yo`Yo&@oBtOW6PtOW6PtOW6PtOW6P ztOW6Ptc2otG)=-zbZdWtcso{tcso{tcso`?)Z4M*JG$qh;1s!(kMA5Dhg@x@~CT@zVLE1AzV$9GF7RVevZTp{t@?c2L-NYq5 zhPtH19~E52GPsnF@0parGLresR($UyB7%@a0b(g1-^V=(af@cX4iO@b)rysJFwJB5CAHfJ^^d(510Jb7*%Ki2GKWI5;^ppC~@$*w$KwSUNw( zZ4UPE4X$n_29K?YKeMG5E>_7mxToZ+HZsn_#bEaGPCG+V-J+>$Ge|RN_X3pqJW;`;vG)+8Nm~kAN#ofGeX%<_?%oxL#aWxy+ zQhKJaBF@k*P2~fiW{#g1InK~7O%-1HF3FUQv!P2-XBymi9kY!%gS(b$xcejcINTlZ zdg~k%^uHSJPC)Pf|M)G^Q4VJ3t(1HXOslt2mNDyKZ>3xg#9>a3@|(5J$x*&PQk)#! zfrvagO76qIm2x*IoRg!BA8>N?Vq`ieM=98UGg{j6JRWR^)(-p?3C~WOaZW#ZtkX>b z&l7IG-^BlS#B)6#2Wv=tKM|iK@g34e;JUs@d@9~c5KQ2E1U;W7l08kl9@z6~Dia~Y zO$nae?(Pr}>#g2~et5)N{V#i~n_y7wt^NhJ{GWQOp9GKgRu^G>aJXp$x2=H1IBYd#F__Vo*OCPN70_#@Frw`V5VdCqUd&={UzUbE)`YsCc_20^M zye7~KWROq4tIy89kJ5w>)^~{&huf=^c4@SI^3G4DnJyU!cPb zN)s;?^xbLEb1bFZrKHgb<=fJeFQ>xAK~JeKA^S4&2(PK{UTd4?*{XQxHTB(}Tq}9# zDfI=jpCpg)n)?1^{i1nx_@@f3={5B|mb?%=@~Ji7EId*VOlr)fWk= z=r$#QUQ^$8QB!q7(U+8c9C?J-)c2%CXR+jYO7YOk=zB)kT6#@=&k7AtQ+i5$$r)!; zfbg37Ua2^2Lc0m4r*D_AfpU8KQghm1^&p*|z7MT2NJs%6DRt=d^nD^al5~3dKFMMq zl}=CJr;a)$Y?AgJPNg))bA5le&ehWPDs|}e^nETW2ZPYj=}XI6OCI6$^zE}A(>z}( z9FN76bt&qDD$wcaOAm2sD4m|ZpRDh-fS;8B(cgY`3Zq6$SEOx&OVp z(>KY@b+dGL`c4f#3aN4!nv%p4q`T7>{boL&dNW@l-JQP3oB0yy?({|6or!dJ`XX=U zOQgHgH%q^nFOlv}U+XvX`DVM1N4ZhHN8h3V2daOU@6ory&3C}zP@eeZfS6?Yws<%c zCD&je6R*iju0>3|CNFsoVmW;AbaEwP-9{q@ZVrQ9F|c{XNaGbf-7C5)9!^82^@_p3 zD=y-c?=WSsJjtAMr0@|n%iE4~j+7UfZ>8~xmlQs(X2pyAb}i7xY#Z;+SFgTnx0xA% zc=rM)V=FTf@m@VAV~3(xr!rEnf^5_8Z9V-pTee}SX)oU4=I_8u#oheo()J$;>Ri6- z#ohec(zGkox}iU+%fE%tI=u!9y7&sD+|8dYHPU*XB~WtFjp$XN$#@8(fSHoPcX@Jg zkhueh_Q*@0Q)!sl9r*H2I4RPeSG+x>2;)^HKgTcS?}PkdXG^3*^Sz?!qG-NdYGmEi ziiSFNSNI>7;#A%~$moaiGlb7DFOv<;N9~Nv5bDaK%^AWOcw8n&RjjFu%n~3fi4doE zMrZPt!?(Q{nahDWhZx}=94~}%-Icio2)ddxgxhUu)*i_>HavS@tq zX1=svrC&roLO1924*;u*lJ)1DVB>z1XhI#&vGY+DKhZFfzgwEwTLzjPXfnJ4x}XUnsz=l z#P^;!pBj3aG&S&Z;ZsAeA@012g>mOoL*q%W7L0c?Uwy`4Bl24<80nlk=z{T0AP%!& zyccL^!MG3cHs|6e&4pzmBW=muwnqO@iMEAEMm|BrKJF|S8P^L&@^f3}BS2@tNWti2 z$Vo6^UQep&XG;gm(943JG&6W92ofITu%e_@q%^6fY&?Qwvd&@u`I<$@rv^kZg$ODEUbvegP<0i0%~f9ODYo$&}bw zKHKmd>#|FQekr()kP0$oB~1dQXOK(Dd^A&}lBKr!@DO_jyW&O57zq^W8RBvu51B#z z(we_$J@LS$)YEz3lI;~taz5rj!Zah9!uY-=@kt!{;3hxj@Oxw>yw@EiEOq$>oK|WF^Ex5|j ztbHyB&v#`J#bY-Voj?Z91upj>Bw|b$Z0*_wVpM)#JS=qB;^va%{ReucX4?tML?Te2=vCPQI-hu$HMKQ7G z(D*fg|HwJCX(%{VpF=wecR;zW@6wJcN#`}rp|KYF92%+gIkY?^cn;eC@P; z=5w%a34Ge&6cjAg#yPYMkSQMsKJBoJ(wuW>eK8l6(k_jbwk|$OT646t%cL}6D}35v zDW(XKb7;pwnm&iNfTGnipHy0(L*x5w^*OYaNMISNp84cg3G_L%KWYJ2B}EC?n6yv` z=#N_A9GVc|oI_&*P86O!!>1jdr8MUpT3AcF#ecp~N1a0>k3NUSL`ZsJ@M#AwmG!3` zjz&V(=Psp=I103-=S7l7y*ubc@;GPL=4zg;ibtJY+b((3*|i4pIA_;3Yn~lSQFV6h zF`=kByQT!Fvuj%^zg<{{qB^_wqO5{CySAMI80T}MA87$UD*>Xz{wj=!W>ja__L0XqyGGeb z;-bYmR$L}xD#lMch>ByBVlG~9gWo7;4nDKM!RWu!nS;+Pbc1qH&K#>K(8UjR{~c%7 z`1t~Tc8#BTk>lxXLnT0eub8vP|raJ`F)Y&ze&JL!j zvuiS)6--lS*JL{CGYferH};U)XRPZ#_dNv;&WAaqMoCeQB5P5AgYm!1QH1X)WJ4UD zYQAnJoGv0T?9GpcT+}u zs(T}H;$O_gd_;V>Ha)NSv@ZyWn={p@BQMLu%p7v_w_p*0n8TcmZ`{3=pR!XIG%C{`N9(9c@3>#V`igf5z`X`(|K|u{&b{daV5zBoDIxg7{$jdFVXE zo`T=w>}up3Z|_7|L+wOZ-~`(O*NOHgoiM$#&jD9~eJy^6+4ZR1aQk=o9bxCA#6o); zG#_dIfLe^Q--n)~?eFnhWZwkrN%mimf3kfJa*Ayi^dDoNjQp|oB>axEuSV%5_SyIy zZ_k1~OYP36*97~oD67maL42Y;4Zo+@laMpXJ{`Z4?d9M-)qWY$rr1NkHPwC%noqNb z;di<{7qy;Y4?=vVJs9y>_E1ok+fP7~*>*O5E9`3_v(o+np8Xr@SZjx1jrn$O{MOlC{MOsa_+4Nx#qa6%I&i^z2d)Nt7V6t* z=fH+db}#%cvaf|Ei|zaIyTopUv@`6zpgGfi0>5Y3n^ErBb`tbC$G#V~U22y><}$k+ zzsv0*_&wJih2Qh+YoX5y`(bdcwCAD3RrU(h^nCjsU@x#cqZSw1V?ndpHt~Cry#k_*ezn9v#Lz8uO3vAeIKaX-Rv$vrqthdib{BrwB&|hJXfzDUj zjgWSgU5uO!_PzMsXupjTe`kM*60f#LL0XG_FMhAFPY3<)?ekHWYwgET_f7VD(DOR` zYQ(R%Q=!id_AlVN(H@Wdo9r-jyV<@M*jwzQQSN5@8A!g>z7D0_X2*g4cKd6{yu*$I z<(>9)lya9{kKaGoKY)IV9S=Eo+aI77_t;NB|9kCsfZb|;f#3V=?a<_YyAZq&*s1@I zy*GiAqPqHqyQ=#3RQF8J-0AMwXJC5vVfJB%VNp=Yz2?1M-`(DZsotRtGA3VxK{+y|H5;jfY|uczZbZTU>t&5jEI~ z{?2(BE+d0pqSTH4UQNSA-g#}I=yP!nLbz_nb*>CZaNN;nqn87sER7HN?C1+o&u2$p z%)A5e@Y&Iqvbcm*d`T#JP*yrZ&Mq_}`m#gZ@yQUjj{Z^erF1gmi2kXF)Xi#B^pzsw zckvVBfQ!EBe1dfjqM707>-rtm*@Biw|12v#q3j#cxab>Fu(EH3ent;T!Onh^g~L*C zLJl!R-*k2p+k7C<(ZA?PdBFBh$SC@@=WZJa_16^1gtJGXU!s32BNP|E$gjhy(Z4$` z?!}{cuA}ejtBFR=Nc}?`btwBy$T#{=!&HJnVH7L&22T!aMJ>yji(12ejPCFpwPR&J zj9alo=)X{`9eruV=AeV@*zsV>3FQzr>RQfCfYKAuY&ROS^jjz;xO*PWwDO1`lzZMe zYcb-OMXhishoI58<@|{C4g+stG{@4NI9h4y=|S~!y?VJ9U5uVgm)GPC|SGf_gw3M)yJ^Agi2vr4O^8>OzqRJOL-%4f3cl0+3DYYdj|#N$+&I;;3{ zJi9XSD*JYXRd^*z*Gf1LZL|tMfzrmrLegutqD@fM+Y{}?*+CQ?AXqdPYONaQeSc?wCE_y zISsc;ycaBT{b2ZcsAai2>Xc6aF8mGWsbnjPJ8A#URlF0!oeKZXjl7eIJC)v@@+I&d zR+eTA5_PJ)yU9{0aS?W?WJx0?pH3*l!JYIPaAa+=D)<=5-Nzg1Qe(DXLrD!4${5WW zJJ5J*mR-TeQRmw;OpTnYh-j-5@4@X%3glW`WbHyzvUmjvyo`n>`PzdmDEmzCcv`vy zJ#B4wa`_xP28V-R0l@sCT>KN<#lV9NF`83JS4-;Q$BbD&hYspMrwn@n{zK zE{)3Tu?dG8$8l+zuaQjOimtWZ3FnX@oSX)0H=ygP?u1TRzYk}T`D1=&a9MhZR-dyg#z4i8A9O|o0M;(?NG%aU=%Rh>qF;m+-JD^q_KW4Xb$2*^ z=Y9ipZNS!kvL!X{4!5xe_Wq0n?+#BRSLh5QpL+}w_NK)~JfAZ>@OXCB^KAOZP1F1S z%h2Gq1plnf^C5rJ^pA(D*z|zL$HSw28q!JYd>UQpYWCt)etEIs;Tpd@-|%ql03Mp) z>aDX359yy6+GhprJRie_QNy#stwvR@^;G37(@?&p)2PbXhKjRkb8q@mYVJAy4g7e{ zNgnD?7z&{j5Lfe8%+3uf?npphHJ5rYAMs$Sxx!C?mvBSWol6D0L2pC_3x#T)^(tNE zRZ1^ogFYILQ}+pzUP0aXXtf|5!5=-huF|t^Lvk*Z+q<(Ar@wD_@BY)*5*%>GdXVlkTZh8P2fr&awZOPr4Jh_#$B(#?{xX)uJldl z3hPlrRNVKyj1#_QXnx^4hSE}HD5SzR^k!9 z-cMBg``4X>so;$v-x$EeQhKV-8z%noh@t+U0TT~`iTblHy_6tn7RbbO8qnvR5k3># z;zfCk=O8O@fNw^*^I^bC*dc!F^UfmU+3u$;Kr~+nxHN8SN5EAzj(&W}f4Ue!$u2O2 zwJ(f|6%$Epy%YJg$LqxbuZKa-sQP-RkzSRjhAL8Y=Vv>SRSz4$V#j=2n-ge;fj`?< zH-t#?x-tB!E1%L~)LrdW^j`K8`gjEf`*EOUo$DyBoaTM3_co?VddmhwM0~~rS zz;%U>Ye}f4&J&RjW$^U+c)BUm*+4m>gd^G*M>F<2xZB{A)FND3n=ghWD&@V~W1P_p z(U~k!DfuE}oK8+`Fcz&#ORzcCNf8MIw=PuMN+IPt@zWnPD6dCd{#l!w5x5x9=Q~Yi z0Nl}ADMHP6j^i>ThqneM3r+@T)CqN3QnhZqhbv*qp}&E-G^emuq2mqNdwY%7FLqL# zZ!oN_+4W7S9@1X5bPsu}auQrbbT;krs?_vX2_^TU3aLwco`YYe$8~K9b^EX#ul>3~ zI3{S*zMxHq?Qubyr0WjbbGf7{Lv{}J@l9JM%?w(8?jgF~;0vWQ=q4h5W8l3Omg9!& zr22!F+Fl~L*N$KCfT^|DG2eJWI-b;X>WatBhKsk?)$_#Mz4mmjgfchF})ZF@o0w%)p}9;WFAVd!V%Ku+F0VV830T+Y7Lyyk)3 z?SWPIz<2!8mPHvEL*MZLuJQoVa^UV)cHH1Fub@wImPn5LxfsP*^%m7?gDoR#>V8w7 zc|iQLHopT9Bk2vkq<8d+q&N7I#sup>0A*cm=Mox|%3Doys}Z|EU z&q9Nwg}tF#x*uz;9e?LuQ?=0RF>CWhfHDnRYkPilX63__#ag?Q55ZEs970@cFX6Z; zQ8E{ctjla!<)J5wxC~MvE;oK_FQ!hPV#j~}B}1$((AQ=}1cult_K3i0gxV?gOj4uO zRIV`y&LlWHJ}uwrt%)q}4qaiW}5G>`UsI%$qb%yo7oAt23&FuiPsPl|x4t2ME!BC+O;@=Z!cUo*IYUdfAH}{6> zPTpZ2`(SSq?0AYI*9Sv8)AqRp~G_L)B+pij==mb}hGf z<@79clk8IfqMM0O1|^I0&JcgZ!I!5}W3 zu-}?(I^q7_%JZo|`>nH${$S1~`tyY81gL8xU)Z01fKb1%hH;Nm-UM3vDGV>xb}N47 zRzt8QF#m%A;q6v~QCy$!c57BZSk9;_r73{5htmrDp6oEqeYb-xt ziLKk4rll89FTY|ICFv_3B}d=1L{Gt^jFJBU@~HEer#uiEPpODh`9!1|4`sZH>)LDR zk3V6>pWb2`^a=9?f3~#2m*gjmIwR6Bg8YQhW{9a$62w1YokL)9Bdxi{Z_N^r=J}S| zW#yo9z7_w>?FKzxo6bLL^Q!@s^M{J<`~hN<-*`RWI)mW-V!Oa6G_&T~%?6{dS7~|6 z!5T|(ub=)0tnl;@`aV4c7gQH4cO3arzOqIfD? z=(lG{sOe92!2fQ1?57QTy94xp1^Q-*t={#PRCn~Yh^u+`6klCh+Tgpach8_Xb0w=) zEaV^FusAdQT{_v2F=q}l=`p3aVOeIIhJolwY@Y2qgsEn(6!sm!bdh(oh4S9$$-Cw& z9;+uBjzbJDl$Ff|Dlr9d1*{`-EC^+=B~6N+n6U>)bN)GA^>+;5&uX}0s(_~;u9#H4_HW~)#B*^$0p z8uHJcJJPntTlNOQ0fx!s_i%?t-Cndp&g zWH?x<#FcVAW)%7|!R+vCzOln9%>6G^&G>=b;KQQaUlK20;b9fabv9q&VU@%MhG`B~ zX%6|%W}1Ulmcv(QcxevV%ZOr_=9;6I=8*FVawrE@tXs2BK|#y>TU#J$=>f0yu^)n|4Y{`$|T3b)*+lcy3w&oXt&1>3$Owpx~LpUrAu3#O>-?v`S&j;+h z=&{56ed{H|P9F33t(Qc|g{i3sJgt|6w{nxeZyj{_R?qxvVBcO3T2^*G>`f;|Lk{|0 zGOf>QLT85x2nE;d@YSXHJDY z^E93pUW@Rr4sWc|{LPWeTGDytp#q|@>MSP< zSPG{hnhjfLTl(X~$-|x2QY(5N7)Cq!&^pI*mJm`hYY;N)Cj#ootP#aC^pIIYv(?4x zQP)Cd4NECQ9ho((#uIY4<8A?wS;(xpjyEN<#`=w=%fOjw7cy%GU`A%m0L;j&5zL_i zRGPA}) zW{sFlsDMZ`g;MN$gDAZGPA~-Y)9!LbTKn)tSNSsfQ6wLk^LN( zGD?IBh{r-^4S%b!;J1jUEM(TOVxeT#SXbJ*Chp=8!zjYXe?dPaiCtTCK1v&KSZ4IeR)fT#;t0ZS(i-)ovP3@D7vxsmMu#9*xR z=}z>M__Q>xU_~ba#?ha}ov9-+b!Y0I0WwQJ z44Aks2cB%b6HjyW&vC8w%ecsJ;3-uac zE7Hf|ez8VufGo=!@L8%4<9?ZDs5nf&1+Iqc-MCY(Z@_0-*8{#nTcA~`d+=GMuLoqc zegv3n^yhG0tGjSrr;kP5dd*$e5&AS>ZqW6()2Ls;ohJPSz%=V=5Lk=0fVowV2TYru zj_dZ2Lm|3TopbO!*^TQ$yu#@ZkY&nyg%f=Ma*YW!U9`kad9QF1l?h2^4PN2&HPlJ+ zjTd$93_UK2I*g#)nK|s3P>PoA&JxuPryBXBQ`WysW{o>Lmo&Z18h4KK7P0XKX5-uw z^)6!LR){-S>V(7(yK|HG0kbO}+MQd>f;L>AB%Z4pNw*rdW7lW@XI#3UDLk=Q*)$+XN;*&MQ|?Uxwoeblws9b~O#`vrWUz^> zVmIe3ru#E56p7`OZ6Rt&Wr=;o{XS81@Q8giL8e0~rn1Dop6o`Q@{s)GSxlEPr#vaC zEU|C7e1)c|^X>S{Xmu#XRF>Fxk}F6j#Z;Eqqdo$rqQnwqeD`2d(o$mIcV`9&e&8Ws z8b@rOa9x;Uu6XQ+f(;xn_al~9KA#9A43$aU&!Fco`7IPmg7 zV)?^wB?8F!H>4yDegH4XDR{A_^5hD$-Gs>o|)(cJ(mOmT-QR+YRD zg>q5pSdFMO?cpn+fuC8zBOJzpxNukvpAKopY8^6{b2qJ6Lh@LBHkDZ4i>D#I5BDwo zJAB$Yg*%RBCRC*vX>$3pk=-Z+0Va->>Dt!ttMD#q|$@)=%vm@Z=) zNbF3nT&ByI1`=E1l}mLQ(?DWpd1XHhBzCs*Bfv#mauN|QgP)#8A4J5EBVw9`k`WQZ zZ(TnEsA6VB#PD0!EQE@g5fQ_0UH=3nx0o3bG5pr`(PEj zN8F#uHO&S;6)o2^;)wf4xu!i9kZcTL8~tTce(O3jrfbkqDZU{iGgB-ml;Uq)XJ(b~ z0jFC30JOa5H#6?=Iw`+(otdL=VNE*X%!KENpJUBL8NIR=<<3lc%FW-p&de8&QJ3Os zeP)q3z1Gw|FqK&{oXEz3+MW2ud%E!{FZ#_ab;jX(7+)%qrIMTo4dY8ivLbn;GK?=3 z$#M%bc%Mf!v!Zfe@;&0wEC$3$N!^HRT?QpdapNkUltCVv0!HGg>|cXIIK|YBcwRQ4 zR4B%Kjkq*%rKE1e^PPjZoAY0Fz8=Smvd;ujEvXw?QaAKNY3i}0ZfHr}(2}~LC3Qnf z>V}ro4gF9#_|?B6SuLp>T2eQ(q;BY2fG1Z=>V}ro4K1k~T2eQ38|qf*m+@JtC3Qnf z>V}ro4K1k~T2eQ(q;6zAX zlDeTKbwhs+PdoJi+@Gx_bwf+)hL+R~EvXy&vyj_7EvXxNNhMM@w4`omN!`$rx}ha? zLrdz0medV>B``10lDeTKbwf+)hL+R~EvXw?Qa7}uZfHr}(BA_mXX`S2F4dB{p(S-g zOX`L$1kUAJQa7}uZfHr}(7k}aKuhX|F0Vl9hL+R~EvXw?Qa7}uZfHr}(2}~LC3Qnf z>V}ro4K1k~T2eQ(q;6$RkA zXi44BlDeTEz|(8Aq;BXF0rN?1;qy8zsT*2SH?*W~Xi44BlDeTKbwf+)hL+R~EvXw? zQa7}uZs-%Lkh-CJfbBC{QaAKhYO(OBC3Qnf>V}ro4K1k~T2eQ(q;6V}ro4K1k~T2eQ(q;6j9}7@!vV) z;6#SI@!zW(;VGE45q~Z&YXHpJh(DLh>u{*tjXxXxE+Enu;G^QgQ2d4HQ+QIbEEIn+ zlS^|I=Y--fWpPEW;u2(An6)Fx+K9jG5O;DimHN?gvFY&iMPs^;0_+L{b6Hal%A^x{ALUDj0zml~P|GRTC(MZ-t{9XMx z(Qt|u|A+YKP>NX_@qZeoiW$Piv2tnf6tGqtSsQntRz5Q^Oso+{)`nXE$w=0QmaGje zSsU79Z4?kTj;xJeqhg_CZN!naF%@-+IYEdcYl8^zIv`|i#F4eZ<&1EsfS_??ZRFu$ zp=52uk+pG4P!Cxf1L`4bL+TZAdnS&o4F-{JF+&oR@>$ZM0-}i{YvTmsl&p<7vNm>N zl#`{0II=cm&Qr|LF^;Sa#*Vs}SsQU=ZJdSxsj!$?8*yZ9u+&=2tc^IbHn>PMvzS>M zab#@}<-B5MZN!na@c>F)#mw4>BWr_ilU-8Gtc^IbHi)IW_;Dy#99bLR#j`7mnY9r| z*2WJ}x>iD#II=eOqqMP@SsQU=ZQKnh-Co>IoXFZ>>CWQohy__2ENw1k)8aei?|Ph0-^)79lt|_?!vnpAgG8-p+{WmO96!zN7lx6 z+^QVgjKMfN#RY<>bMO{?;VDVKj5dg?p+Ym6>n9Y0!JsY7`NdK~)O#T53+xnW(sHBfUBg481#8k*( zHG8D91rb?V)@+q{+`n zL}*V=a2|88il-RuDY<{n0XtUJmk2jC^$SS5+=4i60{;?8+YiyFQw6Y1}Z2IxXYTC?=;z#7hw?9@}#TyM)A!#_9p7~hq z3nboXC3$QfXU(pt{Uao8kF)YAc4yPCKNhNcj%|lYo#YW+N{aZiHZKCv`lT!Rw3XM~ ziHo>IHR50^iU+f(x)-8V{Cfdn<)5|r0AL$R*|vjqtmkaP0s9vlQT}WGHiVfx^j15Z zoMl^au75KPp>d;!XPrS4s{B4N{HfS*iWixMn(n2H9*gTTLve9HaWve!q4=1`>CA>k z%Hpy4R0{0vH_r3YQgTh*P$gH`?B^9#md83nBWAL~6-A`?xjX}P0UQMXtj)vVcnpOr zI{Y>@2#PCCz7G(P_BzS%v3tEHZR>457iV|vtCHN0a5lZOu6fzgkbPagbUhBYR`#(k zHp$e4BB|snvF+Qv@|C?UJb~E^x;UD2g5jreMv1w&#%~4R(`SD}ae~En+cloy0eD}b z%8ya$AIvd4-rfsVV|(#Iys{L9jeWLl#5&r;MY)`nulG)cS9nD5y9+_1|EyGr%j}7QiB@AKBgW2F<^Bz-O}42<}vN$N2L7r zx=L{q(>>$3zqfI|caHVDUOSu53)v?r#wO-$RO_#yfz}*1a;!&xtzj7Iz;v~mr!i#X zaTyC#p@=KPQX!gYO>-mryz{P?1+{(?)SBiF^J>-0di^wa6j$hRV4$`JT47ChWk|(I z_1d41iR0Yp>)^}YbWW)HZFoCtoSVxECwes4X8u{5kAYYXXXD(OK{Up>9fN3$A3|fo z02-H)#wb^jXq86;e8``*`RahiD7VwjYiR0g>>0ZnmNMNP1*`6^rtgK2&=OUj>YB+$}u?&kIusqPiHjn8XkS*N{+e*u`J_Jgc@@%tnCgq z^(Prg7GB6SC^iM$+>Y8c@4)K-WF!mlu{E+q_LGds92R)Krk$krXA}?xxx@Q6aMhZR z0oHmnBl63b!RjFgf3F5uAI(S`tTP*5^1$Bmh_~aA@pm(_Nd%c5z*kC6w`4>v;gJXY zoo~K?@6igM%Pkod#7Dz6Y;MVDGHl+{Yt&#%#w6cK*8Ya7v^_(%D`pkrdAAL zYQ+$yRt#n8qdrlOsg*;RTJ1mgn7V8LQ+%_iHQq?7Lm8&l1|!AyF%K|`I^HlvyEdX4 zZ@6+cebrNe@jhESJXv-0lhstRNf~CMxM`M=-4vhAc_Zhuzvg9F6C#EKBh2YO0=?}74lv(B%yLkmEF3i0Lra*QRm-^M6R|Cy&2{UR$5R4uOxX+Z$-*jfQgwNdMi@n;ja;s zd@C}_l;LaGgtsD7Sf;OO{G5k3?cp^&^ll_kCKwUn`Ke4iFwp8!YhI2-p0^DA_MrJU z2kgA;v(shRdD&-YzG3HOpPhMzotF(eIACdr{~?lXhTD4Db z^m!&CXE+$4R6oE@_*q1Thwp_<%RdruaXPp#RDTvJG9A%nX#B#bftFlCXZWzek?G;s z9pHF2!0~XT#KU2v_i&`jbl&`W;q&20yD85zG#>G3ENMK`Lp#qy+m2>^FCu5UI0*?= zH_;mJG(6n@4+FKxGzSWGZJjU8J0miw!{B7vb!ViBJoQWS&d3;Fnue=8Bh$@|`#te~ zwx6vl{%I)r5gpn3QY6X#0b8{^0c-7y$T<@;GQG=KZcQX|rpMw*UVE&~kCDauU}$(; z!vYZ0#MxbIB5hpTXQ&r(4=AYWbgItENMwSC1-0bQ+MJDX$6#3*sqnE(V;`@KjAC8< z6i=x2ews>mBy#V&rrr%f{WF64-Tn3D;7@mC>?;7n;8!EZg1RHen9f=pYJHQYb7~}# z^zeN)!1r)~@6<@S;it>gKQ+>5>d!Y~IwRr@mgm&IM$dUx#2Z|@L#@Zr5zdQ5_P=8g zPYdwB8sMMj;|KgBl+Ub45I{f#+ zxE>~3XnK7_&Xd6NhZ-0L^xF=@)Zep9~fHRWEvDSN%9 z+^dcw9;S$zrrbBQDPJDiln4B#{M>8G1AbHXuM4%UU|V(=PUm=>`YLB_{xLYM`7Kp_ zhZ;s(!5~DL?@%Ksb68*f%1fb?JJd+?bf!_{|1^d`UthhL-MZCKIPZ{%AoQI1f-I&% zQbrbARS|LU$H_=ytEw{HdL=S2X^mUeNMns}e|${4nAS zRN6GTTbg{0YBo(?Vw!wy(B#jXCWor8qlaH-F#q6ngYu~W^IrnY>(nsA@U`o_KI`=v z_WJBfpJDddk2x@{F{*O0hqfy~doiBY!+O`KVZ5X&ieju$O@{q>!u}dH!LUEmu)j87 z|F(fWcA4K}TodIYX7wl8Eh`N5jjtK9zYD1U%A>wQm5{oqsgPfxMwm8U>9_IXA$obq zz&4)C7@^xx8R=0uJ)qJI!J1Zet18nfqlew9&DTSD57Bu_mMJ+aul^I1%R1AbT=c5J z)!!T3#xW?*H2qB0z1~B0e= zzCu?r&!DXFQ1)}$f~SVld8*9FG~o24A)KB(kkju_(MKtXieLVd;dGMuf}$@4+M11+ zGXSKCtDWMOGN7bZqe^f!cbr$}%R!wVvW_gyG^!4NfwG3{#i%pa@P53-PKxU)1 zV};miQNa>%sCqJmSZv6Y{n6kr@yy8D+=lqlkSSJ^0y2WNSe;<>Y@@+i(vP)P&h@8# ziQq?6s?TMJn5$&*^SggAWEKRixte4IYp&5=*p5MxP_mcHHIknvfgP(I>7lPG||FunR1yv*TV^M$RFO}65tG}8qaUEb79}YuS&BDw88jnTX`Yv zg`w&OGXA%)$n)zj8(fP5oZky@{w*xtfb#q_#r5~FFV9f*cOfC`u))#g;W#6}Q3MuE zTMq{~YCcD@hr`t-bem^zzBvG=ZUVro2Isp6hw^oLfb-RGh1XVtrF9J?oRC(`L=;N5HPNKP;wy`Adf4{($f! zsBDD1KRnzBWTv6KKU{ApPc=%rKRk*4NG6t|wfn=fP5g0xZ_Q#F@&54XM8_3K!^{(5 ziS}tbOR0iC^_k;N0_#?Pl^U?mFjwp`wkhSzC&Z&+F^|_?G}JND$)B}(Yrw>#;VRFJrK=td zPhvU?rm@EDJsLj2czIayTO28O7?jN(%0~i}&N#naJHjJ8Ev)$}m2O9P(nkd6e1mgG zSX?Q(xAwc#urG%DEpQ||_8vnc!=r(v36Jd=0gZdY)gIdh=RM)EhR-FT>Tj^=TMUk; zUodsShlk^{0gf%<4UT!W>&V8oaKi9?VW{mJ)P?m1=kXrSn**Hx3~;Uw zH~Bc}f>32T(|x$A^X(BRZ}8iCPOZ?qI_%9Q*=5w5uCU^{h-uFo6^BEbb>XJ?jz1HUF&5-vr?rS@`ils1-Z` z!YWK^gjUo@*nqO}9W!e_EneL(Pp#R^kOE}ze?#?N}Jt@N5-yOez2@1#$W3f){? z;enZm%k0j!?bM>%P0t+ut*O)BGdHqT67}BhG9MFpjc0n*mU`8=h<&mXWs)P55J$t`_5dF80BV0t zpS8rtiERhLd6th8doK~MD+c0R>f@XTJjf29`urEQaja3FH-2gG_p8s3(13b2daN_v zG#Yk&12wM2iS&BlzM|r7TT?yo7N^mZQRDR!&E_fh;*F<@c*F@Rqo98uyvgb8X9_%%7 zBk-Ei@tJJL!gHi>*ig94qtM?EuX_{@+ogjj9JVV5Q8;Y3coag_chDugZZOt+7^!yrvo;@l ztZDV@cBPL|hO*b~MuP#f1zO4L_P7A!W3;0`8H_If`{R{07G~hc#>U&db{2WjO*o?K)vm4i_JH$=Bl?Rnw^PxwM!UG zjxg!MoOWWdpur?0Bh2Qyc!MoR^5E!06IRf0PLUs8R37<-0r~kL-|&|vLip>l4Yd^F zDI@L!5SE3Sg_-%@bhJA(;l~uwT$!Og`3r*x732?#fxtKMLcI2CZuMT=!do~dc4Gs0 z?kH30o(QFzJIxf%33a?mE1WI3zU<+u3UKWwF2K(o;h_q3Tuxce5cstoJc2*@vo?pO z8~7P@KKz6T1vO3JKjOhx2Jo#O{Itpd{#%s9g!tD0Q|7^s3*avSe8b;pQxjyR4w9d^ z6kck=IKp$EZc;VrjS+hOD@I@h@@H*kTgLce0bH(CosHK)WS3;;T8Rt|!?mlBqBI$| z;G*+GPWFV%iJ9XwXC-m?)qCRN1Z)m~;7R$#M;SFCez~aN_E(68Ehl?&CPBxe?1Q2R`CTnUB0>xQLLgacp%ME1C z;d#IjpC>KL&`hO4vjunZMhzfh7vfZVvo)ni8V)42MHI}`!rP85BE15f{iR3*J%I~R zn*@RzML}(djSU=Bzu2oUB4zy&+z1%t4g6y4;2UMJfIlAn8;_3{~GsU#F^$Ox4qyYEN&D#8FMZhSrjoS;H%Z*o@V0)HG9O7aC-C_-bYVq28}~)3QMnpO{jTb?LqBt8TiDPtVgqT;IlzC)po=u z|JP>dP5)(^@zhm3qA`~tE_6_bz1M-hw=X=)peG${SH5l!^r3;84|Ui7w>$r>?i?)7 zL4Ai8cMR^3;!Nu!NUp*tIJB$$z6*Rs89{^54`bi^c6)ih`$-RV1n)Q8k%vmpJq1H^ z6`As#m+$aIO9nZEnj>=Z{|oIIIF3nhHPrZ1{t%nzkDU2O9ytp*ax#_*40fn1kdbDP zI{B_3(2H!BAGhYF~;` zUy89H4wfhw@7*vQm>4+A56k0&8ai z;td$B83RiF(fR*&aRi75yY-CZ=eyNd@R95UXT?k-IZnxmA(Wll6~kjwDegLFwVKQX%DPdJ2wDH7_7 zfAky3UdF)tzH@30yn!?bjH!ozW6-3OvaI$LN<>FsZ?=Ku=7F^a4HR|#`iNJli9QC^ zG3gk{nD1dc)kczXzn^b3AxP5^$9wYDJk-Uscr6PoqjjkE51L8%#654=K9JCWXa5Jh zRt<1Q{oy9&4>y^^W^_$qRft_iL zX!u|wDj#fwX=76r9wVX^h&uIgcH4DJz{bmXT% z23E7dr4w3DqqqK!1yQ^r9BU=aNwIibxniN~93i;Kc^7yqyfqK~KR2TEBPo2)M z9(6pwI@C0Nxe1k;trDx%uuUr2r&8-xdY{S%w)JXapK9$>vzDpCWvXa{(r&lPTCH%X zb3&^sU8O7+hc#POa)TPyr;0bKSch_#6GzTQRo0=hHYuFC9zFSam3dI%4d`Ge@;oWp zbqQ4;aVM(beJZO%Wo}WE_^?yW<5!<*GhgvVs%VwU2D;g*e3i=UQ>C+2Zl9`}t;Y1J zhCVfYnM!u4#2i)Kr`$f3yFf)(spMi6MX^H(!9F#{AgeMI(){XBMe9|rJ4uzTQVF1+ zqvAujD<*duk2=(_6IFems_s;+9V*$OqLY+bWRFPx&;GB9?GbsZpi@O5@+~U9UgfM; zx<$nouzmefZiu)ORJu>;4wbV-on~Zk0>3=Lbf}RmK?jo8sN7W)U={?}Ndd;!uUF9x zgAwMS=tSJfBv!JJy#dr^vlpyZ@v8?zmPVY_KtlO;D9vYmD(b{{4u;C~@#XTOlOO9< zl3(D(d<|dBuJ3Q?Drx9!JRH!_S~j#98q(>t^;kadRI~Wir^cF+m`jH$oJ-A%cT)NE zY!x4ZD>vd!QOQ+G;e7xDXhfVldfmQBNB`$cDHjBf;nQ~6w(v51D7nOIL2>PNseFD# z>@_JhoL7BnnE7JK>XMS>5|JH&IJ0mOj`SeS72lI0&#O}+PvMmj_NnA}HGHm0eq5EEtdh>!KBb&2;;?Iy%CaXW)hPFeO6^hBA=NrrWs~4TrmGGq z#nLj^x*dl9J10hu_!W4df6pUca@M6Q&%N~jF{el;d(q0}bgiDh^aupyRXyij=sgZW z#iRDkBgKJ+oG0Ny%h#*IK9#v%72tD^qORD@>O_9^sRUcT+Xxs z-mBbYD!Kqj=H#oaHOiW;j_Fpz_o!04I;o1?1e)QtD79A&e^X_`Qa*vvA)$uPrd!lq zD(e?2F@7q8#$+cVa zRLvfhdq@?!NtL_)bXB)UwH#J;Bwx8pmF`tlJu20qnq~u{4G^mCbTz^SO+u9HRkavZ znpNonmA77vSgh)KyA~`~uHUOF_NapOd{)W3>D{VugONgys-b9>u_432{6qBkh0SXC z&ECb-(^b(r;Mt&xu2kiAbAifxNDXr?*sVtNse)!z^{;1I^-pfYBuT&|!IbY?hQ6(5(n%O1QdqEh;hV5Rjigqat z>0M3fjqX+rc56zttWvG3)reJURz4jsFz@}$ zs#1kpReX=Cg7UB-s2eRydh#h1H~V*9FYdY9WrWxJM2uU5?&oL{&BDI ziap|;;KCTcz^&6_5%5U#(4o+mdCq+FOumy1wRft@r7zsQRO@0lrD_kU;=`~bG!!w5 zyGNDnQki?%k!0iS=437=S9+eOCF1goxI?vQ!Y$Py)UoeVIo>4R`P;Ib5QSniGRAZmm++J09i0W4RmMZF1 zZF68Tc0;}@Kcs55DKtb(88!|>X}U+XQb2XEd_;nKRT)b)Fw{d}1R%Rqe66&30lgU* z6vZiH1hGNoZ17r%SF>l~2WQ9~e8WC9{3ez4uyjZ3V=DTB%0{3j?xliulG=?ySd}fJ zIL&qLB1D_bs=`4m_ui)iA@dihl>3HCqJF0;0UN-S-}at+ZO)kpm8cWRtrB-OtJc$1 zd>wq}2H3XUT&SW@5!0Dt+?&uJY_HU6oa5r?N#_8tx+2!_yFi7k6f zqY;_TzE?G&{TNszAm1$(45dvha4y5}A}XbvOlT_bKuOwKRn8t&bT7O&;$0&-b(4z0 z|GT?YbT)cvdKX-u=+!o1F3?ptrsQ@+bD3AGP;bcFD&8`-y)Qg+~{#Iqm@>c1{w@Y zDV2Xn(Se4pT0CQ$=r9s#1Dmff|3IDmL@8S#3s#72IG6 zW@lM9QTAuG+KmaNUQ#)BeM)8SQe`c0M~74t>g>Wg=c~+RD*sIQH^xYqb*)!f_nMfo zA&434C#%9ez<};HW{?LncvHey&O-O8HtzyiwHAAtoxa}&;5-v+XrtS<0m+lVbE zAe?hT-}|@Y%$4U}bjevOSN=B!nm)xNN1mL!f9VtxdFI<436+nL-ig^OEJooldwW_^ zjdUOXfDizZGXX#qG;c(YO!_uZoC5=e_l~2Ss9_vEDM{5T=~Shwm0qSwH?3DGj0u}Q z96@QsJ`tYz=zxnO_9^)UmWkFfHJSMP%oMy+jYf0_gRm(5b zT*%R?eZ3lwxqYW9UQZ(^zFHMvgh4=!1&E_yx+Y@J#YF0;flm?Ok(*R$pDH^F{3Asu zM+r;`Vv_EB6r-DyWGs3r=IS{?l%y%7oifw1*YP^ig-^%K6kT>{1cniD+8$HK(&%8G zZ~_?X)SLlVEl*5QR;5_aC&RQJo=W`pW@#%gy9nuD|5L^jQZr#KFE8@uX?Ye~+;UhY z@D`N(T`J0P@C_~j728$tU01{N)TKB#f;)kmqRZ@5*@*KIQXvXIq>h_R3~;oJ4{}y> zi72|jZcZuXzRBmE@;r7}@D`k?qP?mBl7&Al;M}Y1JgKNws|2P*s}x2!M0f>#>lG$- z6H#}s^x0#o2DyZs@hRYE2e!yUi{mz#Ni_W2TA7ka9Bi#uCt~0`q+)Lh-89GE1F9Ge z+{5{~T?f~22wJnYX8=QmWXL*Q&628IcSGX}4gtefGg0kPu>jc)U=Dq5jSU8>T2<+WiL=u+`jW71fxxg7J}IyHB)I^__< zOBdRgSfv^ePh*1huCl7sOpL|g0+x=ow>|~B(lievtU(Y^|i zWi!1J%GoIARC<8rSPg7e2GIJWDy-)OHUPB_s_aH(Rj4^0g%_~?xLh4Kg)`GSdsI?g zh=8$f>yf@zsSEgQl{}lbN}brL>N?eB&-=HEWO9BMCg)fbjAIl7^e}Wx-)dF7N2T_t zylwopw89gYA=nwwe&WLO0OS{iqdcpskKROxyD2@~; z{y8~Vct6CINQiCZVvbVL8LD84Dl->zm#_39E}sv>bi=H$_b)?EU~hJ+k@pX+ zUM7BLNZpYqzAu>K^r)L;xK!K2CGng-IvK2gCc9M;R_{Ai3+xF-znIJT@foV*1eKPH zG}gPXB%@ZPn%hdxLM7e=Z`ZAgrDj&28hs1bJxWht{EW(_bL3(s)IUxam2fVDLCNxc z#R))%NT$6|9WNd=2WCMzb*h4gJgKx}-K33VBoOSv>_jYwOP!bt(~iLiEGmI3cv4g? zen`O|L}%Kls@enu&IZ$pJd6X&)Hp0s_o}if^63jNZ_&_4CH|wzMPvz6PE27jl4N3a z851Ey{}a%LK2>{$iho?yp2!Jd2inuC(o^_}1yzWu9_|-?I-4ER7nL<5lYk-2TX&p`bLVTUVe^SNG5b=k;(UE&j3^{SkILlp%h#8X-?}H(@bmxte6| zZdl~D;D6PGcK50xX={1UB5?_T@3;%ZnqaG%(A)GKk!}~mXDW{Od-gumu-ZI z+Z=I!nRezjJ4GE%w8P273mI!T;K6i^k`hmYg>3*fenCXuYQH}yF81O#u z3sb@hHE*)YM8MSoRc%q34=QV|noXw<_KV!K*MtdBm|j&b;w$&XCq5NpC;5qBynq|+ zQS(~8k)cS&Jv6_Z98zTp7tu(t6%pLwuwgrw8uyGqxrv%a+g{lID9B4k& zJ!7yqDmd_ZlPvfD9ebBf=+|(2M;S=Umgt4&o!zp0>C%?9nK9OPek{Z^f#$ zP0LrTYH4e2ZfkB0wn>LUdSTz3X%# zJQk8NiRzS@7WQ>>7jkDWz6%~QiA92&R03WKD+CB)`qUCpwobbZey7i_!c5<}92)sm zE&*!U1F<%#<6Bi8HUe^?=hhxO16}?_nT6j2sT^hZ59v;``EoS<$u04ry*6|QoL%^V z+dHl3#xpLLUJN-|7J7-^9l|nGWNdKbI0>=ny%>F4YRg8^afrZb6_rn&_+y&}1 zEJz@N>fpeU*9m=R0~ zLE}dXdxhJKTt5i15KX4=`xg*AoeMNY`e{2Qf2=eV>LpEVBI8??d~IuY-dNY+6w1IE z>u};7(>a7zbU1lXP$#z>*89Xdw;YQJ^=}{!yVfd~KzlvT=sTfr{oB^M=B$+${Wr$g zLhi_`Wn*E;{?EHRDN9w`V^gXOn=!HrQniP>4a2ahf-Mmg%2`mg@`>xpJ$O=ue-*gc zgB?pg3%+qh0KtWg4qzleb#OaPd|q9Fd(RC#?*CJ10D}j7`G}>0+y@~tanvxf$s;`B ziWrF$Op?a?Jllgk*x+vy{#4B-Rp(zc$%S>38i!duVuqb&O%|&oaAz>Z*$lrpNFnyd znUDTLHjZ(8&~xrSFHjdbIn4;cGi8Eb1+(js6)E6zFg`N;aa@jZh<+k#<(qckZE3!D zrIJS)uu^#%Rzr8GbKSi_UG;)N`k|Fg)iY8O-#BKP`tK4au3eEg)J2h}F#9$vMCT}X zm2g46?H+t!QfUUUqANKM0X=cp=aR)=dSg8@ z*$)8=84RK$mz${(Dt?HR$fL0oPC-Fmdb=O@k*L>wFm)BV+@15`ln2--Dbq~Ohne`j zuRa`wVf~Ev9C3J$Kkxvhtw-H`r~ONKKct@x2gezdAE*%?r00I#>-^l=MWt%u$C*>{+Iuia42SHU2HcO|e372t~8k_Yv zZ~~9$8Fwj6(>t%!h5aNJ#)AmVeo&!fwQB28Ma|0P{-AgvEcv*xR zP}Ml9g8Az(tc#?&IFjMyRV88^Y<)_xc@>v0tCtTbZsZxC{-+4`7k#LF4VNe5*xMo* z4~H%0hJ5aBg?*DU7l)vT;XyU$a;{Y6!De#hXwnDjwAXUX(5I@A7#x03TA!}&*~zy=>Lgg9GeeoeU_Q(3z? zHRV29Hcr7{Nu9%PaBVqjqfYCuNmJ5 zYgnM>yn#K2gqndfgd4Hzc@u+tRi5Dri zLY4eTrLggGqDrk((UXn_9bhmZCGCqWY#U$P#dAzJ0(H_R#-^zkRms!;7DD@?A{8A` zfr-OYYTiwD8?r=rcBRlh#-juvH=0tdDb*%L zBg1yB8Og);lU5R^*-wZ-0@woOS(jkfGPzt;>{N3OsIzyf_%FEj(*eD~(kIr4@T_X5 zI`M!yN1l!DP?P1EXpp-|=1;cM<9ezDRtBH1h&VZqi3Vd4ou^4N(2@N5g`9rNfE}=e z2`<0hcmESnKCJ*a=J6}Q(aO@%;<(k&`mnv$e`PUWjY2@Q=MevR;Ne`Sw8Pz~a$bb1 zgXzNTxevxIj^zyFVsKM4RO(tDc9`idgjObAP&r!(4CB@KSJXqlag4k04Tgm{WmxCt zsnjw+%*NAlT);0tbl6yI)qxUhx6eB6B|S8xR?1 z&ZUtB%xK7Qza#V)Vk)cm9tlT{dmr~cy}?N);b!(N2^VG?9k$m3ykWF>1iR#bOx80n zH)RROA5Hh3iqa7e;f#pfs<4&CW)5Pcb6{hHk)4AW@$xo~%t;H*8enIr#mES+xi_2{ zmYUv&72LKXw|Hv3R#vusj_G54)X*oXTLAY9HF6c`;eK_h>3pAFVGoW zr~qQF&)5;W76*{!3P&**hv8^CMQKkm=ge@{T8bT_0XBqARk4k6+MWtn&gD?t5l$3- z-s|rTKu5*fLd~CL`g@yC6z7V}kOd%4O@I!IYuc{FQC6c=Rxj6Xpz&1q681POuLx}O zTf;#atC;91Qt4fkXDK4QKGlS^Ypmb(U#wF(XVMrjmM-Mb)Fzw$QFj3(@o(Si=Rq1b z;-FH?5Q(JJC@0fy!#nQbPQ|+0VW7eFLT35JafB8|iVOpHJ-CvKt+WAG#avjOEp$zHb&`?2fJd`4A+*^Z)I6HI=_I9$a6LjV70OJYScyK_aU~vST^83 zoa~6mO@3z&GH%-X^Gdzw9)SN_&EvxUe`+FJn(9!sV73#7p6mi_l(izs)d}S@Npxt^ zX#e)uk<&;2)!oyOWQu|kx5lt^kMvSM(-fO$gELLd4YO~GP0tV9HyyO|=ArlYOTALC z59gKpPrrIM{Jbl#=q>i66jF6q-S^*)=!~{h*3Urw1}s|cW0=ON z1?Cw%hhp!N~;E;s#t;Oam3y1m{5n4jfMrs`j3am|aehPe1cn~bruad|ei>HEWwaUk7 z@|~Q@BBLd5C8wIO5S-1Hb2K>SN`#oYE*6GIINwArNR~_Xcd2POXkjzZf{NOeNrhCP zES4>t^FA3y%eYmZRUzA>6_b#CCQ$)LjER-CYHNqL3*d!yImcRK|0p z=N&7fcR*SsJ|kTi=pgw?lO>b*el-#Yp6m)l6zhcx&Q;#SMizEMrrC>QXL<;c`Ywxu*Mc6DdnJ7`@vtd6!vsV>fPAD9pMhytE-4|qIHxwH~^#;h%sldE%xU;m2 zhj9{EmBSo-p(@SO~!18vL zRm<#xkBkzg^TBT(_(f7l2@b-<47)?Qvh-Re?!3JmI0mZB;ahIBIq&XYw^Gc^naJiX&ri@TUGWN zF36aHcp3nZ8po^>B%s2VU`m0j1t5*l5Ua+McvuF@uSiG?J}1icz)xL;^#&YRIgk5A zXm1M1WHQj7)+%ceNSVWH0~V;WTcHfQ;FXZ^1Nm5(d$00O-r>aufH=Pu>l#taWpI!M zP&hM~(+$0HF|Y2g!NCM|v*3GpwE%O>Ga{?e?gaouBz9!ft!*aez_J!FL!;~5g$O4R zfbtI9>uf}!UR)Buq>ltcHP68c&mk3uT0wgzF;^=KfuMz%vB=TCPRj^`V>#*&vv~Lk z;{mBtFtX9_A$KwVN?6vhM8}mJG%Uw%N+JG2S^?tC^$_g=CWxduRXOs!C!0po=`PsD zEOCXo8E{gR%p2o_u@D(7G9Rtttp%#qDQvbE0M@Nkne5Um_eJVho4Wz=+>0o32w9FO zf8mk9Mh^iSH55#y{HxSt^L-5)SQfC|xXC6XIGDL|HnDZ}x4BsuQrZ~z)1;I>$ zOPlx-)9x@Qx|$^y6%juMcF>s9YS$!G_KPZ$2l~@$1OpIntjF911y0L2s)xH}%NLug zS<7(@2|0c7Evgs`Xz%}-i^at?P+Da0IhR1|bDaNG+?R*RSyuUe>7qh5LXr+7>LtC9Md3@Os=8BjcU4+ju1x&9TzTg9c6GC zP;qx2pHWf4nZc_d;LLym4tf>u@0{~{zpbmi-uut3=Six*-*?{ayyu+vyvupJ{UOnx z_T4CH1v+XGg0}MD^q)`#aYs-EtIY!Nrwd}*3XEo$+`5V(G?uKgIB%xFwKf8l@VS{}^g06Yx@+2OVc=pgon;XE|cr(x+7d*`SZj!(8-vKCQp*)^A^ zj|a&_`ZSb*M_C1JeE~_pV)%fv&x6D~J(~ojwk_ ziulshFlIifO*nxAZBO+gbQAVHg|oCcxQV{soIW5t;J9RHek3r`wBV8 zfmM;UFgSRF&5{eT0E}f7gri`Je06&H9qK3I@4|?^ zE_kxJBk3y+OPu!#)K9&09DhE7-3qL3f)&q;XN9BJ@E37f5#hJ8cMxyz%h+I)*rA!ijNA`rm+#11r-L63%uG zRwY3!+3yh{!1Nh1uw8OMr09|+{EbOj!#opiRcAWgmtKEf`W5gKk-jb$GQg)#zdyb9 z;q)2WA?snO&a#fgc@S*RLgE51L`@T-;lQ0XoEQ^kiHD5kQ{1ocDhcN3gY5^?0WSKQ z-Q9ZhGKee2Xoa(uYWjw zHC97ZQU+7&#<8o4*#H)3Bs4{Ko`O9m45wJcSo~P}MCdBGgis_Dg&hGYA9oGOG$;s$ z0=wR%ql{xcw|Xq$N+g1O{Y;uJYo~2(8&2}cbpRX7O+{}J2W@b=aq4*0(GI`|^EA4AVq zB7}Se3>N}_adPq4YU6Cp=kZq-9dWP@G7x%6qe zXYi8k61jQaWofKWtR}g_Em_>=R2`?0p-#FoplYet4 zbz6EdHcec$(-_iHC0Ljhsng)WqMcVj_*O#QtmRALAV-48F}s1sv=pno*4ACJ*|ZAh z5D}w~R`w_>waRdzw6QDpN*`ST2XMhWkNnX*bvFwUr^qmM2#vvRS85q{KIG1TXdj(| znuZ+&&u{5Xv(egO**Q^LEP7$6I0m;crIz7l542s@Zx>^;6L$@z4jh&;H|hq{v8g#6 z%*M1Vb94WfA;~ z+qSH9VyNZ@a{(cSiGNRe>rEnZ>tr(rUpJ=P^RoGi+0(judc}v}WWgiZxL+(2R7Ry2 zZU77v1`#Zt!C0xT!+k@n9*%KiEN#c?BW_A*$3Zc8gZQ(=%W?b)I(zKL#42E2lG~u? zN*!#q0aaO!Gr$nG*K0g2{Ft?v(;^LSXL^HN!h~y@a5(qa`&bcpDaa9i{|Xqd-RaG# zWe7J%1KQEym`v%^{|tC%xHtfQ{%0k!XDOzk#v|KaTjOM3ICZ(XHgm#M9EF9~iy+x! z&;U4$>PgUF#dHFvNnn&$d3HUX$UPvOFOZlvx;Y_2rowlSqu&NWBVkE6INk zW(1cmJ`kmW1F>kyUFi+TBmE7bvAddhg%hM081}a=YCoziy(jfttto5I>t%CndD|7> z+}iXBUx(&kf{9IF#H*rWr()a#u-bsrXVYizN}sh2XBIlrr^;fAy^@=5aE}w85Yu(? z&z)Gxvi^c6C`B0C7N=@$1#OZ{DHo@XL*DA)Uy9)m{fPaa;uR2&b&sc)-Y&8TTX-7w z_R=y7fcOUB2>@5LT?#M%v*}l34HRbbF>JA8`XFNt{IV1N1|5Nc7V}lOPwPGqCOrub zWEy_c=hMsDa_yGrL~;1nq2pWu@Ge$jEf)%bz}?k|O^{p>IixMrO$_mZ5a*2l7cUV& zmxHicv#0%4c>4cMD^<8?$#>JM&VtmI#lD>Saa?b6ZTgiM68q9?u1ue-KbE##pbKgL zho*5UDs^4k9_c;oec}I zb}g=5l1Y%P*PJd9(&;5%h(I0gCFHd2701E)s=_T6ZZEuL&E>M4y0OwK0CdsfZ=^4| z3zED1=jm%UrZ+qU;XfctHdtgj25sAhunb%PghF7NbhQ+XS(lRQs+=&&-683=esR+! z)LYt`UiZQ9eFxt6K9ugjaM|{iHgV9QX{5XGI;BJTl4veWBvYCd!V1+4nf_n6_%5ge zc0|Qzz`rv@DKM|qi=5JsQye%y3t#QJoRM0F5%PFU6igN>});K^f@$MP7Q6toUL z^ad=YUU}k@?VDt#u_?XkcDpzQK@8H`C3hf@E430{_J+shN+GSs*BAe+Z8`P{MhCZN z2mI09Ls`Fju)jY$FzPjHljW+f>+B^j@_u`E_s+rL9=~fio7oV1c$Q2-BMn$FjFX2nun6_dj>~6-$#7T1?T(C!~PE1Udqol*RzOAEvW_WmTXN0*YeTjExMxFf~;x7MiuXUnn*! zwW>c}FUN9mEze5R`Ub{2x;I_iVew=g=T0|gtL4il%GGkcQp97SUfh2<0?^Lgd|}7A z6Vb{DC%Q5Neeuua$ zn=WtMS1(sfh3dvq`M}2FM%gNgQo9=GdRuiuqZR2G_}`qYO8+IhQ~PXRp*T4^6HS>N z=K@Dw4#X-U4-vVTsn?1gcFwd7cDL$y1%IBbFddT&_33WVK(mLp3T5v?*2tCyOea(S%Oh(5l>gS<-?i9bxAt`ZO#%CKE1a z)#K6Ov8;#a$+BOao!$q2x3C1+T|~{9D_!;ARQVW>^5y~)dBsv0jP5%nHmk) zql|U)M7c>lmt96b$#EdCICq(rUCXl6Ky8M{p`inXcP>8iB~f@H0V$$Fr#A{S=d zrYcQHh(A}Ww=~GGtz*LjqzxF*iP^U_%eHNxg8|_#RF&*n3RYvwgWrk|8#!8W5=p=v9C{(K2ELWQi&$=ThE+N4# z_wK=gQOHhAjNLo2*03$5+U&mgppeh@x-lWrb1qr$;BYqAHxPEcvaHoGftzYXYa@9$ z4H_8h&kpChJsm{R$20y^`9OI}S_iqRHhtW4v#&PgK`i}&!Je$YJtuam8-1U^Ty6H% zYEyo-Rzh(yR_6wK2Q5)=elRn-`9iN=t3g}`cJK20!Ou)z)&_N&Zy$^ndmk?l+|d+W zxq-~^Zhvsd?;q?LlaW=Ws8SuTS(&!!-XeSOzc-)jMj!O~efhyI4F1Uq<_4sC$#PWT z=T}#Tw)|BX@@DGg1HKH)U{a$wfQE0cR7>vn!0dD$I#Df8UDy8A4g^Q zKo^vfwXsnaClqFwa~0oCrtfS)VcuG4-I1QiuW(rcft9t$lhALj8WQ~+b_DJ#=+ZHsrnEwJQ&j& z&FLmVtC8@aH=pVA&0J@DTyCP+C9heZE&KblExtblTQa&ksIKoPIFK0`fo`aqnCMZ} zVlkKfxE`9;!~P{SXT*qhV&ld7In3uGr~c&yD$`1OtXBjnczkiZtbvHc~ekxT(x7yoJONr z$(F`#Jk_fk&1g}pv4P?2$YB1eEX)&K#`1X68?V&SqbByuV5C^XIKhWL-I#& zTN)#g`=sz+HJIx$2C7s~p=f71XB$-f2*(;~1^vqS0xkB$ad0}fpsCb~j6*j4QhD4p zXt>;*t#jNCgn1Gs$;Y42g(j;Gqw&2{g$Y!n+&lowl~85ztCVhxs!nG0QV+a(WnzER z!{FSc>4V=n5m=T$kJUhGF9#4510K$NdkU4$c8{X-@BE|(fU&P`R|jMS=_ ze_`sRVm&`S2Q>6IT53Wp5=n8M$3j!Ygq~40)uLO%xPsY?1%^?^I5%X9&k-l1m!r9f zPb$+b9|Bgc%NP+GNLAaD+#lmaW_}|>qn4<74f^T_yjK zUJ%P1ydq|6UK}g{yb$pmJUOc9Y0(%8U;$>!Ef_F15NM^kj>$@3;M?v^*POnwI`9wR z9H>NU-$QLVrnV@;jaj}aO(1y~>a0J^6pUJ={)z7G$z7GhWWEB?YF5T8<$7|A z#t5DF3U%PB-3=WA$_H_68YV2$Gni1#(?auS93$1KgX&LKYjag=NGM&Io*sjOJ{!pP zVbI1TQJkn*Oo;Xl^LKTYRwbsam1Q^y74@=8I~gpUm`x${zMR zMm`MtQiFuaSMMDD+r9#%hqZIoKdiT3s$ufP*E_|xOXf3XUbJegud@!TOjv~`)~uu_ z;gU*UBr_Np#GFTK6Oo}{5eyu0GcB(!BbVN71jn)ofp_j293HhOAePw}g~$9Mbb&Wl zn3{xW$&46okT?SvU#1E(uy6X<@MKUGE;U3B4?vutC9jz+LrYYyd6ZX&$dU5&5U$Z3 z5!J$6uu!Va!B;iWDwli~F4d#wg*@Q}Te2(p?M zQzu_7Wo2AbDASk`-6G7JwZ`bq3OFkrRj-w1F)$F10MbQ1G#h=!;#~i@=TN#x5Q?m) zoW`^k{piT8Q(Q^)@^meHXHz+5BOZrK1ZRzCP@0dmg-X?HpgRvuW9p#FEM2XaF^1-f zbm;AA2oe+mbFh%i7#TiC>K=luatH*Kh~$JSf=*c;5?XJD&n6Zyh7gBSJkgx^5#`vokdqikm~SO*WC zUx%5U!}|$GgL~MDu9ETk%)p6mD)*!T_D%*k!?F4@U8rJKS@K2iU`~rrgo&VX?z*pt zZhA8{oI#8_}X>yJ1>tmgFim*6?<`)19TAO>^M zq-LmVrpr>GNK64GAN(2`9O{P4<#I(%!S7L)0IKfMJrNjf&5UqnY(ukZYNd40YM>>< z8JU%}IomN|{>CoUMHlaEWKwTj=KJNT^0W?9VeUGYWA)AX;{(R!fHx80m$y<~^%EQL zC@^rq-t2R&m1LmF55lt^!HTOkTzLbx!PfdO!BRg+ICF5s*b;Dg1YI6*GeE{v+aPu` zI&A3=f zqzIYU&o*afn^-a|mDzetmct5SeO9^AQ)m{%`@%*9HgaHRTqT7IlBE z5NSFyXv*vhXHA zg5tGPM3~^wVk=?PnF#5A7M&LzI#9-(6HJ3K@hf;K<7fR4sYPi>+!s+e{I{qpSO&S@+!Z;NRDWO>)$sSZE--(K;uRkR& zq|M`G@QUz7Gx0Bxc^|wr;Vw9eGS$3#m1Ik>5y~e`)`W7YiouJ=eh<>#fC`He=@m@(9IRzmwH z#aZL5H3M0hAfP;LpX95m*Q~KyxjNMc^_G0`9w}IvsHEYIBk0cCV2L`6Y#oMRxt6#| zBQwhG2nJP{oIxXnVjng75ZFg}Lg5>Eus28^rr|^ICQO4j zmL@Wcs~IKtq4DK#mo&&wx?=?IFt-b|1wCrYfFFSkz?y+H zsXyC4h&`@8ISHbo7EyUuf=wAHX!brBdIK*>C()*DBE`^NSpmkzoD)!8_XyHiZB5W} zy}mdfCZx`0OU75>EQKu11{D$WD797#CssjMdpH_NuLVOGyf3w-suz(_UaM(>ESUth z5&bJAI%DNlid2>RY}FozHsH<~U4N!8*A4m7vj!2D#8s{@YqNSaO{}m;l$+y-;lT8U zZ!nI@FVue^i(?X4fScz;&DG&VV*O7?C7~8QRfFP~gXvfZ2hOjm7f4NhQGx@;T*uIU zOWJ^e(F6gD0?~;ea}~@xb)i4TzES7dg?$puQayWe%?3KHy3~#iinPvLT$0g(nZN6( zjRHe8Rf27hCJKp4i4MFLY|i79LSb87pNhd(&l2fuco8ct)&NUAGinN4L!IP+QkVz* zn=0%pPl@4_?IyLV;FNf0ngk_9D+iu<)3dhp%`7;R5Jp5f>Wri=a)LDIVzAp)#s*N~ zKL$ym(e5NOgI3EMGt{E~>}YK=8YnN#ps7jj8O9DXbAr*-x5!jQQEH&_Ek9%mI3xBi z$Uw(^cp6L%n?pXBmkO87yd6yM<+Pe?ohyeq=Fmcp1J#r4}nri zD*{o78WzjVHCF9+^A zAf)U8$Z|(jre^rxR%`bi0<+zUO0z86^}5las}faRwPZgom;a5-8d+g z?SoZypzi#_Kfp-|Y>?I(KHPmQx8g_+R{Z>Wp^E)?UCzdt&LPxq7#sUI5FsZDdoy_M zkqvPih8V{Yppw+Vs)}VfxQF77>w!1&3#+-h3JWs0&e$^Yu~39rgHu_-wFO*=(#eq# z>WmosW@LyHN7*4^Z5voao!MW&eqOA?enyW=z%Xh3y%Oez;GkHKZgU6fBepbL^2bY9 zo@>lbVe%x+@yiFXf+VX$uDBvrDKV>&-O2^|f#YLC*qM^)w5+zEbLJxLu;LXEf{A)< zF6aw(Q1{p{&i##g)3S8w`U&e213ej>nYFEYRH$Hm9kfDMm1VsM@5cFVKemA*h0CG} zwriU>*ck5-^fmaXofa}Ux=t2ZpAL%_F_Xe%Q415vs>u!zcXUB>#j|yxmM#uckf>S4 z>Mh>y3&j>IZ6eVy@SD!R#KU5v@Xwd|yso^#kE0p{qQb!x+2}MHD;?hWG^YPjxY4SU zW{M=*(|}DXL4}-<>DiwO7MPJm?Btjof&j_}$W%|3l2u%!S|wRFp%I2aO*HpoF+^G* zb267(qgdnUT=>xaZ+?tECZ?E znuSxZDRglSy(@~1zhB+7r3ZOd-4d0DXuy}OHX(Q_M#fRu7nYUJgGr&$bTiHRCOwp+ z(&Nd&SZOU*`LqW^?wRg@Z8)WErcG=F4%HRegVFlWH#1~{tmLvQ(JxZ_#(uDTGRbau z=5x+Wq7I2Y7S}gw?A(L;i;|DopjiwE@=8u{%YQmaM}cUt;1pS`a;yE31#T<`6oYzT zg|np0gxog#QUx39;p`Plx(y*eAmr8@2$peB3?|grZ`5Y%MXVOf9v-L~wC%d4Ld!Kc zV|!qDZMmSIpyE}mnUEr5zK|}_K`CljVFGcS8)l+~U%JkU{mc^9H>6w>0&Qsp+;D=a zLzMg{vnE^9mIm2Df5~6_#VnmlnJOkNAJ}((JehJBsZ{skY$NKa+WK?#njN#JK8mV? z!daVO%n{IrA(u5Rn+%CqY{cu(;IIf^q#T-!Q|1_q1&oncc52Ubp22ntp*hlK$#rm+ zp~bN(Fx$BSQDKnBtg17R+H~|lBtNY>Ha_;%uM-AhozFCKmoiIc2A3Qm$Cf$OSAH375L_0|Z4ZDwrxB(y48Qqu{ zQ&cIJ%NJjy%8bz+=WJ1SAPAu!65+jei|jrNvyH`A)YK|i4nj)~<5#Rp!*;3X;{-u< zW_YKEWtkEb+D^SOYduyRt?3`PgxCkbQ8qExC>i|(pG9`S%XVZTk{F zhk|r-`}H6arfpM@FSWm@6ZH~?SNspRI)Ie{6^tOUZa>NsrA9{Kxq4v+=PPVM5w_p6 zC>>8v4n$0z2`Tgu=3cT;`=vZ|_6}vCfv$7uxXF~vJZE@)a6{c|8?bSB7iWgmv8JmU z)K#1(+2+#&4N_$~OyZQu`83%A^TbsSQm8(=n&FLSY_HG7csqX-<&l^^#FZd5yG)p3 z&bum@Wd&()^;g-=3?cfbCyuEkx>|^LG`7tCa?$<#K52zLpUQ803jcR>FJB&~JADCq zNB3#cJGwI#pud!KbAKZJ61m(BpL=i%oqYatiGBZ)-}V&#@8~YaZFBN@*;4yHhu`)T z{_p5MKzf(&a|`6}=)OgINB3U~&^x-FxE)VEj_$V$&^x;4N$==>zX1In{2fgByqn)1 z+nHLRz0Ji&|2)4P-Qor49o_XT-_aet0R7%mE&oGj*mrh=efRR)p8jwCPkD>HkFfWn z=~B3u@XIanl=nnS{3ve;do7+%+B>@?zSz6laW#@4{6q4EC|xVO9eA5} zjCc3x@f61qe>8!gO}v9z=~Bs`H(ca}d~@8}ruh7Rd=2xNN#t|A($ANNzXsl_{&y<< zI`2{T<9k`~XPCdU9&3p|p!Dm#MeJW!&u=V{{|}h|4ev0@`|&KF$MH|vyNdas<@)(0 z{uh4Uc7Z*Q*_W3>a>1Vz%-uaBmE%l{j)xM z?kD~s;%hR7yZZk<@xLK{EbH?v;-4gAj#x79r^I(;4R|^2^s~h8%^5z0XZb9}d#TTv z+wJ*5`|>srf0DRUoK3`^$Q$7z=CcF%BG|o0FEF5k`AoQc`VCmY`rin=mE69K^uM4W zyoKYy9ShKZ+~vJeU=MBUMi}swcFYhq%!^F>Kd&P^B_P&qx zxsCLn1m3FOA0WN^bKPseNBKNN{DG=He+3n_e0vx0Mcz7Z?>mj~W=rOMU;+A1EP&q&T=?VueB;S7Fyiw? z;&tN_jqVZB-$Fe1 z4#SUQzuy5|>UlToxz=8Le^2~KuT}7F;{V8e{5uTT$b7y{`mZscm8AbE>EHSR119k- zpJ$1G?_>5H_}6HM+F|C?Zm+%LiQnI6^>O3NX~3o5*Rp~;S)WZxzur5-ar_46lOg@& zJqCP^`Z&z|pJlmZo41$rXMNh}H#7g&62JOh!*3z(^vK(0^<2erZ(;t^TMc*lzn}PP z68J}%|BDY;27kwV?j`==FB;(Z@MYo`f64G)lm2_e&;7Ci&R_aD@yvsU%eXF|-xB}P zSM2#Lw(D5TPlV5Z^&P`+CjA-2JsPS@Nq;f%OTTIKPmn%O{Pb@dULd}g`0M}4@b%26 zO8ks}HvBZwUq?LiUBj;=d#AFd$%s#A>q)lQFyPjwjn z7;&HYjx!A}TK1R`x9+b7UM%ufdnb$In)tNp-y0<(Z_T`UWQwCf~JikCb1=3&iun}$}{ecDOZvoyxn&{Vy#|S=u-u+?b z-}{(R-^N6rBR)E3z!J*sw~61n!Enci$BEzlqT#QiSUgMojco>Sc<@roj6Xl4gZ}}R z+fMv1|EB?TgS-vIedfP|^p_C->N5uXka#!n)fhKBUTNjBI^KxOM<$r~yxG3IN#alb zy8)LIzmfQ3bd=ss{N2ReAFS9&{6oZtkF^qM7QMTPrzj6@h2m?9GjZhW$D}{7!t!}F z8}R3_L#^cPY0`i8dzJ~ON#06`zR2NQj6^D_(N|6S(uB;{la^Z7CHJ7mEDpG)k^dy4p7zc+wx ztM|W%pYo95j()`osn2?E3;mz7nUAdQOMkukkO3bi-l;erB3~KO?|Ra}Yxr(p0s0DX z;lmjTKD?IsoJf8A2J^X@_$yZ$gI`YkT?^#@cclLj?MWx;?CgR%0d5_m zhxqr|kLQto7`XJ~VfG``Q$PDj|DE62b2srh;$7z(K=tr$Rh&eTuaA@dFel>w#&@3~ z{yL5eoOXKOBEJ6uBXs@sW8yb2v3`7l`8-AZOJuzBi+%@O>_c*$b}7bF;pcPI-xHb7 z$-spVH;@ldXZ@V5^n8eXUA6$egZcl8?Q;1~5`WtRmPw6y-3YuRlCS%DnDlqBp-wN3 z5P$GrjPgz{6T z$fsMkcmC?{NS~&i*+cpzAQe8BC_hug*Ac(-IRie+YMn_uPu%5m5%J%X4_wCba>Q3s zpe|-U1>)U5v;5f%uK`^8cP1g{Zz285C_h82=lh92`clidO#BnXulu1SC_%YJ= zAfHue@7}MFF~l)MX+AfcZoo$3Co!KdK5D=Y;x8w@mcV}EmlOXD?b1EOw<^wu$k)}t zr9R2=y25-uHe$qESl#Ov$mi{({}lcFQ|Q;doA{?WjyO5_An_N-ux)6+eC{FMId0GY z#&W-^xM9)%e@uGZYO3&keEAFF|9p($jz2FD@8x)LCF${}`@sMCpLL33ou3)snlhS= z#9#amd%l`UFC+d^;%?mOC4RxvaeCZrtNs4;Ay}s(>?P3ocM#3D>r`KLj2EmSo&+o=i7-tyvzW%{&^Si%CkmKbKu=a{B8obv1;EW zej@GIUgD1sFZ|kowbZXCh#zEoFD3nNh_86WfPWzU`gY@I?HR*&k^ZH?&*1OqR~P9I zQINOsWuEvP6}nD*H}O}}aK422wZz+hV!(;SUq^iQ3&g2k?Cs{wI4UAOu!$4N_*p9B5(69-$NB0eVry|377kDPxQ)eUa99av z;c@I|)(+9i5%f~$d95jMV5wS>lWm1V3<@4cz;4+u%}!4rLXyanp4*O*%IQSARyMqi ziC5(rfXEiT^k8-d>ImuLEZKT`63ucmcINbV*yK}q(Tha^6AlVSJ=~eHT{*IgQowr`c>f-tUjen_13To8TO86JOk ze2#`JcWw#_cSA?yx(rtjXIV6aG!|K_h>HT|p<4!w@=5PJaK~{a^hyjXpXIj;!i$h3 zAgfpcjE2)QDT4$Vtw#{OCxP{G5VAE7W0WnEX?$YjcaQ-@87gf@SvxOwKQ_A`=y?tP zMyJZjT024>Jq*m(7dSdxv1SQ2MPgGN-y?AjF-Q*wbBKw=ZM2HzU^>Ra=?HFdvV7sX z-w|lmK7tf8{aFe6#!b5Nw+s;66tjCpBwGR<*Ls48tv~E*K1U-qeL!R zP%N@TYwv0l++`&s34ckY1srBz2ZLIYp;Io%rA642NfFMROBA|05AWhKR7-iopWMnU zqG^Y|=S4(n8zd@A1Bp}`Lh5KlU-D>q5Dph>GxB#=bAhAHS}D#@WSxxG)8slx;K;n( z-egU}$RSmWRNW-CtWj~u$Hks#@8LNvOvwudEZQn$g5+!A3YsnIinyA2btQcmRmrGG z2@Qzx7}@*c-xVh@noj!TxV$pVOihCw`bVjeXheBZV}NK&JtIFaN{%*~ZH)`OMk;u? zm9;z>mL+O|Y_(S#5@vyDsfNVkCF&$}VGGOwi68Z(UA8^DsS; zV4i3wg*>?kGvOU##SqaJ&n>KtUcjYdp(f8o5K6Z3B$8|L8f%7-sIKYM76kz#3KzEpsCD~ z!Oe76Dj3Fjsj`V!xF{Y8@?pGd81Cu>J`}HDu#^ZtEkV@=aa-E%xXR%ALka#=`BGX= z^qjoUXhY&@G*aBPOM|L4WiYB)p`7Fe_j{u6(ySOc+(Gt&XwM;<;cC<4Lv5 z=r|FY9mZ_Iups}Cp@bRAvGi8xK zxB>EHjI-n2#2 z#^MqVl&9?v2RZGbP`+q{Lw3`G1q^eR-D?#S8FJGC0Ih!{-q+PKxK{x+X>F%WZG|ym zPy2rHU;&&$G%{EnwulDL?5as7MLg1b4F5!qPMrc1VM$_gW)oEHO|x8#3=X=<(u8A& z^3LnT!U5><4M#}7_q$&jM?K?pRuOUBiMvKSMFdLcR!W32UAc4RYE*qEE}Pd`I#fk| z_Kgs6eIs$1vdR&C@bRu*o+?NJ{+hv!6P>DJo%+WaI%NeA?`rBwb(TdWWd(4532EJv zr4Ugl9P%`U`;CkXxRM{G;t#pVf1O%@Wd`fwbz-Wa%UYeK^1fNQWJK=y0B(=+*IL}~ z!an@ztpn~!|1=M&z$ynbIhRfUpTAB*N?DoZvTP8C<>IkUPULK>xFIOZ`A0|6yLc`4 z?bhvG3b(K6o;N4bySOg*-QfuNolM^Y{MUc@L(SFS#ecbPSN}BAFG=J#fam4-=hC}# ztnT|}zE}(zX}e3m9>3*t75>Rmw@dHh$=vsq35F#eJ=u5uL!|yL?#z7)f8^up@5*uC zlX&-HB)yAIbKgUn+Vhh2C+x|#sqob0=i=Dh_x@!@>B>*G|0bsIGO{4v?NRIl$>#+& zSkfPlf64T31tug?KmByXzePTypJe~b`Jia}jt--C-+Sd{wn;5nM!#rL`I zPX&y%gvs(hok;KE0NwY&L7(z`gtAHL2Ko{e|Wk4x{qAIHmR zde5B$xxv!kA5DzkE}i?9ZRBYB`Q;V!e zj|7InGH~gbo$@Y0qOT4gW$Cwc80G2sx(EN9+_~{fj>`nHW2E~3cg{5QtJsf?ev;*j SnQxW;J(n1|BatBS=>2b_#ofFB literal 223000 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

uQ(O1==Fr*NGUPZN^`hLR6TCD3SDng$U;!{VB= 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 } -static OnyxAstNode* parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) { +static AstNode* parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) { // NOTE: Maybe don't want to recreate the tokenizer and parser for every file if (compiler_state->options->verbose_output) bh_printf("[Lexing] %s\n", file_contents->filename); @@ -142,33 +142,33 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* bh_table_put(bh_file_contents, compiler_state->loaded_files, (char *) filename, fc); fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename); - OnyxAstNode* root_node = parse_source_file(compiler_state, &fc); + AstNode* root_node = parse_source_file(compiler_state, &fc); if (compiler_state->options->print_ast) { onyx_ast_print(root_node, 0); bh_printf("\n"); } - OnyxAstNode* walker = root_node; + AstNode* walker = root_node; while (walker) { switch (walker->kind) { - case ONYX_AST_NODE_KIND_USE: - bh_arr_push(compiler_state->program.uses, &walker->as_use); + case AST_NODE_KIND_USE: + bh_arr_push(compiler_state->program.uses, (AstNodeUse *) walker); break; - case ONYX_AST_NODE_KIND_GLOBAL: - bh_arr_push(compiler_state->program.globals, &walker->as_global); + case AST_NODE_KIND_GLOBAL: + bh_arr_push(compiler_state->program.globals, (AstNodeGlobal *) walker); break; - case ONYX_AST_NODE_KIND_FOREIGN: - bh_arr_push(compiler_state->program.foreigns, &walker->as_foreign); + case AST_NODE_KIND_FOREIGN: + bh_arr_push(compiler_state->program.foreigns, (AstNodeForeign *) walker); break; - case ONYX_AST_NODE_KIND_FUNCTION: - bh_arr_push(compiler_state->program.functions, &walker->as_function); + case AST_NODE_KIND_FUNCTION: + bh_arr_push(compiler_state->program.functions, (AstNodeFunction *) walker); break; - case ONYX_AST_NODE_KIND_PROGRAM: + case AST_NODE_KIND_PROGRAM: // Dummy initial node break; @@ -180,7 +180,7 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* walker = walker->next; } - bh_arr_each(OnyxAstNodeUse *, use_node, compiler_state->program.uses) { + bh_arr_each(AstNodeUse *, use_node, compiler_state->program.uses) { char* formatted_name = bh_aprintf( global_heap_allocator, "%b.onyx", diff --git a/src/onyxlex.c b/src/onyxlex.c index 95c543a4..b16d9736 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -1,7 +1,7 @@ #include "bh.h" #include "onyxlex.h" -static const char* onyx_token_type_names[] = { +static const char* token_type_names[] = { "TOKEN_TYPE_UNKNOWN", "TOKEN_TYPE_END_STREAM", @@ -76,7 +76,7 @@ static const char* onyx_token_type_names[] = { } #endif -static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, OnyxTokenType type) { +static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, TokenType type) { i64 len = chars_match(tokenizer->curr, lit); if (len > 0) { if (is_word && char_is_alphanum(*(tokenizer->curr + len)) || charset_contains("_$", *(tokenizer->curr + len))) @@ -95,14 +95,14 @@ static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_ return 0; } -const char* onyx_get_token_type_name(OnyxTokenType tkn_type) { - return onyx_token_type_names[tkn_type]; +const char* onyx_get_token_type_name(TokenType tkn_type) { + return token_type_names[tkn_type]; } -void onyx_token_null_toggle(OnyxToken tkn) { +void onyx_token_null_toggle(OnyxToken* tkn) { static char backup = 0; - char tmp = tkn.token[tkn.length]; - tkn.token[tkn.length] = backup; + char tmp = tkn->token[tkn->length]; + tkn->token[tkn->length] = backup; backup = tmp; } diff --git a/src/onyxparser.c b/src/onyxparser.c index d3379eba..3bc38e8d 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -3,6 +3,9 @@ #include "onyxparser.h" #include "onyxutils.h" +// NOTE: The one weird define you need to know before read the code below +#define make_node(nclass, kind) onyx_ast_node_new(parser->allocator, sizeof(nclass), kind) + static const char* ast_node_names[] = { "ERROR", "PROGRAM", @@ -32,53 +35,53 @@ static const char* ast_node_names[] = { "BREAK", "CONTINUE", - "ONYX_AST_NODE_KIND_COUNT", + "AST_NODE_KIND_COUNT", }; -struct OnyxTypeInfo builtin_types[] = { - { ONYX_TYPE_INFO_KIND_UNKNOWN, 0, "unknown" }, - { ONYX_TYPE_INFO_KIND_VOID, 0, "void", 0, 0, 0, 0, 1 }, +struct TypeInfo builtin_types[] = { + { TYPE_INFO_KIND_UNKNOWN, 0, "unknown" }, + { TYPE_INFO_KIND_VOID, 0, "void", 0, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_BOOL, 1, "bool", 0, 1, 0, 1, 1 }, + { TYPE_INFO_KIND_BOOL, 1, "bool", 0, 1, 0, 1, 1 }, - { ONYX_TYPE_INFO_KIND_UINT32, 4, "u32", 1, 1, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_UINT64, 8, "u64", 1, 1, 0, 0, 1 }, + { TYPE_INFO_KIND_UINT32, 4, "u32", 1, 1, 0, 0, 1 }, + { TYPE_INFO_KIND_UINT64, 8, "u64", 1, 1, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_INT32, 4, "i32", 1, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_INT64, 8, "i64", 1, 0, 0, 0, 1 }, + { TYPE_INFO_KIND_INT32, 4, "i32", 1, 0, 0, 0, 1 }, + { TYPE_INFO_KIND_INT64, 8, "i64", 1, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_FLOAT32, 4, "f32", 0, 0, 1, 0, 1 }, - { ONYX_TYPE_INFO_KIND_FLOAT64, 8, "f64", 0, 0, 1, 0, 1}, - { ONYX_TYPE_INFO_KIND_SOFT_FLOAT, 8, "sf64", 0, 0, 1, 0, 1 }, + { TYPE_INFO_KIND_FLOAT32, 4, "f32", 0, 0, 1, 0, 1 }, + { TYPE_INFO_KIND_FLOAT64, 8, "f64", 0, 0, 1, 0, 1}, + { TYPE_INFO_KIND_SOFT_FLOAT, 8, "sf64", 0, 0, 1, 0, 1 }, { 0xffffffff } // Sentinel }; -static OnyxAstNode error_node = { { ONYX_AST_NODE_KIND_ERROR, 0, NULL, &builtin_types[0], 0, NULL, NULL, NULL } }; +static AstNode error_node = { AST_NODE_KIND_ERROR, 0, NULL, NULL }; // NOTE: Forward declarations static void parser_next_token(OnyxParser* parser); static void parser_prev_token(OnyxParser* parser); -static b32 is_terminating_token(OnyxTokenType token_type); -static OnyxToken* expect(OnyxParser* parser, OnyxTokenType token_type); -static OnyxAstNodeScope* enter_scope(OnyxParser* parser); -static OnyxAstNodeScope* leave_scope(OnyxParser* parser); -static void insert_identifier(OnyxParser* parser, OnyxAstNode* ident, b32 is_local); -static void remove_identifier(OnyxParser* parser, OnyxAstNode* ident); -static OnyxAstNodeNumLit* parse_numeric_literal(OnyxParser* parser); -static OnyxAstNode* parse_factor(OnyxParser* parser); -static OnyxAstNode* parse_bin_op(OnyxParser* parser, OnyxAstNode* left); -static OnyxAstNode* parse_expression(OnyxParser* parser); -static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser); -static OnyxAstNodeWhile* parse_while_stmt(OnyxParser* parser); -static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret); -static OnyxAstNode* parse_return_statement(OnyxParser* parser); -static OnyxAstNodeBlock* parse_block(OnyxParser* parser); -static OnyxAstNode* parse_statement(OnyxParser* parser); -static OnyxTypeInfo* parse_type(OnyxParser* parser); -static OnyxAstNodeParam* parse_function_params(OnyxParser* parser); -static OnyxAstNodeFunction* parse_function_definition(OnyxParser* parser); -static OnyxAstNode* parse_top_level_statement(OnyxParser* parser); +static b32 is_terminating_token(TokenType token_type); +static OnyxToken* expect(OnyxParser* parser, TokenType token_type); +static AstNodeScope* enter_scope(OnyxParser* parser); +static AstNodeScope* leave_scope(OnyxParser* parser); +static void insert_identifier(OnyxParser* parser, AstNode* ident, b32 is_local); +static void remove_identifier(OnyxParser* parser, AstNode* ident); +static AstNodeNumLit* parse_numeric_literal(OnyxParser* parser); +static AstNodeTyped* parse_factor(OnyxParser* parser); +static AstNodeTyped* parse_bin_op(OnyxParser* parser, AstNode* left); +static AstNodeTyped* parse_expression(OnyxParser* parser); +static AstNodeIf* parse_if_stmt(OnyxParser* parser); +static AstNodeWhile* parse_while_stmt(OnyxParser* parser); +static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret); +static AstNodeReturn* parse_return_statement(OnyxParser* parser); +static AstNodeBlock* parse_block(OnyxParser* parser); +static AstNode* parse_statement(OnyxParser* parser); +static TypeInfo* parse_type(OnyxParser* parser); +static AstNodeLocal* parse_function_params(OnyxParser* parser); +static AstNodeFunction* parse_function_definition(OnyxParser* parser); +static AstNode* parse_top_level_statement(OnyxParser* parser); static void parser_next_token(OnyxParser* parser) { parser->prev_token = parser->curr_token; @@ -93,7 +96,7 @@ static void parser_prev_token(OnyxParser* parser) { parser->prev_token--; } -static b32 is_terminating_token(OnyxTokenType token_type) { +static b32 is_terminating_token(TokenType token_type) { switch (token_type) { case TOKEN_TYPE_SYM_SEMICOLON: case TOKEN_TYPE_CLOSE_BRACE: @@ -105,14 +108,14 @@ static b32 is_terminating_token(OnyxTokenType token_type) { } } -static void find_token(OnyxParser* parser, OnyxTokenType token_type) { +static void find_token(OnyxParser* parser, TokenType token_type) { while (parser->curr_token->type != token_type && !is_terminating_token(parser->curr_token->type)) { parser_next_token(parser); } } // Advances to next token no matter what -static OnyxToken* expect(OnyxParser* parser, OnyxTokenType token_type) { +static OnyxToken* expect(OnyxParser* parser, TokenType token_type) { OnyxToken* token = parser->curr_token; parser_next_token(parser); @@ -127,51 +130,51 @@ static OnyxToken* expect(OnyxParser* parser, OnyxTokenType token_type) { return token; } -static OnyxAstNodeNumLit* parse_numeric_literal(OnyxParser* parser) { - OnyxAstNodeNumLit* lit_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LITERAL); - lit_node->token = expect(parser, TOKEN_TYPE_LITERAL_NUMERIC); - lit_node->flags |= ONYX_AST_FLAG_COMPTIME; +static AstNodeNumLit* parse_numeric_literal(OnyxParser* parser) { + AstNodeNumLit* lit_node = make_node(AstNodeNumLit, AST_NODE_KIND_LITERAL); + lit_node->base.token = expect(parser, TOKEN_TYPE_LITERAL_NUMERIC); + lit_node->base.flags |= ONYX_AST_FLAG_COMPTIME; lit_node->value.l = 0ll; - onyx_token_null_toggle(*lit_node->token); + onyx_token_null_toggle(lit_node->base.token); - OnyxTypeInfo* type; - char* tok = lit_node->token->token; + TypeInfo* type; + char* tok = lit_node->base.token->token; // NOTE: charset_contains() behaves more like string_contains() // so I'm using it in this case if (charset_contains(tok, '.')) { - if (tok[lit_node->token->length - 1] == 'f') { - type = &builtin_types[ONYX_TYPE_INFO_KIND_FLOAT32]; + if (tok[lit_node->base.token->length - 1] == 'f') { + type = &builtin_types[TYPE_INFO_KIND_FLOAT32]; lit_node->value.f = strtof(tok, NULL); } else { - type = &builtin_types[ONYX_TYPE_INFO_KIND_FLOAT64]; + type = &builtin_types[TYPE_INFO_KIND_FLOAT64]; lit_node->value.d = strtod(tok, NULL); } } else { i64 value = strtoll(tok, NULL, 0); if (bh_abs(value) < ((u64) 1 << 32)) { - type = &builtin_types[ONYX_TYPE_INFO_KIND_INT32]; + type = &builtin_types[TYPE_INFO_KIND_INT32]; } else { - type = &builtin_types[ONYX_TYPE_INFO_KIND_INT64]; + type = &builtin_types[TYPE_INFO_KIND_INT64]; } lit_node->value.l = value; } - lit_node->type = type; - onyx_token_null_toggle(*lit_node->token); + lit_node->base.type = type; + onyx_token_null_toggle(lit_node->base.token); return lit_node; } -static OnyxAstNode* parse_factor(OnyxParser* parser) { - OnyxAstNode* retval = NULL; +static AstNodeTyped* parse_factor(OnyxParser* parser) { + AstNodeTyped* retval = NULL; switch (parser->curr_token->type) { case TOKEN_TYPE_OPEN_PAREN: { parser_next_token(parser); - OnyxAstNode* expr = parse_expression(parser); + AstNodeTyped* expr = parse_expression(parser); expect(parser, TOKEN_TYPE_CLOSE_PAREN); retval = expr; break; @@ -180,25 +183,24 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { case TOKEN_TYPE_SYM_MINUS: { parser_next_token(parser); - OnyxAstNode* factor = parse_factor(parser); + AstNodeTyped* factor = parse_factor(parser); - OnyxAstNodeUnaryOp* negate_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_UNARY_OP); + AstNodeUnaryOp* negate_node = make_node(AstNodeUnaryOp, AST_NODE_KIND_UNARY_OP); negate_node->operation = ONYX_UNARY_OP_NEGATE; - negate_node->left = factor; - negate_node->type = factor->type; + negate_node->expr = factor; if ((factor->flags & ONYX_AST_FLAG_COMPTIME) != 0) { - negate_node->flags |= ONYX_AST_FLAG_COMPTIME; + negate_node->base.flags |= ONYX_AST_FLAG_COMPTIME; } - retval = (OnyxAstNode *) negate_node; + retval = (AstNodeTyped *) negate_node; break; } case TOKEN_TYPE_SYMBOL: { OnyxToken* sym_token = expect(parser, TOKEN_TYPE_SYMBOL); - OnyxAstNode* sym_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); + AstNodeTyped* sym_node = make_node(AstNode, AST_NODE_KIND_SYMBOL); sym_node->token = sym_token; if (parser->curr_token->type != TOKEN_TYPE_OPEN_PAREN) { @@ -207,23 +209,19 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { } // NOTE: Function call - OnyxAstNodeCall* call_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_CALL); - call_node->token = expect(parser, TOKEN_TYPE_OPEN_PAREN); - call_node->callee = sym_node; - // NOTE: Return type is stored on function definition's type - // This may have to change if we want multiple returns - call_node->type = sym_node->type; - - OnyxAstNode** prev = &call_node->arguments; - OnyxAstNode* curr = NULL; + AstNodeCall* call_node = make_node(AstNodeCall, AST_NODE_KIND_CALL); + call_node->base.token = expect(parser, TOKEN_TYPE_OPEN_PAREN); + call_node->callee = (AstNode *) sym_node; + + AstNodeArgument** prev = &call_node->arguments; + AstNodeArgument* curr = NULL; while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { - curr = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ARGUMENT); - curr->left = parse_expression(parser); - curr->type = curr->left->type; + curr = make_node(AstNodeArgument, AST_NODE_KIND_ARGUMENT); + curr->value = parse_expression(parser); - if (curr != NULL && curr->kind != ONYX_AST_NODE_KIND_ERROR) { + if (curr != NULL && curr->base.kind != AST_NODE_KIND_ERROR) { *prev = curr; - prev = &curr->next; + prev = (AstNodeArgument **) &curr->base.next; } if (parser->curr_token->type == TOKEN_TYPE_CLOSE_PAREN) @@ -235,38 +233,38 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { parser->curr_token->pos, onyx_get_token_type_name(TOKEN_TYPE_SYM_COMMA), onyx_get_token_type_name(parser->curr_token->type)); - return &error_node; + return (AstNodeTyped *) &error_node; } parser_next_token(parser); } parser_next_token(parser); - retval = (OnyxAstNode *) call_node; + retval = (AstNodeTyped *) call_node; break; } case TOKEN_TYPE_LITERAL_NUMERIC: - retval = (OnyxAstNode *) parse_numeric_literal(parser); + retval = (AstNodeTyped *) parse_numeric_literal(parser); break; case TOKEN_TYPE_LITERAL_BOOL_TRUE: { - OnyxAstNodeNumLit* bool_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LITERAL); - bool_node->type = &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]; - bool_node->token = expect(parser, TOKEN_TYPE_LITERAL_BOOL_TRUE); + AstNodeNumLit* bool_node = make_node(AstNodeNumLit, AST_NODE_KIND_LITERAL); + bool_node->base.type = &builtin_types[TYPE_INFO_KIND_BOOL]; + bool_node->base.token = expect(parser, TOKEN_TYPE_LITERAL_BOOL_TRUE); bool_node->value.i = 1; - retval = (OnyxAstNode *) bool_node; + retval = (AstNodeTyped *) bool_node; break; } case TOKEN_TYPE_LITERAL_BOOL_FALSE: { - OnyxAstNodeNumLit* bool_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LITERAL); - bool_node->type = &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]; - bool_node->token = expect(parser, TOKEN_TYPE_LITERAL_BOOL_FALSE); + AstNodeNumLit* bool_node = make_node(AstNodeNumLit, AST_NODE_KIND_LITERAL); + bool_node->base.type = &builtin_types[TYPE_INFO_KIND_BOOL]; + bool_node->base.token = expect(parser, TOKEN_TYPE_LITERAL_BOOL_FALSE); bool_node->value.i = 0; - retval = (OnyxAstNode *) bool_node; + retval = (AstNodeTyped *) bool_node; break; } @@ -281,11 +279,11 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_CAST) { parser_next_token(parser); - OnyxAstNodeUnaryOp* cast_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_UNARY_OP); + AstNodeUnaryOp* cast_node = make_node(AstNodeUnaryOp, AST_NODE_KIND_UNARY_OP); + cast_node->base.type = parse_type(parser); cast_node->operation = ONYX_UNARY_OP_CAST; - cast_node->type = parse_type(parser); - cast_node->left = retval; - retval = (OnyxAstNode *) cast_node; + cast_node->expr = retval; + retval = (AstNodeTyped *) cast_node; } return retval; @@ -312,14 +310,14 @@ static inline i32 get_precedence(OnyxBinaryOp kind) { } } -static OnyxAstNode* parse_expression(OnyxParser* parser) { - bh_arr(OnyxAstNodeBinOp*) tree_stack = NULL; +static AstNodeTyped* parse_expression(OnyxParser* parser) { + bh_arr(AstNodeBinOp*) tree_stack = NULL; bh_arr_new(global_scratch_allocator, tree_stack, 4); bh_arr_set_length(tree_stack, 0); - OnyxAstNode* left = parse_factor(parser); - OnyxAstNode* right; - OnyxAstNode* root = left; + AstNodeTyped* left = parse_factor(parser); + AstNodeTyped* right; + AstNodeTyped* root = left; OnyxBinaryOp bin_op_kind; OnyxToken* bin_op_tok; @@ -346,9 +344,9 @@ static OnyxAstNode* parse_expression(OnyxParser* parser) { bin_op_tok = parser->curr_token; parser_next_token(parser); - OnyxAstNodeBinOp* bin_op = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BIN_OP); + AstNodeBinOp* bin_op = make_node(AstNodeBinOp, AST_NODE_KIND_BIN_OP); bin_op->operation = bin_op_kind; - bin_op->token = bin_op_tok; + bin_op->base.token = bin_op_tok; while ( !bh_arr_is_empty(tree_stack) && get_precedence(bh_arr_last(tree_stack)->operation) >= get_precedence(bin_op_kind)) @@ -357,20 +355,19 @@ static OnyxAstNode* parse_expression(OnyxParser* parser) { if (bh_arr_is_empty(tree_stack)) { // NOTE: new is now the root node bin_op->left = root; - root = (OnyxAstNode *) bin_op; + root = (AstNodeTyped *) bin_op; } else { bin_op->left = bh_arr_last(tree_stack)->right; - bh_arr_last(tree_stack)->right = (OnyxAstNode *) bin_op; + bh_arr_last(tree_stack)->right = (AstNodeTyped *) bin_op; } bh_arr_push(tree_stack, bin_op); right = parse_factor(parser); bin_op->right = right; - bin_op->type = right->type; if ((left->flags & ONYX_AST_FLAG_COMPTIME) != 0 && (right->flags & ONYX_AST_FLAG_COMPTIME) != 0) { - bin_op->flags |= ONYX_AST_FLAG_COMPTIME; + bin_op->base.flags |= ONYX_AST_FLAG_COMPTIME; } } } @@ -379,14 +376,14 @@ expression_done: return root; } -static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser) { +static AstNodeIf* parse_if_stmt(OnyxParser* parser) { expect(parser, TOKEN_TYPE_KEYWORD_IF); - OnyxAstNode* cond = parse_expression(parser); - OnyxAstNode* true_block = (OnyxAstNode *) parse_block(parser); + AstNodeTyped* cond = parse_expression(parser); + AstNode* true_block = (AstNode *) parse_block(parser); - OnyxAstNodeIf* if_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_IF); - OnyxAstNodeIf* root_if = if_node; + AstNodeIf* if_node = make_node(AstNodeIf, AST_NODE_KIND_IF); + AstNodeIf* root_if = if_node; if_node->cond = cond; if (true_block != NULL) @@ -394,23 +391,23 @@ static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser) { while (parser->curr_token->type == TOKEN_TYPE_KEYWORD_ELSEIF) { parser_next_token(parser); - OnyxAstNodeIf* elseif_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_IF); + AstNodeIf* elseif_node = make_node(AstNodeIf, AST_NODE_KIND_IF); cond = parse_expression(parser); - true_block = (OnyxAstNode *) parse_block(parser); + true_block = (AstNode *) parse_block(parser); elseif_node->cond = cond; if (true_block != NULL) elseif_node->true_block = true_block; - if_node->false_block = (OnyxAstNode *) elseif_node; + if_node->false_block = (AstNode *) elseif_node; if_node = elseif_node; } if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_ELSE) { parser_next_token(parser); - OnyxAstNode* false_block = (OnyxAstNode *) parse_block(parser); + AstNode* false_block = (AstNode *) parse_block(parser); if (false_block != NULL) if_node->false_block = false_block; } @@ -418,14 +415,14 @@ static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser) { return root_if; } -static OnyxAstNodeWhile* parse_while_stmt(OnyxParser* parser) { +static AstNodeWhile* parse_while_stmt(OnyxParser* parser) { OnyxToken* while_token = expect(parser, TOKEN_TYPE_KEYWORD_WHILE); - OnyxAstNode* cond = parse_expression(parser); - OnyxAstNodeBlock* body = parse_block(parser); + AstNodeTyped* cond = parse_expression(parser); + AstNodeBlock* body = parse_block(parser); - OnyxAstNodeWhile* while_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_WHILE); - while_node->token = while_token; + AstNodeWhile* while_node = make_node(AstNodeWhile, AST_NODE_KIND_WHILE); + while_node->base.token = while_token; while_node->cond = cond; while_node->body = body; @@ -434,7 +431,7 @@ static OnyxAstNodeWhile* parse_while_stmt(OnyxParser* parser) { // Returns 1 if the symbol was consumed. Returns 0 otherwise // ret is set to the statement to insert -static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { +static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) { if (parser->curr_token->type != TOKEN_TYPE_SYMBOL) return 0; OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); @@ -443,44 +440,44 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { case TOKEN_TYPE_SYM_COLON: { parser_next_token(parser); - OnyxTypeInfo* type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + TypeInfo* type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; // NOTE: var: type if (parser->curr_token->type == TOKEN_TYPE_SYMBOL) { type = parse_type(parser); } - OnyxAstNodeLocal* local = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LOCAL); - local->token = symbol; - local->type = type; - local->flags |= ONYX_AST_FLAG_LVAL; // NOTE: DELETE - *ret = (OnyxAstNode *) local; + AstNodeLocal* local = make_node(AstNodeLocal, AST_NODE_KIND_LOCAL); + local->base.token = symbol; + local->base.type = type; + local->base.flags |= ONYX_AST_FLAG_LVAL; // NOTE: DELETE + *ret = (AstNode *) local; if (parser->curr_token->type == TOKEN_TYPE_SYM_EQUALS || parser->curr_token->type == TOKEN_TYPE_SYM_COLON) { if (parser->curr_token->type == TOKEN_TYPE_SYM_COLON) { - local->flags |= ONYX_AST_FLAG_CONST; + local->base.flags |= ONYX_AST_FLAG_CONST; } - OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT); - local->next = assignment; - assignment->token = parser->curr_token; + AstNodeAssign* assignment = make_node(AstNodeAssign, AST_NODE_KIND_ASSIGNMENT); + local->base.next = (AstNode *) assignment; + assignment->base.token = parser->curr_token; parser_next_token(parser); - OnyxAstNode* expr = parse_expression(parser); + AstNodeTyped* expr = parse_expression(parser); if (expr == NULL) { - onyx_token_null_toggle(*parser->curr_token); + onyx_token_null_toggle(parser->curr_token); onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_EXPECTED_EXPRESSION, - assignment->token->pos, + assignment->base.token->pos, parser->curr_token->token); - onyx_token_null_toggle(*parser->curr_token); + onyx_token_null_toggle(parser->curr_token); return 1; } - assignment->right = expr; + assignment->expr = expr; - OnyxAstNode* left_symbol = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); + AstNode* left_symbol = make_node(AstNode, AST_NODE_KIND_SYMBOL); left_symbol->token = symbol; - assignment->left = left_symbol; + assignment->lval = (AstNodeTyped *) left_symbol; } return 1; } @@ -488,17 +485,17 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { // NOTE: Assignment case TOKEN_TYPE_SYM_EQUALS: { - OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT); - assignment->token = parser->curr_token; + AstNodeAssign* assignment = make_node(AstNodeAssign, AST_NODE_KIND_ASSIGNMENT); + assignment->base.token = parser->curr_token; parser_next_token(parser); - OnyxAstNode* lval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); + AstNode* lval = make_node(AstNode, AST_NODE_KIND_SYMBOL); lval->token = symbol; - OnyxAstNode* rval = parse_expression(parser); - assignment->right = rval; - assignment->left = lval; - *ret = assignment; + AstNodeTyped* rval = parse_expression(parser); + assignment->expr = rval; + assignment->lval = (AstNodeTyped *) lval; + *ret = (AstNode *) assignment; return 1; } @@ -509,37 +506,37 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { return 0; } -static OnyxAstNode* parse_return_statement(OnyxParser* parser) { - OnyxAstNode* return_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_RETURN); - return_node->token = expect(parser, TOKEN_TYPE_KEYWORD_RETURN); +static AstNodeReturn* parse_return_statement(OnyxParser* parser) { + AstNodeReturn* return_node = make_node(AstNodeReturn, AST_NODE_KIND_RETURN); + return_node->base.token = expect(parser, TOKEN_TYPE_KEYWORD_RETURN); - OnyxAstNode* expr = NULL; + AstNodeTyped* expr = NULL; if (parser->curr_token->type != TOKEN_TYPE_SYM_SEMICOLON) { expr = parse_expression(parser); - if (expr == NULL || expr == &error_node) { - return &error_node; + if (expr == NULL || expr == (AstNodeTyped *) &error_node) { + return (AstNodeReturn *) &error_node; } else { - return_node->left = expr; + return_node->expr = expr; } } return return_node; } -static OnyxAstNode* parse_statement(OnyxParser* parser) { +static AstNode* parse_statement(OnyxParser* parser) { b32 needs_semicolon = 1; - OnyxAstNode* retval = NULL; + AstNode* retval = NULL; switch (parser->curr_token->type) { case TOKEN_TYPE_KEYWORD_RETURN: - retval = parse_return_statement(parser); + retval = (AstNode *) parse_return_statement(parser); break; case TOKEN_TYPE_OPEN_BRACE: needs_semicolon = 0; - retval = (OnyxAstNode *) parse_block(parser); + retval = (AstNode *) parse_block(parser); break; case TOKEN_TYPE_SYMBOL: @@ -552,26 +549,26 @@ static OnyxAstNode* parse_statement(OnyxParser* parser) { case TOKEN_TYPE_SYM_BANG: case TOKEN_TYPE_LITERAL_NUMERIC: case TOKEN_TYPE_LITERAL_STRING: - retval = parse_expression(parser); + retval = (AstNode *) parse_expression(parser); break; case TOKEN_TYPE_KEYWORD_IF: needs_semicolon = 0; - retval = (OnyxAstNode *) parse_if_stmt(parser); + retval = (AstNode *) parse_if_stmt(parser); break; case TOKEN_TYPE_KEYWORD_WHILE: needs_semicolon = 0; - retval = (OnyxAstNode *) parse_while_stmt(parser); + retval = (AstNode *) parse_while_stmt(parser); break; case TOKEN_TYPE_KEYWORD_BREAK: - retval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BREAK); + retval = make_node(AstNode, AST_NODE_KIND_BREAK); retval->token = expect(parser, TOKEN_TYPE_KEYWORD_BREAK); break; case TOKEN_TYPE_KEYWORD_CONTINUE: - retval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_CONTINUE); + retval = make_node(AstNode, AST_NODE_KIND_BREAK); retval->token = expect(parser, TOKEN_TYPE_KEYWORD_CONTINUE); break; @@ -595,9 +592,9 @@ static OnyxAstNode* parse_statement(OnyxParser* parser) { return retval; } -static OnyxAstNodeBlock* parse_block(OnyxParser* parser) { - OnyxAstNodeBlock* block = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK); - OnyxAstNodeScope* scope = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SCOPE); +static AstNodeBlock* parse_block(OnyxParser* parser) { + AstNodeBlock* block = make_node(AstNodeBlock, AST_NODE_KIND_BLOCK); + AstNodeScope* scope = make_node(AstNodeScope, AST_NODE_KIND_SCOPE); block->scope = scope; // --- is for an empty block @@ -610,12 +607,12 @@ static OnyxAstNodeBlock* parse_block(OnyxParser* parser) { expect(parser, TOKEN_TYPE_OPEN_BRACE); - OnyxAstNode** next = &block->body; - OnyxAstNode* stmt = NULL; + AstNode** next = &block->body; + AstNode* stmt = NULL; while (parser->curr_token->type != TOKEN_TYPE_CLOSE_BRACE) { stmt = parse_statement(parser); - if (stmt != NULL && stmt->kind != ONYX_AST_NODE_KIND_ERROR) { + if (stmt != NULL && stmt->kind != AST_NODE_KIND_ERROR) { *next = stmt; while (stmt->next != NULL) stmt = stmt->next; @@ -628,29 +625,29 @@ static OnyxAstNodeBlock* parse_block(OnyxParser* parser) { return block; } -static OnyxTypeInfo* parse_type(OnyxParser* parser) { - OnyxTypeInfo* type_info = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; +static TypeInfo* parse_type(OnyxParser* parser) { + TypeInfo* type_info = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); if (symbol == NULL) return type_info; - onyx_token_null_toggle(*symbol); + onyx_token_null_toggle(symbol); - if (!bh_table_has(OnyxAstNode*, parser->identifiers, symbol->token)) { + if (!bh_table_has(AstNode*, parser->identifiers, symbol->token)) { onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_UNKNOWN_TYPE, symbol->pos, symbol->token); } else { - OnyxAstNode* type_info_node = bh_table_get(OnyxAstNode*, parser->identifiers, symbol->token); + AstNodeTyped* type_info_node = bh_table_get(AstNodeTyped*, parser->identifiers, symbol->token); - if (type_info_node->kind == ONYX_AST_NODE_KIND_TYPE) { + if (type_info_node->kind == AST_NODE_KIND_TYPE) { type_info = type_info_node->type; } } - onyx_token_null_toggle(*symbol); + onyx_token_null_toggle(symbol); return type_info; } -static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { +static AstNodeLocal* parse_function_params(OnyxParser* parser) { if (parser->curr_token->type != TOKEN_TYPE_OPEN_PAREN) return NULL; @@ -661,9 +658,9 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { return NULL; } - OnyxAstNodeParam* first_param = NULL; - OnyxAstNodeParam* curr_param = NULL; - OnyxAstNodeParam* trailer = NULL; + AstNodeLocal* first_param = NULL; + AstNodeLocal* curr_param = NULL; + AstNodeLocal* trailer = NULL; OnyxToken* symbol; while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { @@ -672,15 +669,15 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { symbol = expect(parser, TOKEN_TYPE_SYMBOL); expect(parser, TOKEN_TYPE_SYM_COLON); - curr_param = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PARAM); - curr_param->token = symbol; - curr_param->type = parse_type(parser); - curr_param->flags |= ONYX_AST_FLAG_CONST; + curr_param = make_node(AstNodeLocal, AST_NODE_KIND_PARAM); + curr_param->base.token = symbol; + curr_param->base.flags |= ONYX_AST_FLAG_CONST; + curr_param->base.type = parse_type(parser); if (first_param == NULL) first_param = curr_param; - curr_param->next = NULL; - if (trailer) trailer->next = curr_param; + curr_param->base.next = NULL; + if (trailer) trailer->base.next = (AstNode *) curr_param; trailer = curr_param; } @@ -689,21 +686,21 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { return first_param; } -static OnyxAstNodeFunction* parse_function_definition(OnyxParser* parser) { +static AstNodeFunction* parse_function_definition(OnyxParser* parser) { expect(parser, TOKEN_TYPE_KEYWORD_PROC); - OnyxAstNodeFunction* func_def = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FUNCTION); + AstNodeFunction* func_def = make_node(AstNodeFunction, AST_NODE_KIND_FUNCTION); - OnyxAstNodeParam* params = parse_function_params(parser); + AstNodeLocal* params = parse_function_params(parser); func_def->params = params; if (parser->curr_token->type == TOKEN_TYPE_RIGHT_ARROW) { expect(parser, TOKEN_TYPE_RIGHT_ARROW); - OnyxTypeInfo* return_type = parse_type(parser); - func_def->return_type = return_type; + TypeInfo* return_type = parse_type(parser); + func_def->base.type = return_type; } else { - func_def->return_type = &builtin_types[ONYX_TYPE_INFO_KIND_VOID]; + func_def->base.type = &builtin_types[TYPE_INFO_KIND_VOID]; } func_def->body = parse_block(parser); @@ -711,62 +708,62 @@ static OnyxAstNodeFunction* parse_function_definition(OnyxParser* parser) { return func_def; } -static OnyxAstNode* parse_foreign(OnyxParser* parser) { +static AstNode* parse_foreign(OnyxParser* parser) { expect(parser, TOKEN_TYPE_KEYWORD_FOREIGN); - OnyxAstNodeForeign* foreign = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FOREIGN); + AstNodeForeign* foreign = make_node(AstNodeForeign, AST_NODE_KIND_FOREIGN); foreign->mod_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); foreign->name_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { - foreign->import = (OnyxAstNode *) parse_function_definition(parser); + foreign->import = (AstNode *) parse_function_definition(parser); } else { - OnyxTypeInfo* type = parse_type(parser); + TypeInfo* type = parse_type(parser); - OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); - global->type = type; - global->flags |= ONYX_AST_FLAG_LVAL; + AstNodeGlobal* global = make_node(AstNodeGlobal, AST_NODE_KIND_GLOBAL); + global->base.type = type; + global->base.flags |= ONYX_AST_FLAG_LVAL; - foreign->import = (OnyxAstNode *) global; + foreign->import = (AstNode *) global; } - return (OnyxAstNode *) foreign; + return (AstNode *) foreign; } -static OnyxAstNode* parse_top_level_constant_symbol(OnyxParser* parser) { +static AstNode* parse_top_level_constant_symbol(OnyxParser* parser) { if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { - return (OnyxAstNode *) parse_function_definition(parser); + return (AstNode *) parse_function_definition(parser); } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_STRUCT) { // Handle struct case assert(0); } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_FOREIGN) { - return (OnyxAstNode *) parse_foreign(parser); + return (AstNode *) parse_foreign(parser); } else { // Global constant with initial value - OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); + AstNodeGlobal* global = make_node(AstNodeGlobal, AST_NODE_KIND_GLOBAL); global->initial_value = parse_expression(parser); - global->type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; - global->flags |= ONYX_AST_FLAG_CONST; - global->flags |= ONYX_AST_FLAG_LVAL; - global->flags |= ONYX_AST_FLAG_COMPTIME; + global->base.type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; + global->base.flags |= ONYX_AST_FLAG_CONST; + global->base.flags |= ONYX_AST_FLAG_LVAL; + global->base.flags |= ONYX_AST_FLAG_COMPTIME; - return (OnyxAstNode *) global; + return (AstNode *) global; } } -static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { +static AstNode* parse_top_level_statement(OnyxParser* parser) { switch (parser->curr_token->type) { case TOKEN_TYPE_KEYWORD_USE: { - OnyxAstNodeUse* use_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_USE); - use_node->token = expect(parser, TOKEN_TYPE_KEYWORD_USE); + AstNodeUse* use_node = make_node(AstNodeUse, AST_NODE_KIND_USE); + use_node->base.token = expect(parser, TOKEN_TYPE_KEYWORD_USE); use_node->filename = expect(parser, TOKEN_TYPE_LITERAL_STRING); - return (OnyxAstNode *) use_node; + return (AstNode *) use_node; } case TOKEN_TYPE_KEYWORD_EXPORT: @@ -781,7 +778,7 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { break; } - OnyxAstNode* top_level_decl = parse_top_level_statement(parser); + AstNode* top_level_decl = parse_top_level_statement(parser); top_level_decl->flags |= ONYX_AST_FLAG_EXPORTED; return top_level_decl; } @@ -793,7 +790,7 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { expect(parser, TOKEN_TYPE_SYM_COLON); - OnyxTypeInfo* type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + TypeInfo* type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; if (parser->curr_token->type == TOKEN_TYPE_SYMBOL) { type = parse_type(parser); @@ -802,14 +799,14 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { if (parser->curr_token->type == TOKEN_TYPE_SYM_COLON) { parser_next_token(parser); - OnyxAstNode* node = parse_top_level_constant_symbol(parser); + AstNode* node = parse_top_level_constant_symbol(parser); - if (node->kind == ONYX_AST_NODE_KIND_GLOBAL) { - node->type = type; + if (node->kind == AST_NODE_KIND_GLOBAL) { + ((AstNodeGlobal *) node)->base.type = type; } - if (node->kind == ONYX_AST_NODE_KIND_FOREIGN) { - node->as_foreign.import->token = symbol; + if (node->kind == AST_NODE_KIND_FOREIGN) { + ((AstNodeForeign *) node)->import->token = symbol; } else { node->token = symbol; @@ -820,21 +817,21 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { } else if (parser->curr_token->type == TOKEN_TYPE_SYM_EQUALS) { parser_next_token(parser); - OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); - global->token = symbol; - global->flags |= ONYX_AST_FLAG_LVAL; + AstNodeGlobal* global = make_node(AstNodeGlobal, AST_NODE_KIND_GLOBAL); + global->base.token = symbol; + global->base.flags |= ONYX_AST_FLAG_LVAL; global->initial_value = parse_expression(parser); - global->type = type; + global->base.type = type; - return (OnyxAstNode *) global; + return (AstNode *) global; } else { - onyx_token_null_toggle(*parser->curr_token); + onyx_token_null_toggle(parser->curr_token); onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, parser->curr_token->pos, parser->curr_token->token); - onyx_token_null_toggle(*parser->curr_token); + onyx_token_null_toggle(parser->curr_token); } return &error_node; @@ -851,21 +848,16 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { -const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind) { +const char* onyx_ast_node_kind_string(AstNodeKind kind) { return ast_node_names[kind]; } // NOTE: This returns a void* so I don't need to cast it everytime I use it -void* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind) { - OnyxAstNode* node = bh_alloc_item(alloc, OnyxAstNode); - node->kind = kind; - node->flags = 0; - node->token = NULL; - node->type = NULL; - node->data = 0; - node->next = NULL; - node->left = NULL; - node->right = NULL; +void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstNodeKind kind) { + void* node = bh_alloc(alloc, size); + + memset(node, 0, size); + *(AstNodeKind *) node = kind; return node; } @@ -875,11 +867,11 @@ OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, Onyx bh_table_init(bh_heap_allocator(), parser.identifiers, 61); - OnyxTypeInfo* it = &builtin_types[0]; + TypeInfo* it = &builtin_types[0]; while (it->kind != 0xffffffff) { - OnyxAstNode* tmp = onyx_ast_node_new(alloc, ONYX_AST_NODE_KIND_TYPE); + AstNodeTyped* tmp = onyx_ast_node_new(alloc, sizeof(AstNodeTyped), AST_NODE_KIND_TYPE); tmp->type = it; - bh_table_put(OnyxAstNode*, parser.identifiers, (char *)it->name, tmp); + bh_table_put(AstNode*, parser.identifiers, (char *)it->name, tmp); it++; } @@ -896,11 +888,11 @@ void onyx_parser_free(OnyxParser* parser) { bh_table_free(parser->identifiers); } -OnyxAstNode* onyx_parse(OnyxParser *parser) { - OnyxAstNode* program = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM); +AstNode* onyx_parse(OnyxParser *parser) { + AstNode* program = make_node(AstNode, AST_NODE_KIND_PROGRAM); - OnyxAstNode** prev_stmt = &program->next; - OnyxAstNode* curr_stmt = NULL; + AstNode** prev_stmt = &program->next; + AstNode* curr_stmt = NULL; while (parser->curr_token->type != TOKEN_TYPE_END_STREAM) { curr_stmt = parse_top_level_statement(parser); diff --git a/src/onyxsempass.c b/src/onyxsempass.c index 856055f5..6bc95533 100644 --- a/src/onyxsempass.c +++ b/src/onyxsempass.c @@ -13,7 +13,7 @@ OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc .symbols = NULL, }; - bh_table_init(bh_heap_allocator(), state.symbols, 61); + bh_table_init(global_heap_allocator, state.symbols, 61); return state; } @@ -24,29 +24,29 @@ OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc // defined in sub-scopes up to the function-block level. This is a // requirement of WASM, but not of other targets. static void collapse_scopes(OnyxProgram* program) { - bh_arr(OnyxAstNodeBlock*) traversal_queue = NULL; + bh_arr(AstNodeBlock*) traversal_queue = NULL; bh_arr_new(global_scratch_allocator, traversal_queue, 4); bh_arr_set_length(traversal_queue, 0); - bh_arr_each(OnyxAstNodeFunction *, func, program->functions) { - OnyxAstNodeScope* top_scope = (*func)->body->scope; + bh_arr_each(AstNodeFunction *, func, program->functions) { + AstNodeScope* top_scope = (*func)->body->scope; bh_arr_push(traversal_queue, (*func)->body); while (!bh_arr_is_empty(traversal_queue)) { - OnyxAstNodeBlock* block = traversal_queue[0]; + AstNodeBlock* block = traversal_queue[0]; - if (block->kind == ONYX_AST_NODE_KIND_IF) { - OnyxAstNodeIf* if_node = (OnyxAstNodeIf *) block; + if (block->base.kind == AST_NODE_KIND_IF) { + AstNodeIf* if_node = (AstNodeIf *) block; if (if_node->true_block) - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->true_block); + bh_arr_push(traversal_queue, (AstNodeBlock *) if_node->true_block); if (if_node->false_block) - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->false_block); + bh_arr_push(traversal_queue, (AstNodeBlock *) if_node->false_block); } else { if (block->scope != top_scope && block->scope->last_local != NULL) { - OnyxAstNodeLocal* last_local = block->scope->last_local; + AstNodeLocal* last_local = block->scope->last_local; while (last_local && last_local->prev_local != NULL) last_local = last_local->prev_local; last_local->prev_local = top_scope->last_local; @@ -54,20 +54,20 @@ static void collapse_scopes(OnyxProgram* program) { block->scope->last_local = NULL; } - OnyxAstNode* walker = block->body; + AstNode* walker = block->body; while (walker) { - if (walker->kind == ONYX_AST_NODE_KIND_BLOCK) { - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker); + if (walker->kind == AST_NODE_KIND_BLOCK) { + bh_arr_push(traversal_queue, (AstNodeBlock *) walker); - } else if (walker->kind == ONYX_AST_NODE_KIND_WHILE) { - bh_arr_push(traversal_queue, walker->as_while.body); + } else if (walker->kind == AST_NODE_KIND_WHILE) { + bh_arr_push(traversal_queue, ((AstNodeWhile *) walker)->body); - } else if (walker->kind == ONYX_AST_NODE_KIND_IF) { - if (walker->as_if.true_block) - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.true_block); + } else if (walker->kind == AST_NODE_KIND_IF) { + if (((AstNodeIf *) walker)->true_block) + bh_arr_push(traversal_queue, (AstNodeBlock *) ((AstNodeIf *) walker)->true_block); - if (walker->as_if.false_block) - bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.false_block); + if (((AstNodeIf *) walker)->false_block) + bh_arr_push(traversal_queue, (AstNodeBlock *) ((AstNodeIf *) walker)->false_block); } walker = walker->next; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 37c39aea..32abbbb8 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -1,26 +1,26 @@ #define BH_DEBUG #include "onyxsempass.h" -static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol); -static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxAstNode* symbol); -static void symbol_remove(OnyxSemPassState* state, OnyxAstNode* symbol); -static OnyxAstNode* symbol_resolve(OnyxSemPassState* state, OnyxAstNode* symbol); -static void scope_enter(OnyxSemPassState* state, OnyxAstNodeScope* scope); -static OnyxAstNodeScope* scope_leave(OnyxSemPassState* state); -static void symres_local(OnyxSemPassState* state, OnyxAstNodeLocal** local); -static void symres_call(OnyxSemPassState* state, OnyxAstNode* call); -static void symres_expression(OnyxSemPassState* state, OnyxAstNode** expr); -static void symres_assignment(OnyxSemPassState* state, OnyxAstNode* assign); -static void symres_return(OnyxSemPassState* state, OnyxAstNode* ret); -static void symres_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode); -static void symres_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode); -static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, OnyxAstNode** trailer); -static b32 symres_statement(OnyxSemPassState* state, OnyxAstNode* stmt); -static void symres_block(OnyxSemPassState* state, OnyxAstNodeBlock* block); -static void symres_function(OnyxSemPassState* state, OnyxAstNodeFunction* func); - -static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); +static void symbol_introduce(OnyxSemPassState* state, AstNode* symbol); +static b32 symbol_unique_introduce(OnyxSemPassState* state, AstNode* symbol); +static void symbol_remove(OnyxSemPassState* state, AstNode* symbol); +static AstNode* symbol_resolve(OnyxSemPassState* state, AstNode* symbol); +static void scope_enter(OnyxSemPassState* state, AstNodeScope* scope); +static AstNodeScope* scope_leave(OnyxSemPassState* state); +static void symres_local(OnyxSemPassState* state, AstNodeLocal** local); +static void symres_call(OnyxSemPassState* state, AstNodeCall* call); +static void symres_expression(OnyxSemPassState* state, AstNode** expr); +static void symres_assignment(OnyxSemPassState* state, AstNodeAssign* assign); +static void symres_return(OnyxSemPassState* state, AstNodeReturn* ret); +static void symres_if(OnyxSemPassState* state, AstNodeIf* ifnode); +static void symres_while(OnyxSemPassState* state, AstNodeWhile* whilenode); +static void symres_statement_chain(OnyxSemPassState* state, AstNode* walker, AstNode** trailer); +static b32 symres_statement(OnyxSemPassState* state, AstNode* stmt); +static void symres_block(OnyxSemPassState* state, AstNodeBlock* block); +static void symres_function(OnyxSemPassState* state, AstNodeFunction* func); + +static void symbol_introduce(OnyxSemPassState* state, AstNode* symbol) { + onyx_token_null_toggle(symbol->token); SemPassSymbol* sp_sym = (SemPassSymbol *) bh_alloc_item(state->allocator, SemPassSymbol); sp_sym->node = symbol; @@ -32,17 +32,17 @@ static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) { bh_table_put(SemPassSymbol *, state->symbols, symbol->token->token, sp_sym); - if (symbol->kind == ONYX_AST_NODE_KIND_LOCAL) { - OnyxAstNodeLocal* local = &symbol->as_local; + if (symbol->kind == AST_NODE_KIND_LOCAL) { + AstNodeLocal* local = (AstNodeLocal *) symbol; local->prev_local = state->curr_scope->last_local; state->curr_scope->last_local = local; } - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); } -static void symbol_remove(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); +static void symbol_remove(OnyxSemPassState* state, AstNode* symbol) { + onyx_token_null_toggle(symbol->token); SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); @@ -52,11 +52,11 @@ static void symbol_remove(OnyxSemPassState* state, OnyxAstNode* symbol) { bh_table_delete(SemPassSymbol *, state->symbols, symbol->token->token); } - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); } -static OnyxAstNode* symbol_resolve(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); +static AstNode* symbol_resolve(OnyxSemPassState* state, AstNode* symbol) { + onyx_token_null_toggle(symbol->token); if (!bh_table_has(SemPassSymbol *, state->symbols, symbol->token->token)) { onyx_message_add(state->msgs, @@ -64,35 +64,35 @@ static OnyxAstNode* symbol_resolve(OnyxSemPassState* state, OnyxAstNode* symbol) symbol->token->pos, symbol->token->token); - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); return symbol; } SemPassSymbol* sp_sym = bh_table_get(SemPassSymbol *, state->symbols, symbol->token->token); - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); return sp_sym->node; } -static void scope_enter(OnyxSemPassState* state, OnyxAstNodeScope* scope) { +static void scope_enter(OnyxSemPassState* state, AstNodeScope* scope) { scope->prev_scope = state->curr_scope; state->curr_scope = scope; } -static OnyxAstNodeScope* scope_leave(OnyxSemPassState* state) { +static AstNodeScope* scope_leave(OnyxSemPassState* state) { // NOTE: Can't leave a scope if there is no scope assert(state->curr_scope != NULL); - for (OnyxAstNodeLocal *walker = state->curr_scope->last_local; walker != NULL; walker = walker->prev_local) { - symbol_remove(state, (OnyxAstNode *) walker); + for (AstNodeLocal *walker = state->curr_scope->last_local; walker != NULL; walker = walker->prev_local) { + symbol_remove(state, (AstNode *) walker); } state->curr_scope = state->curr_scope->prev_scope; return state->curr_scope; } -static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) { - onyx_token_null_toggle(*symbol->token); +static b32 symbol_unique_introduce(OnyxSemPassState* state, AstNode* symbol) { + onyx_token_null_toggle(symbol->token); // NOTE: If the function hasn't already been defined if (!bh_table_has(SemPassSymbol *, state->symbols, symbol->token->token)) { @@ -107,51 +107,49 @@ static b32 symbol_unique_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) symbol->token->token); // NOTE: I really wish C had defer... - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); return 0; } - onyx_token_null_toggle(*symbol->token); + onyx_token_null_toggle(symbol->token); return 1; } -static void symres_local(OnyxSemPassState* state, OnyxAstNodeLocal** local) { - symbol_introduce(state, (OnyxAstNode *) *local); +static void symres_local(OnyxSemPassState* state, AstNodeLocal** local) { + symbol_introduce(state, (AstNode *) *local); } -static void symres_call(OnyxSemPassState* state, OnyxAstNode* stmt) { - OnyxAstNodeCall* call = &stmt->as_call; - - OnyxAstNode* callee = symbol_resolve(state, call->callee); +static void symres_call(OnyxSemPassState* state, AstNodeCall* call) { + AstNode* callee = symbol_resolve(state, call->callee); if (callee) call->callee = callee; else DEBUG_HERE; - symres_statement_chain(state, call->arguments, &call->arguments); + symres_statement_chain(state, (AstNode *) call->arguments, (AstNode **) &call->arguments); } -static void symres_expression(OnyxSemPassState* state, OnyxAstNode** expr) { +static void symres_expression(OnyxSemPassState* state, AstNode** expr) { switch ((*expr)->kind) { - case ONYX_AST_NODE_KIND_BIN_OP: - symres_expression(state, &(*expr)->left); - symres_expression(state, &(*expr)->right); + case AST_NODE_KIND_BIN_OP: + symres_expression(state, (AstNode **) &((AstNodeBinOp *)(*expr))->left); + symres_expression(state, (AstNode **) &((AstNodeBinOp *)(*expr))->right); break; - case ONYX_AST_NODE_KIND_UNARY_OP: - symres_expression(state, &(*expr)->left); + case AST_NODE_KIND_UNARY_OP: + symres_expression(state, (AstNode **) &((AstNodeUnaryOp *)(*expr))->expr); break; - case ONYX_AST_NODE_KIND_CALL: symres_call(state, *expr); break; + case AST_NODE_KIND_CALL: symres_call(state, (AstNodeCall *) *expr); break; - case ONYX_AST_NODE_KIND_BLOCK: symres_block(state, &(*expr)->as_block); break; + case AST_NODE_KIND_BLOCK: symres_block(state, (AstNodeBlock *) *expr); break; - case ONYX_AST_NODE_KIND_SYMBOL: + case AST_NODE_KIND_SYMBOL: *expr = symbol_resolve(state, *expr); break; // NOTE: This is a good case, since it means the symbol is already resolved - case ONYX_AST_NODE_KIND_LOCAL: break; + case AST_NODE_KIND_LOCAL: break; - case ONYX_AST_NODE_KIND_LITERAL: break; + case AST_NODE_KIND_LITERAL: break; default: DEBUG_HERE; @@ -159,69 +157,69 @@ static void symres_expression(OnyxSemPassState* state, OnyxAstNode** expr) { } } -static void symres_assignment(OnyxSemPassState* state, OnyxAstNode* assign) { - OnyxAstNode* lval = symbol_resolve(state, assign->left); +static void symres_assignment(OnyxSemPassState* state, AstNodeAssign* assign) { + AstNodeTyped* lval = (AstNodeTyped *) symbol_resolve(state, (AstNode *) assign->lval); if (lval == NULL) return; - assign->left = lval; + assign->lval = lval; - symres_expression(state, &assign->right); + symres_expression(state, (AstNode **) &assign->expr); } -static void symres_return(OnyxSemPassState* state, OnyxAstNode* ret) { - if (ret->left) - symres_expression(state, &ret->left); +static void symres_return(OnyxSemPassState* state, AstNodeReturn* ret) { + if (ret->expr) + symres_expression(state, (AstNode **) &ret->expr); } -static void symres_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode) { - symres_expression(state, &ifnode->cond); +static void symres_if(OnyxSemPassState* state, AstNodeIf* ifnode) { + symres_expression(state, (AstNode **) &ifnode->cond); if (ifnode->true_block) { - if (ifnode->true_block->kind == ONYX_AST_NODE_KIND_BLOCK) - symres_block(state, &ifnode->true_block->as_block); + if (ifnode->true_block->kind == AST_NODE_KIND_BLOCK) + symres_block(state, (AstNodeBlock *) ifnode->true_block); - else if (ifnode->true_block->kind == ONYX_AST_NODE_KIND_IF) - symres_if(state, &ifnode->true_block->as_if); + else if (ifnode->true_block->kind == AST_NODE_KIND_IF) + symres_if(state, (AstNodeIf *) ifnode->true_block); else DEBUG_HERE; } if (ifnode->false_block) { - if (ifnode->false_block->kind == ONYX_AST_NODE_KIND_BLOCK) - symres_block(state, &ifnode->false_block->as_block); + if (ifnode->false_block->kind == AST_NODE_KIND_BLOCK) + symres_block(state, (AstNodeBlock *) ifnode->false_block); - else if (ifnode->false_block->kind == ONYX_AST_NODE_KIND_IF) - symres_if(state, &ifnode->false_block->as_if); + else if (ifnode->false_block->kind == AST_NODE_KIND_IF) + symres_if(state, (AstNodeIf *) ifnode->false_block); else DEBUG_HERE; } } -static void symres_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode) { - symres_expression(state, &whilenode->cond); +static void symres_while(OnyxSemPassState* state, AstNodeWhile* whilenode) { + symres_expression(state, (AstNode **) &whilenode->cond); symres_block(state, whilenode->body); } // NOTE: Returns 1 if the statment should be removed -static b32 symres_statement(OnyxSemPassState* state, OnyxAstNode* stmt) { +static b32 symres_statement(OnyxSemPassState* state, AstNode* stmt) { switch (stmt->kind) { - case ONYX_AST_NODE_KIND_LOCAL: symres_local(state, (OnyxAstNodeLocal **) &stmt); return 1; - case ONYX_AST_NODE_KIND_ASSIGNMENT: symres_assignment(state, stmt); return 0; - case ONYX_AST_NODE_KIND_RETURN: symres_return(state, stmt); return 0; - case ONYX_AST_NODE_KIND_IF: symres_if(state, &stmt->as_if); return 0; - case ONYX_AST_NODE_KIND_WHILE: symres_while(state, &stmt->as_while); return 0; - case ONYX_AST_NODE_KIND_CALL: symres_call(state, stmt); return 0; - case ONYX_AST_NODE_KIND_ARGUMENT: symres_expression(state, (OnyxAstNode **) &stmt->left); return 0; - case ONYX_AST_NODE_KIND_BLOCK: symres_block(state, &stmt->as_block); return 0; + case AST_NODE_KIND_LOCAL: symres_local(state, (AstNodeLocal **) &stmt); return 1; + case AST_NODE_KIND_ASSIGNMENT: symres_assignment(state, (AstNodeAssign *) stmt); return 0; + case AST_NODE_KIND_RETURN: symres_return(state, (AstNodeReturn *) stmt); return 0; + case AST_NODE_KIND_IF: symres_if(state, (AstNodeIf *) stmt); return 0; + case AST_NODE_KIND_WHILE: symres_while(state, (AstNodeWhile *) stmt); return 0; + case AST_NODE_KIND_CALL: symres_call(state, (AstNodeCall *) stmt); return 0; + case AST_NODE_KIND_ARGUMENT: symres_expression(state, (AstNode **) &((AstNodeArgument *)stmt)->value); return 0; + case AST_NODE_KIND_BLOCK: symres_block(state, (AstNodeBlock *) stmt); return 0; default: return 0; } } -static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, OnyxAstNode** trailer) { +static void symres_statement_chain(OnyxSemPassState* state, AstNode* walker, AstNode** trailer) { while (walker) { if (symres_statement(state, walker)) { *trailer = walker->next; - OnyxAstNode* tmp = walker->next; + AstNode* tmp = walker->next; walker->next = NULL; walker = tmp; } else { @@ -231,43 +229,43 @@ static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, } } -static void symres_block(OnyxSemPassState* state, OnyxAstNodeBlock* block) { +static void symres_block(OnyxSemPassState* state, AstNodeBlock* block) { scope_enter(state, block->scope); if (block->body) symres_statement_chain(state, block->body, &block->body); scope_leave(state); } -static void symres_function(OnyxSemPassState* state, OnyxAstNodeFunction* func) { - forll(OnyxAstNodeParam, param, func->params, next) { - symbol_introduce(state, (OnyxAstNode *) param); +static void symres_function(OnyxSemPassState* state, AstNodeFunction* func) { + for (AstNodeLocal *param = func->params; param != NULL; param = (AstNodeLocal *) param->base.next) { + symbol_introduce(state, (AstNode *) param); } symres_block(state, func->body); - forll(OnyxAstNodeParam, param, func->params, next) { - symbol_remove(state, (OnyxAstNode *) param); + for (AstNodeLocal *param = func->params; param != NULL; param = (AstNodeLocal *) param->base.next) { + symbol_remove(state, (AstNode *) param); } } void onyx_resolve_symbols(OnyxSemPassState* state, OnyxProgram* program) { // NOTE: First, introduce all global symbols - bh_arr_each(OnyxAstNodeGlobal *, global, program->globals) - if (!symbol_unique_introduce(state, (OnyxAstNode *) *global)) return; + bh_arr_each(AstNodeGlobal *, global, program->globals) + if (!symbol_unique_introduce(state, (AstNode *) *global)) return; - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) - if (!symbol_unique_introduce(state, (OnyxAstNode *) *function)) return; + bh_arr_each(AstNodeFunction *, function, program->functions) + if (!symbol_unique_introduce(state, (AstNode *) *function)) return; - bh_arr_each(OnyxAstNodeForeign *, foreign, program->foreigns) { - OnyxAstNodeKind import_kind = (*foreign)->import->kind; + bh_arr_each(AstNodeForeign *, foreign, program->foreigns) { + AstNodeKind import_kind = (*foreign)->import->kind; - if (import_kind == ONYX_AST_NODE_KIND_FUNCTION || import_kind == ONYX_AST_NODE_KIND_GLOBAL) + if (import_kind == AST_NODE_KIND_FUNCTION || import_kind == AST_NODE_KIND_GLOBAL) if (!symbol_unique_introduce(state, (*foreign)->import)) return; } // NOTE: Then, resolve all symbols in all functions - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) + bh_arr_each(AstNodeFunction *, function, program->functions) symres_function(state, *function); } diff --git a/src/onyxtypecheck.c b/src/onyxtypecheck.c index 9d2f96e3..1cc14cde 100644 --- a/src/onyxtypecheck.c +++ b/src/onyxtypecheck.c @@ -1,81 +1,81 @@ #define BH_DEBUG #include "onyxsempass.h" -static void typecheck_function(OnyxSemPassState* state, OnyxAstNodeFunction* func); -static void typecheck_block(OnyxSemPassState* state, OnyxAstNodeBlock* block); -static void typecheck_statement_chain(OnyxSemPassState* state, OnyxAstNode* start); -static void typecheck_statement(OnyxSemPassState* state, OnyxAstNode* stmt); -static void typecheck_assignment(OnyxSemPassState* state, OnyxAstNode* assign); -static void typecheck_return(OnyxSemPassState* state, OnyxAstNode* retnode); -static void typecheck_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode); -static void typecheck_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode); -static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call); -static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr); -static void typecheck_global(OnyxSemPassState* state, OnyxAstNodeGlobal* global); - -static void typecheck_assignment(OnyxSemPassState* state, OnyxAstNode* assign) { - if (assign->left->kind == ONYX_AST_NODE_KIND_SYMBOL) { +static void typecheck_function(OnyxSemPassState* state, AstNodeFunction* func); +static void typecheck_block(OnyxSemPassState* state, AstNodeBlock* block); +static void typecheck_statement_chain(OnyxSemPassState* state, AstNode* start); +static void typecheck_statement(OnyxSemPassState* state, AstNode* stmt); +static void typecheck_assignment(OnyxSemPassState* state, AstNodeAssign* assign); +static void typecheck_return(OnyxSemPassState* state, AstNodeReturn* retnode); +static void typecheck_if(OnyxSemPassState* state, AstNodeIf* ifnode); +static void typecheck_while(OnyxSemPassState* state, AstNodeWhile* whilenode); +static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call); +static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr); +static void typecheck_global(OnyxSemPassState* state, AstNodeGlobal* global); + +static void typecheck_assignment(OnyxSemPassState* state, AstNodeAssign* assign) { + if (assign->lval->kind == AST_NODE_KIND_SYMBOL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, - assign->left->token->pos, - assign->left->token->token, assign->left->token->length); + assign->lval->token->pos, + assign->lval->token->token, assign->lval->token->length); return; } - if ((assign->left->flags & ONYX_AST_FLAG_CONST) != 0 && assign->left->type->is_known) { + if ((assign->lval->flags & ONYX_AST_FLAG_CONST) != 0 && assign->lval->type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_ASSIGN_CONST, - assign->token->pos, - assign->left->token->token, assign->left->token->length); + assign->base.token->pos, + assign->lval->token->token, assign->lval->token->length); return; } - if ((assign->left->flags & ONYX_AST_FLAG_LVAL) == 0) { + if ((assign->lval->flags & ONYX_AST_FLAG_LVAL) == 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_NOT_LVAL, - assign->token->pos, - assign->left->token->token, assign->left->token->length); + assign->base.token->pos, + assign->lval->token->token, assign->lval->token->length); return; } - typecheck_expression(state, assign->right); + typecheck_expression(state, assign->expr); - if (!assign->left->type->is_known) { - assign->left->type = assign->right->type; + if (!assign->lval->type->is_known) { + assign->lval->type = assign->expr->type; } else { - if (assign->left->type != assign->right->type) { + if (assign->lval->type != assign->expr->type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_ASSIGNMENT_TYPE_MISMATCH, - assign->token->pos, - assign->left->type->name, assign->right->type->name); + assign->base.token->pos, + assign->lval->type->name, assign->expr->type->name); return; } } } -static void typecheck_return(OnyxSemPassState* state, OnyxAstNode* retnode) { - if (retnode->left) { - typecheck_expression(state, retnode->left); +static void typecheck_return(OnyxSemPassState* state, AstNodeReturn* retnode) { + if (retnode->expr) { + typecheck_expression(state, retnode->expr); - if (retnode->left->type != state->expected_return_type) { + if (retnode->expr->type != state->expected_return_type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_FUNCTION_RETURN_MISMATCH, - retnode->left->token->pos, - retnode->left->type->name, state->expected_return_type->name); + retnode->expr->token->pos, + retnode->expr->type->name, state->expected_return_type->name); } } else { if (state->expected_return_type->size > 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - retnode->token->pos, + retnode->base.token->pos, "returning from non-void function without value"); } } } -static void typecheck_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode) { +static void typecheck_if(OnyxSemPassState* state, AstNodeIf* ifnode) { typecheck_expression(state, ifnode->cond); - if (ifnode->cond->type != &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]) { + if (ifnode->cond->type != &builtin_types[TYPE_INFO_KIND_BOOL]) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, ifnode->cond->token->pos, @@ -87,9 +87,9 @@ static void typecheck_if(OnyxSemPassState* state, OnyxAstNodeIf* ifnode) { if (ifnode->false_block) typecheck_statement(state, ifnode->false_block); } -static void typecheck_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode) { +static void typecheck_while(OnyxSemPassState* state, AstNodeWhile* whilenode) { typecheck_expression(state, whilenode->cond); - if (whilenode->cond->type != &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]) { + if (whilenode->cond->type != &builtin_types[TYPE_INFO_KIND_BOOL]) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, whilenode->cond->token->pos, @@ -100,53 +100,53 @@ static void typecheck_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode typecheck_block(state, whilenode->body); } -static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call) { - OnyxAstNodeFunction* callee = (OnyxAstNodeFunction *) call->callee; +static void typecheck_call(OnyxSemPassState* state, AstNodeCall* call) { + AstNodeFunction* callee = (AstNodeFunction *) call->callee; - if (callee->kind == ONYX_AST_NODE_KIND_SYMBOL) { + if (callee->base.kind == AST_NODE_KIND_SYMBOL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, - callee->token->pos, - callee->token->token, callee->token->length); + callee->base.token->pos, + callee->base.token->token, callee->base.token->length); return; } - if (callee->kind != ONYX_AST_NODE_KIND_FUNCTION) { + if (callee->base.kind != AST_NODE_KIND_FUNCTION) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION, - call->token->pos, - callee->token->token, callee->token->length); + call->base.token->pos, + callee->base.token->token, callee->base.token->length); return; } - call->type = callee->return_type; + call->base.type = callee->base.type; - OnyxAstNodeParam* formal_param = callee->params; - OnyxAstNode* actual_param = call->arguments; + AstNodeLocal* formal_param = callee->params; + AstNodeArgument* actual_param = call->arguments; i32 arg_pos = 0; while (formal_param != NULL && actual_param != NULL) { - typecheck_expression(state, actual_param); + typecheck_expression(state, (AstNodeTyped *) actual_param); - if (formal_param->type != actual_param->type) { + if (formal_param->base.type != actual_param->base.type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_FUNCTION_PARAM_TYPE_MISMATCH, - call->token->pos, - callee->token->token, callee->token->length, - formal_param->type->name, arg_pos, - actual_param->type->name); + call->base.token->pos, + callee->base.token->token, callee->base.token->length, + formal_param->base.type->name, arg_pos, + actual_param->base.type->name); return; } arg_pos++; - formal_param = formal_param->next; - actual_param = actual_param->next; + formal_param = (AstNodeLocal *) formal_param->base.next; + actual_param = (AstNodeArgument *) actual_param->base.next; } if (formal_param != NULL && actual_param == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - call->token->pos, + call->base.token->pos, "too few arguments to function call"); return; } @@ -154,21 +154,21 @@ static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call) { if (formal_param == NULL && actual_param != NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - call->token->pos, + call->base.token->pos, "too many arguments to function call"); return; } } -static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { +static void typecheck_expression(OnyxSemPassState* state, AstNodeTyped* expr) { switch (expr->kind) { - case ONYX_AST_NODE_KIND_BIN_OP: - expr->type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + case AST_NODE_KIND_BIN_OP: + expr->type = &builtin_types[TYPE_INFO_KIND_UNKNOWN]; - typecheck_expression(state, expr->left); - typecheck_expression(state, expr->right); + typecheck_expression(state, ((AstNodeBinOp *) expr)->left); + typecheck_expression(state, ((AstNodeBinOp *) expr)->right); - if (expr->left->type == NULL) { + if (((AstNodeBinOp *) expr)->left->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, expr->token->pos, @@ -176,7 +176,7 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { return; } - if (expr->right->type == NULL) { + if (((AstNodeBinOp *) expr)->right->type == NULL) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, expr->token->pos, @@ -184,48 +184,48 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { return; } - if (expr->left->type != expr->right->type) { + if (((AstNodeBinOp *) expr)->left->type != ((AstNodeBinOp *) expr)->right->type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE, expr->token->pos, - expr->left->type->name, - expr->right->type->name); + ((AstNodeBinOp *) expr)->left->type->name, + ((AstNodeBinOp *) expr)->right->type->name); return; } - if (expr->as_binop.operation >= ONYX_BINARY_OP_EQUAL - && expr->as_binop.operation <= ONYX_BINARY_OP_GREATER_EQUAL) { - expr->type = &builtin_types[ONYX_TYPE_INFO_KIND_BOOL]; + if (((AstNodeBinOp *) expr)->operation >= ONYX_BINARY_OP_EQUAL + && ((AstNodeBinOp *) expr)->operation <= ONYX_BINARY_OP_GREATER_EQUAL) { + expr->type = &builtin_types[TYPE_INFO_KIND_BOOL]; } else { - expr->type = expr->left->type; + expr->type = ((AstNodeBinOp *) expr)->left->type; } break; - case ONYX_AST_NODE_KIND_UNARY_OP: - if (expr->as_unaryop.operation != ONYX_UNARY_OP_CAST) { - typecheck_expression(state, expr->left); - expr->type = expr->left->type; + case AST_NODE_KIND_UNARY_OP: + if (((AstNodeUnaryOp *) expr)->operation != ONYX_UNARY_OP_CAST) { + typecheck_expression(state, ((AstNodeUnaryOp *) expr)->expr); + expr->type = ((AstNodeUnaryOp *) expr)->expr->type; } break; - case ONYX_AST_NODE_KIND_CALL: - typecheck_call(state, &expr->as_call); + case AST_NODE_KIND_CALL: + typecheck_call(state, (AstNodeCall *) expr); break; - case ONYX_AST_NODE_KIND_BLOCK: - typecheck_block(state, &expr->as_block); + case AST_NODE_KIND_BLOCK: + typecheck_block(state, (AstNodeBlock *) expr); break; - case ONYX_AST_NODE_KIND_SYMBOL: + case AST_NODE_KIND_SYMBOL: onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, expr->token->pos, expr->token->token, expr->token->length); break; - case ONYX_AST_NODE_KIND_LOCAL: - case ONYX_AST_NODE_KIND_PARAM: + case AST_NODE_KIND_LOCAL: + case AST_NODE_KIND_PARAM: if (!expr->type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, @@ -234,7 +234,7 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { } break; - case ONYX_AST_NODE_KIND_GLOBAL: + case AST_NODE_KIND_GLOBAL: if (!expr->type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, @@ -243,12 +243,12 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { } break; - case ONYX_AST_NODE_KIND_ARGUMENT: - typecheck_expression(state, expr->left); - expr->type = expr->left->type; + case AST_NODE_KIND_ARGUMENT: + typecheck_expression(state, ((AstNodeArgument *) expr)->value); + expr->type = ((AstNodeArgument *) expr)->value->type; break; - case ONYX_AST_NODE_KIND_LITERAL: + case AST_NODE_KIND_LITERAL: // NOTE: Literal types should have been decided // in the parser (for now). assert(expr->type->is_known); @@ -260,88 +260,88 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { } } -static void typecheck_global(OnyxSemPassState* state, OnyxAstNodeGlobal* global) { +static void typecheck_global(OnyxSemPassState* state, AstNodeGlobal* global) { if (global->initial_value) { typecheck_expression(state, global->initial_value); - if (global->type->is_known) { - if (global->type != global->initial_value->type) { + if (global->base.type->is_known) { + if (global->base.type != global->initial_value->type) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_GLOBAL_TYPE_MISMATCH, - global->token->pos, - global->token->token, global->token->length, - global->type->name, global->initial_value->type->name); + global->base.token->pos, + global->base.token->token, global->base.token->length, + global->base.type->name, global->initial_value->type->name); return; } } else { if (global->initial_value->type) - global->type = global->initial_value->type; + global->base.type = global->initial_value->type; } } else { - if (!global->type || !global->type->is_known) { + if (!global->base.type || !global->base.type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - global->token->pos, + global->base.token->pos, "global variable with unknown type"); } } } -static void typecheck_statement(OnyxSemPassState* state, OnyxAstNode* stmt) { +static void typecheck_statement(OnyxSemPassState* state, AstNode* stmt) { switch (stmt->kind) { - case ONYX_AST_NODE_KIND_ASSIGNMENT: typecheck_assignment(state, stmt); break; - case ONYX_AST_NODE_KIND_RETURN: typecheck_return(state, stmt); break; - case ONYX_AST_NODE_KIND_IF: typecheck_if(state, &stmt->as_if); break; - case ONYX_AST_NODE_KIND_WHILE: typecheck_while(state, &stmt->as_while); break; - case ONYX_AST_NODE_KIND_CALL: typecheck_call(state, &stmt->as_call); break; - case ONYX_AST_NODE_KIND_BLOCK: typecheck_block(state, &stmt->as_block); break; + case AST_NODE_KIND_ASSIGNMENT: typecheck_assignment(state, (AstNodeAssign *) stmt); break; + case AST_NODE_KIND_RETURN: typecheck_return(state, (AstNodeReturn *) stmt); break; + case AST_NODE_KIND_IF: typecheck_if(state, (AstNodeIf *) stmt); break; + case AST_NODE_KIND_WHILE: typecheck_while(state, (AstNodeWhile *) stmt); break; + case AST_NODE_KIND_CALL: typecheck_call(state, (AstNodeCall *) stmt); break; + case AST_NODE_KIND_BLOCK: typecheck_block(state, (AstNodeBlock *) stmt); break; default: break; } } -static void typecheck_statement_chain(OnyxSemPassState* state, OnyxAstNode* start) { +static void typecheck_statement_chain(OnyxSemPassState* state, AstNode* start) { while (start) { typecheck_statement(state, start); start = start->next; } } -static void typecheck_block(OnyxSemPassState* state, OnyxAstNodeBlock* block) { +static void typecheck_block(OnyxSemPassState* state, AstNodeBlock* block) { typecheck_statement_chain(state, block->body); - forll(OnyxAstNodeLocal, local, block->scope->last_local, prev_local) { - if (!local->type->is_known) { + forll(AstNodeLocal, local, block->scope->last_local, prev_local) { + if (!local->base.type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, - local->token->pos, - local->token->token, local->token->length); + local->base.token->pos, + local->base.token->token, local->base.token->length); return; } } } -static void typecheck_function(OnyxSemPassState* state, OnyxAstNodeFunction* func) { - forll(OnyxAstNodeParam, param, func->params, next) { - if (!param->type->is_known) { +static void typecheck_function(OnyxSemPassState* state, AstNodeFunction* func) { + for (AstNodeLocal *param = func->params; param != NULL; param = (AstNodeLocal *) param->base.next) { + if (!param->base.type->is_known) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - param->token->pos, + param->base.token->pos, "function parameter types must be known"); return; } - if (param->type->size == 0) { + if (param->base.type->size == 0) { onyx_message_add(state->msgs, ONYX_MESSAGE_TYPE_LITERAL, - param->token->pos, + param->base.token->pos, "function parameters must have non-void types"); return; } } - state->expected_return_type = func->return_type; + state->expected_return_type = func->base.type; if (func->body) { typecheck_block(state, func->body); } @@ -349,9 +349,9 @@ static void typecheck_function(OnyxSemPassState* state, OnyxAstNodeFunction* fun void onyx_type_check(OnyxSemPassState* state, OnyxProgram* program) { - bh_arr_each(OnyxAstNodeGlobal *, global, program->globals) + bh_arr_each(AstNodeGlobal *, global, program->globals) typecheck_global(state, *global); - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) + bh_arr_each(AstNodeFunction *, function, program->functions) typecheck_function(state, *function); } diff --git a/src/onyxutils.c b/src/onyxutils.c index 20726026..b5537cb4 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -10,208 +10,182 @@ bh_allocator global_heap_allocator; #define print_indent { if (indent > 0) bh_printf("\n"); for (int i = 0; i < indent; i++) bh_printf(" "); } -void onyx_ast_print(OnyxAstNode* node, i32 indent) { - if (node == NULL) return; - - print_indent; - bh_printf("(%d) %s ", node->flags, onyx_ast_node_kind_string(node->kind)); - - switch (node->kind) { - case ONYX_AST_NODE_KIND_USE: { - OnyxAstNodeUse* use_node = &node->as_use; - bh_printf("%b", use_node->filename->token, use_node->filename->length); - - if (use_node->next) - onyx_ast_print(use_node->next, indent); - - break; - } - - case ONYX_AST_NODE_KIND_FUNCTION: { - if (node->token) - bh_printf("(%b) ", node->token->token, node->token->length); - OnyxAstNodeFunction* fd = &node->as_function; - +void onyx_ast_print(AstNode* node, i32 indent) { + while (node) { print_indent; - bh_printf("Params "); - if (fd->params) - onyx_ast_print((OnyxAstNode *) fd->params, 0); + bh_printf("(%d) %s ", node->flags, onyx_ast_node_kind_string(node->kind)); - print_indent; - bh_printf("Returns %s", fd->return_type->name); + switch (node->kind) { + case AST_NODE_KIND_USE: { + AstNodeUse* use_node = (AstNodeUse *) node; + bh_printf("%b", use_node->filename->token, use_node->filename->length); - print_indent; - bh_printf("Body"); - if (fd->body) - onyx_ast_print((OnyxAstNode *) fd->body, indent + 1); + break; + } - if (fd->next) - onyx_ast_print((OnyxAstNode *) fd->next, indent); + case AST_NODE_KIND_FUNCTION: { + if (node->token) + bh_printf("(%b) ", node->token->token, node->token->length); + AstNodeFunction* fd = (AstNodeFunction *) node; - break; - } + print_indent; + bh_printf("Params "); + if (fd->params) + onyx_ast_print((AstNode *) fd->params, 0); - case ONYX_AST_NODE_KIND_PARAM: { - OnyxAstNodeParam* param = &node->as_param; - bh_printf("%b %s", param->token->token, param->token->length, param->type->name); - if (param->next && indent == 0) { - bh_printf(", "); - onyx_ast_print((OnyxAstNode *) param->next, 0); - } + print_indent; + bh_printf("Returns %s", fd->base.type->name); - break; - } + print_indent; + bh_printf("Body"); + if (fd->body) + onyx_ast_print((AstNode *) fd->body, indent + 1); - case ONYX_AST_NODE_KIND_BLOCK: { - OnyxAstNodeBlock* block = &node->as_block; - if (block->scope) { - onyx_ast_print((OnyxAstNode *) block->scope, indent + 1); + break; } - if (block->body) { - onyx_ast_print((OnyxAstNode *) block->body, indent + 1); - } + case AST_NODE_KIND_PARAM: { + AstNodeLocal* param = (AstNodeLocal *) node; + bh_printf("%b %s", param->base.token->token, param->base.token->length, param->base.type->name); + if (param->base.next && indent == 0) { + bh_printf(", "); + onyx_ast_print((AstNode *) param->base.next, 0); + } - if (block->next) { - onyx_ast_print(block->next, indent); + return; } - break; - } + case AST_NODE_KIND_BLOCK: { + AstNodeBlock* block = (AstNodeBlock *) node; + if (block->scope) { + onyx_ast_print((AstNode *) block->scope, indent + 1); + } - case ONYX_AST_NODE_KIND_SCOPE: { - OnyxAstNodeScope* scope = &node->as_scope; - if (scope->last_local) { - onyx_ast_print((OnyxAstNode *) scope->last_local, 0); + if (block->body) { + onyx_ast_print((AstNode *) block->body, indent + 1); + } + + break; } - break; - } + case AST_NODE_KIND_SCOPE: { + AstNodeScope* scope = (AstNodeScope *) scope; + if (scope->last_local) { + onyx_ast_print((AstNode *) scope->last_local, 0); + } - case ONYX_AST_NODE_KIND_LOCAL: { - OnyxAstNodeLocal* local = &node->as_local; - bh_printf("%b %s", local->token->token, local->token->length, local->type->name); - if (local->prev_local && indent == 0) { - bh_printf(", "); - onyx_ast_print((OnyxAstNode *) local->prev_local, 0); - } else if (local->next && indent != 0) { - onyx_ast_print(local->next, indent); + break; } - break; - } - case ONYX_AST_NODE_KIND_GLOBAL: { - OnyxAstNodeGlobal* global = &node->as_global; - bh_printf("%b %s", global->token->token, global->token->length, global->type->name); - if (global->initial_value) { - onyx_ast_print(global->initial_value, indent + 1); + case AST_NODE_KIND_LOCAL: { + AstNodeLocal* local = (AstNodeLocal *) node; + bh_printf("%b %s", local->base.token->token, local->base.token->length, local->base.type->name); + if (local->prev_local && indent == 0) { + bh_printf(", "); + onyx_ast_print((AstNode *) local->prev_local, 0); + } + break; } - if (node->next) { - onyx_ast_print(node->next, indent); + case AST_NODE_KIND_GLOBAL: { + AstNodeGlobal* global = (AstNodeGlobal *) node; + bh_printf("%b %s", global->base.token->token, global->base.token->length, global->base.type->name); + if (global->initial_value) { + onyx_ast_print((AstNode *) global->initial_value, indent + 1); + } + + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; } - break; - } - case ONYX_AST_NODE_KIND_SYMBOL: { - bh_printf("%b", node->token->token, node->token->length); - if (node->next) { - onyx_ast_print(node->next, indent); + case AST_NODE_KIND_SYMBOL: { + bh_printf("%b", node->token->token, node->token->length); + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; } - break; - } - case ONYX_AST_NODE_KIND_RETURN: { - if (node->left) { - onyx_ast_print(node->left, indent + 1); + case AST_NODE_KIND_RETURN: { + AstNodeReturn* ret = (AstNodeReturn *) node; + if (ret->expr) { + onyx_ast_print((AstNode *) ret->expr, indent + 1); + } + + break; } - break; - } + case AST_NODE_KIND_LITERAL: { + AstNodeNumLit* lit = (AstNodeNumLit *) node; + bh_printf("(%s) %b", lit->base.type->name, lit->base.token->token, lit->base.token->length); - case ONYX_AST_NODE_KIND_LITERAL: { - bh_printf("(%s) %b", node->type->name, node->token->token, node->token->length); - if (node->next) { - onyx_ast_print(node->next, indent); + break; } - break; - } - case ONYX_AST_NODE_KIND_CALL: { - OnyxAstNodeCall* call = &node->as_call; - if (call->callee) { - if (call->callee->kind == ONYX_AST_NODE_KIND_FUNCTION) { - bh_printf("function: %b", call->callee->token->token, call->callee->token->length); - } else { - onyx_ast_print(call->callee, indent + 1); + case AST_NODE_KIND_CALL: { + AstNodeCall* call = (AstNodeCall *) node; + if (call->callee) { + if (call->callee->kind == AST_NODE_KIND_FUNCTION) { + bh_printf("function: %b", call->callee->token->token, call->callee->token->length); + } else { + onyx_ast_print(call->callee, indent + 1); + } } + onyx_ast_print((AstNode *) call->arguments, indent + 1); + + break; } - onyx_ast_print(call->arguments, indent + 1); - if (call->next) { - onyx_ast_print(call->next, indent); - } - break; - } - case ONYX_AST_NODE_KIND_FOREIGN: { - OnyxAstNodeForeign* foreign = &node->as_foreign; - bh_printf("%b:%b", - foreign->mod_token->token, foreign->mod_token->length, - foreign->name_token->token, foreign->name_token->length); + case AST_NODE_KIND_FOREIGN: { + AstNodeForeign* foreign = (AstNodeForeign *) node; + bh_printf("%b:%b", + foreign->mod_token->token, foreign->mod_token->length, + foreign->name_token->token, foreign->name_token->length); - if (foreign->import) { - onyx_ast_print(foreign->import, indent + 1); - } + if (foreign->import) { + onyx_ast_print(foreign->import, indent + 1); + } - if (foreign->next) { - onyx_ast_print(foreign->next, indent); + break; } - break; - } - case ONYX_AST_NODE_KIND_IF: { - OnyxAstNodeIf* if_node = &node->as_if; - if (if_node->cond) { - print_indent; - bh_printf("Condition:"); - onyx_ast_print(if_node->cond, indent + 1); - } - if (if_node->true_block) { - print_indent; - bh_printf("True block:"); - onyx_ast_print(if_node->true_block, indent + 1); - } - if (if_node->false_block) { - print_indent; - bh_printf("False block:"); - onyx_ast_print(if_node->false_block, indent + 1); - } - if (if_node->next) { - onyx_ast_print(if_node->next, indent); + case AST_NODE_KIND_IF: { + AstNodeIf* if_node = (AstNodeIf *) node; + if (if_node->cond) { + print_indent; + bh_printf("Condition:"); + onyx_ast_print((AstNode *) if_node->cond, indent + 1); + } + if (if_node->true_block) { + print_indent; + bh_printf("True block:"); + onyx_ast_print(if_node->true_block, indent + 1); + } + if (if_node->false_block) { + print_indent; + bh_printf("False block:"); + onyx_ast_print(if_node->false_block, indent + 1); + } + + break; } - break; - } - case ONYX_AST_NODE_KIND_BIN_OP: { - OnyxAstNodeBinOp* binop = &node->as_binop; - bh_printf("%b", binop->token->token, binop->token->length); + case AST_NODE_KIND_BIN_OP: { + AstNodeBinOp* binop = (AstNodeBinOp *) node; + bh_printf("%b", binop->base.token->token, binop->base.token->length); - onyx_ast_print(node->left, indent + 1); - onyx_ast_print(node->right, indent + 1); - if (node->next) { - onyx_ast_print(node->next, indent); - } + onyx_ast_print((AstNode *) binop->left, indent + 1); + onyx_ast_print((AstNode *) binop->right, indent + 1); - break; - } + break; + } - default: { - onyx_ast_print(node->left, indent + 1); - onyx_ast_print(node->right, indent + 1); - if (node->next) { - onyx_ast_print(node->next, indent); + default: + break; } - break; - } + + node = node->next; } } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 206883f2..f8796556 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -195,7 +195,7 @@ static const char* wi_string(WasmInstructionType wit) { } } -static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) { +static WasmType onyx_type_to_wasm_type(TypeInfo* type) { if (type->is_bool) return WASM_TYPE_INT32; else if (type->is_int) { if (type->size == 4) return WASM_TYPE_INT32; @@ -209,25 +209,25 @@ static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) { return WASM_TYPE_VOID; } -static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeFunction* fd); -static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBlock* block); -static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* stmt); -static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* lval); -static void compile_assignment(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* assign); -static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeIf* if_node); -static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeWhile* while_node); -static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBinOp* binop); -static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* unop); -static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* expr); -static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* cast); -static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* ret); - -static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeFunction* fd) { +static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeFunction* fd); +static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBlock* block); +static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNode* stmt); +static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* lval); +static void compile_assignment(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeAssign* assign); +static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeIf* if_node); +static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeWhile* while_node); +static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBinOp* binop); +static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* unop); +static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* expr); +static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* cast); +static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeReturn* ret); + +static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeFunction* fd) { if (fd->body == NULL) return; bh_arr(WasmInstruction) code = *pcode; - forll (OnyxAstNode, stmt, fd->body->body, next) { + forll (AstNode, stmt, fd->body->body, next) { compile_statement(mod, &code, stmt); } @@ -236,12 +236,12 @@ static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* *pcode = code; } -static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBlock* block) { +static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBlock* block) { bh_arr(WasmInstruction) code = *pcode; bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_START, 0x40 })); - forll (OnyxAstNode, stmt, block->body, next) { + forll (AstNode, stmt, block->body, next) { compile_statement(mod, &code, stmt); } @@ -276,19 +276,19 @@ static void compile_structured_jump(OnyxWasmModule* mod, bh_arr(WasmInstruction) *pcode = code; } -static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* stmt) { +static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNode* stmt) { bh_arr(WasmInstruction) code = *pcode; switch (stmt->kind) { - case ONYX_AST_NODE_KIND_SCOPE: break; - case ONYX_AST_NODE_KIND_RETURN: compile_return(mod, &code, stmt); break; - case ONYX_AST_NODE_KIND_ASSIGNMENT: compile_assignment(mod, &code, stmt); break; - case ONYX_AST_NODE_KIND_IF: compile_if(mod, &code, (OnyxAstNodeIf *) stmt); break; - case ONYX_AST_NODE_KIND_WHILE: compile_while(mod, &code, (OnyxAstNodeWhile *) stmt); break; - case ONYX_AST_NODE_KIND_BREAK: compile_structured_jump(mod, &code, 0); break; - case ONYX_AST_NODE_KIND_CONTINUE: compile_structured_jump(mod, &code, 1); break; - case ONYX_AST_NODE_KIND_CALL: compile_expression(mod, &code, stmt); break; - case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, &code, (OnyxAstNodeBlock *) stmt); break; + case AST_NODE_KIND_SCOPE: break; + case AST_NODE_KIND_RETURN: compile_return(mod, &code, (AstNodeReturn *) stmt); break; + case AST_NODE_KIND_ASSIGNMENT: compile_assignment(mod, &code, (AstNodeAssign *) stmt); break; + case AST_NODE_KIND_IF: compile_if(mod, &code, (AstNodeIf *) stmt); break; + case AST_NODE_KIND_WHILE: compile_while(mod, &code, (AstNodeWhile *) stmt); break; + case AST_NODE_KIND_BREAK: compile_structured_jump(mod, &code, 0); break; + case AST_NODE_KIND_CONTINUE: compile_structured_jump(mod, &code, 1); break; + case AST_NODE_KIND_CALL: compile_expression(mod, &code, (AstNodeTyped *) stmt); break; + case AST_NODE_KIND_BLOCK: compile_block(mod, &code, (AstNodeBlock *) stmt); break; default: break; } @@ -296,15 +296,15 @@ static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcod *pcode = code; } -static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* lval) { +static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* lval) { bh_arr(WasmInstruction) code = *pcode; - if (lval->kind == ONYX_AST_NODE_KIND_LOCAL || lval->kind == ONYX_AST_NODE_KIND_PARAM) { + if (lval->kind == AST_NODE_KIND_LOCAL || lval->kind == AST_NODE_KIND_PARAM) { i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) lval); bh_arr_push(code, ((WasmInstruction){ WI_LOCAL_SET, localidx })); - } else if (lval->kind == ONYX_AST_NODE_KIND_GLOBAL) { + } else if (lval->kind == AST_NODE_KIND_GLOBAL) { i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) lval); bh_arr_push(code, ((WasmInstruction){ WI_GLOBAL_SET, globalidx })); @@ -316,7 +316,7 @@ static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pc *pcode = code; } -static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeIf* if_node) { +static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeIf* if_node) { bh_arr(WasmInstruction) code = *pcode; compile_expression(mod, &code, if_node->cond); @@ -327,12 +327,12 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, Onyx if (if_node->true_block) { // NOTE: This is kind of gross, but making a function for this doesn't feel right - if (if_node->true_block->kind == ONYX_AST_NODE_KIND_IF) { - forll (OnyxAstNode, stmt, if_node->true_block, next) { + if (if_node->true_block->kind == AST_NODE_KIND_IF) { + forll (AstNode, stmt, if_node->true_block, next) { compile_statement(mod, &code, stmt); } - } else if (if_node->true_block->kind == ONYX_AST_NODE_KIND_BLOCK) { - forll (OnyxAstNode, stmt, if_node->true_block->as_block.body, next) { + } else if (if_node->true_block->kind == AST_NODE_KIND_BLOCK) { + forll (AstNode, stmt, ((AstNodeBlock *) if_node->true_block)->body, next) { compile_statement(mod, &code, stmt); } } @@ -341,12 +341,12 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, Onyx if (if_node->false_block) { bh_arr_push(code, ((WasmInstruction){ WI_ELSE, 0x00 })); - if (if_node->false_block->kind == ONYX_AST_NODE_KIND_IF) { - forll (OnyxAstNode, stmt, if_node->false_block, next) { + if (if_node->false_block->kind == AST_NODE_KIND_IF) { + forll (AstNode, stmt, if_node->false_block, next) { compile_statement(mod, &code, stmt); } - } else if (if_node->false_block->kind == ONYX_AST_NODE_KIND_BLOCK) { - forll (OnyxAstNode, stmt, if_node->false_block->as_block.body, next) { + } else if (if_node->false_block->kind == AST_NODE_KIND_BLOCK) { + forll (AstNode, stmt, ((AstNodeBlock *) if_node->false_block)->body, next) { compile_statement(mod, &code, stmt); } } @@ -359,7 +359,7 @@ static void compile_if(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, Onyx *pcode = code; } -static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeWhile* while_node) { +static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeWhile* while_node) { bh_arr(WasmInstruction) code = *pcode; bh_arr_push(code, ((WasmInstruction){ WI_BLOCK_START, 0x40 })); @@ -372,7 +372,7 @@ static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, O bh_arr_push(mod->structured_jump_target, 1); bh_arr_push(mod->structured_jump_target, 2); - forll (OnyxAstNode, stmt, while_node->body->body, next) { + forll (AstNode, stmt, while_node->body->body, next) { compile_statement(mod, &code, stmt); } @@ -387,11 +387,11 @@ static void compile_while(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, O *pcode = code; } -static void compile_assignment(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* assign) { +static void compile_assignment(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeAssign* assign) { bh_arr(WasmInstruction) code = *pcode; - compile_expression(mod, &code, assign->right); - compile_assign_lval(mod, &code, assign->left); + compile_expression(mod, &code, assign->expr); + compile_assign_lval(mod, &code, assign->lval); *pcode = code; } @@ -414,7 +414,7 @@ static const WasmInstructionType binop_map[][4] = { /* GTE */ { WI_I32_GE_S, WI_I64_GE_S, WI_F32_GE, WI_F64_GE }, }; -static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBinOp* binop) { +static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeBinOp* binop) { bh_arr(WasmInstruction) code = *pcode; b32 is_sign_significant = 0; @@ -461,31 +461,31 @@ static void compile_binop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, O *pcode = code; } -static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* unop) { +static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* unop) { bh_arr(WasmInstruction) code = *pcode; switch (unop->operation) { case ONYX_UNARY_OP_NEGATE: { - OnyxTypeInfoKind type_kind = unop->type->kind; + TypeInfoKind type_kind = unop->base.type->kind; - if (type_kind == ONYX_TYPE_INFO_KIND_INT32) { + if (type_kind == TYPE_INFO_KIND_INT32) { bh_arr_push(code, ((WasmInstruction){ WI_I32_CONST, 0x00 })); - compile_expression(mod, &code, unop->left); + compile_expression(mod, &code, unop->expr); bh_arr_push(code, ((WasmInstruction){ WI_I32_SUB, 0x00 })); - } else if (type_kind == ONYX_TYPE_INFO_KIND_INT64) { + } else if (type_kind == TYPE_INFO_KIND_INT64) { bh_arr_push(code, ((WasmInstruction){ WI_I64_CONST, 0x00 })); - compile_expression(mod, &code, unop->left); + compile_expression(mod, &code, unop->expr); bh_arr_push(code, ((WasmInstruction){ WI_I64_SUB, 0x00 })); } else { - compile_expression(mod, &code, unop->left); + compile_expression(mod, &code, unop->expr); - if (type_kind == ONYX_TYPE_INFO_KIND_FLOAT32) + if (type_kind == TYPE_INFO_KIND_FLOAT32) bh_arr_push(code, ((WasmInstruction){ WI_F32_NEG, 0x00 })); - if (type_kind == ONYX_TYPE_INFO_KIND_FLOAT64) + if (type_kind == TYPE_INFO_KIND_FLOAT64) bh_arr_push(code, ((WasmInstruction){ WI_F32_NEG, 0x00 })); } @@ -493,7 +493,7 @@ static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, } case ONYX_UNARY_OP_NOT: - compile_expression(mod, &code, unop->left); + compile_expression(mod, &code, unop->expr); bh_arr_push(code, ((WasmInstruction){ WI_I32_EQZ, 0x00 })); break; @@ -503,20 +503,20 @@ static void compile_unaryop(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, *pcode = code; } -static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* expr) { +static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeTyped* expr) { bh_arr(WasmInstruction) code = *pcode; switch (expr->kind) { - case ONYX_AST_NODE_KIND_BIN_OP: - compile_binop(mod, &code, &expr->as_binop); + case AST_NODE_KIND_BIN_OP: + compile_binop(mod, &code, (AstNodeBinOp *) expr); break; - case ONYX_AST_NODE_KIND_UNARY_OP: - compile_unaryop(mod, &code, &expr->as_unaryop); + case AST_NODE_KIND_UNARY_OP: + compile_unaryop(mod, &code, (AstNodeUnaryOp *) expr); break; - case ONYX_AST_NODE_KIND_LOCAL: - case ONYX_AST_NODE_KIND_PARAM: + case AST_NODE_KIND_LOCAL: + case AST_NODE_KIND_PARAM: { i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) expr); @@ -524,7 +524,7 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco break; } - case ONYX_AST_NODE_KIND_GLOBAL: + case AST_NODE_KIND_GLOBAL: { i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) expr); @@ -532,10 +532,10 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco break; } - case ONYX_AST_NODE_KIND_LITERAL: + case AST_NODE_KIND_LITERAL: { - OnyxAstNodeNumLit* lit = &expr->as_numlit; - WasmType lit_type = onyx_type_to_wasm_type(lit->type); + AstNodeNumLit* lit = (AstNodeNumLit *) expr; + WasmType lit_type = onyx_type_to_wasm_type(lit->base.type); WasmInstruction instr = { WI_NOP, 0 }; if (lit_type == WASM_TYPE_INT32) { @@ -556,13 +556,15 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco break; } - case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, &code, (OnyxAstNodeBlock *) expr); break; + case AST_NODE_KIND_BLOCK: compile_block(mod, &code, (AstNodeBlock *) expr); break; - case ONYX_AST_NODE_KIND_CALL: + case AST_NODE_KIND_CALL: { - OnyxAstNodeCall* call = &expr->as_call; - forll (OnyxAstNode, arg, call->arguments, next) { - compile_expression(mod, &code, arg->left); + AstNodeCall* call = (AstNodeCall *) expr; + for (AstNodeArgument *arg = call->arguments; + arg != NULL; + arg = (AstNodeArgument *) arg->base.next) { + compile_expression(mod, &code, arg->value); } i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) call->callee); @@ -590,13 +592,13 @@ static const WasmInstructionType cast_map[][6] = { /* F64 */ { WI_I32_FROM_F64_S, WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64, WI_NOP, }, }; -static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* cast) { +static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeUnaryOp* cast) { bh_arr(WasmInstruction) code = *pcode; - compile_expression(mod, &code, cast->left); + compile_expression(mod, &code, cast->expr); - OnyxTypeInfo* from = cast->left->type; - OnyxTypeInfo* to = cast->type; + TypeInfo* from = cast->expr->type; + TypeInfo* to = cast->base.type; i32 fromidx = 0, toidx = 0; if (from->is_int) { @@ -627,11 +629,11 @@ static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, On *pcode = code; } -static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* ret) { +static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, AstNodeReturn* ret) { bh_arr(WasmInstruction) code = *pcode; - if (ret->left) { - compile_expression(mod, &code, ret->left); + if (ret->expr) { + compile_expression(mod, &code, ret->expr); } bh_arr_push(code, ((WasmInstruction){ WI_RETURN, 0x00 })); @@ -639,22 +641,22 @@ static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, *pcode = code; } -static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { +static i32 generate_type_idx(OnyxWasmModule* mod, AstNodeFunction* fd) { static char type_repr_buf[128]; char* t = type_repr_buf; - OnyxAstNodeParam* param = fd->params; + AstNodeLocal* param = fd->params; i32 param_count = 0; while (param) { // HACK: Using these directly as part of a string feels weird but they are // valid characters so I don't think it is going to be much of an issue - *(t++) = (char) onyx_type_to_wasm_type(param->type); + *(t++) = (char) onyx_type_to_wasm_type(param->base.type); param_count++; - param = param->next; + param = (AstNodeLocal *) param->base.next; } *(t++) = ':'; - WasmType return_type = onyx_type_to_wasm_type(fd->return_type); + WasmType return_type = onyx_type_to_wasm_type(fd->base.type); *(t++) = (char) return_type; *t = '\0'; @@ -681,7 +683,7 @@ static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { return type_idx; } -static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { +static void compile_function(OnyxWasmModule* mod, AstNodeFunction* fd) { i32 type_idx = generate_type_idx(mod, fd); WasmFunc wasm_func = { @@ -697,8 +699,8 @@ static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { bh_arr_new(mod->allocator, wasm_func.code, 4); - if (fd->flags & ONYX_AST_FLAG_EXPORTED) { - onyx_token_null_toggle(*fd->token); + if (fd->base.flags & ONYX_AST_FLAG_EXPORTED) { + onyx_token_null_toggle(fd->base.token); i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) fd); @@ -706,17 +708,17 @@ static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { .kind = WASM_FOREIGN_FUNCTION, .idx = func_idx, }; - bh_table_put(WasmExport, mod->exports, fd->token->token, wasm_export); + bh_table_put(WasmExport, mod->exports, fd->base.token->token, wasm_export); mod->export_count++; - onyx_token_null_toggle(*fd->token); + onyx_token_null_toggle(fd->base.token); } // If there is no body then don't process the code if (fd->body != NULL) { // NOTE: Generate the local map i32 localidx = 0; - forll (OnyxAstNodeParam, param, fd->params, next) { + for (AstNodeLocal *param = fd->params; param != NULL; param = (AstNodeLocal *) param->base.next) { bh_imap_put(&mod->local_map, (u64) param, localidx++); } @@ -726,8 +728,8 @@ static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { // is the same as the order of the local_types above u8* count = &wasm_func.locals.i32_count; fori (ti, 0, 3) { - forll (OnyxAstNodeLocal, local, fd->body->scope->last_local, prev_local) { - if (onyx_type_to_wasm_type(local->type) == local_types[ti]) { + forll (AstNodeLocal, local, fd->body->scope->last_local, prev_local) { + if (onyx_type_to_wasm_type(local->base.type) == local_types[ti]) { bh_imap_put(&mod->local_map, (u64) local, localidx++); (*count)++; @@ -751,23 +753,23 @@ static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) { bh_imap_clear(&mod->local_map); } -static void compile_global_declaration(OnyxWasmModule* module, OnyxAstNodeGlobal* global) { +static void compile_global_declaration(OnyxWasmModule* module, AstNodeGlobal* global) { WasmGlobal glob = { - .type = onyx_type_to_wasm_type(global->type), - .mutable = (global->flags & ONYX_AST_FLAG_CONST) == 0, + .type = onyx_type_to_wasm_type(global->base.type), + .mutable = (global->base.flags & ONYX_AST_FLAG_CONST) == 0, .initial_value = NULL, }; if (!global->initial_value) { onyx_message_add(module->msgs, ONYX_MESSAGE_TYPE_LITERAL, - global->token->pos, + global->base.token->pos, "global without initial value"); return; } - if ((global->flags & ONYX_AST_FLAG_EXPORTED) != 0) { - onyx_token_null_toggle(*global->token); + if ((global->base.flags & ONYX_AST_FLAG_EXPORTED) != 0) { + onyx_token_null_toggle(global->base.token); i32 global_idx = (i32) bh_imap_get(&module->func_map, (u64) global); @@ -775,19 +777,19 @@ static void compile_global_declaration(OnyxWasmModule* module, OnyxAstNodeGlobal .kind = WASM_FOREIGN_GLOBAL, .idx = global_idx, }; - bh_table_put(WasmExport, module->exports, global->token->token, wasm_export); + bh_table_put(WasmExport, module->exports, global->base.token->token, wasm_export); module->export_count++; - onyx_token_null_toggle(*global->token); + onyx_token_null_toggle(global->base.token); } compile_expression(module, &glob.initial_value, global->initial_value); bh_arr_push(module->globals, glob); } -static void compile_foreign(OnyxWasmModule* module, OnyxAstNodeForeign* foreign) { - if (foreign->import->kind == ONYX_AST_NODE_KIND_FUNCTION) { - i32 type_idx = generate_type_idx(module, &foreign->import->as_function); +static void compile_foreign(OnyxWasmModule* module, AstNodeForeign* foreign) { + if (foreign->import->kind == AST_NODE_KIND_FUNCTION) { + i32 type_idx = generate_type_idx(module, (AstNodeFunction *) foreign->import); WasmImport import = { .kind = WASM_FOREIGN_FUNCTION, @@ -798,8 +800,8 @@ static void compile_foreign(OnyxWasmModule* module, OnyxAstNodeForeign* foreign) bh_arr_push(module->imports, import); - } else if (foreign->import->kind == ONYX_AST_NODE_KIND_GLOBAL) { - WasmType global_type = onyx_type_to_wasm_type(foreign->import->type); + } else if (foreign->import->kind == AST_NODE_KIND_GLOBAL) { + WasmType global_type = onyx_type_to_wasm_type(((AstNodeGlobal *) foreign->import)->base.type); WasmImport import = { .kind = WASM_FOREIGN_GLOBAL, @@ -864,14 +866,14 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) { void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxProgram* program) { // NOTE: First, introduce all indicies for globals and functions - bh_arr_each(OnyxAstNodeForeign *, foreign, program->foreigns) { - OnyxAstNodeKind import_kind = (*foreign)->import->kind; + bh_arr_each(AstNodeForeign *, foreign, program->foreigns) { + AstNodeKind import_kind = (*foreign)->import->kind; - if (import_kind == ONYX_AST_NODE_KIND_FUNCTION) { + if (import_kind == AST_NODE_KIND_FUNCTION) { module->next_func_idx++; bh_imap_put(&module->func_map, (u64) (*foreign)->import, module->next_import_func_idx++); } - else if (import_kind == ONYX_AST_NODE_KIND_GLOBAL) { + else if (import_kind == AST_NODE_KIND_GLOBAL) { module->next_global_idx++; bh_imap_put(&module->global_map, (u64) (*foreign)->import, module->next_import_func_idx++); } @@ -879,18 +881,18 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxProgram* program) { compile_foreign(module, *foreign); } - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) + bh_arr_each(AstNodeFunction *, function, program->functions) bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++); - bh_arr_each(OnyxAstNodeGlobal *, global, program->globals) + bh_arr_each(AstNodeGlobal *, global, program->globals) bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++); // NOTE: Then, compile everything - bh_arr_each(OnyxAstNodeFunction *, function, program->functions) + bh_arr_each(AstNodeFunction *, function, program->functions) compile_function(module, *function); - bh_arr_each(OnyxAstNodeGlobal *, global, program->globals) + bh_arr_each(AstNodeGlobal *, global, program->globals) compile_global_declaration(module, *global); } -- 2.25.1