1 %{ 2 #include <u.h> 3 #include <libc.h> 4 #include <bio.h> 5 #include <mach.h> 6 #define Extern extern 7 #include "acid.h" 8 %} 9 10 %union 11 { 12 Node *node; 13 Lsym *sym; 14 uvlong ival; 15 float fval; 16 String *string; 17 } 18 19 %type <node> expr monexpr term stmnt name args zexpr slist 20 %type <node> member members mname castexpr idlist 21 %type <sym> zname 22 23 %left ';' 24 %right '=' 25 %left Tfmt 26 %left Toror 27 %left Tandand 28 %left '|' 29 %left '^' 30 %left '&' 31 %left Teq Tneq 32 %left '<' '>' Tleq Tgeq 33 %left Tlsh Trsh 34 %left '+' '-' 35 %left '*' '/' '%' 36 %right Tdec Tinc Tindir '.' '[' '(' 37 38 %token <sym> Tid 39 %token <ival> Tconst Tfmt 40 %token <fval> Tfconst 41 %token <string> Tstring 42 %token Tif Tdo Tthen Telse Twhile Tloop Thead Ttail Tappend Tfn Tret Tlocal 43 %token Tcomplex Twhat Tdelete Teval Tbuiltin 44 45 %% 46 47 prog : 48 | prog bigstmnt 49 ; 50 51 bigstmnt : stmnt 52 { 53 /* make stmnt a root so it isn't collected! */ 54 mkvar("_thiscmd")->proc = $1; 55 execute($1); 56 mkvar("_thiscmd")->proc = nil; 57 gc(); 58 if(interactive) 59 Bprint(bout, "acid: "); 60 } 61 | Tfn Tid '(' args ')' zsemi '{' slist '}' 62 { 63 $2->proc = an(OLIST, $4, $8); 64 } 65 | Tfn Tid 66 { 67 $2->proc = nil; 68 } 69 | Tcomplex name '{' members '}' ';' 70 { 71 defcomplex($2, $4); 72 } 73 ; 74 75 zsemi : 76 | ';' zsemi 77 78 members : member 79 | members member 80 { 81 $$ = an(OLIST, $1, $2); 82 } 83 ; 84 85 mname : Tid 86 { 87 $$ = an(ONAME, ZN, ZN); 88 $$->sym = $1; 89 } 90 ; 91 92 member : Tconst Tconst mname ';' 93 { 94 $3->ival = $2; 95 $3->fmt = $1; 96 $$ = $3; 97 } 98 | Tconst mname Tconst mname ';' 99 { 100 $4->ival = $3; 101 $4->fmt = $1; 102 $4->right = $2; 103 $$ = $4; 104 } 105 | mname Tconst mname ';' 106 { 107 $3->ival = $2; 108 $3->left = $1; 109 $$ = $3; 110 } 111 | '{' members '}' ';' 112 { 113 $$ = an(OCTRUCT, $2, ZN); 114 } 115 ; 116 117 zname : 118 { $$ = 0; } 119 | Tid 120 ; 121 122 slist : stmnt 123 | slist stmnt 124 { 125 $$ = an(OLIST, $1, $2); 126 } 127 ; 128 129 stmnt : zexpr ';' 130 | '{' slist '}' 131 { 132 $$ = $2; 133 } 134 | Tif expr Tthen stmnt 135 { 136 $$ = an(OIF, $2, $4); 137 } 138 | Tif expr Tthen stmnt Telse stmnt 139 { 140 $$ = an(OIF, $2, an(OELSE, $4, $6)); 141 } 142 | Tloop expr ',' expr Tdo stmnt 143 { 144 $$ = an(ODO, an(OLIST, $2, $4), $6); 145 } 146 | Twhile expr Tdo stmnt 147 { 148 $$ = an(OWHILE, $2, $4); 149 } 150 | Tret expr ';' 151 { 152 $$ = an(ORET, $2, ZN); 153 } 154 | Tlocal idlist 155 { 156 $$ = an(OLOCAL, $2, ZN); 157 } 158 | Tcomplex Tid name ';' 159 { 160 $$ = an(OCOMPLEX, $3, ZN); 161 $$->sym = $2; 162 } 163 ; 164 165 idlist : Tid 166 { 167 $$ = an(ONAME, ZN, ZN); 168 $$->sym = $1; 169 } 170 | idlist ',' Tid 171 { 172 $$ = an(ONAME, $1, ZN); 173 $$->sym = $3; 174 } 175 ; 176 177 zexpr : 178 { $$ = 0; } 179 | expr 180 ; 181 182 expr : castexpr 183 | expr '*' expr 184 { 185 $$ = an(OMUL, $1, $3); 186 } 187 | expr '/' expr 188 { 189 $$ = an(ODIV, $1, $3); 190 } 191 | expr '%' expr 192 { 193 $$ = an(OMOD, $1, $3); 194 } 195 | expr '+' expr 196 { 197 $$ = an(OADD, $1, $3); 198 } 199 | expr '-' expr 200 { 201 $$ = an(OSUB, $1, $3); 202 } 203 | expr Trsh expr 204 { 205 $$ = an(ORSH, $1, $3); 206 } 207 | expr Tlsh expr 208 { 209 $$ = an(OLSH, $1, $3); 210 } 211 | expr '<' expr 212 { 213 $$ = an(OLT, $1, $3); 214 } 215 | expr '>' expr 216 { 217 $$ = an(OGT, $1, $3); 218 } 219 | expr Tleq expr 220 { 221 $$ = an(OLEQ, $1, $3); 222 } 223 | expr Tgeq expr 224 { 225 $$ = an(OGEQ, $1, $3); 226 } 227 | expr Teq expr 228 { 229 $$ = an(OEQ, $1, $3); 230 } 231 | expr Tneq expr 232 { 233 $$ = an(ONEQ, $1, $3); 234 } 235 | expr '&' expr 236 { 237 $$ = an(OLAND, $1, $3); 238 } 239 | expr '^' expr 240 { 241 $$ = an(OXOR, $1, $3); 242 } 243 | expr '|' expr 244 { 245 $$ = an(OLOR, $1, $3); 246 } 247 | expr Tandand expr 248 { 249 $$ = an(OCAND, $1, $3); 250 } 251 | expr Toror expr 252 { 253 $$ = an(OCOR, $1, $3); 254 } 255 | expr '=' expr 256 { 257 $$ = an(OASGN, $1, $3); 258 } 259 | expr Tfmt 260 { 261 $$ = an(OFMT, $1, con($2)); 262 } 263 ; 264 265 castexpr : monexpr 266 | '(' Tid ')' monexpr 267 { 268 $$ = an(OCAST, $4, ZN); 269 $$->sym = $2; 270 } 271 ; 272 273 monexpr : term 274 | '*' monexpr 275 { 276 $$ = an(OINDM, $2, ZN); 277 } 278 | '@' monexpr 279 { 280 $$ = an(OINDC, $2, ZN); 281 } 282 | '+' monexpr 283 { 284 $$ = an(OADD, $2, ZN); 285 } 286 | '-' monexpr 287 { 288 $$ = con(0); 289 $$ = an(OSUB, $$, $2); 290 } 291 | Tdec monexpr 292 { 293 $$ = an(OEDEC, $2, ZN); 294 } 295 | Tinc monexpr 296 { 297 $$ = an(OEINC, $2, ZN); 298 } 299 | Thead monexpr 300 { 301 $$ = an(OHEAD, $2, ZN); 302 } 303 | Ttail monexpr 304 { 305 $$ = an(OTAIL, $2, ZN); 306 } 307 | Tappend monexpr ',' monexpr 308 { 309 $$ = an(OAPPEND, $2, $4); 310 } 311 | Tdelete monexpr ',' monexpr 312 { 313 $$ = an(ODELETE, $2, $4); 314 } 315 | '!' monexpr 316 { 317 $$ = an(ONOT, $2, ZN); 318 } 319 | '~' monexpr 320 { 321 $$ = an(OXOR, $2, con(-1)); 322 } 323 | Teval monexpr 324 { 325 $$ = an(OEVAL, $2, ZN); 326 } 327 ; 328 329 term : '(' expr ')' 330 { 331 $$ = $2; 332 } 333 | '{' args '}' 334 { 335 $$ = an(OCTRUCT, $2, ZN); 336 } 337 | term '[' expr ']' 338 { 339 $$ = an(OINDEX, $1, $3); 340 } 341 | term Tdec 342 { 343 $$ = an(OPDEC, $1, ZN); 344 } 345 | term '.' Tid 346 { 347 $$ = an(ODOT, $1, ZN); 348 $$->sym = $3; 349 } 350 | term Tindir Tid 351 { 352 $$ = an(ODOT, an(OINDM, $1, ZN), ZN); 353 $$->sym = $3; 354 } 355 | term Tinc 356 { 357 $$ = an(OPINC, $1, ZN); 358 } 359 | name '(' args ')' 360 { 361 $$ = an(OCALL, $1, $3); 362 } 363 | Tbuiltin name '(' args ')' 364 { 365 $$ = an(OCALL, $2, $4); 366 $$->builtin = 1; 367 } 368 | name 369 | Tconst 370 { 371 $$ = con($1); 372 } 373 | Tfconst 374 { 375 $$ = an(OCONST, ZN, ZN); 376 $$->type = TFLOAT; 377 $$->fmt = 'f'; 378 $$->fval = $1; 379 } 380 | Tstring 381 { 382 $$ = an(OCONST, ZN, ZN); 383 $$->type = TSTRING; 384 $$->string = $1; 385 $$->fmt = 's'; 386 } 387 | Twhat zname 388 { 389 $$ = an(OWHAT, ZN, ZN); 390 $$->sym = $2; 391 } 392 ; 393 394 name : Tid 395 { 396 $$ = an(ONAME, ZN, ZN); 397 $$->sym = $1; 398 } 399 | Tid ':' name 400 { 401 $$ = an(OFRAME, $3, ZN); 402 $$->sym = $1; 403 } 404 ; 405 406 args : zexpr 407 | args ',' zexpr 408 { 409 $$ = an(OLIST, $1, $3); 410 } 411 ; 412