3 Extension module for the rfxswf library.
4 Part of the swftools package.
6 Copyright (c) 2009 Matthias Kramm <kramm@quiss.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
24 #include "tokenizer.h"
26 #define IS_INT(a) (TYPE_IS_INT((a)) || TYPE_IS_UINT((a)))
27 #define BOTH_INT(a,b) (IS_INT(a) && IS_INT(b))
29 #define READ_HEADER_LEFTRIGHT \
30 typedcode_t left = n->child[0]->type->read(n->child[0]);\
31 typedcode_t right = n->child[1]->type->read(n->child[1]);\
35 #define READ_HEADER_ONE \
36 typedcode_t x = n->child[0]->type->read(n->child[0]);\
40 #define EXEC_HEADER_ONE \
41 code_t* x = n->child[0]->type->exec(n->child[0]);\
45 #define EXEC_HEADER_LEFTRIGHT \
46 code_t* left = n->child[0]->type->exec(n->child[0]);\
47 code_t* right = n->child[1]->type->exec(n->child[1]);\
51 #define EVAL_HEADER_LEFTRIGHT \
52 constant_t left = n->child[0]->type->eval(n->child[0]);\
53 constant_t right = n->child[1]->type->eval(n->child[1]);\
55 if(left.type==CONSTANT_UNKNOWN || right.type==CONSTANT_UNKNOWN) {\
56 r.type = CONSTANT_UNKNOWN;return r; \
66 static classinfo_t*join_types(classinfo_t*type1, classinfo_t*type2, nodetype_t*t)
68 if(TYPE_IS_ANY(type1))
72 if(TYPE_IS_XMLLIST(type1))
74 if(BOTH_INT(type1, type2))
76 if(IS_NUMBER_OR_INT(type1) && IS_NUMBER_OR_INT(type2))
78 if(TYPE_IS_ANY(type2))
80 return TYPE_OBJECT; // e.g. string+string = object
87 static char is_getlocal(code_t*c)
89 if(!c || c->prev || c->next)
91 return(c->opcode == OPCODE_GETLOCAL
92 || c->opcode == OPCODE_GETLOCAL_0
93 || c->opcode == OPCODE_GETLOCAL_1
94 || c->opcode == OPCODE_GETLOCAL_2
95 || c->opcode == OPCODE_GETLOCAL_3);
97 static int getlocalnr(code_t*c)
99 if(c->opcode == OPCODE_GETLOCAL) {return (ptroff_t)c->data[0];}
100 else if(c->opcode == OPCODE_GETLOCAL_0) {return 0;}
101 else if(c->opcode == OPCODE_GETLOCAL_1) {return 1;}
102 else if(c->opcode == OPCODE_GETLOCAL_2) {return 2;}
103 else if(c->opcode == OPCODE_GETLOCAL_3) {return 3;}
104 else syntaxerror("Internal error: opcode %02x is not a getlocal call", c->opcode);
109 int gettempvar(); /* FIXME: we should use a function pointer here */
112 static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char readbefore, char pushvalue)
116 [prefix code] [read instruction]
120 [prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar]
122 if(in && in->opcode == OPCODE_COERCE_A) {
123 in = code_cutlast(in);
126 syntaxerror("internal error");
128 /* chop off read instruction */
132 prefix = r->prev;r->prev = 0;
138 char use_temp_var = readbefore;
140 /* generate the write instruction, and maybe append a dup to the prefix code */
141 code_t* write = abc_nop(0);
142 if(r->opcode == OPCODE_GETPROPERTY) {
143 write->opcode = OPCODE_SETPROPERTY;
144 multiname_t*m = (multiname_t*)r->data[0];
145 write->data[0] = multiname_clone(m);
146 if(m->type == QNAME || m->type == MULTINAME ||
147 m->type == QNAMEA || m->type == MULTINAMEA) {
149 prefix = abc_dup(prefix); // we need the object, too
152 } else if(m->type == MULTINAMEL) {
154 /* dupping two values on the stack requires 5 operations and one register-
155 couldn't adobe just have given us a dup2? */
156 int temp = gettempvar();
157 prefix = abc_setlocal(prefix, temp);
158 prefix = abc_dup(prefix);
159 prefix = abc_getlocal(prefix, temp);
160 prefix = abc_swap(prefix);
161 prefix = abc_getlocal(prefix, temp);
163 prefix = abc_kill(prefix, temp);
167 syntaxerror("illegal lvalue: can't assign a value to this expression (not a qname/multiname)");
169 } else if(r->opcode == OPCODE_GETSLOT) {
170 write->opcode = OPCODE_SETSLOT;
171 write->data[0] = r->data[0];
173 prefix = abc_dup(prefix); // we need the object, too
176 } else if(r->opcode == OPCODE_GETLOCAL) {
177 write->opcode = OPCODE_SETLOCAL;
178 write->data[0] = r->data[0];
179 } else if(r->opcode == OPCODE_GETLOCAL_0) {
180 write->opcode = OPCODE_SETLOCAL_0;
181 } else if(r->opcode == OPCODE_GETLOCAL_1) {
182 write->opcode = OPCODE_SETLOCAL_1;
183 } else if(r->opcode == OPCODE_GETLOCAL_2) {
184 write->opcode = OPCODE_SETLOCAL_2;
185 } else if(r->opcode == OPCODE_GETLOCAL_3) {
186 write->opcode = OPCODE_SETLOCAL_3;
187 } else if(r->opcode == OPCODE_GETSUPER) {
188 write->opcode = OPCODE_SETSUPER;
189 multiname_t*m = (multiname_t*)r->data[0];
190 write->data[0] = multiname_clone(m);
193 syntaxerror("illegal lvalue: can't assign a value to this expression");
200 /* with getproperty/getslot, we have to be extra careful not
201 to execute the read code twice, as it might have side-effects
202 (e.g. if the property is in fact a setter/getter combination)
204 So read the value, modify it, and write it again,
205 using prefix only once and making sure (by using a temporary
206 register) that the return value is what we just wrote */
208 c = code_append(c, prefix);
209 c = code_append(c, r);
210 if(pushvalue && readbefore) {
212 c = abc_setlocal(c, temp);
214 c = code_append(c, middlepart);
215 if(pushvalue && !readbefore) {
217 c = abc_setlocal(c, temp);
219 c = code_append(c, write);
221 c = abc_getlocal(c, temp);
222 c = abc_kill(c, temp);
225 /* if we're allowed to execute the read code twice *and*
226 the middlepart doesn't modify the code, things are easier.
228 //c = code_append(c, prefix);
229 if(prefix) syntaxerror("internal error (prefix)");
234 c = code_append(c, r);
235 c = code_append(c, middlepart);
236 c = code_append(c, write);
238 c = code_append(c, r2);
242 /* even smaller version: overwrite the value without reading
246 c = code_append(c, prefix);
249 c = code_append(c, middlepart);
250 c = code_append(c, write);
252 c = code_append(c, r);
258 c = code_append(c, prefix);
260 c = code_append(c, middlepart);
263 c = abc_setlocal(c, temp);
265 c = code_append(c, write);
267 c = abc_getlocal(c, temp);
268 c = abc_kill(c, temp);
275 code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to);
277 int constant_to_int(constant_t*c)
280 case CONSTANT_INT: return c->i;
281 case CONSTANT_UINT: return (int)c->u;
282 case CONSTANT_FLOAT: return c->f;
283 case CONSTANT_TRUE: return 1;
284 case CONSTANT_FALSE: return 0;
285 case CONSTANT_STRING: return atoi(c->s->str);
286 default: syntaxerror("can't convert this constant to an integer");
290 double constant_to_float(constant_t*c)
293 case CONSTANT_INT: return (double)c->i;
294 case CONSTANT_UINT: return (double)c->u;
295 case CONSTANT_FLOAT: return c->f;
296 case CONSTANT_TRUE: return (double)1;
297 case CONSTANT_FALSE: return (double)0;
298 case CONSTANT_STRING: return atof(c->s->str);
299 default: syntaxerror("can't convert this constant to a float");
303 // -------------------------- x + y -----------------------------------
305 typedcode_t node_plus_write(node_t*n)
307 syntaxerror("can't assign to this expression");
309 typedcode_t node_plus_read(node_t*n)
311 READ_HEADER_LEFTRIGHT;
312 c = code_append(left.c, right.c);
313 if(BOTH_INT(left.t, right.t)) {
318 t = join_types(left.t,right.t,n->type);
322 code_t* node_plus_exec(node_t*n)
324 EXEC_HEADER_LEFTRIGHT;
325 return code_append(left, right);
327 constant_t node_plus_eval(node_t*n)
329 EVAL_HEADER_LEFTRIGHT;
330 char left_int = left.type == CONSTANT_INT || left.type == CONSTANT_UINT;
331 if(left_int && (right.type == CONSTANT_INT || right.type == CONSTANT_UINT)) {
332 /* FIXME: what to do about signed/unsigned overflows? */
333 int i = constant_to_int(&left) + constant_to_int(&right);
334 r.type = CONSTANT_INT;
336 } else if(left_int && right.type == CONSTANT_FLOAT) {
337 double f = constant_to_int(&left) + constant_to_float(&right);
338 r.type = CONSTANT_FLOAT;
340 } else if(left.type == CONSTANT_STRING) {
341 char*add = constant_tostring(&right);
342 int l1 = left.s->len;
343 int l2 = strlen(add);
344 char*s = malloc(l1+l2+1);
345 memcpy(s, left.s->str, l1);
346 memcpy(s+l1, add, l2);
348 r.type = CONSTANT_STRING;
349 r.s = malloc(sizeof(string_t));
354 r.type = CONSTANT_UNKNOWN;
358 nodetype_t node_plus =
361 flags:NODE_HAS_CHILDREN,
363 write:node_plus_write,
368 // -------------------------- x - y -----------------------------------
370 typedcode_t node_minus_write(node_t*n)
372 syntaxerror("can't assign to this expression");
374 typedcode_t node_minus_read(node_t*n)
376 READ_HEADER_LEFTRIGHT;
377 c = code_append(left.c, right.c);
378 if(BOTH_INT(left.t,right.t)) {
379 c = abc_subtract_i(c);
387 code_t* node_minus_exec(node_t*n)
389 EXEC_HEADER_LEFTRIGHT;
390 return code_append(left, right);
392 constant_t node_minus_eval(node_t*n)
394 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
396 nodetype_t node_minus =
399 flags:NODE_HAS_CHILDREN,
400 eval: node_minus_eval,
401 write: node_minus_write,
402 read: node_minus_read,
403 exec: node_minus_exec
406 // ---------------------------- ++x -----------------------------------
408 typedcode_t node_lplusplus_write(node_t*n)
410 syntaxerror("can't assign to this expression");
412 typedcode_t node_lplusplus_read(node_t*n)
416 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
417 int nr = getlocalnr(x.c);
418 code_free(x.c);x.c=0;
419 if(TYPE_IS_INT(x.t)) {
420 c = abc_inclocal_i(c, nr);
421 c = abc_getlocal(c, nr);
422 } else if(TYPE_IS_NUMBER(x.t)) {
423 c = abc_inclocal(c, nr);
424 c = abc_getlocal(c, nr);
425 } else syntaxerror("internal error");
427 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
428 c = abc_increment_i(c);
431 c = abc_increment(c);
434 c = converttype(c, t, x.t);
435 c = toreadwrite(x.c, c, 0, 0, 1);
440 code_t* node_lplusplus_exec(node_t*n)
442 typedcode_t x = n->child[0]->type->read(n->child[0]);
444 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
445 int nr = getlocalnr(x.c);
446 code_free(x.c);x.c=0;
447 if(TYPE_IS_INT(x.t)) {
448 c = abc_inclocal_i(c, nr);
449 } else if(TYPE_IS_NUMBER(x.t)) {
450 c = abc_inclocal(c, nr);
451 } else syntaxerror("internal error");
454 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
455 c = abc_increment_i(c);
458 c = abc_increment(c);
461 c = converttype(c, t, x.t); //convert back to original type
462 c = toreadwrite(x.c, c, 0, 0, 0);
467 constant_t node_lplusplus_eval(node_t*n)
469 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
471 nodetype_t node_lplusplus =
474 flags:NODE_HAS_CHILDREN,
475 eval: node_lplusplus_eval,
476 write: node_lplusplus_write,
477 read: node_lplusplus_read,
478 exec: node_lplusplus_exec
482 // ---------------------------- --x -----------------------------------
484 typedcode_t node_lminusminus_write(node_t*n)
486 syntaxerror("can't assign to this expression");
488 typedcode_t node_lminusminus_read(node_t*n)
492 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
493 int nr = getlocalnr(x.c);
494 code_free(x.c);x.c=0;
495 if(TYPE_IS_INT(x.t)) {
496 c = abc_declocal_i(c, nr);
497 c = abc_getlocal(c, nr);
498 } else if(TYPE_IS_NUMBER(x.t)) {
499 c = abc_declocal(c, nr);
500 c = abc_getlocal(c, nr);
501 } else syntaxerror("internal error");
503 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
504 c = abc_decrement_i(c);
507 c = abc_decrement(c);
510 c = converttype(c, t, x.t);
511 c = toreadwrite(x.c, c, 0, 0, 1);
516 code_t* node_lminusminus_exec(node_t*n)
518 typedcode_t x = n->child[0]->type->read(n->child[0]);
520 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
521 int nr = getlocalnr(x.c);
522 code_free(x.c);x.c=0;
523 if(TYPE_IS_INT(x.t)) {
524 c = abc_declocal_i(c, nr);
525 } else if(TYPE_IS_NUMBER(x.t)) {
526 c = abc_declocal(c, nr);
527 } else syntaxerror("internal error");
530 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
531 c = abc_decrement_i(c);
534 c = abc_decrement(c);
537 c = converttype(c, t, x.t); //convert back to original type
538 c = toreadwrite(x.c, c, 0, 0, 0);
543 constant_t node_lminusminus_eval(node_t*n)
545 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
547 nodetype_t node_lminusminus =
550 flags:NODE_HAS_CHILDREN,
551 eval: node_lminusminus_eval,
552 write: node_lminusminus_write,
553 read: node_lminusminus_read,
554 exec: node_lminusminus_exec
559 // ---------------------------- x++ -----------------------------------
561 typedcode_t node_rplusplus_write(node_t*n)
563 syntaxerror("can't assign to this expression");
565 typedcode_t node_rplusplus_read(node_t*n)
569 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
570 int nr = getlocalnr(x.c);
571 code_free(x.c);x.c=0;
572 if(TYPE_IS_INT(x.t)) {
573 c = abc_getlocal(0, nr);
574 c = abc_inclocal_i(c, nr);
575 } else if(TYPE_IS_NUMBER(x.t)) {
576 c = abc_getlocal(0, nr);
577 c = abc_inclocal(c, nr);
578 } else syntaxerror("internal error");
580 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
581 c = abc_increment_i(c);
584 c = abc_increment(c);
587 c = converttype(c, t, x.t);
588 c = toreadwrite(x.c, c, 0, 1, 1);
593 code_t* node_rplusplus_exec(node_t*n)
595 typedcode_t x = n->child[0]->type->read(n->child[0]);
597 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
598 int nr = getlocalnr(x.c);
599 code_free(x.c);x.c=0;
600 if(TYPE_IS_INT(x.t)) {
601 c = abc_inclocal_i(c, nr);
602 } else if(TYPE_IS_NUMBER(x.t)) {
603 c = abc_inclocal(c, nr);
604 } else syntaxerror("internal error");
607 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
608 c = abc_increment_i(c);
611 c = abc_increment(c);
614 c = converttype(c, t, x.t); //convert back to original type
615 c = toreadwrite(x.c, c, 0, 1, 0);
620 constant_t node_rplusplus_eval(node_t*n)
622 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
624 nodetype_t node_rplusplus =
627 flags:NODE_HAS_CHILDREN,
628 eval: node_rplusplus_eval,
629 write: node_rplusplus_write,
630 read: node_rplusplus_read,
631 exec: node_rplusplus_exec
634 // ---------------------------- x-- -----------------------------------
636 typedcode_t node_rminusminus_write(node_t*n)
638 syntaxerror("can't assign to this expression");
640 typedcode_t node_rminusminus_read(node_t*n)
644 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
645 int nr = getlocalnr(x.c);
646 code_free(x.c);x.c=0;
647 if(TYPE_IS_INT(x.t)) {
648 c = abc_getlocal(0, nr);
649 c = abc_declocal_i(c, nr);
650 } else if(TYPE_IS_NUMBER(x.t)) {
651 c = abc_getlocal(0, nr);
652 c = abc_declocal(c, nr);
653 } else syntaxerror("internal error");
655 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
656 c = abc_decrement_i(c);
659 c = abc_decrement(c);
662 c = converttype(c, t, x.t);
663 c = toreadwrite(x.c, c, 0, 1, 1);
668 code_t* node_rminusminus_exec(node_t*n)
670 typedcode_t x = n->child[0]->type->read(n->child[0]);
672 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
673 int nr = getlocalnr(x.c);
674 code_free(x.c);x.c=0;
675 if(TYPE_IS_INT(x.t)) {
676 c = abc_declocal_i(c, nr);
677 } else if(TYPE_IS_NUMBER(x.t)) {
678 c = abc_declocal(c, nr);
679 } else syntaxerror("internal error");
682 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
683 c = abc_decrement_i(c);
686 c = abc_decrement(c);
689 c = converttype(c, t, x.t); //convert back to original type
690 c = toreadwrite(x.c, c, 0, 1, 0);
695 constant_t node_rminusminus_eval(node_t*n)
697 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
699 nodetype_t node_rminusminus =
702 flags:NODE_HAS_CHILDREN,
703 eval: node_rminusminus_eval,
704 write: node_rminusminus_write,
705 read: node_rminusminus_read,
706 exec: node_rminusminus_exec
709 // ---------------------------- x*y -----------------------------------
711 typedcode_t node_multiply_write(node_t*n)
713 syntaxerror("can't assign to this expression");
715 typedcode_t node_multiply_read(node_t*n)
717 READ_HEADER_LEFTRIGHT;
718 c = code_append(left.c,right.c);
719 if(BOTH_INT(left.t,right.t)) {
720 c = abc_multiply_i(c);
728 code_t* node_multiply_exec(node_t*n)
730 EXEC_HEADER_LEFTRIGHT;
731 return code_append(left, right);
733 constant_t node_multiply_eval(node_t*n)
735 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
737 nodetype_t node_multiply =
740 flags:NODE_HAS_CHILDREN,
741 eval: node_multiply_eval,
742 write: node_multiply_write,
743 read: node_multiply_read,
744 exec: node_multiply_exec
747 // ---------------------------- x/y -----------------------------------
749 typedcode_t node_div_write(node_t*n)
751 syntaxerror("can't assign to this expression");
753 typedcode_t node_div_read(node_t*n)
755 READ_HEADER_LEFTRIGHT;
756 c = code_append(left.c, right.c);
761 code_t* node_div_exec(node_t*n)
763 EXEC_HEADER_LEFTRIGHT;
764 return code_append(left, right);
766 constant_t node_div_eval(node_t*n)
768 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
770 nodetype_t node_div =
773 flags:NODE_HAS_CHILDREN,
775 write: node_div_write,
780 // ---------------------------- x%y -----------------------------------
782 typedcode_t node_mod_write(node_t*n)
784 syntaxerror("can't assign to this expression");
786 typedcode_t node_mod_read(node_t*n)
788 READ_HEADER_LEFTRIGHT;
789 c = code_append(left.c, right.c);
794 code_t* node_mod_exec(node_t*n)
796 EXEC_HEADER_LEFTRIGHT;
797 return code_append(left, right);
799 constant_t node_mod_eval(node_t*n)
801 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
803 nodetype_t node_mod =
806 flags:NODE_HAS_CHILDREN,
808 write: node_mod_write,
813 // ---------------------------- x<y -----------------------------------
815 typedcode_t node_lt_write(node_t*n)
817 syntaxerror("can't assign to this expression");
819 typedcode_t node_lt_read(node_t*n)
821 READ_HEADER_LEFTRIGHT;
822 c = code_append(left.c,right.c);
827 code_t* node_lt_exec(node_t*n)
829 EXEC_HEADER_LEFTRIGHT;
830 return code_append(left, right);
832 constant_t node_lt_eval(node_t*n)
834 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
839 flags:NODE_HAS_CHILDREN,
841 write: node_lt_write,
846 // ---------------------------- x>y -----------------------------------
848 typedcode_t node_gt_write(node_t*n)
850 syntaxerror("can't assign to this expression");
852 typedcode_t node_gt_read(node_t*n)
854 READ_HEADER_LEFTRIGHT;
855 c = code_append(left.c,right.c);
856 c = abc_greaterthan(c);
860 code_t* node_gt_exec(node_t*n)
862 EXEC_HEADER_LEFTRIGHT;
863 return code_append(left, right);
865 constant_t node_gt_eval(node_t*n)
867 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
872 flags:NODE_HAS_CHILDREN,
874 write: node_gt_write,
879 // ---------------------------- x<=y ----------------------------------
881 typedcode_t node_le_write(node_t*n)
883 syntaxerror("can't assign to this expression");
885 typedcode_t node_le_read(node_t*n)
887 READ_HEADER_LEFTRIGHT;
888 c = code_append(left.c,right.c);
889 c = abc_lessequals(c);
893 code_t* node_le_exec(node_t*n)
895 EXEC_HEADER_LEFTRIGHT;
896 return code_append(left, right);
898 constant_t node_le_eval(node_t*n)
900 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
902 nodetype_t node_le = //<=
905 flags:NODE_HAS_CHILDREN,
907 write: node_le_write,
912 // ---------------------------- x>=y ----------------------------------
914 typedcode_t node_ge_write(node_t*n)
916 syntaxerror("can't assign to this expression");
918 typedcode_t node_ge_read(node_t*n)
920 READ_HEADER_LEFTRIGHT;
921 c = code_append(left.c,right.c);
922 c = abc_greaterequals(c);
926 code_t* node_ge_exec(node_t*n)
928 EXEC_HEADER_LEFTRIGHT;
929 return code_append(left, right);
931 constant_t node_ge_eval(node_t*n)
933 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
935 nodetype_t node_ge = //>=
938 flags:NODE_HAS_CHILDREN,
940 write: node_ge_write,
945 // ---------------------------- x==y ----------------------------------
947 typedcode_t node_eqeq_write(node_t*n)
949 syntaxerror("can't assign to this expression");
951 typedcode_t node_eqeq_read(node_t*n)
953 READ_HEADER_LEFTRIGHT;
954 c = code_append(left.c,right.c);
959 code_t* node_eqeq_exec(node_t*n)
961 EXEC_HEADER_LEFTRIGHT;
962 return code_append(left, right);
964 constant_t node_eqeq_eval(node_t*n)
966 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
968 nodetype_t node_eqeq = //==
971 flags:NODE_HAS_CHILDREN,
972 eval: node_eqeq_eval,
973 write: node_eqeq_write,
974 read: node_eqeq_read,
978 // --------------------------- x===y ----------------------------------
980 typedcode_t node_eqeqeq_write(node_t*n)
982 syntaxerror("can't assign to this expression");
984 typedcode_t node_eqeqeq_read(node_t*n)
986 READ_HEADER_LEFTRIGHT;
987 c = code_append(left.c,right.c);
988 c = abc_strictequals(c);
992 code_t* node_eqeqeq_exec(node_t*n)
994 EXEC_HEADER_LEFTRIGHT;
995 return code_append(left, right);
997 constant_t node_eqeqeq_eval(node_t*n)
999 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1001 nodetype_t node_eqeqeq = //===
1004 flags:NODE_HAS_CHILDREN,
1005 eval: node_eqeqeq_eval,
1006 write: node_eqeqeq_write,
1007 read: node_eqeqeq_read,
1008 exec: node_eqeqeq_exec
1011 // --------------------------- x!==y ----------------------------------
1013 typedcode_t node_noteqeq_write(node_t*n)
1015 syntaxerror("can't assign to this expression");
1017 typedcode_t node_noteqeq_read(node_t*n)
1019 READ_HEADER_LEFTRIGHT;
1020 c = code_append(left.c,right.c);
1021 c = abc_strictequals(c);
1026 code_t* node_noteqeq_exec(node_t*n)
1028 EXEC_HEADER_LEFTRIGHT;
1029 return code_append(left, right);
1031 constant_t node_noteqeq_eval(node_t*n)
1033 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1035 nodetype_t node_noteqeq = //!==
1038 flags:NODE_HAS_CHILDREN,
1039 eval: node_noteqeq_eval,
1040 write: node_noteqeq_write,
1041 read: node_noteqeq_read,
1042 exec: node_noteqeq_exec
1045 // --------------------------- x!=y ----------------------------------
1047 typedcode_t node_noteq_write(node_t*n)
1049 syntaxerror("can't assign to this expression");
1051 typedcode_t node_noteq_read(node_t*n)
1053 READ_HEADER_LEFTRIGHT;
1054 c = code_append(left.c,right.c);
1060 code_t* node_noteq_exec(node_t*n)
1062 EXEC_HEADER_LEFTRIGHT;
1063 return code_append(left, right);
1065 constant_t node_noteq_eval(node_t*n)
1067 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1069 nodetype_t node_noteq = //!=
1072 flags:NODE_HAS_CHILDREN,
1073 eval: node_noteq_eval,
1074 write: node_noteq_write,
1075 read: node_noteq_read,
1076 exec: node_noteq_exec
1079 // --------------------------- x||y ----------------------------------
1081 typedcode_t node_oror_write(node_t*n)
1083 syntaxerror("can't assign to this expression");
1085 typedcode_t node_oror_read(node_t*n)
1087 READ_HEADER_LEFTRIGHT;
1088 t = join_types(left.t, right.t, n->type);
1090 c = converttype(c, left.t, t);
1092 code_t*jmp = c = abc_iftrue(c, 0);
1093 c = cut_last_push(c);
1094 c = code_append(c, right.c);
1095 c = converttype(c, right.t, t);
1096 code_t*label = c = abc_label(c);
1097 jmp->branch = label;
1100 code_t* node_oror_exec(node_t*n)
1102 typedcode_t left = n->child[0]->type->read(n->child[0]);
1103 code_t* right = n->child[1]->type->exec(n->child[1]);
1105 code_t*jmp = c = abc_iftrue(c, 0);
1106 c = code_append(c, right);
1107 code_t*label = c = abc_label(c);
1108 jmp->branch = label;
1111 constant_t node_oror_eval(node_t*n)
1113 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1115 nodetype_t node_oror = //||
1118 flags:NODE_HAS_CHILDREN,
1119 eval: node_oror_eval,
1120 write: node_oror_write,
1121 read: node_oror_read,
1122 exec: node_oror_exec
1125 // --------------------------- x&&y ----------------------------------
1127 typedcode_t node_andand_write(node_t*n)
1129 syntaxerror("can't assign to this expression");
1131 typedcode_t node_andand_read(node_t*n)
1133 READ_HEADER_LEFTRIGHT;
1134 t = join_types(left.t, right.t, &node_andand);
1136 c = converttype(c, left.t, t);
1138 code_t*jmp = c = abc_iffalse(c, 0);
1139 c = cut_last_push(c);
1140 c = code_append(c,right.c);
1141 c = converttype(c, right.t, t);
1142 code_t*label = c = abc_label(c);
1143 jmp->branch = label;
1146 code_t* node_andand_exec(node_t*n)
1148 typedcode_t left = n->child[0]->type->read(n->child[0]);\
1149 code_t* right = n->child[1]->type->exec(n->child[1]);\
1151 code_t*jmp = c = abc_iffalse(c, 0);
1152 c = code_append(c, right);
1153 code_t*label = c = abc_label(c);
1154 jmp->branch = label;
1157 constant_t node_andand_eval(node_t*n)
1159 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1161 nodetype_t node_andand = //&&
1164 flags:NODE_HAS_CHILDREN,
1165 eval: node_andand_eval,
1166 write: node_andand_write,
1167 read: node_andand_read,
1168 exec: node_andand_exec
1171 // ----------------------------- !x -----------------------------------
1173 typedcode_t node_not_write(node_t*n)
1175 syntaxerror("can't assign to this expression");
1177 typedcode_t node_not_read(node_t*n)
1185 code_t* node_not_exec(node_t*n)
1190 constant_t node_not_eval(node_t*n)
1192 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1194 nodetype_t node_not =
1197 flags:NODE_HAS_CHILDREN,
1198 eval: node_not_eval,
1199 write: node_not_write,
1200 read: node_not_read,
1204 // ----------------------------- ~x -----------------------------------
1206 typedcode_t node_bitnot_write(node_t*n)
1208 syntaxerror("can't assign to this expression");
1210 typedcode_t node_bitnot_read(node_t*n)
1218 code_t* node_bitnot_exec(node_t*n)
1223 constant_t node_bitnot_eval(node_t*n)
1225 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1227 nodetype_t node_bitnot =
1230 flags:NODE_HAS_CHILDREN,
1231 eval: node_bitnot_eval,
1232 write: node_bitnot_write,
1233 read: node_bitnot_read,
1234 exec: node_bitnot_exec
1237 // ----------------------------- x&y -----------------------------------
1239 typedcode_t node_bitand_write(node_t*n)
1241 syntaxerror("can't assign to this expression");
1243 typedcode_t node_bitand_read(node_t*n)
1245 READ_HEADER_LEFTRIGHT;
1246 c = code_append(left.c,right.c);
1251 code_t* node_bitand_exec(node_t*n)
1253 EXEC_HEADER_LEFTRIGHT;
1254 return code_append(left, right);
1256 constant_t node_bitand_eval(node_t*n)
1258 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1260 nodetype_t node_bitand =
1263 flags:NODE_HAS_CHILDREN,
1264 eval: node_bitand_eval,
1265 write: node_bitand_write,
1266 read: node_bitand_read,
1267 exec: node_bitand_exec
1270 // ----------------------------- x^y -----------------------------------
1272 typedcode_t node_bitxor_write(node_t*n)
1274 syntaxerror("can't assign to this expression");
1276 typedcode_t node_bitxor_read(node_t*n)
1278 READ_HEADER_LEFTRIGHT;
1279 c = code_append(left.c,right.c);
1284 code_t* node_bitxor_exec(node_t*n)
1286 EXEC_HEADER_LEFTRIGHT;
1287 return code_append(left, right);
1289 constant_t node_bitxor_eval(node_t*n)
1291 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1293 nodetype_t node_bitxor =
1296 flags:NODE_HAS_CHILDREN,
1297 eval: node_bitxor_eval,
1298 write: node_bitxor_write,
1299 read: node_bitxor_read,
1300 exec: node_bitxor_exec
1303 // ----------------------------- x|y -----------------------------------
1305 typedcode_t node_bitor_write(node_t*n)
1307 syntaxerror("can't assign to this expression");
1309 typedcode_t node_bitor_read(node_t*n)
1311 READ_HEADER_LEFTRIGHT;
1312 c = code_append(left.c,right.c);
1317 code_t* node_bitor_exec(node_t*n)
1319 EXEC_HEADER_LEFTRIGHT;
1320 return code_append(left, right);
1322 constant_t node_bitor_eval(node_t*n)
1324 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1326 nodetype_t node_bitor =
1329 flags:NODE_HAS_CHILDREN,
1330 eval: node_bitor_eval,
1331 write: node_bitor_write,
1332 read: node_bitor_read,
1333 exec: node_bitor_exec
1336 // ---------------------------- x>>y -----------------------------------
1338 typedcode_t node_shr_write(node_t*n)
1340 syntaxerror("can't assign to this expression");
1342 typedcode_t node_shr_read(node_t*n)
1344 READ_HEADER_LEFTRIGHT;
1345 c = code_append(left.c,right.c);
1350 code_t* node_shr_exec(node_t*n)
1352 EXEC_HEADER_LEFTRIGHT;
1353 return code_append(left, right);
1355 constant_t node_shr_eval(node_t*n)
1357 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1359 nodetype_t node_shr = //>>
1362 flags:NODE_HAS_CHILDREN,
1363 eval: node_shr_eval,
1364 write: node_shr_write,
1365 read: node_shr_read,
1369 // ---------------------------- x<<y -----------------------------------
1371 typedcode_t node_shl_write(node_t*n)
1373 syntaxerror("can't assign to this expression");
1375 typedcode_t node_shl_read(node_t*n)
1377 READ_HEADER_LEFTRIGHT;
1378 c = code_append(left.c,right.c);
1383 code_t* node_shl_exec(node_t*n)
1385 EXEC_HEADER_LEFTRIGHT;
1386 return code_append(left, right);
1388 constant_t node_shl_eval(node_t*n)
1390 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1392 nodetype_t node_shl = //<<
1395 flags:NODE_HAS_CHILDREN,
1396 eval: node_shl_eval,
1397 write: node_shl_write,
1398 read: node_shl_read,
1402 // ---------------------------- x>>>y -----------------------------------
1404 typedcode_t node_ushr_write(node_t*n)
1406 syntaxerror("can't assign to this expression");
1408 typedcode_t node_ushr_read(node_t*n)
1410 READ_HEADER_LEFTRIGHT;
1411 c = code_append(left.c,right.c);
1416 code_t* node_ushr_exec(node_t*n)
1418 EXEC_HEADER_LEFTRIGHT;
1419 return code_append(left, right);
1421 constant_t node_ushr_eval(node_t*n)
1423 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1425 nodetype_t node_ushr = //>>>
1428 flags:NODE_HAS_CHILDREN,
1429 eval: node_ushr_eval,
1430 write: node_ushr_write,
1431 read: node_ushr_read,
1432 exec: node_ushr_exec
1435 // ---------------------------- x in y ----------------------------------
1437 typedcode_t node_in_write(node_t*n)
1439 syntaxerror("can't assign to this expression");
1441 typedcode_t node_in_read(node_t*n)
1443 READ_HEADER_LEFTRIGHT;
1444 c = code_append(left.c,right.c);
1449 code_t* node_in_exec(node_t*n)
1451 EXEC_HEADER_LEFTRIGHT;
1452 return code_append(left, right);
1454 constant_t node_in_eval(node_t*n)
1456 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1458 nodetype_t node_in = //in
1461 flags:NODE_HAS_CHILDREN,
1463 write: node_in_write,
1468 // ---------------------------- x as y ----------------------------------
1470 typedcode_t node_as_write(node_t*n)
1473 syntaxerror("can't assign to this expression");
1475 typedcode_t node_as_read(node_t*n)
1477 READ_HEADER_LEFTRIGHT;
1478 c = code_append(left.c, right.c);
1479 c = abc_astypelate(c);
1480 if(TYPE_IS_CLASS(right.t) && right.t->data) {
1481 t = (classinfo_t*)right.t->data;
1487 code_t* node_as_exec(node_t*n)
1489 /* we assume here that "as" doesn't have side-effects (like
1490 early run time type checking) */
1491 EXEC_HEADER_LEFTRIGHT;
1492 return code_append(left, right);
1494 constant_t node_as_eval(node_t*n)
1496 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1498 nodetype_t node_as = //as
1501 flags:NODE_HAS_CHILDREN,
1503 write: node_as_write,
1508 // ------------------------- x instanceof y -----------------------------
1510 typedcode_t node_instanceof_write(node_t*n)
1512 syntaxerror("can't assign to this expression");
1514 typedcode_t node_instanceof_read(node_t*n)
1516 READ_HEADER_LEFTRIGHT;
1517 c = code_append(left.c, right.c);
1518 c = abc_instanceof(c);
1522 code_t* node_instanceof_exec(node_t*n)
1524 EXEC_HEADER_LEFTRIGHT;
1525 return code_append(left, right);
1527 constant_t node_instanceof_eval(node_t*n)
1529 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1531 nodetype_t node_instanceof = //instanceof
1534 flags:NODE_HAS_CHILDREN,
1535 eval: node_instanceof_eval,
1536 write: node_instanceof_write,
1537 read: node_instanceof_read,
1538 exec: node_instanceof_exec
1541 // ------------------------- x is y --------------------------------------
1543 typedcode_t node_is_write(node_t*n)
1545 syntaxerror("can't assign to this expression");
1547 typedcode_t node_is_read(node_t*n)
1549 READ_HEADER_LEFTRIGHT;
1550 c = code_append(left.c, right.c);
1551 c = abc_istypelate(c);
1555 code_t* node_is_exec(node_t*n)
1557 EXEC_HEADER_LEFTRIGHT;
1558 return code_append(left, right);
1560 constant_t node_is_eval(node_t*n)
1562 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1564 nodetype_t node_is = //is
1567 flags:NODE_HAS_CHILDREN,
1569 write: node_is_write,
1574 // ------------------------- x[y] --------------------------------------
1576 typedcode_t node_arraylookup_write(node_t*n)
1578 syntaxerror("not implemented yet");
1580 typedcode_t node_arraylookup_read(node_t*n)
1582 READ_HEADER_LEFTRIGHT;
1583 c = code_append(left.c, right.c);
1585 /* XXX not sure whether this access logic is correct */
1586 namespace_t ns = {left.t?left.t->access:ACCESS_PACKAGE, ""};
1587 namespace_set_t nsset;
1588 namespace_list_t l;l.next = 0;
1589 nsset.namespaces = &l;
1591 multiname_t m = {MULTINAMEL, 0, &nsset, 0};
1593 c = abc_getproperty2(c, &m);
1594 t = 0; // array elements have unknown type
1597 code_t* node_arraylookup_exec(node_t*n)
1599 EXEC_HEADER_LEFTRIGHT;
1600 return code_append(left, right);
1602 constant_t node_arraylookup_eval(node_t*n)
1604 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1606 nodetype_t node_arraylookup =
1608 name: "arraylookup",
1609 flags:NODE_HAS_CHILDREN,
1610 eval: node_arraylookup_eval,
1611 write: node_arraylookup_write,
1612 read: node_arraylookup_read,
1613 exec: node_arraylookup_exec
1616 // ------------------------- typeof(x) ------------------------------------
1618 typedcode_t node_typeof_write(node_t*n)
1620 syntaxerror("can't assign to this expression");
1622 typedcode_t node_typeof_read(node_t*n)
1630 code_t* node_typeof_exec(node_t*n)
1635 constant_t node_typeof_eval(node_t*n)
1637 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1639 nodetype_t node_typeof = //typeof
1642 flags:NODE_HAS_CHILDREN,
1643 eval: node_typeof_eval,
1644 write: node_typeof_write,
1645 read: node_typeof_read,
1646 exec: node_typeof_exec
1649 // ------------------------- (void)(x) ------------------------------------
1651 typedcode_t node_void_write(node_t*n)
1653 syntaxerror("can't assign to this expression");
1655 typedcode_t node_void_read(node_t*n)
1657 code_t*c = n->type->exec(n);
1658 c = abc_pushundefined(c);
1659 classinfo_t*t = TYPE_ANY;
1662 code_t* node_void_exec(node_t*n)
1667 constant_t node_void_eval(node_t*n)
1669 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1671 nodetype_t node_void = //void
1674 flags:NODE_HAS_CHILDREN,
1675 eval: node_void_eval,
1676 write: node_void_write,
1677 read: node_void_read,
1678 exec: node_void_exec
1681 // ---------------------------- -x ----------------------------------------
1683 typedcode_t node_neg_write(node_t*n)
1685 syntaxerror("can't assign to this expression");
1687 typedcode_t node_neg_read(node_t*n)
1692 c = abc_negate_i(c);
1700 code_t* node_neg_exec(node_t*n)
1705 constant_t node_neg_eval(node_t*n)
1707 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1709 nodetype_t node_neg = //-
1712 flags:NODE_HAS_CHILDREN,
1713 eval: node_neg_eval,
1714 write: node_neg_write,
1715 read: node_neg_read,
1719 // ---------------------------- x*=y ----------------------------------------
1721 typedcode_t node_muleq_write(node_t*n)
1723 syntaxerror("can't assign to this expression");
1725 typedcode_t node_muleq_read(node_t*n)
1727 READ_HEADER_LEFTRIGHT;
1730 if(BOTH_INT(left.t,right.t)) {
1731 c=abc_multiply_i(c);
1737 c=converttype(c, f, left.t);
1738 c = toreadwrite(left.c, c, 0, 0, 1);
1742 code_t* node_muleq_exec(node_t*n)
1744 READ_HEADER_LEFTRIGHT;
1747 if(BOTH_INT(left.t,right.t)) {
1748 c=abc_multiply_i(c);
1754 c = converttype(c, f, left.t);
1755 return toreadwrite(left.c, c, 0, 0, 0);
1757 constant_t node_muleq_eval(node_t*n)
1759 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1761 nodetype_t node_muleq =
1764 flags:NODE_HAS_CHILDREN,
1765 eval: node_muleq_eval,
1766 write: node_muleq_write,
1767 read: node_muleq_read,
1768 exec: node_muleq_exec
1771 // ---------------------------- x%=y ----------------------------------------
1773 typedcode_t node_modeq_write(node_t*n)
1775 syntaxerror("can't assign to this expression");
1777 typedcode_t node_modeq_read(node_t*n)
1779 READ_HEADER_LEFTRIGHT;
1780 c = abc_modulo(right.c);
1781 c = converttype(c, TYPE_NUMBER, left.t);
1782 c = toreadwrite(left.c, c, 0, 0, 1);
1786 code_t* node_modeq_exec(node_t*n)
1788 READ_HEADER_LEFTRIGHT;
1789 c = abc_modulo(right.c);
1790 c = converttype(c, TYPE_NUMBER, left.t);
1791 return toreadwrite(left.c, c, 0, 0, 0);
1793 constant_t node_modeq_eval(node_t*n)
1795 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1797 nodetype_t node_modeq = //%=
1800 flags:NODE_HAS_CHILDREN,
1801 eval: node_modeq_eval,
1802 write: node_modeq_write,
1803 read: node_modeq_read,
1804 exec: node_modeq_exec
1807 // ---------------------------- x<<=y ----------------------------------------
1809 typedcode_t node_shleq_write(node_t*n)
1811 syntaxerror("can't assign to this expression");
1813 typedcode_t node_shleq_read(node_t*n)
1815 READ_HEADER_LEFTRIGHT;
1816 c = abc_lshift(right.c);
1817 c = converttype(c, TYPE_INT, left.t);
1818 c = toreadwrite(left.c, c, 0, 0, 1);
1822 code_t* node_shleq_exec(node_t*n)
1824 READ_HEADER_LEFTRIGHT;
1825 c = abc_lshift(right.c);
1826 c = converttype(c, TYPE_INT, left.t);
1827 return toreadwrite(left.c, c, 0, 0, 0);
1829 constant_t node_shleq_eval(node_t*n)
1831 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1833 nodetype_t node_shleq = //<<=
1836 flags:NODE_HAS_CHILDREN,
1837 eval: node_shleq_eval,
1838 write: node_shleq_write,
1839 read: node_shleq_read,
1840 exec: node_shleq_exec
1843 // ---------------------------- x>>=y ----------------------------------------
1845 typedcode_t node_shreq_write(node_t*n)
1847 syntaxerror("can't assign to this expression");
1849 typedcode_t node_shreq_read(node_t*n)
1851 READ_HEADER_LEFTRIGHT;
1852 c = abc_rshift(right.c);
1853 c = converttype(c, TYPE_INT, left.t);
1854 c = toreadwrite(left.c, c, 0, 0, 1);
1858 code_t* node_shreq_exec(node_t*n)
1860 READ_HEADER_LEFTRIGHT;
1861 c = abc_rshift(right.c);
1862 c = converttype(c, TYPE_INT, left.t);
1863 return toreadwrite(left.c, c, 0, 0, 0);
1865 constant_t node_shreq_eval(node_t*n)
1867 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1869 nodetype_t node_shreq = //>>=
1872 flags:NODE_HAS_CHILDREN,
1873 eval: node_shreq_eval,
1874 write: node_shreq_write,
1875 read: node_shreq_read,
1876 exec: node_shreq_exec
1879 // --------------------------- x>>>=y ----------------------------------------
1881 typedcode_t node_ushreq_write(node_t*n)
1883 syntaxerror("can't assign to this expression");
1885 typedcode_t node_ushreq_read(node_t*n)
1887 READ_HEADER_LEFTRIGHT;
1888 c = abc_urshift(right.c);
1889 c = converttype(c, TYPE_UINT, left.t);
1890 c = toreadwrite(left.c, c, 0, 0, 1);
1894 code_t* node_ushreq_exec(node_t*n)
1896 READ_HEADER_LEFTRIGHT;
1897 c = abc_urshift(right.c);
1898 c = converttype(c, TYPE_UINT, left.t);
1899 return toreadwrite(left.c, c, 0, 0, 0);
1901 constant_t node_ushreq_eval(node_t*n)
1903 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1905 nodetype_t node_ushreq = //>>>=
1908 flags:NODE_HAS_CHILDREN,
1909 eval: node_ushreq_eval,
1910 write: node_ushreq_write,
1911 read: node_ushreq_read,
1912 exec: node_ushreq_exec
1915 // --------------------------- x/=y ----------------------------------------
1917 typedcode_t node_diveq_write(node_t*n)
1919 syntaxerror("can't assign to this expression");
1921 typedcode_t node_diveq_read(node_t*n)
1923 READ_HEADER_LEFTRIGHT;
1924 c = abc_divide(right.c);
1925 c = converttype(c, TYPE_NUMBER, left.t);
1926 c = toreadwrite(left.c, c, 0, 0, 1);
1930 code_t* node_diveq_exec(node_t*n)
1932 READ_HEADER_LEFTRIGHT;
1933 c = abc_divide(right.c);
1934 c = converttype(c, TYPE_NUMBER, left.t);
1935 return toreadwrite(left.c, c, 0, 0, 0);
1937 constant_t node_diveq_eval(node_t*n)
1939 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1941 nodetype_t node_diveq =
1944 flags:NODE_HAS_CHILDREN,
1945 eval: node_diveq_eval,
1946 write: node_diveq_write,
1947 read: node_diveq_read,
1948 exec: node_diveq_exec
1951 // --------------------------- x|=y ----------------------------------------
1953 typedcode_t node_bitoreq_write(node_t*n)
1955 syntaxerror("can't assign to this expression");
1957 typedcode_t node_bitoreq_read(node_t*n)
1959 READ_HEADER_LEFTRIGHT;
1960 c = abc_bitor(right.c);
1961 c = converttype(c, TYPE_INT, left.t);
1962 c = toreadwrite(left.c, c, 0, 0, 1);
1966 code_t* node_bitoreq_exec(node_t*n)
1968 READ_HEADER_LEFTRIGHT;
1969 c = abc_bitor(right.c);
1970 c = converttype(c, TYPE_INT, left.t);
1971 return toreadwrite(left.c, c, 0, 0, 0);
1973 constant_t node_bitoreq_eval(node_t*n)
1975 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1977 nodetype_t node_bitoreq = //|=
1980 flags:NODE_HAS_CHILDREN,
1981 eval: node_bitoreq_eval,
1982 write: node_bitoreq_write,
1983 read: node_bitoreq_read,
1984 exec: node_bitoreq_exec
1987 // --------------------------- x^=y ----------------------------------------
1989 typedcode_t node_bitxoreq_write(node_t*n)
1991 syntaxerror("can't assign to this expression");
1993 typedcode_t node_bitxoreq_read(node_t*n)
1995 READ_HEADER_LEFTRIGHT;
1996 c = abc_bitxor(right.c);
1997 c = converttype(c, TYPE_INT, left.t);
1998 c = toreadwrite(left.c, c, 0, 0, 1);
2002 code_t* node_bitxoreq_exec(node_t*n)
2004 READ_HEADER_LEFTRIGHT;
2005 c = abc_bitxor(right.c);
2006 c = converttype(c, TYPE_INT, left.t);
2007 return toreadwrite(left.c, c, 0, 0, 0);
2009 constant_t node_bitxoreq_eval(node_t*n)
2011 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2013 nodetype_t node_bitxoreq = //^=
2016 flags:NODE_HAS_CHILDREN,
2017 eval: node_bitxoreq_eval,
2018 write: node_bitxoreq_write,
2019 read: node_bitxoreq_read,
2020 exec: node_bitxoreq_exec
2023 // --------------------------- x&=y ----------------------------------------
2025 typedcode_t node_bitandeq_write(node_t*n)
2027 syntaxerror("can't assign to this expression");
2029 typedcode_t node_bitandeq_read(node_t*n)
2031 READ_HEADER_LEFTRIGHT;
2032 c = abc_bitand(right.c);
2033 c = converttype(c, TYPE_INT, left.t);
2034 c = toreadwrite(left.c, c, 0, 0, 1);
2038 code_t* node_bitandeq_exec(node_t*n)
2040 READ_HEADER_LEFTRIGHT;
2041 c = abc_bitand(right.c);
2042 c = converttype(c, TYPE_INT, left.t);
2043 return toreadwrite(left.c, c, 0, 0, 0);
2045 constant_t node_bitandeq_eval(node_t*n)
2047 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2049 nodetype_t node_bitandeq = //^=
2052 flags:NODE_HAS_CHILDREN,
2053 eval: node_bitandeq_eval,
2054 write: node_bitandeq_write,
2055 read: node_bitandeq_read,
2056 exec: node_bitandeq_exec
2059 // --------------------------- x+=y ----------------------------------------
2061 typedcode_t node_pluseq_write(node_t*n)
2063 syntaxerror("can't assign to this expression");
2065 typedcode_t node_pluseq_read(node_t*n)
2067 READ_HEADER_LEFTRIGHT;
2069 if(TYPE_IS_INT(left.t)) {
2073 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2075 c = toreadwrite(left.c, c, 0, 0, 1);
2079 code_t* node_pluseq_exec(node_t*n)
2081 READ_HEADER_LEFTRIGHT;
2083 if(TYPE_IS_INT(left.t)) {
2087 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2089 return toreadwrite(left.c, c, 0, 0, 0);
2091 constant_t node_pluseq_eval(node_t*n)
2093 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2095 nodetype_t node_pluseq = //+=
2098 flags:NODE_HAS_CHILDREN,
2099 eval: node_pluseq_eval,
2100 write: node_pluseq_write,
2101 read: node_pluseq_read,
2102 exec: node_pluseq_exec
2105 // --------------------------- x-=y ----------------------------------------
2107 typedcode_t node_minuseq_write(node_t*n)
2109 syntaxerror("can't assign to this expression");
2111 typedcode_t node_minuseq_read(node_t*n)
2113 READ_HEADER_LEFTRIGHT;
2115 if(TYPE_IS_INT(left.t)) {
2116 c = abc_subtract_i(c);
2118 c = abc_subtract(c);
2119 c = converttype(c, TYPE_NUMBER, left.t);
2121 c = toreadwrite(left.c, c, 0, 0, 1);
2125 code_t* node_minuseq_exec(node_t*n)
2127 READ_HEADER_LEFTRIGHT;
2129 if(TYPE_IS_INT(left.t)) {
2130 c = abc_subtract_i(c);
2132 c = abc_subtract(c);
2133 c = converttype(c, TYPE_NUMBER, left.t);
2135 return toreadwrite(left.c, c, 0, 0, 0);
2137 constant_t node_minuseq_eval(node_t*n)
2139 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2141 nodetype_t node_minuseq = //-=
2144 flags:NODE_HAS_CHILDREN,
2145 eval: node_minuseq_eval,
2146 write: node_minuseq_write,
2147 read: node_minuseq_read,
2148 exec: node_minuseq_exec
2151 // --------------------------- x=y -----------------------------------------
2153 typedcode_t node_assign_write(node_t*n)
2155 syntaxerror("can't assign to this expression");
2157 typedcode_t node_assign_read(node_t*n)
2159 READ_HEADER_LEFTRIGHT;
2161 c = converttype(c, right.t, left.t);
2162 c = toreadwrite(left.c, c, 1, 0, 1);
2166 code_t* node_assign_exec(node_t*n)
2168 READ_HEADER_LEFTRIGHT;
2170 c = converttype(c, right.t, left.t);
2171 return toreadwrite(left.c, c, 1, 0, 0);
2173 constant_t node_assign_eval(node_t*n)
2175 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2177 nodetype_t node_assign =
2180 flags:NODE_HAS_CHILDREN,
2181 eval: node_assign_eval,
2182 write: node_assign_write,
2183 read: node_assign_read,
2184 exec: node_assign_exec
2187 // --------------------------- x?y1:y2 --------------------------------------
2189 typedcode_t node_tenary_write(node_t*n)
2191 /* TODO: this might actually be kinda useful.
2192 (global?global.x:this.x) = 3;
2194 syntaxerror("can't assign to this expression");
2196 typedcode_t node_tenary_read(node_t*n)
2198 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2199 typedcode_t left = n->child[1]->type->read(n->child[1]);
2200 typedcode_t right = n->child[2]->type->read(n->child[2]);
2201 classinfo_t*t = join_types(left.t,right.t,&node_tenary);
2203 code_t*j1 = c = abc_iffalse(c, 0);
2204 c = code_append(c, left.c);
2205 c = converttype(c, left.t, t);
2206 code_t*j2 = c = abc_jump(c, 0);
2207 c = j1->branch = abc_label(c);
2208 c = code_append(c, right.c);
2209 c = converttype(c, right.t, t);
2210 c = j2->branch = abc_label(c);
2213 code_t* node_tenary_exec(node_t*n)
2215 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2216 code_t* left = n->child[1]->type->exec(n->child[1]);
2217 code_t* right = n->child[2]->type->exec(n->child[2]);
2219 code_t*j1 = c = abc_iffalse(c, 0);
2220 c = code_append(c, left);
2221 code_t*j2 = c = abc_jump(c, 0);
2222 c = j1->branch = abc_label(c);
2223 c = code_append(c, right);
2224 c = j2->branch = abc_label(c);
2227 constant_t node_tenary_eval(node_t*n)
2229 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2231 nodetype_t node_tenary =
2234 flags:NODE_HAS_CHILDREN,
2235 eval: node_tenary_eval,
2236 write: node_tenary_write,
2237 read: node_tenary_read,
2238 exec: node_tenary_exec
2241 // ---------------------------- comma ----------------------------------------
2243 typedcode_t node_comma_write(node_t*n)
2245 syntaxerror("can't assign to this expression");
2247 typedcode_t node_comma_read(node_t*n)
2252 for(i=0;i<n->num_children-1;i++) {
2253 c = code_append(c, n->child[i]->type->exec(n->child[i]));
2255 typedcode_t o = n->child[i]->type->read(n->child[i]);
2256 c = code_append(c, o.c);
2260 code_t* node_comma_exec(node_t*n)
2264 for(t=0;t<n->num_children;t++) {
2265 c = code_append(c, n->child[t]->type->exec(n->child[t]));
2269 constant_t node_comma_eval(node_t*n)
2271 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2273 nodetype_t node_comma =
2276 flags: NODE_HAS_CHILDREN,
2277 eval: node_comma_eval,
2278 write: node_comma_write,
2279 read: node_comma_read,
2280 exec: node_comma_exec
2285 // -------------------------- new x -----------------------------------
2287 typedcode_t node_new_write(node_t*n)
2290 typedcode_t node_new_read(node_t*n)
2293 code_t* node_new_exec(node_t*n)
2296 constant_t node_new_eval(node_t*n)
2298 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2300 nodetype_t node_new = //new
2302 write: node_new_write,
2303 read: node_new_read,
2304 eval: node_new_eval,
2308 // ------------------------ delete x ----------------------------------
2310 typedcode_t node_delete_write(node_t*n)
2313 typedcode_t node_delete_read(node_t*n)
2316 code_t* node_delete_exec(node_t*n)
2319 constant_t node_delete_eval(node_t*n)
2321 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2323 nodetype_t node_delete = //delete
2325 write: node_delete_write,
2326 read: node_delete_read,
2327 eval: node_delete_eval,
2328 exec: node_delete_exec
2331 // ---------------------------- x.y -----------------------------------
2333 typedcode_t node_dot_write(node_t*n)
2336 typedcode_t node_dot_read(node_t*n)
2339 code_t* node_dot_exec(node_t*n)
2342 constant_t node_dot_eval(node_t*n)
2344 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2346 nodetype_t node_dot =
2348 write: node_dot_write,
2349 read: node_dot_read,
2350 eval: node_dot_eval,
2354 // --------------------------- x..y -----------------------------------
2356 typedcode_t node_dotdot_write(node_t*n)
2359 typedcode_t node_dotdot_read(node_t*n)
2362 code_t* node_dotdot_exec(node_t*n)
2366 constant_t node_dotdot_eval(node_t*n)
2368 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2370 nodetype_t node_dotdot = //..
2372 write: node_dotdot_write,
2373 read: node_dotdot_read,
2374 eval: node_dotdot_eval,
2375 exec: node_dotdot_exec
2378 // --------------------------- x.@y -----------------------------------
2380 typedcode_t node_dotat_write(node_t*n)
2383 typedcode_t node_dotat_read(node_t*n)
2386 code_t* node_dotat_exec(node_t*n)
2389 constant_t node_dotat_eval(node_t*n)
2391 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2393 nodetype_t node_dotat = //.@
2395 write: node_dotat_write,
2396 read: node_dotat_read,
2397 eval: node_dotat_eval,
2398 exec: node_dotat_exec
2401 // --------------------------- x.*y -----------------------------------
2403 typedcode_t node_dotstar_write(node_t*n)
2406 typedcode_t node_dotstar_read(node_t*n)
2409 code_t* node_dotstar_exec(node_t*n)
2412 constant_t node_dotstar_eval(node_t*n)
2414 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2416 nodetype_t node_dotstar = //.*
2418 write: node_dotstar_write,
2419 read: node_dotstar_read,
2420 eval: node_dotstar_eval,
2421 exec: node_dotstar_exec
2424 // -------------------------- x.(y) -----------------------------------
2426 typedcode_t node_filter_write(node_t*n)
2429 typedcode_t node_filter_read(node_t*n)
2432 code_t* node_filter_exec(node_t*n)
2435 constant_t node_filter_eval(node_t*n)
2437 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2439 nodetype_t node_filter = //.(
2441 write: node_filter_write,
2442 read: node_filter_read,
2443 eval: node_filter_eval,
2444 exec: node_filter_exec
2447 // ------------------------ x(y1,...,yn) ------------------------------
2449 typedcode_t node_call_write(node_t*n)
2452 typedcode_t node_call_read(node_t*n)
2455 code_t* node_call_exec(node_t*n)
2458 constant_t node_call_eval(node_t*n)
2460 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2462 nodetype_t node_call = //functioncall
2464 write: node_call_write,
2465 read: node_call_read,
2466 eval: node_call_eval,
2467 exec: node_call_exec
2470 // ------------------------------ @x ----------------------------------------
2472 typedcode_t node_at_write(node_t*n)
2475 typedcode_t node_at_read(node_t*n)
2478 code_t* node_at_exec(node_t*n)
2481 constant_t node_at_eval(node_t*n)
2483 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2485 nodetype_t node_at = //@
2487 write: node_at_write,
2493 // ---------------------------- x.ns::y ----------------------------------------
2495 typedcode_t node_dotns_write(node_t*n)
2498 typedcode_t node_dotns_read(node_t*n)
2501 code_t* node_dotns_exec(node_t*n)
2504 constant_t node_dotns_eval(node_t*n)
2506 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2508 nodetype_t node_dotns = //.::
2510 write: node_dotns_write,
2511 read: node_dotns_read,
2512 eval: node_dotns_eval,
2513 exec: node_dotns_exec
2517 // ------------------------ constant ------------------------------
2519 typedcode_t node_const_write(node_t*n)
2521 syntaxerror("can't assign a value to a constant");
2523 typedcode_t node_const_read(node_t*n)
2525 constant_t*v = n->value;
2530 if(v->i>-128 && v->i<128) {
2531 c = abc_pushbyte(0,v->i);
2532 } else if(v->i>=-32768 && v->i<32768) {
2533 c = abc_pushshort(0,v->i);
2535 c = abc_pushint(0,v->i);
2540 c = abc_pushuint(0,v->u);
2542 c = abc_pushbyte(0,v->u);
2543 } else if(v->u<32768) {
2544 c = abc_pushshort(0,v->u);
2546 c = abc_pushint(0,v->u);
2550 case CONSTANT_FLOAT:
2551 c = abc_pushdouble(0,v->f);
2555 c = abc_pushtrue(0);
2558 case CONSTANT_FALSE:
2559 c = abc_pushfalse(0);
2563 c = abc_pushnull(0);
2566 case CONSTANT_STRING:
2567 c = abc_pushstring2(0,v->s);
2570 case CONSTANT_UNDEFINED:
2571 c = abc_pushundefined(0);
2574 case CONSTANT_NAMESPACE:
2575 case CONSTANT_NAMESPACE_PACKAGE:
2576 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
2577 case CONSTANT_NAMESPACE_PROTECTED:
2578 case CONSTANT_NAMESPACE_EXPLICIT:
2579 case CONSTANT_NAMESPACE_STATICPROTECTED:
2580 case CONSTANT_NAMESPACE_PRIVATE:
2581 c = abc_pushnamespace(0, v->ns);
2583 case CONSTANT_UNKNOWN:
2584 syntaxerror("internal error: invalid constant");
2587 syntaxerror("invalid constant (%d)", v->type);
2593 code_t* node_const_exec(node_t*n)
2597 constant_t node_const_eval(node_t*n)
2599 constant_t*c = constant_clone(n->value);
2601 free(c); //shallow free
2604 nodetype_t node_const =
2608 eval: node_const_eval,
2609 write: node_const_write,
2610 read: node_const_read,
2611 exec: node_const_exec
2614 // ------------------------ code node ------------------------------
2616 typedcode_t node_code_write(node_t*n)
2618 syntaxerror("not implemented yet");
2620 typedcode_t node_code_read(node_t*n)
2628 code_t* node_code_exec(node_t*n)
2630 code_t*c = code_dup(n->code.c);
2631 c = cut_last_push(c);
2634 constant_t node_code_eval(node_t*n)
2636 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2638 nodetype_t node_code =
2642 eval: node_code_eval,
2643 write: node_code_write,
2644 read: node_code_read,
2645 exec: node_code_exec
2648 // ------------------------ dummy node ------------------------------
2650 typedcode_t node_dummy_write(node_t*n)
2652 syntaxerror("not implemented yet");
2654 typedcode_t node_dummy_read(node_t*n)
2657 t.c = abc_pushundefined(0);
2661 code_t* node_dummy_exec(node_t*n)
2665 constant_t node_dummy_eval(node_t*n)
2667 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2669 nodetype_t node_dummy =
2673 eval: node_dummy_eval,
2674 write: node_dummy_write,
2675 read: node_dummy_read,
2676 exec: node_dummy_exec
2679 // ======================== node handling ==============================
2681 node_t* mkdummynode()
2683 node_t*n = (node_t*)rfx_calloc(sizeof(node_t));
2684 n->type = &node_dummy;
2688 node_t* mkconstnode(constant_t*c)
2690 node_t*n = (node_t*)malloc(sizeof(node_t));
2691 n->type = &node_const;
2697 node_t* mkcodenode(typedcode_t c)
2699 node_t*n = (node_t*)malloc(sizeof(node_t));
2700 n->type = &node_code;
2706 node_t* mkmultinode(nodetype_t*t, node_t*one)
2708 node_t*n = (node_t*)malloc(sizeof(node_t));
2711 n->child = (node_t**)malloc(sizeof(node_t*)*1);
2713 n->num_children = 1;
2717 node_t* multinode_extend(node_t*n, node_t*add)
2719 n->child = realloc(n->child, (n->num_children+1)*sizeof(node_t*));
2720 n->child[n->num_children] = add;
2725 node_t* mknode1(nodetype_t*t, node_t*node)
2727 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*2);
2728 node_t**x = (node_t**)&n[1];
2732 n->num_children = 1;
2738 node_t* mknode2(nodetype_t*t, node_t*left, node_t*right)
2740 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*3);
2741 node_t**x = (node_t**)&n[1];
2745 n->num_children = 2;
2751 node_t* mknode3(nodetype_t*t, node_t*one, node_t*two, node_t*three)
2753 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*4);
2754 node_t**x = (node_t**)&n[1];
2758 n->num_children = 3;
2766 void node_free(node_t*n)
2769 if(n->type == &node_code) {
2771 code_free(n->code.c);n->code.c = 0;
2773 } else if(n->type == &node_const) {
2774 /* keep, this is not our reference */
2775 } else for(t=0;t<n->num_children;t++) {
2776 node_free(n->child[t]);n->child[t] = 0;
2781 typedcode_t node_read(node_t*n)
2783 typedcode_t t = n->type->read(n);
2787 code_t* node_exec(node_t*n)
2789 code_t*c = n->type->exec(n);
2793 constant_t node_eval(node_t*n)
2795 constant_t c = n->type->eval(n);
2813 void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
2815 if(n->type->flags&NODE_HAS_CHILDREN) {
2816 fprintf(fi, "%s%s\n", p1, n->type->name);
2818 char*o2 = malloc(strlen(p2)+3);
2819 strcpy(o2, p2);strcat(o2, "| ");
2820 char*o3 = malloc(strlen(p2)+3);
2821 strcpy(o3, p2);strcat(o3, "+-");
2822 char*o4 = malloc(strlen(p2)+3);
2823 strcpy(o4, p2);strcat(o4, " ");
2825 for(t=0;t<n->num_children;t++) {
2826 fprintf(fi, "%s\n", o2);
2827 node_dump2(n->child[t], o3, t<n->num_children-1?o2:o4, fi);
2832 } else if(n->type == &node_const) {
2833 char*s = constant_tostring(n->value);
2834 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
2836 } else if(n->type == &node_code) {
2837 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, n->code.t?n->code.t->name:"*");
2838 code_dump2(n->code.c, 0, 0, (char*)p2, fi);
2840 fprintf(fi, "%s%s\n", p1, n->type->name);
2844 void node_dump(node_t*n)
2846 printf("------------VVVV---------------\n");
2847 node_dump2(n,"","",stdout);
2848 printf("-------------------------------\n");