%{ #include #include #include #include "paper.h" #include "impl.h" %} %union { Node *node; Lsym *sym; uvlong ival; float fval; String *string; } %type expr monexpr zindex term stmnt name args zexpr slist %type idlist %type zname %left ';' %right '=' %left Toror %left Tandand %left '|' %left '^' %left '&' %left Teq Tneq %left '<' '>' Tleq Tgeq %left Tlsh Trsh %left '+' '-' %left '*' '/' '%' %right Tdec Tinc Tindir '.' '[' '(' %token Tid %token Tconst %token Tfconst %token Tstring %token Tif Tdo Tthen Telse Twhile Thead Ttail Tappend Tfn Tret Tlocal %token Tfor Tbreak Tcontinue %token Twhat Tdelete Teval Tbuiltin %% prog : | prog bigstmnt ; bigstmnt : stmnt { syncheck($1); execrec($1); } | Tfn Tid '(' args ')' zsemi '{' slist '}' { syncheck($8); $2->proc = an(OLIST, $4, $8); $2->v->set = 1; $2->v->store.type = TCODE; } | Tfn Tid { $2->proc = nil; $2->v->set = 0; } ; zsemi : | ';' zsemi zname : { $$ = 0; } | Tid ; slist : stmnt | slist stmnt { $$ = an(OLIST, $1, $2); } ; stmnt : zexpr ';' | '{' slist '}' { $$ = $2; } | Tif expr Tthen stmnt { $$ = an(OIF, $2, $4); } | Tif expr Tthen stmnt Telse stmnt { $$ = an(OIF, $2, an(OELSE, $4, $6)); } | Tfor '(' zexpr ';' zexpr ';' zexpr ')' stmnt { $$ = an(OFOR, an(OLIST, $3, an(OLIST, $5, $7)), $9); } | Twhile expr Tdo stmnt { $$ = an(OWHILE, $2, $4); } | Tret expr ';' { $$ = an(ORET, $2, ZN); } | Tlocal idlist { $$ = an(OLOCAL, $2, ZN); } | Tbreak ';' { $$ = an(OBREAK, ZN, ZN); } | Tcontinue ';' { $$ = an(OCONTINUE, ZN, ZN); } ; idlist : Tid { $$ = an(ONAME, ZN, ZN); $$->sym = $1; } | idlist ',' Tid { $$ = an(ONAME, $1, ZN); $$->sym = $3; } ; zexpr : { $$ = 0; } | expr ; expr : monexpr | expr '*' expr { $$ = an(OMUL, $1, $3); } | expr '/' expr { $$ = an(ODIV, $1, $3); } | expr '%' expr { $$ = an(OMOD, $1, $3); } | expr '+' expr { $$ = an(OADD, $1, $3); } | expr '-' expr { $$ = an(OSUB, $1, $3); } | expr Trsh expr { $$ = an(ORSH, $1, $3); } | expr Tlsh expr { $$ = an(OLSH, $1, $3); } | expr '<' expr { $$ = an(OLT, $1, $3); } | expr '>' expr { $$ = an(OGT, $1, $3); } | expr Tleq expr { $$ = an(OLEQ, $1, $3); } | expr Tgeq expr { $$ = an(OGEQ, $1, $3); } | expr Teq expr { $$ = an(OEQ, $1, $3); } | expr Tneq expr { $$ = an(ONEQ, $1, $3); } | expr '&' expr { $$ = an(OLAND, $1, $3); } | expr '^' expr { $$ = an(OXOR, $1, $3); } | expr '|' expr { $$ = an(OLOR, $1, $3); } | expr Tandand expr { $$ = an(OCAND, $1, $3); } | expr Toror expr { $$ = an(OCOR, $1, $3); } | expr '=' expr { $$ = an(OASGN, $1, $3); } ; monexpr : term | '*' monexpr { $$ = an(OINDM, $2, ZN); } | '@' monexpr { $$ = an(OINDC, $2, ZN); } | '+' monexpr { $$ = an(OADD, $2, ZN); } | '-' monexpr { $$ = ppconst(0); $$ = an(OSUB, $$, $2); } | Tdec monexpr { $$ = an(OEDEC, $2, ZN); } | Tinc monexpr { $$ = an(OEINC, $2, ZN); } | Thead monexpr { $$ = an(OHEAD, $2, ZN); } | Ttail monexpr { $$ = an(OTAIL, $2, ZN); } | Tappend monexpr ',' monexpr { $$ = an(OAPPEND2, $2, $4); } | Tdelete monexpr ',' monexpr { $$ = an(ODELETE, $2, $4); } | '!' monexpr { $$ = an(ONOT, $2, ZN); } | '~' monexpr { $$ = an(OXOR, $2, ppconst(-1)); } | Teval monexpr { $$ = an(OEVAL, $2, ZN); } ; zindex : term '[' expr ']' { $$ = an(OINDEX, $1, $3); } ; term : zindex | '(' expr ')' { $$ = $2; } | '{' args '}' { $$ = an(OCTRUCT, $2, ZN); } | term Tdec { $$ = an(OPDEC, $1, ZN); } | term '.' Tid { $$ = an(ODOT, $1, ZN); $$->sym = $3; } | term Tindir Tid { $$ = an(ODOT, an(OINDM, $1, ZN), ZN); $$->sym = $3; } | term Tinc { $$ = an(OPINC, $1, ZN); } | name '(' args ')' { $$ = an(OCALL, $1, $3); } | Tbuiltin name '(' args ')' { $$ = an(OCALL, $2, $4); $$->builtin = 1; } | name | Tconst { $$ = ppconst($1); } | Tfconst { $$ = an(OCONST, ZN, ZN); $$->store.type = TFLOAT; $$->store.fval = $1; } | Tstring { $$ = an(OCONST, ZN, ZN); $$->store.type = TSTRING; $$->store.string = $1; } | Twhat zname { $$ = an(OWHAT, ZN, ZN); $$->sym = $2; } ; name : Tid { $$ = an(ONAME, ZN, ZN); $$->sym = $1; } ; args : zexpr | args ',' zexpr { $$ = an(OLIST, $1, $3); } ;