123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706 |
- %{
- #include "sol.h"
- #include "ast.h"
-
- #include <string.h>
-
- #define YYSTYPE void *
- #define YYLTYPE loc_t
-
- /* Hacks */
- #define first_line line
- #define last_line line
- #define first_column col
- #define last_column col
-
- int yylex(YYSTYPE *, loc_t *);
- void yyerror(loc_t *, stmt_node **, char *);
-
- %}
-
- %define lr.type ielr
- %define api.pure full
-
- %token IF THEN ELSEIF ELSE
- %token WHILE FOR IN DO
- %token FUNC MACRO LAMBDA RETURN BREAK CONTINUE
- %token END NONE
- %token IDENT
- %token INT FLOAT STRING
- %token PLUS MINUS STAR SLASH PERCENT DSTAR BAND BOR BXOR BNOT LAND LOR LNOT
- %token ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNSTAR ASSIGNSLASH ASSIGNDSTAR ASSIGNBAND ASSIGNBOR ASSIGNBXOR
- %token EQUAL NEQUAL LESS GREATER LESSEQ GREATEREQ RSHIFT LSHIFT
- %token LBRACE RBRACE BLPAREN LPAREN RPAREN LBRACKET RBRACKET DOT COLON SEMICOLON COMMA POUND
- %token TBANG
-
- %parse-param {stmt_node **program}
-
- %debug
- %locations
- %initial-action {
- @$.first_line = 1; @$.first_column = 0;
- @$.last_line = 1; @$.last_column = 1;
- }
-
- %%
-
- program:
- stmt_list { *program = AS_ST($1); }
- ;
-
- stmt_list:
- stmt_list stmt {
- stmtlist_node *cur = AS_ST($1)->stmtlist;
- while(cur->next) cur = cur->next;
- if(cur->stmt) {
- cur->next = NEW(stmtlist_node);
- cur = cur->next;
- }
- cur->stmt = $2;
- cur->next = NULL;
- $$ = $1;
- }
- | /* empty */ {
- $$ = NEW_ST();
- AS_ST($$)->type = ST_LIST;
- AS_ST($$)->stmtlist = NEW(stmtlist_node);
- AS_ST($$)->stmtlist->stmt = NULL;
- AS_ST($$)->stmtlist->next = NULL;
- }
- ;
-
- stmt:
- expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_EXPR; AS_ST($$)->expr = $1; }
- | RETURN expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = $2; }
- | RETURN { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_RET; AS_ST($$)->ret = NEW(ret_node); AS_ST($$)->ret->ret = NULL; }
- | BREAK { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_BREAK; AS_ST($$)->brk = NEW(break_node); AS_ST($$)->brk->val = NULL;}
- | BREAK expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_BREAK; AS_ST($$)->brk = NEW(break_node); AS_ST($$)->brk->val = $2; }
- | CONTINUE { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_CONT; AS_ST($$)->cont = NEW(cont_node); AS_ST($$)->cont->val = NULL; }
- | CONTINUE expr { $$ = NEW_ST(); SET_LOC(AS_ST($$), @$); AS_ST($$)->type = ST_CONT; AS_ST($$)->cont = NEW(cont_node); AS_ST($$)->cont->val = $2; }
- | stmt SEMICOLON { $$ = $1; }
- ;
-
- expr:
- control_expr { $$ = $1; }
- ;
-
- control_expr:
- IF expr THEN stmt_list if_termin {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_IFELSE;
- AS_EX($$)->ifelse = NEW(ifelse_node);
- AS_EX($$)->ifelse->cond = $2;
- AS_EX($$)->ifelse->iftrue = $4;
- AS_EX($$)->ifelse->iffalse = $5;
- }
- | WHILE expr DO stmt_list END {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_LOOP;
- AS_EX($$)->loop = NEW(loop_node);
- AS_EX($$)->loop->cond = $2;
- AS_EX($$)->loop->loop = $4;
- }
- | FOR IDENT IN expr DO stmt_list END {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ITER;
- AS_EX($$)->iter = NEW(iter_node);
- AS_EX($$)->iter->var = $2;
- AS_EX($$)->iter->iter = $4;
- AS_EX($$)->iter->loop = $6;
- }
- | assign_expr { $$ = $1; }
- ;
-
- if_termin:
- ELSEIF expr THEN stmt_list if_termin {
- $$ = NEW_ST();
- AS_ST($$)->type = ST_EXPR;
- AS_ST($$)->expr = NEW_EX();
- AS_ST($$)->expr->type = EX_IFELSE;
- AS_ST($$)->expr->ifelse = NEW(ifelse_node);
- AS_ST($$)->expr->ifelse->cond = $2;
- AS_ST($$)->expr->ifelse->iftrue = $4;
- AS_ST($$)->expr->ifelse->iffalse = $5;
- }
- | ELSE stmt_list END {
- $$ = $2;
- }
- | END { $$ = NULL; }
- ;
-
- assign_expr:
- IDENT ASSIGN expr { $$ = NEW_EX(); AS_EX($$)->type = EX_ASSIGN; AS_EX($$)->assign = NEW(assign_node); AS_EX($$)->assign->ident = $1; AS_EX($$)->assign->value = $3; }
- | IDENT ASSIGNPLUS expr {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ASSIGN;
- AS_EX($$)->assign = NEW(assign_node);
- AS_EX($$)->assign->ident = $1;
- MAKE_REF_BINOP(AS_EX($$)->assign->value, OP_ADD, $1, $3);
- }
- | IDENT ASSIGNMINUS expr {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ASSIGN;
- AS_EX($$)->assign = NEW(assign_node);
- AS_EX($$)->assign->ident = $1;
- MAKE_REF_BINOP(AS_EX($$)->assign->value, OP_SUB, $1, $3);
- }
- | IDENT ASSIGNSTAR expr {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ASSIGN;
- AS_EX($$)->assign = NEW(assign_node);
- AS_EX($$)->assign->ident = $1;
- MAKE_REF_BINOP(AS_EX($$)->assign->value, OP_MUL, $1, $3);
- }
- | IDENT ASSIGNSLASH expr {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ASSIGN;
- AS_EX($$)->assign = NEW(assign_node);
- AS_EX($$)->assign->ident = $1;
- MAKE_REF_BINOP(AS_EX($$)->assign->value, OP_DIV, $1, $3);
- }
- | IDENT ASSIGNDSTAR expr {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ASSIGN;
- AS_EX($$)->assign = NEW(assign_node);
- AS_EX($$)->assign->ident = $1;
- MAKE_REF_BINOP(AS_EX($$)->assign->value, OP_POW, $1, $3);
- }
- | IDENT ASSIGNBAND expr {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ASSIGN;
- AS_EX($$)->assign = NEW(assign_node);
- AS_EX($$)->assign->ident = $1;
- MAKE_REF_BINOP(AS_EX($$)->assign->value, OP_BAND, $1, $3);
- }
- | IDENT ASSIGNBOR expr {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ASSIGN;
- AS_EX($$)->assign = NEW(assign_node);
- AS_EX($$)->assign->ident = $1;
- MAKE_REF_BINOP(AS_EX($$)->assign->value, OP_BOR, $1, $3);
- }
- | IDENT ASSIGNBXOR expr {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_ASSIGN;
- AS_EX($$)->assign = NEW(assign_node);
- AS_EX($$)->assign->ident = $1;
- MAKE_REF_BINOP(AS_EX($$)->assign->value, OP_BXOR, $1, $3);
- }
- | ex_index_expr ASSIGN expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- AS_EX($$)->setindex->value = $3;
- ex_free(AS_EX($1));
- }
- | ex_index_expr ASSIGNPLUS expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_ADD, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
- ex_free(AS_EX($1));
- }
- | ex_index_expr ASSIGNMINUS expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_SUB, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
- ex_free(AS_EX($1));
- }
- | ex_index_expr ASSIGNSTAR expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_MUL, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
- ex_free(AS_EX($1));
- }
- | ex_index_expr ASSIGNSLASH expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_DIV, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
- ex_free(AS_EX($1));
- }
- | ex_index_expr ASSIGNDSTAR expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_POW, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
- ex_free(AS_EX($1));
- }
- | ex_index_expr ASSIGNBAND expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BAND, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
- ex_free(AS_EX($1));
- }
- | ex_index_expr ASSIGNBOR expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BOR, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
- ex_free(AS_EX($1));
- }
- | ex_index_expr ASSIGNBXOR expr {
- if(AS_EX($1)->type != EX_INDEX) {
- yyerror(&@$, NULL, "Assigning to non-indexing expression");
- YYABORT;
- }
- $$ = NEW_EX();
- AS_EX($$)->type = EX_SETINDEX;
- AS_EX($$)->setindex = NEW(setindex_node);
- AS_EX($$)->setindex->expr = ex_copy(AS_EX($1)->index->expr);
- AS_EX($$)->setindex->index = ex_copy(AS_EX($1)->index->index);
- MAKE_IDX_BINOP(AS_EX($$)->setindex->value, OP_BXOR, AS_EX($1)->index->expr, AS_EX($1)->index->index, $3);
- ex_free(AS_EX($1));
- }
- | logic_expr { $$ = $1; }
- ;
-
- logic_expr:
- logic_expr LAND ulogic_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_LAND; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | logic_expr LOR ulogic_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_LOR; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | ulogic_expr { $$ = $1; }
- ;
-
- ulogic_expr:
- LNOT ulogic_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_UNOP; AS_EX($$)->unop = NEW(unop_node); AS_EX($$)->unop->type = OP_LNOT; AS_EX($$)->unop->expr = $2; }
- | rel_expr { $$ = $1; }
- ;
-
- rel_expr:
- term_expr EQUAL rel_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_EQUAL; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | term_expr NEQUAL rel_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_NEQUAL; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | term_expr LESS rel_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_LESS; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | term_expr GREATER rel_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_GREATER; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | term_expr LESSEQ rel_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_LESSEQ; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | term_expr GREATEREQ rel_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_GREATEREQ; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | term_expr { $$ = $1; }
- ;
-
- term_expr:
- term_expr PLUS factor_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_ADD; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | term_expr MINUS factor_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_SUB; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | factor_expr { $$ = $1; }
- ;
-
- factor_expr:
- factor_expr STAR power_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_MUL; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | factor_expr SLASH power_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_DIV; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | factor_expr PERCENT power_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_MOD; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | power_expr { $$ = $1; }
- ;
-
- power_expr:
- tbang_expr DSTAR power_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_POW; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | tbang_expr { $$ = $1; }
- ;
-
- tbang_expr:
- binary_expr TBANG tbang_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_TBANG; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | binary_expr { $$ = $1; }
- ;
-
-
- binary_expr:
- binary_expr BAND binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BAND; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | binary_expr BOR binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BOR; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | binary_expr BXOR binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_BXOR; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | binary_expr LSHIFT binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_LSHIFT; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | binary_expr RSHIFT binary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_BINOP; AS_EX($$)->binop = NEW(binop_node); AS_EX($$)->binop->type = OP_RSHIFT; AS_EX($$)->binop->left = $1; AS_EX($$)->binop->right = $3; }
- | ubinary_expr { $$ = $1; }
- ;
-
- ubinary_expr:
- BNOT ubinary_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_UNOP; AS_EX($$)->unop = NEW(unop_node); AS_EX($$)->unop->type = OP_BNOT; AS_EX($$)->unop->expr = $2; }
- | ulen_expr { $$ = $1; }
- ;
-
- ulen_expr:
- POUND ulen_expr { $$ = NEW_EX(); AS_EX($$)->type = EX_UNOP; AS_EX($$)->unop = NEW(unop_node); AS_EX($$)->unop->type = OP_LEN; AS_EX($$)->unop->expr = $2; }
- | call_expr { $$ = $1; }
- ;
-
- call_expr:
- call_expr LPAREN expr_list RPAREN { $$ = NEW_EX(); AS_EX($$)->type = EX_CALL; AS_EX($$)->call = NEW(call_node); AS_EX($$)->call->expr = $1; AS_EX($$)->call->args = $3; AS_EX($$)->call->method = NULL; }
- | call_expr COLON IDENT LPAREN expr_list RPAREN {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_CALL;
- AS_EX($$)->call = NEW(call_node);
- AS_EX($$)->call->expr = $1;
- AS_EX($$)->call->args = $5;
- AS_EX($$)->call->method = $3;
- }
- | funcdecl_expr { $$ = $1; }
- ;
-
- funcdecl_expr:
- FUNC IDENT any_lparen param_list RPAREN maybe_anno stmt_list END {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_FUNCDECL;
- AS_EX($$)->funcdecl = NEW(funcdecl_node);
- AS_EX($$)->funcdecl->name = $2;
- AS_EX($$)->funcdecl->params = $4;
- AS_EX($$)->funcdecl->anno = $6;
- AS_EX($$)->funcdecl->body = $7;
- AS_EX($$)->funcdecl->flags = 0;
- }
- | FUNC any_lparen param_list RPAREN maybe_anno stmt_list END {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_FUNCDECL;
- AS_EX($$)->funcdecl = NEW(funcdecl_node);
- AS_EX($$)->funcdecl->name = NULL;
- AS_EX($$)->funcdecl->params = $3;
- AS_EX($$)->funcdecl->anno = $5;
- AS_EX($$)->funcdecl->body = $6;
- AS_EX($$)->funcdecl->flags = 0;
- }
- | MACRO IDENT any_lparen param_list RPAREN maybe_anno stmt_list END {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_FUNCDECL;
- AS_EX($$)->funcdecl = NEW(funcdecl_node);
- AS_EX($$)->funcdecl->name = $2;
- AS_EX($$)->funcdecl->params = $4;
- AS_EX($$)->funcdecl->anno = $6;
- AS_EX($$)->funcdecl->body = $7;
- AS_EX($$)->funcdecl->flags = FUNC_IS_MACRO;
- }
- | MACRO any_lparen param_list RPAREN maybe_anno stmt_list END {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_FUNCDECL;
- AS_EX($$)->funcdecl = NEW(funcdecl_node);
- AS_EX($$)->funcdecl->name = NULL;
- AS_EX($$)->funcdecl->params = $3;
- AS_EX($$)->funcdecl->anno = $5;
- AS_EX($$)->funcdecl->body = $6;
- AS_EX($$)->funcdecl->flags = FUNC_IS_MACRO;
- }
- | LAMBDA any_lparen param_list RPAREN maybe_anno expr END {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_FUNCDECL;
- AS_EX($$)->funcdecl = NEW(funcdecl_node);
- AS_EX($$)->funcdecl->name = NULL;
- AS_EX($$)->funcdecl->params = $3;
- AS_EX($$)->funcdecl->anno = $5;
- AS_EX($$)->funcdecl->body = NEW_ST();
- AS_EX($$)->funcdecl->body->type = ST_RET;
- AS_EX($$)->funcdecl->body->ret = NEW(ret_node);
- AS_EX($$)->funcdecl->body->ret->ret = $6;
- AS_EX($$)->funcdecl->flags = 0;
- }
- | MACRO LAMBDA any_lparen param_list RPAREN maybe_anno expr END {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_FUNCDECL;
- AS_EX($$)->funcdecl = NEW(funcdecl_node);
- AS_EX($$)->funcdecl->name = NULL;
- AS_EX($$)->funcdecl->params = $4;
- AS_EX($$)->funcdecl->anno = $6;
- AS_EX($$)->funcdecl->body = NEW_ST();
- AS_EX($$)->funcdecl->body->type = ST_RET;
- AS_EX($$)->funcdecl->body->ret = NEW(ret_node);
- AS_EX($$)->funcdecl->body->ret->ret = $7;
- AS_EX($$)->funcdecl->flags = FUNC_IS_MACRO;
- }
- | index_expr { $$ = $1; }
- ;
-
- index_expr:
- expr LBRACKET expr RBRACKET { $$ = NEW_EX(); AS_EX($$)->type = EX_INDEX; AS_EX($$)->index = NEW(index_node); AS_EX($$)->index->expr = $1; AS_EX($$)->index->index = $3; }
- | expr DOT IDENT {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_INDEX;
- AS_EX($$)->index = NEW(index_node);
- AS_EX($$)->index->expr = $1;
- AS_EX($$)->index->index = NEW_EX();
- AS_EX($$)->index->index->type = EX_LIT;
- AS_EX($$)->index->index->lit = NEW(lit_node);
- AS_EX($$)->index->index->lit->type = LIT_STRING;
- AS_EX($$)->index->index->lit->str = $3;
- }
- | ref_expr { $$ = $1; }
- ;
-
- ex_index_expr:
- expr LBRACKET expr RBRACKET { $$ = NEW_EX(); AS_EX($$)->type = EX_INDEX; AS_EX($$)->index = NEW(index_node); AS_EX($$)->index->expr = $1; AS_EX($$)->index->index = $3; }
- | expr DOT IDENT {
- $$ = NEW_EX();
- AS_EX($$)->type = EX_INDEX;
- AS_EX($$)->index = NEW(index_node);
- AS_EX($$)->index->expr = $1;
- AS_EX($$)->index->index = NEW_EX();
- AS_EX($$)->index->index->type = EX_LIT;
- AS_EX($$)->index->index->lit = NEW(lit_node);
- AS_EX($$)->index->index->lit->type = LIT_STRING;
- AS_EX($$)->index->index->lit->str = $3;
- }
- ;
-
- ref_expr:
- IDENT { $$ = NEW_EX(); AS_EX($$)->type = EX_REF; AS_EX($$)->ref = NEW(ref_node); AS_EX($$)->ref->ident = $1; }
- | lit_expr { $$ = $1; }
- ;
-
- lit_expr:
- INT { $$ = NEW_EX(); AS_EX($$)->type = EX_LIT; AS_EX($$)->lit = NEW(lit_node); AS_EX($$)->lit->type = LIT_INT; AS_EX($$)->lit->ival = *AS($1, long); free($1); }
- | MINUS INT { $$ = NEW_EX(); AS_EX($$)->type = EX_LIT; AS_EX($$)->lit = NEW(lit_node); AS_EX($$)->lit->type = LIT_INT; AS_EX($$)->lit->ival = -(*AS($2, long)); free($2); }
- | FLOAT { $$ = NEW_EX(); AS_EX($$)->type = EX_LIT; AS_EX($$)->lit = NEW(lit_node); AS_EX($$)->lit->type = LIT_FLOAT; AS_EX($$)->lit->fval = *AS($1, double); free($1); }
- | STRING { $$ = NEW_EX(); AS_EX($$)->type = EX_LIT; AS_EX($$)->lit = NEW(lit_node); AS_EX($$)->lit->type = LIT_BUFFER; AS_EX($$)->lit->buf = $1; }
- | NONE { $$ = NEW_EX(); AS_EX($$)->type = EX_LIT; AS_EX($$)->lit = NEW(lit_node); AS_EX($$)->lit->type = LIT_NONE; }
- | gen_expr { $$ = $1; }
- ;
-
- gen_expr:
- LBRACKET expr_list RBRACKET { $$ = NEW_EX(); AS_EX($$)->type = EX_LISTGEN; AS_EX($$)->listgen = NEW(listgen_node); AS_EX($$)->listgen->list = $2; }
- | LBRACE assoc_list RBRACE { $$ = NEW_EX(); AS_EX($$)->type = EX_MAPGEN; AS_EX($$)->mapgen = NEW(mapgen_node); AS_EX($$)->mapgen->map = $2; }
- | paren_expr { $$ = $1; }
- ;
-
- paren_expr:
- any_lparen expr RPAREN { $$ = $2; }
- ;
-
- expr_list:
- /*empty*/ { $$ = NULL; }
- | expr {
- $$ = NEW(exprlist_node);
- AS($$, exprlist_node)->expr = $1;
- AS($$, exprlist_node)->next = NULL;
- }
- | expr_list COMMA { $$ = $1; }
- | expr_list expr {
- exprlist_node *cur = $1;
- if(!cur) {
- cur = NEW(exprlist_node);
- cur->expr = $2;
- cur->next = NULL;
- $$ = cur;
- } else {
- while(cur->next) cur = cur->next;
- cur->next = NEW(exprlist_node);
- cur = cur->next;
- cur->expr = $2;
- cur->next = NULL;
- $$ = $1;
- }
- }
- ;
-
- ident_list:
- /*empty*/ { $$ = NULL; }
- | IDENT {
- $$ = NEW(identlist_node);
- AS($$, identlist_node)->ident = $1;
- AS($$, identlist_node)->next = NULL;
- }
- | ident_list COMMA { $$ = $1; }
- | ident_list IDENT {
- identlist_node *cur = $1;
- if(!cur) {
- cur = NEW(identlist_node);
- cur->ident = $2;
- cur->next = NULL;
- $$ = cur;
- } else {
- while(cur->next) cur = cur->next;
- cur->next = NEW(identlist_node);
- cur = cur->next;
- cur->ident = $2;
- cur->next = NULL;
- $$ = $1;
- }
- }
- ;
-
- param_list:
- /*empty*/ { $$ = NULL; }
- | param_list IDENT ASSIGN expr {
- paramlist_node *pl = $1;
- identlist_node *curk;
- exprlist_node *curv;
- if(!pl) {
- pl = NEW(paramlist_node);
- pl->args = NULL;
- pl->annos = NULL;
- pl->clkeys = NULL;
- pl->clvalues = NULL;
- pl->rest = NULL;
- }
- if(!pl->clkeys) {
- pl->clkeys = NEW(identlist_node);
- curk = pl->clkeys;
- pl->clvalues = NEW(exprlist_node);
- curv = pl->clvalues;
- } else {
- curk = pl->clkeys;
- curv = pl->clvalues;
- while(curk->next) {
- curk = curk->next;
- curv = curv->next;
- }
- curk->next = NEW(identlist_node);
- curk = curk->next;
- curv->next = NEW(exprlist_node);
- curv = curv->next;
- }
- curk->ident = $2;
- curk->next = NULL;
- curv->expr = $4;
- curv->next = NULL;
- $$ = pl;
- }
- | param_list STAR IDENT {
- paramlist_node *pl = $1;
- if(!pl) {
- pl = NEW(paramlist_node);
- pl->args = NULL;
- pl->annos = NULL;
- pl->clkeys = NULL;
- pl->clvalues = NULL;
- pl->rest = NULL;
- }
- pl-> rest = $3;
- $$ = pl;
- }
- | param_list IDENT maybe_anno {
- paramlist_node *pl = $1;
- identlist_node *cura;
- exprlist_node *curn;
- if(!pl) {
- pl = NEW(paramlist_node);
- pl->args = NULL;
- pl->annos = NULL;
- pl->clkeys = NULL;
- pl->clvalues = NULL;
- pl->rest = NULL;
- }
- if(!pl->args) {
- pl->args = NEW(identlist_node);
- cura = pl->args;
- pl->annos = NEW(exprlist_node);
- curn = pl->annos;
- } else {
- cura = pl->args;
- curn = pl->annos;
- while(cura->next) {
- cura = cura->next;
- curn = curn->next;
- }
- cura->next = NEW(identlist_node);
- cura = cura->next;
- curn->next = NEW(exprlist_node);
- curn = curn->next;
- }
- cura->ident = $2;
- cura->next = NULL;
- curn->expr = $3;
- curn->next = NULL;
- $$ = pl;
- }
- | param_list COMMA { $$ = $1; }
- ;
-
- assoc_list:
- /*empty*/ { $$ = NULL; }
- | assoc_item {
- $$ = NEW(assoclist_node);
- AS($$, assoclist_node)->item = $1;
- AS($$, assoclist_node)->next = NULL;
- }
- | assoc_list COMMA { $$ = $1; }
- | assoc_list assoc_item {
- assoclist_node *cur = $1;
- if(!cur) {
- cur = NEW(assoclist_node);
- cur->item = $2;
- cur->next = NULL;
- $$ = cur;
- } else {
- while(cur->next) cur = cur->next;
- cur->next = NEW(assoclist_node);
- cur = cur->next;
- cur->item = $2;
- cur->next = NULL;
- $$ = $1;
- }
- }
- ;
-
- assoc_item:
- LBRACKET expr RBRACKET ASSIGN expr {
- $$ = NEW(associtem_node);
- AS($$, associtem_node)->key = $2;
- AS($$, associtem_node)->value = $5;
- }
- | IDENT ASSIGN expr {
- $$ = NEW(associtem_node);
- AS($$, associtem_node)->key = NEW_EX();
- AS($$, associtem_node)->key->type = EX_LIT;
- AS($$, associtem_node)->key->lit = NEW(lit_node);
- AS($$, associtem_node)->key->lit->type = LIT_STRING;
- AS($$, associtem_node)->key->lit->str = $1;
- AS($$, associtem_node)->value = $3;
- }
- ;
-
- any_lparen:
- LPAREN
- | BLPAREN
- ;
-
- maybe_anno:
- COLON expr { $$ = $2; }
- | /* empty */ { $$ = NULL; }
- ;
-
- %%
-
- // TODO
|