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)
69 if((TYPE_IS_XMLLIST(type1) || TYPE_IS_XML(type1)) &&
70 (TYPE_IS_XMLLIST(type2) || TYPE_IS_XML(type2)))
72 if(BOTH_INT(type1, type2))
74 if(IS_NUMBER_OR_INT(type1) && IS_NUMBER_OR_INT(type2))
76 if(TYPE_IS_DATE(type1) || TYPE_IS_DATE(type2))
78 if(TYPE_IS_STRING(type1) || TYPE_IS_STRING(type2)) {
79 /* depending on where the strings come from, the result type
80 of an "add" might be an object or a string, depending on the
81 verifier's mood. So basically we just don't know the type. */
84 if(TYPE_IS_ANY(type1) || TYPE_IS_ANY(type2))
86 return TYPE_OBJECT; // e.g. array+array = object
93 static char is_getlocal(code_t*c)
95 if(!c || c->prev || c->next)
97 return(c->opcode == OPCODE_GETLOCAL
98 || c->opcode == OPCODE_GETLOCAL_0
99 || c->opcode == OPCODE_GETLOCAL_1
100 || c->opcode == OPCODE_GETLOCAL_2
101 || c->opcode == OPCODE_GETLOCAL_3);
103 static int getlocalnr(code_t*c)
105 if(c->opcode == OPCODE_GETLOCAL) {return (ptroff_t)c->data[0];}
106 else if(c->opcode == OPCODE_GETLOCAL_0) {return 0;}
107 else if(c->opcode == OPCODE_GETLOCAL_1) {return 1;}
108 else if(c->opcode == OPCODE_GETLOCAL_2) {return 2;}
109 else if(c->opcode == OPCODE_GETLOCAL_3) {return 3;}
110 else syntaxerror("Internal error: opcode %02x is not a getlocal call", c->opcode);
115 int gettempvar(); /* FIXME: we should use a function pointer here */
118 static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char readbefore, char pushvalue)
122 [prefix code] [read instruction]
126 [prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar]
128 if(in && in->opcode == OPCODE_COERCE_A) {
129 in = code_cutlast(in);
132 syntaxerror("internal error");
134 /* chop off read instruction */
138 prefix = r->prev;r->prev = 0;
144 char use_temp_var = readbefore;
146 /* generate the write instruction, and maybe append a dup to the prefix code */
147 code_t* write = abc_nop(0);
148 if(r->opcode == OPCODE_GETPROPERTY) {
149 write->opcode = OPCODE_SETPROPERTY;
150 multiname_t*m = (multiname_t*)r->data[0];
151 write->data[0] = multiname_clone(m);
152 if(m->type == QNAME || m->type == MULTINAME ||
153 m->type == QNAMEA || m->type == MULTINAMEA) {
155 prefix = abc_dup(prefix); // we need the object, too
158 } else if(m->type == MULTINAMEL) {
160 /* dupping two values on the stack requires 5 operations and one register-
161 couldn't adobe just have given us a dup2? */
162 int temp = gettempvar();
163 prefix = abc_setlocal(prefix, temp);
164 prefix = abc_dup(prefix);
165 prefix = abc_getlocal(prefix, temp);
166 prefix = abc_swap(prefix);
167 prefix = abc_getlocal(prefix, temp);
169 prefix = abc_kill(prefix, temp);
173 syntaxerror("illegal lvalue: can't assign a value to this expression (not a qname/multiname)");
175 } else if(r->opcode == OPCODE_GETSLOT) {
176 write->opcode = OPCODE_SETSLOT;
177 write->data[0] = r->data[0];
179 prefix = abc_dup(prefix); // we need the object, too
182 } else if(r->opcode == OPCODE_GETLOCAL) {
183 write->opcode = OPCODE_SETLOCAL;
184 write->data[0] = r->data[0];
185 } else if(r->opcode == OPCODE_GETLOCAL_0) {
186 write->opcode = OPCODE_SETLOCAL_0;
187 } else if(r->opcode == OPCODE_GETLOCAL_1) {
188 write->opcode = OPCODE_SETLOCAL_1;
189 } else if(r->opcode == OPCODE_GETLOCAL_2) {
190 write->opcode = OPCODE_SETLOCAL_2;
191 } else if(r->opcode == OPCODE_GETLOCAL_3) {
192 write->opcode = OPCODE_SETLOCAL_3;
193 } else if(r->opcode == OPCODE_GETSUPER) {
194 write->opcode = OPCODE_SETSUPER;
195 multiname_t*m = (multiname_t*)r->data[0];
196 write->data[0] = multiname_clone(m);
199 syntaxerror("illegal lvalue: can't assign a value to this expression");
206 /* with getproperty/getslot, we have to be extra careful not
207 to execute the read code twice, as it might have side-effects
208 (e.g. if the property is in fact a setter/getter combination)
210 So read the value, modify it, and write it again,
211 using prefix only once and making sure (by using a temporary
212 register) that the return value is what we just wrote */
214 c = code_append(c, prefix);
215 c = code_append(c, r);
216 if(pushvalue && readbefore) {
218 c = abc_setlocal(c, temp);
220 c = code_append(c, middlepart);
221 if(pushvalue && !readbefore) {
223 c = abc_setlocal(c, temp);
225 c = code_append(c, write);
227 c = abc_getlocal(c, temp);
228 c = abc_kill(c, temp);
231 /* if we're allowed to execute the read code twice *and*
232 the middlepart doesn't modify the code, things are easier.
234 //c = code_append(c, prefix);
235 if(prefix) syntaxerror("internal error (prefix)");
240 c = code_append(c, r);
241 c = code_append(c, middlepart);
242 c = code_append(c, write);
244 c = code_append(c, r2);
248 /* even smaller version: overwrite the value without reading
252 c = code_append(c, prefix);
255 c = code_append(c, middlepart);
256 c = code_append(c, write);
258 c = code_append(c, r);
264 c = code_append(c, prefix);
266 c = code_append(c, middlepart);
269 c = abc_setlocal(c, temp);
271 c = code_append(c, write);
273 c = abc_getlocal(c, temp);
274 c = abc_kill(c, temp);
281 code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to);
283 int constant_to_int(constant_t*c)
286 case CONSTANT_INT: return c->i;
287 case CONSTANT_UINT: return (int)c->u;
288 case CONSTANT_FLOAT: return c->f;
289 case CONSTANT_TRUE: return 1;
290 case CONSTANT_FALSE: return 0;
291 case CONSTANT_STRING: return atoi(c->s->str);
292 default: syntaxerror("can't convert this constant to an integer");
296 double constant_to_float(constant_t*c)
299 case CONSTANT_INT: return (double)c->i;
300 case CONSTANT_UINT: return (double)c->u;
301 case CONSTANT_FLOAT: return c->f;
302 case CONSTANT_TRUE: return (double)1;
303 case CONSTANT_FALSE: return (double)0;
304 case CONSTANT_STRING: return atof(c->s->str);
305 default: syntaxerror("can't convert this constant to a float");
309 // -------------------------- x + y -----------------------------------
311 typedcode_t node_plus_write(node_t*n)
313 syntaxerror("can't assign to this expression");
315 typedcode_t node_plus_read(node_t*n)
317 READ_HEADER_LEFTRIGHT;
318 c = code_append(left.c, right.c);
319 if(BOTH_INT(left.t, right.t)) {
324 t = join_types(left.t,right.t,n->type);
328 code_t* node_plus_exec(node_t*n)
330 EXEC_HEADER_LEFTRIGHT;
331 return code_append(left, right);
333 constant_t node_plus_eval(node_t*n)
335 EVAL_HEADER_LEFTRIGHT;
336 char left_int = left.type == CONSTANT_INT || left.type == CONSTANT_UINT;
337 if(left_int && (right.type == CONSTANT_INT || right.type == CONSTANT_UINT)) {
338 int i = constant_to_int(&left) + constant_to_int(&right);
339 r.type = CONSTANT_INT;
341 } else if(left_int && right.type == CONSTANT_FLOAT) {
342 double f = constant_to_int(&left) + constant_to_float(&right);
343 r.type = CONSTANT_FLOAT;
345 } else if(left.type == CONSTANT_STRING) {
346 char*add = constant_tostring(&right);
347 int l1 = left.s->len;
348 int l2 = strlen(add);
349 char*s = malloc(l1+l2+1);
350 memcpy(s, left.s->str, l1);
351 memcpy(s+l1, add, l2);
353 r.type = CONSTANT_STRING;
354 r.s = malloc(sizeof(string_t));
359 r.type = CONSTANT_UNKNOWN;
363 nodetype_t node_plus =
366 flags:NODE_HAS_CHILDREN,
368 write:node_plus_write,
373 // -------------------------- x - y -----------------------------------
375 typedcode_t node_minus_write(node_t*n)
377 syntaxerror("can't assign to this expression");
379 typedcode_t node_minus_read(node_t*n)
381 READ_HEADER_LEFTRIGHT;
382 c = code_append(left.c, right.c);
383 if(BOTH_INT(left.t,right.t)) {
384 c = abc_subtract_i(c);
392 code_t* node_minus_exec(node_t*n)
394 EXEC_HEADER_LEFTRIGHT;
395 return code_append(left, right);
397 constant_t node_minus_eval(node_t*n)
399 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
401 nodetype_t node_minus =
404 flags:NODE_HAS_CHILDREN,
405 eval: node_minus_eval,
406 write: node_minus_write,
407 read: node_minus_read,
408 exec: node_minus_exec
411 // ---------------------------- ++x -----------------------------------
413 typedcode_t node_lplusplus_write(node_t*n)
415 syntaxerror("can't assign to this expression");
417 typedcode_t node_lplusplus_read(node_t*n)
421 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
422 int nr = getlocalnr(x.c);
423 code_free(x.c);x.c=0;
424 if(TYPE_IS_INT(x.t)) {
425 c = abc_inclocal_i(c, nr);
426 c = abc_getlocal(c, nr);
427 } else if(TYPE_IS_NUMBER(x.t)) {
428 c = abc_inclocal(c, nr);
429 c = abc_getlocal(c, nr);
430 } else syntaxerror("internal error");
432 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
433 c = abc_increment_i(c);
436 c = abc_increment(c);
439 c = converttype(c, t, x.t);
440 c = toreadwrite(x.c, c, 0, 0, 1);
445 code_t* node_lplusplus_exec(node_t*n)
447 typedcode_t x = n->child[0]->type->read(n->child[0]);
449 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
450 int nr = getlocalnr(x.c);
451 code_free(x.c);x.c=0;
452 if(TYPE_IS_INT(x.t)) {
453 c = abc_inclocal_i(c, nr);
454 } else if(TYPE_IS_NUMBER(x.t)) {
455 c = abc_inclocal(c, nr);
456 } else syntaxerror("internal error");
459 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
460 c = abc_increment_i(c);
463 c = abc_increment(c);
466 c = converttype(c, t, x.t); //convert back to original type
467 c = toreadwrite(x.c, c, 0, 0, 0);
472 constant_t node_lplusplus_eval(node_t*n)
474 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
476 nodetype_t node_lplusplus =
479 flags:NODE_HAS_CHILDREN,
480 eval: node_lplusplus_eval,
481 write: node_lplusplus_write,
482 read: node_lplusplus_read,
483 exec: node_lplusplus_exec
487 // ---------------------------- --x -----------------------------------
489 typedcode_t node_lminusminus_write(node_t*n)
491 syntaxerror("can't assign to this expression");
493 typedcode_t node_lminusminus_read(node_t*n)
497 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
498 int nr = getlocalnr(x.c);
499 code_free(x.c);x.c=0;
500 if(TYPE_IS_INT(x.t)) {
501 c = abc_declocal_i(c, nr);
502 c = abc_getlocal(c, nr);
503 } else if(TYPE_IS_NUMBER(x.t)) {
504 c = abc_declocal(c, nr);
505 c = abc_getlocal(c, nr);
506 } else syntaxerror("internal error");
508 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
509 c = abc_decrement_i(c);
512 c = abc_decrement(c);
515 c = converttype(c, t, x.t);
516 c = toreadwrite(x.c, c, 0, 0, 1);
521 code_t* node_lminusminus_exec(node_t*n)
523 typedcode_t x = n->child[0]->type->read(n->child[0]);
525 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
526 int nr = getlocalnr(x.c);
527 code_free(x.c);x.c=0;
528 if(TYPE_IS_INT(x.t)) {
529 c = abc_declocal_i(c, nr);
530 } else if(TYPE_IS_NUMBER(x.t)) {
531 c = abc_declocal(c, nr);
532 } else syntaxerror("internal error");
535 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
536 c = abc_decrement_i(c);
539 c = abc_decrement(c);
542 c = converttype(c, t, x.t); //convert back to original type
543 c = toreadwrite(x.c, c, 0, 0, 0);
548 constant_t node_lminusminus_eval(node_t*n)
550 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
552 nodetype_t node_lminusminus =
555 flags:NODE_HAS_CHILDREN,
556 eval: node_lminusminus_eval,
557 write: node_lminusminus_write,
558 read: node_lminusminus_read,
559 exec: node_lminusminus_exec
564 // ---------------------------- x++ -----------------------------------
566 typedcode_t node_rplusplus_write(node_t*n)
568 syntaxerror("can't assign to this expression");
570 typedcode_t node_rplusplus_read(node_t*n)
574 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
575 int nr = getlocalnr(x.c);
576 code_free(x.c);x.c=0;
577 if(TYPE_IS_INT(x.t)) {
578 c = abc_getlocal(0, nr);
579 c = abc_inclocal_i(c, nr);
580 } else if(TYPE_IS_NUMBER(x.t)) {
581 c = abc_getlocal(0, nr);
582 c = abc_inclocal(c, nr);
583 } else syntaxerror("internal error");
585 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
586 c = abc_increment_i(c);
589 c = abc_increment(c);
592 c = converttype(c, t, x.t);
593 c = toreadwrite(x.c, c, 0, 1, 1);
598 code_t* node_rplusplus_exec(node_t*n)
600 typedcode_t x = n->child[0]->type->read(n->child[0]);
602 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
603 int nr = getlocalnr(x.c);
604 code_free(x.c);x.c=0;
605 if(TYPE_IS_INT(x.t)) {
606 c = abc_inclocal_i(c, nr);
607 } else if(TYPE_IS_NUMBER(x.t)) {
608 c = abc_inclocal(c, nr);
609 } else syntaxerror("internal error");
612 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
613 c = abc_increment_i(c);
616 c = abc_increment(c);
619 c = converttype(c, t, x.t); //convert back to original type
620 c = toreadwrite(x.c, c, 0, 1, 0);
625 constant_t node_rplusplus_eval(node_t*n)
627 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
629 nodetype_t node_rplusplus =
632 flags:NODE_HAS_CHILDREN,
633 eval: node_rplusplus_eval,
634 write: node_rplusplus_write,
635 read: node_rplusplus_read,
636 exec: node_rplusplus_exec
639 // ---------------------------- x-- -----------------------------------
641 typedcode_t node_rminusminus_write(node_t*n)
643 syntaxerror("can't assign to this expression");
645 typedcode_t node_rminusminus_read(node_t*n)
649 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
650 int nr = getlocalnr(x.c);
651 code_free(x.c);x.c=0;
652 if(TYPE_IS_INT(x.t)) {
653 c = abc_getlocal(0, nr);
654 c = abc_declocal_i(c, nr);
655 } else if(TYPE_IS_NUMBER(x.t)) {
656 c = abc_getlocal(0, nr);
657 c = abc_declocal(c, nr);
658 } else syntaxerror("internal error");
660 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
661 c = abc_decrement_i(c);
664 c = abc_decrement(c);
667 c = converttype(c, t, x.t);
668 c = toreadwrite(x.c, c, 0, 1, 1);
673 code_t* node_rminusminus_exec(node_t*n)
675 typedcode_t x = n->child[0]->type->read(n->child[0]);
677 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
678 int nr = getlocalnr(x.c);
679 code_free(x.c);x.c=0;
680 if(TYPE_IS_INT(x.t)) {
681 c = abc_declocal_i(c, nr);
682 } else if(TYPE_IS_NUMBER(x.t)) {
683 c = abc_declocal(c, nr);
684 } else syntaxerror("internal error");
687 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
688 c = abc_decrement_i(c);
691 c = abc_decrement(c);
694 c = converttype(c, t, x.t); //convert back to original type
695 c = toreadwrite(x.c, c, 0, 1, 0);
700 constant_t node_rminusminus_eval(node_t*n)
702 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
704 nodetype_t node_rminusminus =
707 flags:NODE_HAS_CHILDREN,
708 eval: node_rminusminus_eval,
709 write: node_rminusminus_write,
710 read: node_rminusminus_read,
711 exec: node_rminusminus_exec
714 // ---------------------------- x*y -----------------------------------
716 typedcode_t node_multiply_write(node_t*n)
718 syntaxerror("can't assign to this expression");
720 typedcode_t node_multiply_read(node_t*n)
722 READ_HEADER_LEFTRIGHT;
723 c = code_append(left.c,right.c);
724 if(BOTH_INT(left.t,right.t)) {
725 c = abc_multiply_i(c);
733 code_t* node_multiply_exec(node_t*n)
735 EXEC_HEADER_LEFTRIGHT;
736 return code_append(left, right);
738 constant_t node_multiply_eval(node_t*n)
740 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
742 nodetype_t node_multiply =
745 flags:NODE_HAS_CHILDREN,
746 eval: node_multiply_eval,
747 write: node_multiply_write,
748 read: node_multiply_read,
749 exec: node_multiply_exec
752 // ---------------------------- x/y -----------------------------------
754 typedcode_t node_div_write(node_t*n)
756 syntaxerror("can't assign to this expression");
758 typedcode_t node_div_read(node_t*n)
760 READ_HEADER_LEFTRIGHT;
761 c = code_append(left.c, right.c);
766 code_t* node_div_exec(node_t*n)
768 EXEC_HEADER_LEFTRIGHT;
769 return code_append(left, right);
771 constant_t node_div_eval(node_t*n)
773 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
775 nodetype_t node_div =
778 flags:NODE_HAS_CHILDREN,
780 write: node_div_write,
785 // ---------------------------- x%y -----------------------------------
787 typedcode_t node_mod_write(node_t*n)
789 syntaxerror("can't assign to this expression");
791 typedcode_t node_mod_read(node_t*n)
793 READ_HEADER_LEFTRIGHT;
794 c = code_append(left.c, right.c);
799 code_t* node_mod_exec(node_t*n)
801 EXEC_HEADER_LEFTRIGHT;
802 return code_append(left, right);
804 constant_t node_mod_eval(node_t*n)
806 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
808 nodetype_t node_mod =
811 flags:NODE_HAS_CHILDREN,
813 write: node_mod_write,
818 // ---------------------------- x<y -----------------------------------
820 typedcode_t node_lt_write(node_t*n)
822 syntaxerror("can't assign to this expression");
824 typedcode_t node_lt_read(node_t*n)
826 READ_HEADER_LEFTRIGHT;
827 c = code_append(left.c,right.c);
832 code_t* node_lt_exec(node_t*n)
834 EXEC_HEADER_LEFTRIGHT;
835 return code_append(left, right);
837 constant_t node_lt_eval(node_t*n)
839 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
844 flags:NODE_HAS_CHILDREN,
846 write: node_lt_write,
851 // ---------------------------- x>y -----------------------------------
853 typedcode_t node_gt_write(node_t*n)
855 syntaxerror("can't assign to this expression");
857 typedcode_t node_gt_read(node_t*n)
859 READ_HEADER_LEFTRIGHT;
860 c = code_append(left.c,right.c);
861 c = abc_greaterthan(c);
865 code_t* node_gt_exec(node_t*n)
867 EXEC_HEADER_LEFTRIGHT;
868 return code_append(left, right);
870 constant_t node_gt_eval(node_t*n)
872 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
877 flags:NODE_HAS_CHILDREN,
879 write: node_gt_write,
884 // ---------------------------- x<=y ----------------------------------
886 typedcode_t node_le_write(node_t*n)
888 syntaxerror("can't assign to this expression");
890 typedcode_t node_le_read(node_t*n)
892 READ_HEADER_LEFTRIGHT;
893 c = code_append(left.c,right.c);
894 c = abc_lessequals(c);
898 code_t* node_le_exec(node_t*n)
900 EXEC_HEADER_LEFTRIGHT;
901 return code_append(left, right);
903 constant_t node_le_eval(node_t*n)
905 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
907 nodetype_t node_le = //<=
910 flags:NODE_HAS_CHILDREN,
912 write: node_le_write,
917 // ---------------------------- x>=y ----------------------------------
919 typedcode_t node_ge_write(node_t*n)
921 syntaxerror("can't assign to this expression");
923 typedcode_t node_ge_read(node_t*n)
925 READ_HEADER_LEFTRIGHT;
926 c = code_append(left.c,right.c);
927 c = abc_greaterequals(c);
931 code_t* node_ge_exec(node_t*n)
933 EXEC_HEADER_LEFTRIGHT;
934 return code_append(left, right);
936 constant_t node_ge_eval(node_t*n)
938 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
940 nodetype_t node_ge = //>=
943 flags:NODE_HAS_CHILDREN,
945 write: node_ge_write,
950 // ---------------------------- x==y ----------------------------------
952 typedcode_t node_eqeq_write(node_t*n)
954 syntaxerror("can't assign to this expression");
956 typedcode_t node_eqeq_read(node_t*n)
958 READ_HEADER_LEFTRIGHT;
959 c = code_append(left.c,right.c);
964 code_t* node_eqeq_exec(node_t*n)
966 EXEC_HEADER_LEFTRIGHT;
967 return code_append(left, right);
969 constant_t node_eqeq_eval(node_t*n)
971 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
973 nodetype_t node_eqeq = //==
976 flags:NODE_HAS_CHILDREN,
977 eval: node_eqeq_eval,
978 write: node_eqeq_write,
979 read: node_eqeq_read,
983 // --------------------------- x===y ----------------------------------
985 typedcode_t node_eqeqeq_write(node_t*n)
987 syntaxerror("can't assign to this expression");
989 typedcode_t node_eqeqeq_read(node_t*n)
991 READ_HEADER_LEFTRIGHT;
992 c = code_append(left.c,right.c);
993 c = abc_strictequals(c);
997 code_t* node_eqeqeq_exec(node_t*n)
999 EXEC_HEADER_LEFTRIGHT;
1000 return code_append(left, right);
1002 constant_t node_eqeqeq_eval(node_t*n)
1004 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1006 nodetype_t node_eqeqeq = //===
1009 flags:NODE_HAS_CHILDREN,
1010 eval: node_eqeqeq_eval,
1011 write: node_eqeqeq_write,
1012 read: node_eqeqeq_read,
1013 exec: node_eqeqeq_exec
1016 // --------------------------- x!==y ----------------------------------
1018 typedcode_t node_noteqeq_write(node_t*n)
1020 syntaxerror("can't assign to this expression");
1022 typedcode_t node_noteqeq_read(node_t*n)
1024 READ_HEADER_LEFTRIGHT;
1025 c = code_append(left.c,right.c);
1026 c = abc_strictequals(c);
1031 code_t* node_noteqeq_exec(node_t*n)
1033 EXEC_HEADER_LEFTRIGHT;
1034 return code_append(left, right);
1036 constant_t node_noteqeq_eval(node_t*n)
1038 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1040 nodetype_t node_noteqeq = //!==
1043 flags:NODE_HAS_CHILDREN,
1044 eval: node_noteqeq_eval,
1045 write: node_noteqeq_write,
1046 read: node_noteqeq_read,
1047 exec: node_noteqeq_exec
1050 // --------------------------- x!=y ----------------------------------
1052 typedcode_t node_noteq_write(node_t*n)
1054 syntaxerror("can't assign to this expression");
1056 typedcode_t node_noteq_read(node_t*n)
1058 READ_HEADER_LEFTRIGHT;
1059 c = code_append(left.c,right.c);
1065 code_t* node_noteq_exec(node_t*n)
1067 EXEC_HEADER_LEFTRIGHT;
1068 return code_append(left, right);
1070 constant_t node_noteq_eval(node_t*n)
1072 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1074 nodetype_t node_noteq = //!=
1077 flags:NODE_HAS_CHILDREN,
1078 eval: node_noteq_eval,
1079 write: node_noteq_write,
1080 read: node_noteq_read,
1081 exec: node_noteq_exec
1084 // --------------------------- x||y ----------------------------------
1086 typedcode_t node_oror_write(node_t*n)
1088 syntaxerror("can't assign to this expression");
1090 typedcode_t node_oror_read(node_t*n)
1092 READ_HEADER_LEFTRIGHT;
1093 t = join_types(left.t, right.t, n->type);
1095 c = converttype(c, left.t, t);
1097 code_t*jmp = c = abc_iftrue(c, 0);
1098 c = cut_last_push(c);
1099 c = code_append(c, right.c);
1100 c = converttype(c, right.t, t);
1101 code_t*label = c = abc_label(c);
1102 jmp->branch = label;
1105 code_t* node_oror_exec(node_t*n)
1107 typedcode_t left = n->child[0]->type->read(n->child[0]);
1108 code_t* right = n->child[1]->type->exec(n->child[1]);
1110 code_t*jmp = c = abc_iftrue(c, 0);
1111 c = code_append(c, right);
1112 code_t*label = c = abc_label(c);
1113 jmp->branch = label;
1116 constant_t node_oror_eval(node_t*n)
1118 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1120 nodetype_t node_oror = //||
1123 flags:NODE_HAS_CHILDREN,
1124 eval: node_oror_eval,
1125 write: node_oror_write,
1126 read: node_oror_read,
1127 exec: node_oror_exec
1130 // --------------------------- x&&y ----------------------------------
1132 typedcode_t node_andand_write(node_t*n)
1134 syntaxerror("can't assign to this expression");
1136 typedcode_t node_andand_read(node_t*n)
1138 READ_HEADER_LEFTRIGHT;
1139 t = join_types(left.t, right.t, &node_andand);
1141 c = converttype(c, left.t, t);
1143 code_t*jmp = c = abc_iffalse(c, 0);
1144 c = cut_last_push(c);
1145 c = code_append(c,right.c);
1146 c = converttype(c, right.t, t);
1147 code_t*label = c = abc_label(c);
1148 jmp->branch = label;
1151 code_t* node_andand_exec(node_t*n)
1153 typedcode_t left = n->child[0]->type->read(n->child[0]);\
1154 code_t* right = n->child[1]->type->exec(n->child[1]);\
1156 code_t*jmp = c = abc_iffalse(c, 0);
1157 c = code_append(c, right);
1158 code_t*label = c = abc_label(c);
1159 jmp->branch = label;
1162 constant_t node_andand_eval(node_t*n)
1164 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1166 nodetype_t node_andand = //&&
1169 flags:NODE_HAS_CHILDREN,
1170 eval: node_andand_eval,
1171 write: node_andand_write,
1172 read: node_andand_read,
1173 exec: node_andand_exec
1176 // ----------------------------- !x -----------------------------------
1178 typedcode_t node_not_write(node_t*n)
1180 syntaxerror("can't assign to this expression");
1182 typedcode_t node_not_read(node_t*n)
1190 code_t* node_not_exec(node_t*n)
1195 constant_t node_not_eval(node_t*n)
1197 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1199 nodetype_t node_not =
1202 flags:NODE_HAS_CHILDREN,
1203 eval: node_not_eval,
1204 write: node_not_write,
1205 read: node_not_read,
1209 // ----------------------------- ~x -----------------------------------
1211 typedcode_t node_bitnot_write(node_t*n)
1213 syntaxerror("can't assign to this expression");
1215 typedcode_t node_bitnot_read(node_t*n)
1223 code_t* node_bitnot_exec(node_t*n)
1228 constant_t node_bitnot_eval(node_t*n)
1230 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1232 nodetype_t node_bitnot =
1235 flags:NODE_HAS_CHILDREN,
1236 eval: node_bitnot_eval,
1237 write: node_bitnot_write,
1238 read: node_bitnot_read,
1239 exec: node_bitnot_exec
1242 // ----------------------------- x&y -----------------------------------
1244 typedcode_t node_bitand_write(node_t*n)
1246 syntaxerror("can't assign to this expression");
1248 typedcode_t node_bitand_read(node_t*n)
1250 READ_HEADER_LEFTRIGHT;
1251 c = code_append(left.c,right.c);
1256 code_t* node_bitand_exec(node_t*n)
1258 EXEC_HEADER_LEFTRIGHT;
1259 return code_append(left, right);
1261 constant_t node_bitand_eval(node_t*n)
1263 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1265 nodetype_t node_bitand =
1268 flags:NODE_HAS_CHILDREN,
1269 eval: node_bitand_eval,
1270 write: node_bitand_write,
1271 read: node_bitand_read,
1272 exec: node_bitand_exec
1275 // ----------------------------- x^y -----------------------------------
1277 typedcode_t node_bitxor_write(node_t*n)
1279 syntaxerror("can't assign to this expression");
1281 typedcode_t node_bitxor_read(node_t*n)
1283 READ_HEADER_LEFTRIGHT;
1284 c = code_append(left.c,right.c);
1289 code_t* node_bitxor_exec(node_t*n)
1291 EXEC_HEADER_LEFTRIGHT;
1292 return code_append(left, right);
1294 constant_t node_bitxor_eval(node_t*n)
1296 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1298 nodetype_t node_bitxor =
1301 flags:NODE_HAS_CHILDREN,
1302 eval: node_bitxor_eval,
1303 write: node_bitxor_write,
1304 read: node_bitxor_read,
1305 exec: node_bitxor_exec
1308 // ----------------------------- x|y -----------------------------------
1310 typedcode_t node_bitor_write(node_t*n)
1312 syntaxerror("can't assign to this expression");
1314 typedcode_t node_bitor_read(node_t*n)
1316 READ_HEADER_LEFTRIGHT;
1317 c = code_append(left.c,right.c);
1322 code_t* node_bitor_exec(node_t*n)
1324 EXEC_HEADER_LEFTRIGHT;
1325 return code_append(left, right);
1327 constant_t node_bitor_eval(node_t*n)
1329 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1331 nodetype_t node_bitor =
1334 flags:NODE_HAS_CHILDREN,
1335 eval: node_bitor_eval,
1336 write: node_bitor_write,
1337 read: node_bitor_read,
1338 exec: node_bitor_exec
1341 // ---------------------------- x>>y -----------------------------------
1343 typedcode_t node_shr_write(node_t*n)
1345 syntaxerror("can't assign to this expression");
1347 typedcode_t node_shr_read(node_t*n)
1349 READ_HEADER_LEFTRIGHT;
1350 c = code_append(left.c,right.c);
1355 code_t* node_shr_exec(node_t*n)
1357 EXEC_HEADER_LEFTRIGHT;
1358 return code_append(left, right);
1360 constant_t node_shr_eval(node_t*n)
1362 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1364 nodetype_t node_shr = //>>
1367 flags:NODE_HAS_CHILDREN,
1368 eval: node_shr_eval,
1369 write: node_shr_write,
1370 read: node_shr_read,
1374 // ---------------------------- x<<y -----------------------------------
1376 typedcode_t node_shl_write(node_t*n)
1378 syntaxerror("can't assign to this expression");
1380 typedcode_t node_shl_read(node_t*n)
1382 READ_HEADER_LEFTRIGHT;
1383 c = code_append(left.c,right.c);
1388 code_t* node_shl_exec(node_t*n)
1390 EXEC_HEADER_LEFTRIGHT;
1391 return code_append(left, right);
1393 constant_t node_shl_eval(node_t*n)
1395 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1397 nodetype_t node_shl = //<<
1400 flags:NODE_HAS_CHILDREN,
1401 eval: node_shl_eval,
1402 write: node_shl_write,
1403 read: node_shl_read,
1407 // ---------------------------- x>>>y -----------------------------------
1409 typedcode_t node_ushr_write(node_t*n)
1411 syntaxerror("can't assign to this expression");
1413 typedcode_t node_ushr_read(node_t*n)
1415 READ_HEADER_LEFTRIGHT;
1416 c = code_append(left.c,right.c);
1421 code_t* node_ushr_exec(node_t*n)
1423 EXEC_HEADER_LEFTRIGHT;
1424 return code_append(left, right);
1426 constant_t node_ushr_eval(node_t*n)
1428 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1430 nodetype_t node_ushr = //>>>
1433 flags:NODE_HAS_CHILDREN,
1434 eval: node_ushr_eval,
1435 write: node_ushr_write,
1436 read: node_ushr_read,
1437 exec: node_ushr_exec
1440 // ---------------------------- x in y ----------------------------------
1442 typedcode_t node_in_write(node_t*n)
1444 syntaxerror("can't assign to this expression");
1446 typedcode_t node_in_read(node_t*n)
1448 READ_HEADER_LEFTRIGHT;
1449 c = code_append(left.c,right.c);
1454 code_t* node_in_exec(node_t*n)
1456 EXEC_HEADER_LEFTRIGHT;
1457 return code_append(left, right);
1459 constant_t node_in_eval(node_t*n)
1461 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1463 nodetype_t node_in = //in
1466 flags:NODE_HAS_CHILDREN,
1468 write: node_in_write,
1473 // ---------------------------- x as y ----------------------------------
1475 typedcode_t node_as_write(node_t*n)
1478 syntaxerror("can't assign to this expression");
1480 typedcode_t node_as_read(node_t*n)
1482 READ_HEADER_LEFTRIGHT;
1483 c = code_append(left.c, right.c);
1484 c = abc_astypelate(c);
1485 if(TYPE_IS_CLASS(right.t) && right.t->data) {
1486 t = (classinfo_t*)right.t->data;
1492 code_t* node_as_exec(node_t*n)
1494 /* we assume here that "as" doesn't have side-effects (like
1495 early run time type checking) */
1496 EXEC_HEADER_LEFTRIGHT;
1497 return code_append(left, right);
1499 constant_t node_as_eval(node_t*n)
1501 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1503 nodetype_t node_as = //as
1506 flags:NODE_HAS_CHILDREN,
1508 write: node_as_write,
1513 // ------------------------- x instanceof y -----------------------------
1515 typedcode_t node_instanceof_write(node_t*n)
1517 syntaxerror("can't assign to this expression");
1519 typedcode_t node_instanceof_read(node_t*n)
1521 READ_HEADER_LEFTRIGHT;
1522 c = code_append(left.c, right.c);
1523 c = abc_instanceof(c);
1527 code_t* node_instanceof_exec(node_t*n)
1529 EXEC_HEADER_LEFTRIGHT;
1530 return code_append(left, right);
1532 constant_t node_instanceof_eval(node_t*n)
1534 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1536 nodetype_t node_instanceof = //instanceof
1539 flags:NODE_HAS_CHILDREN,
1540 eval: node_instanceof_eval,
1541 write: node_instanceof_write,
1542 read: node_instanceof_read,
1543 exec: node_instanceof_exec
1546 // ------------------------- x is y --------------------------------------
1548 typedcode_t node_is_write(node_t*n)
1550 syntaxerror("can't assign to this expression");
1552 typedcode_t node_is_read(node_t*n)
1554 READ_HEADER_LEFTRIGHT;
1555 c = code_append(left.c, right.c);
1556 c = abc_istypelate(c);
1560 code_t* node_is_exec(node_t*n)
1562 EXEC_HEADER_LEFTRIGHT;
1563 return code_append(left, right);
1565 constant_t node_is_eval(node_t*n)
1567 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1569 nodetype_t node_is = //is
1572 flags:NODE_HAS_CHILDREN,
1574 write: node_is_write,
1579 // ------------------------- x[y] --------------------------------------
1581 typedcode_t node_arraylookup_write(node_t*n)
1583 syntaxerror("not implemented yet");
1585 typedcode_t node_arraylookup_read(node_t*n)
1587 READ_HEADER_LEFTRIGHT;
1588 c = code_append(left.c, right.c);
1590 /* XXX not sure whether this access logic is correct */
1591 namespace_t ns = {left.t?left.t->access:ACCESS_PACKAGE, ""};
1592 namespace_set_t nsset;
1593 namespace_list_t l;l.next = 0;
1594 nsset.namespaces = &l;
1596 multiname_t m = {MULTINAMEL, 0, &nsset, 0};
1598 c = abc_getproperty2(c, &m);
1599 t = 0; // array elements have unknown type
1602 code_t* node_arraylookup_exec(node_t*n)
1604 EXEC_HEADER_LEFTRIGHT;
1605 return code_append(left, right);
1607 constant_t node_arraylookup_eval(node_t*n)
1609 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1611 nodetype_t node_arraylookup =
1613 name: "arraylookup",
1614 flags:NODE_HAS_CHILDREN,
1615 eval: node_arraylookup_eval,
1616 write: node_arraylookup_write,
1617 read: node_arraylookup_read,
1618 exec: node_arraylookup_exec
1621 // ------------------------- typeof(x) ------------------------------------
1623 typedcode_t node_typeof_write(node_t*n)
1625 syntaxerror("can't assign to this expression");
1627 typedcode_t node_typeof_read(node_t*n)
1635 code_t* node_typeof_exec(node_t*n)
1640 constant_t node_typeof_eval(node_t*n)
1642 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1644 nodetype_t node_typeof = //typeof
1647 flags:NODE_HAS_CHILDREN,
1648 eval: node_typeof_eval,
1649 write: node_typeof_write,
1650 read: node_typeof_read,
1651 exec: node_typeof_exec
1654 // ------------------------- (void)(x) ------------------------------------
1656 typedcode_t node_void_write(node_t*n)
1658 syntaxerror("can't assign to this expression");
1660 typedcode_t node_void_read(node_t*n)
1662 code_t*c = n->type->exec(n);
1663 c = abc_pushundefined(c);
1664 classinfo_t*t = TYPE_ANY;
1667 code_t* node_void_exec(node_t*n)
1672 constant_t node_void_eval(node_t*n)
1674 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1676 nodetype_t node_void = //void
1679 flags:NODE_HAS_CHILDREN,
1680 eval: node_void_eval,
1681 write: node_void_write,
1682 read: node_void_read,
1683 exec: node_void_exec
1686 // ---------------------------- -x ----------------------------------------
1688 typedcode_t node_neg_write(node_t*n)
1690 syntaxerror("can't assign to this expression");
1692 typedcode_t node_neg_read(node_t*n)
1697 c = abc_negate_i(c);
1705 code_t* node_neg_exec(node_t*n)
1710 constant_t node_neg_eval(node_t*n)
1712 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1714 nodetype_t node_neg = //-
1717 flags:NODE_HAS_CHILDREN,
1718 eval: node_neg_eval,
1719 write: node_neg_write,
1720 read: node_neg_read,
1724 // ---------------------------- x*=y ----------------------------------------
1726 typedcode_t node_muleq_write(node_t*n)
1728 syntaxerror("can't assign to this expression");
1730 typedcode_t node_muleq_read(node_t*n)
1732 READ_HEADER_LEFTRIGHT;
1735 if(BOTH_INT(left.t,right.t)) {
1736 c=abc_multiply_i(c);
1742 c=converttype(c, f, left.t);
1743 c = toreadwrite(left.c, c, 0, 0, 1);
1747 code_t* node_muleq_exec(node_t*n)
1749 READ_HEADER_LEFTRIGHT;
1752 if(BOTH_INT(left.t,right.t)) {
1753 c=abc_multiply_i(c);
1759 c = converttype(c, f, left.t);
1760 return toreadwrite(left.c, c, 0, 0, 0);
1762 constant_t node_muleq_eval(node_t*n)
1764 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1766 nodetype_t node_muleq =
1769 flags:NODE_HAS_CHILDREN,
1770 eval: node_muleq_eval,
1771 write: node_muleq_write,
1772 read: node_muleq_read,
1773 exec: node_muleq_exec
1776 // ---------------------------- x%=y ----------------------------------------
1778 typedcode_t node_modeq_write(node_t*n)
1780 syntaxerror("can't assign to this expression");
1782 typedcode_t node_modeq_read(node_t*n)
1784 READ_HEADER_LEFTRIGHT;
1785 c = abc_modulo(right.c);
1786 c = converttype(c, TYPE_NUMBER, left.t);
1787 c = toreadwrite(left.c, c, 0, 0, 1);
1791 code_t* node_modeq_exec(node_t*n)
1793 READ_HEADER_LEFTRIGHT;
1794 c = abc_modulo(right.c);
1795 c = converttype(c, TYPE_NUMBER, left.t);
1796 return toreadwrite(left.c, c, 0, 0, 0);
1798 constant_t node_modeq_eval(node_t*n)
1800 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1802 nodetype_t node_modeq = //%=
1805 flags:NODE_HAS_CHILDREN,
1806 eval: node_modeq_eval,
1807 write: node_modeq_write,
1808 read: node_modeq_read,
1809 exec: node_modeq_exec
1812 // ---------------------------- x<<=y ----------------------------------------
1814 typedcode_t node_shleq_write(node_t*n)
1816 syntaxerror("can't assign to this expression");
1818 typedcode_t node_shleq_read(node_t*n)
1820 READ_HEADER_LEFTRIGHT;
1821 c = abc_lshift(right.c);
1822 c = converttype(c, TYPE_INT, left.t);
1823 c = toreadwrite(left.c, c, 0, 0, 1);
1827 code_t* node_shleq_exec(node_t*n)
1829 READ_HEADER_LEFTRIGHT;
1830 c = abc_lshift(right.c);
1831 c = converttype(c, TYPE_INT, left.t);
1832 return toreadwrite(left.c, c, 0, 0, 0);
1834 constant_t node_shleq_eval(node_t*n)
1836 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1838 nodetype_t node_shleq = //<<=
1841 flags:NODE_HAS_CHILDREN,
1842 eval: node_shleq_eval,
1843 write: node_shleq_write,
1844 read: node_shleq_read,
1845 exec: node_shleq_exec
1848 // ---------------------------- x>>=y ----------------------------------------
1850 typedcode_t node_shreq_write(node_t*n)
1852 syntaxerror("can't assign to this expression");
1854 typedcode_t node_shreq_read(node_t*n)
1856 READ_HEADER_LEFTRIGHT;
1857 c = abc_rshift(right.c);
1858 c = converttype(c, TYPE_INT, left.t);
1859 c = toreadwrite(left.c, c, 0, 0, 1);
1863 code_t* node_shreq_exec(node_t*n)
1865 READ_HEADER_LEFTRIGHT;
1866 c = abc_rshift(right.c);
1867 c = converttype(c, TYPE_INT, left.t);
1868 return toreadwrite(left.c, c, 0, 0, 0);
1870 constant_t node_shreq_eval(node_t*n)
1872 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1874 nodetype_t node_shreq = //>>=
1877 flags:NODE_HAS_CHILDREN,
1878 eval: node_shreq_eval,
1879 write: node_shreq_write,
1880 read: node_shreq_read,
1881 exec: node_shreq_exec
1884 // --------------------------- x>>>=y ----------------------------------------
1886 typedcode_t node_ushreq_write(node_t*n)
1888 syntaxerror("can't assign to this expression");
1890 typedcode_t node_ushreq_read(node_t*n)
1892 READ_HEADER_LEFTRIGHT;
1893 c = abc_urshift(right.c);
1894 c = converttype(c, TYPE_UINT, left.t);
1895 c = toreadwrite(left.c, c, 0, 0, 1);
1899 code_t* node_ushreq_exec(node_t*n)
1901 READ_HEADER_LEFTRIGHT;
1902 c = abc_urshift(right.c);
1903 c = converttype(c, TYPE_UINT, left.t);
1904 return toreadwrite(left.c, c, 0, 0, 0);
1906 constant_t node_ushreq_eval(node_t*n)
1908 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1910 nodetype_t node_ushreq = //>>>=
1913 flags:NODE_HAS_CHILDREN,
1914 eval: node_ushreq_eval,
1915 write: node_ushreq_write,
1916 read: node_ushreq_read,
1917 exec: node_ushreq_exec
1920 // --------------------------- x/=y ----------------------------------------
1922 typedcode_t node_diveq_write(node_t*n)
1924 syntaxerror("can't assign to this expression");
1926 typedcode_t node_diveq_read(node_t*n)
1928 READ_HEADER_LEFTRIGHT;
1929 c = abc_divide(right.c);
1930 c = converttype(c, TYPE_NUMBER, left.t);
1931 c = toreadwrite(left.c, c, 0, 0, 1);
1935 code_t* node_diveq_exec(node_t*n)
1937 READ_HEADER_LEFTRIGHT;
1938 c = abc_divide(right.c);
1939 c = converttype(c, TYPE_NUMBER, left.t);
1940 return toreadwrite(left.c, c, 0, 0, 0);
1942 constant_t node_diveq_eval(node_t*n)
1944 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1946 nodetype_t node_diveq =
1949 flags:NODE_HAS_CHILDREN,
1950 eval: node_diveq_eval,
1951 write: node_diveq_write,
1952 read: node_diveq_read,
1953 exec: node_diveq_exec
1956 // --------------------------- x|=y ----------------------------------------
1958 typedcode_t node_bitoreq_write(node_t*n)
1960 syntaxerror("can't assign to this expression");
1962 typedcode_t node_bitoreq_read(node_t*n)
1964 READ_HEADER_LEFTRIGHT;
1965 c = abc_bitor(right.c);
1966 c = converttype(c, TYPE_INT, left.t);
1967 c = toreadwrite(left.c, c, 0, 0, 1);
1971 code_t* node_bitoreq_exec(node_t*n)
1973 READ_HEADER_LEFTRIGHT;
1974 c = abc_bitor(right.c);
1975 c = converttype(c, TYPE_INT, left.t);
1976 return toreadwrite(left.c, c, 0, 0, 0);
1978 constant_t node_bitoreq_eval(node_t*n)
1980 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1982 nodetype_t node_bitoreq = //|=
1985 flags:NODE_HAS_CHILDREN,
1986 eval: node_bitoreq_eval,
1987 write: node_bitoreq_write,
1988 read: node_bitoreq_read,
1989 exec: node_bitoreq_exec
1992 // --------------------------- x^=y ----------------------------------------
1994 typedcode_t node_bitxoreq_write(node_t*n)
1996 syntaxerror("can't assign to this expression");
1998 typedcode_t node_bitxoreq_read(node_t*n)
2000 READ_HEADER_LEFTRIGHT;
2001 c = abc_bitxor(right.c);
2002 c = converttype(c, TYPE_INT, left.t);
2003 c = toreadwrite(left.c, c, 0, 0, 1);
2007 code_t* node_bitxoreq_exec(node_t*n)
2009 READ_HEADER_LEFTRIGHT;
2010 c = abc_bitxor(right.c);
2011 c = converttype(c, TYPE_INT, left.t);
2012 return toreadwrite(left.c, c, 0, 0, 0);
2014 constant_t node_bitxoreq_eval(node_t*n)
2016 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2018 nodetype_t node_bitxoreq = //^=
2021 flags:NODE_HAS_CHILDREN,
2022 eval: node_bitxoreq_eval,
2023 write: node_bitxoreq_write,
2024 read: node_bitxoreq_read,
2025 exec: node_bitxoreq_exec
2028 // --------------------------- x&=y ----------------------------------------
2030 typedcode_t node_bitandeq_write(node_t*n)
2032 syntaxerror("can't assign to this expression");
2034 typedcode_t node_bitandeq_read(node_t*n)
2036 READ_HEADER_LEFTRIGHT;
2037 c = abc_bitand(right.c);
2038 c = converttype(c, TYPE_INT, left.t);
2039 c = toreadwrite(left.c, c, 0, 0, 1);
2043 code_t* node_bitandeq_exec(node_t*n)
2045 READ_HEADER_LEFTRIGHT;
2046 c = abc_bitand(right.c);
2047 c = converttype(c, TYPE_INT, left.t);
2048 return toreadwrite(left.c, c, 0, 0, 0);
2050 constant_t node_bitandeq_eval(node_t*n)
2052 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2054 nodetype_t node_bitandeq = //^=
2057 flags:NODE_HAS_CHILDREN,
2058 eval: node_bitandeq_eval,
2059 write: node_bitandeq_write,
2060 read: node_bitandeq_read,
2061 exec: node_bitandeq_exec
2064 // --------------------------- x+=y ----------------------------------------
2066 typedcode_t node_pluseq_write(node_t*n)
2068 syntaxerror("can't assign to this expression");
2070 typedcode_t node_pluseq_read(node_t*n)
2072 READ_HEADER_LEFTRIGHT;
2074 if(TYPE_IS_INT(left.t)) {
2078 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2080 c = toreadwrite(left.c, c, 0, 0, 1);
2084 code_t* node_pluseq_exec(node_t*n)
2086 READ_HEADER_LEFTRIGHT;
2088 if(TYPE_IS_INT(left.t)) {
2092 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2094 return toreadwrite(left.c, c, 0, 0, 0);
2096 constant_t node_pluseq_eval(node_t*n)
2098 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2100 nodetype_t node_pluseq = //+=
2103 flags:NODE_HAS_CHILDREN,
2104 eval: node_pluseq_eval,
2105 write: node_pluseq_write,
2106 read: node_pluseq_read,
2107 exec: node_pluseq_exec
2110 // --------------------------- x-=y ----------------------------------------
2112 typedcode_t node_minuseq_write(node_t*n)
2114 syntaxerror("can't assign to this expression");
2116 typedcode_t node_minuseq_read(node_t*n)
2118 READ_HEADER_LEFTRIGHT;
2120 if(TYPE_IS_INT(left.t)) {
2121 c = abc_subtract_i(c);
2123 c = abc_subtract(c);
2124 c = converttype(c, TYPE_NUMBER, left.t);
2126 c = toreadwrite(left.c, c, 0, 0, 1);
2130 code_t* node_minuseq_exec(node_t*n)
2132 READ_HEADER_LEFTRIGHT;
2134 if(TYPE_IS_INT(left.t)) {
2135 c = abc_subtract_i(c);
2137 c = abc_subtract(c);
2138 c = converttype(c, TYPE_NUMBER, left.t);
2140 return toreadwrite(left.c, c, 0, 0, 0);
2142 constant_t node_minuseq_eval(node_t*n)
2144 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2146 nodetype_t node_minuseq = //-=
2149 flags:NODE_HAS_CHILDREN,
2150 eval: node_minuseq_eval,
2151 write: node_minuseq_write,
2152 read: node_minuseq_read,
2153 exec: node_minuseq_exec
2156 // --------------------------- x=y -----------------------------------------
2158 typedcode_t node_assign_write(node_t*n)
2160 syntaxerror("can't assign to this expression");
2162 typedcode_t node_assign_read(node_t*n)
2164 READ_HEADER_LEFTRIGHT;
2166 c = converttype(c, right.t, left.t);
2167 c = toreadwrite(left.c, c, 1, 0, 1);
2171 code_t* node_assign_exec(node_t*n)
2173 READ_HEADER_LEFTRIGHT;
2175 c = converttype(c, right.t, left.t);
2176 return toreadwrite(left.c, c, 1, 0, 0);
2178 constant_t node_assign_eval(node_t*n)
2180 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2182 nodetype_t node_assign =
2185 flags:NODE_HAS_CHILDREN,
2186 eval: node_assign_eval,
2187 write: node_assign_write,
2188 read: node_assign_read,
2189 exec: node_assign_exec
2192 // --------------------------- x?y1:y2 --------------------------------------
2194 typedcode_t node_tenary_write(node_t*n)
2196 /* TODO: this might actually be kinda useful.
2197 (global?global.x:this.x) = 3;
2199 syntaxerror("can't assign to this expression");
2201 typedcode_t node_tenary_read(node_t*n)
2203 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2204 typedcode_t left = n->child[1]->type->read(n->child[1]);
2205 typedcode_t right = n->child[2]->type->read(n->child[2]);
2206 classinfo_t*t = join_types(left.t,right.t,&node_tenary);
2208 code_t*j1 = c = abc_iffalse(c, 0);
2209 c = code_append(c, left.c);
2210 c = converttype(c, left.t, t);
2211 code_t*j2 = c = abc_jump(c, 0);
2212 c = j1->branch = abc_label(c);
2213 c = code_append(c, right.c);
2214 c = converttype(c, right.t, t);
2215 c = j2->branch = abc_label(c);
2218 code_t* node_tenary_exec(node_t*n)
2220 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2221 code_t* left = n->child[1]->type->exec(n->child[1]);
2222 code_t* right = n->child[2]->type->exec(n->child[2]);
2224 code_t*j1 = c = abc_iffalse(c, 0);
2225 c = code_append(c, left);
2226 code_t*j2 = c = abc_jump(c, 0);
2227 c = j1->branch = abc_label(c);
2228 c = code_append(c, right);
2229 c = j2->branch = abc_label(c);
2232 constant_t node_tenary_eval(node_t*n)
2234 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2236 nodetype_t node_tenary =
2239 flags:NODE_HAS_CHILDREN,
2240 eval: node_tenary_eval,
2241 write: node_tenary_write,
2242 read: node_tenary_read,
2243 exec: node_tenary_exec
2246 // ---------------------------- comma ----------------------------------------
2248 typedcode_t node_comma_write(node_t*n)
2250 syntaxerror("can't assign to this expression");
2252 typedcode_t node_comma_read(node_t*n)
2257 for(i=0;i<n->num_children-1;i++) {
2258 c = code_append(c, n->child[i]->type->exec(n->child[i]));
2260 typedcode_t o = n->child[i]->type->read(n->child[i]);
2261 c = code_append(c, o.c);
2265 code_t* node_comma_exec(node_t*n)
2269 for(t=0;t<n->num_children;t++) {
2270 c = code_append(c, n->child[t]->type->exec(n->child[t]));
2274 constant_t node_comma_eval(node_t*n)
2276 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2278 nodetype_t node_comma =
2281 flags: NODE_HAS_CHILDREN,
2282 eval: node_comma_eval,
2283 write: node_comma_write,
2284 read: node_comma_read,
2285 exec: node_comma_exec
2290 // -------------------------- new x -----------------------------------
2292 typedcode_t node_new_write(node_t*n)
2295 typedcode_t node_new_read(node_t*n)
2298 code_t* node_new_exec(node_t*n)
2301 constant_t node_new_eval(node_t*n)
2303 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2305 nodetype_t node_new = //new
2307 write: node_new_write,
2308 read: node_new_read,
2309 eval: node_new_eval,
2313 // ------------------------ delete x ----------------------------------
2315 typedcode_t node_delete_write(node_t*n)
2318 typedcode_t node_delete_read(node_t*n)
2321 code_t* node_delete_exec(node_t*n)
2324 constant_t node_delete_eval(node_t*n)
2326 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2328 nodetype_t node_delete = //delete
2330 write: node_delete_write,
2331 read: node_delete_read,
2332 eval: node_delete_eval,
2333 exec: node_delete_exec
2336 // ---------------------------- x.y -----------------------------------
2338 typedcode_t node_dot_write(node_t*n)
2341 typedcode_t node_dot_read(node_t*n)
2344 code_t* node_dot_exec(node_t*n)
2347 constant_t node_dot_eval(node_t*n)
2349 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2351 nodetype_t node_dot =
2353 write: node_dot_write,
2354 read: node_dot_read,
2355 eval: node_dot_eval,
2359 // --------------------------- x..y -----------------------------------
2361 typedcode_t node_dotdot_write(node_t*n)
2364 typedcode_t node_dotdot_read(node_t*n)
2367 code_t* node_dotdot_exec(node_t*n)
2371 constant_t node_dotdot_eval(node_t*n)
2373 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2375 nodetype_t node_dotdot = //..
2377 write: node_dotdot_write,
2378 read: node_dotdot_read,
2379 eval: node_dotdot_eval,
2380 exec: node_dotdot_exec
2383 // --------------------------- x.@y -----------------------------------
2385 typedcode_t node_dotat_write(node_t*n)
2388 typedcode_t node_dotat_read(node_t*n)
2391 code_t* node_dotat_exec(node_t*n)
2394 constant_t node_dotat_eval(node_t*n)
2396 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2398 nodetype_t node_dotat = //.@
2400 write: node_dotat_write,
2401 read: node_dotat_read,
2402 eval: node_dotat_eval,
2403 exec: node_dotat_exec
2406 // --------------------------- x.*y -----------------------------------
2408 typedcode_t node_dotstar_write(node_t*n)
2411 typedcode_t node_dotstar_read(node_t*n)
2414 code_t* node_dotstar_exec(node_t*n)
2417 constant_t node_dotstar_eval(node_t*n)
2419 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2421 nodetype_t node_dotstar = //.*
2423 write: node_dotstar_write,
2424 read: node_dotstar_read,
2425 eval: node_dotstar_eval,
2426 exec: node_dotstar_exec
2429 // -------------------------- x.(y) -----------------------------------
2431 typedcode_t node_filter_write(node_t*n)
2434 typedcode_t node_filter_read(node_t*n)
2437 code_t* node_filter_exec(node_t*n)
2440 constant_t node_filter_eval(node_t*n)
2442 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2444 nodetype_t node_filter = //.(
2446 write: node_filter_write,
2447 read: node_filter_read,
2448 eval: node_filter_eval,
2449 exec: node_filter_exec
2452 // ------------------------ x(y1,...,yn) ------------------------------
2454 typedcode_t node_call_write(node_t*n)
2457 typedcode_t node_call_read(node_t*n)
2460 code_t* node_call_exec(node_t*n)
2463 constant_t node_call_eval(node_t*n)
2465 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2467 nodetype_t node_call = //functioncall
2469 write: node_call_write,
2470 read: node_call_read,
2471 eval: node_call_eval,
2472 exec: node_call_exec
2475 // ------------------------------ @x ----------------------------------------
2477 typedcode_t node_at_write(node_t*n)
2480 typedcode_t node_at_read(node_t*n)
2483 code_t* node_at_exec(node_t*n)
2486 constant_t node_at_eval(node_t*n)
2488 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2490 nodetype_t node_at = //@
2492 write: node_at_write,
2498 // ---------------------------- x.ns::y ----------------------------------------
2500 typedcode_t node_dotns_write(node_t*n)
2503 typedcode_t node_dotns_read(node_t*n)
2506 code_t* node_dotns_exec(node_t*n)
2509 constant_t node_dotns_eval(node_t*n)
2511 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2513 nodetype_t node_dotns = //.::
2515 write: node_dotns_write,
2516 read: node_dotns_read,
2517 eval: node_dotns_eval,
2518 exec: node_dotns_exec
2522 // ------------------------ constant ------------------------------
2524 typedcode_t node_const_write(node_t*n)
2526 syntaxerror("can't assign a value to a constant");
2528 typedcode_t node_const_read(node_t*n)
2530 constant_t*v = n->value;
2535 if(v->i>-128 && v->i<128) {
2536 c = abc_pushbyte(0,v->i);
2537 } else if(v->i>=-32768 && v->i<32768) {
2538 c = abc_pushshort(0,v->i);
2540 c = abc_pushint(0,v->i);
2545 c = abc_pushuint(0,v->u);
2547 c = abc_pushbyte(0,v->u);
2548 } else if(v->u<32768) {
2549 c = abc_pushshort(0,v->u);
2551 c = abc_pushint(0,v->u);
2555 case CONSTANT_FLOAT:
2556 c = abc_pushdouble(0,v->f);
2560 c = abc_pushtrue(0);
2563 case CONSTANT_FALSE:
2564 c = abc_pushfalse(0);
2568 c = abc_pushnull(0);
2571 case CONSTANT_STRING:
2572 c = abc_pushstring2(0,v->s);
2575 case CONSTANT_UNDEFINED:
2576 c = abc_pushundefined(0);
2579 case CONSTANT_NAMESPACE:
2580 case CONSTANT_NAMESPACE_PACKAGE:
2581 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
2582 case CONSTANT_NAMESPACE_PROTECTED:
2583 case CONSTANT_NAMESPACE_EXPLICIT:
2584 case CONSTANT_NAMESPACE_STATICPROTECTED:
2585 case CONSTANT_NAMESPACE_PRIVATE:
2586 c = abc_pushnamespace(0, v->ns);
2588 case CONSTANT_UNKNOWN:
2589 syntaxerror("internal error: invalid constant");
2592 syntaxerror("invalid constant (%d)", v->type);
2598 code_t* node_const_exec(node_t*n)
2602 constant_t node_const_eval(node_t*n)
2604 constant_t*c = constant_clone(n->value);
2606 free(c); //shallow free
2609 nodetype_t node_const =
2613 eval: node_const_eval,
2614 write: node_const_write,
2615 read: node_const_read,
2616 exec: node_const_exec
2619 // ------------------------ code node ------------------------------
2621 typedcode_t node_code_write(node_t*n)
2623 syntaxerror("not implemented yet");
2625 typedcode_t node_code_read(node_t*n)
2633 code_t* node_code_exec(node_t*n)
2635 code_t*c = code_dup(n->code.c);
2636 c = cut_last_push(c);
2639 constant_t node_code_eval(node_t*n)
2641 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2643 nodetype_t node_code =
2647 eval: node_code_eval,
2648 write: node_code_write,
2649 read: node_code_read,
2650 exec: node_code_exec
2653 // ------------------------ dummy node ------------------------------
2655 typedcode_t node_dummy_write(node_t*n)
2657 syntaxerror("not implemented yet");
2659 typedcode_t node_dummy_read(node_t*n)
2662 t.c = abc_pushundefined(0);
2666 code_t* node_dummy_exec(node_t*n)
2670 constant_t node_dummy_eval(node_t*n)
2672 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2674 nodetype_t node_dummy =
2678 eval: node_dummy_eval,
2679 write: node_dummy_write,
2680 read: node_dummy_read,
2681 exec: node_dummy_exec
2684 // ======================== node handling ==============================
2686 node_t* mkdummynode()
2688 node_t*n = (node_t*)rfx_calloc(sizeof(node_t));
2689 n->type = &node_dummy;
2693 node_t* mkconstnode(constant_t*c)
2695 node_t*n = (node_t*)malloc(sizeof(node_t));
2696 n->type = &node_const;
2702 node_t* mkcodenode(typedcode_t c)
2704 node_t*n = (node_t*)malloc(sizeof(node_t));
2705 n->type = &node_code;
2711 node_t* mkmultinode(nodetype_t*t, node_t*one)
2713 node_t*n = (node_t*)malloc(sizeof(node_t));
2716 n->child = (node_t**)malloc(sizeof(node_t*)*1);
2718 n->num_children = 1;
2722 node_t* multinode_extend(node_t*n, node_t*add)
2724 n->child = realloc(n->child, (n->num_children+1)*sizeof(node_t*));
2725 n->child[n->num_children] = add;
2730 node_t* mknode1(nodetype_t*t, node_t*node)
2732 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*2);
2733 node_t**x = (node_t**)&n[1];
2737 n->num_children = 1;
2743 node_t* mknode2(nodetype_t*t, node_t*left, node_t*right)
2745 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*3);
2746 node_t**x = (node_t**)&n[1];
2750 n->num_children = 2;
2756 node_t* mknode3(nodetype_t*t, node_t*one, node_t*two, node_t*three)
2758 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*4);
2759 node_t**x = (node_t**)&n[1];
2763 n->num_children = 3;
2771 void node_free(node_t*n)
2774 if(n->type == &node_code) {
2776 code_free(n->code.c);n->code.c = 0;
2778 } else if(n->type == &node_const) {
2779 /* keep, this is not our reference */
2780 } else for(t=0;t<n->num_children;t++) {
2781 node_free(n->child[t]);n->child[t] = 0;
2786 typedcode_t node_read(node_t*n)
2788 typedcode_t t = n->type->read(n);
2792 code_t* node_exec(node_t*n)
2794 code_t*c = n->type->exec(n);
2798 constant_t node_eval(node_t*n)
2800 constant_t c = n->type->eval(n);
2818 void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
2820 if(n->type->flags&NODE_HAS_CHILDREN) {
2821 fprintf(fi, "%s%s\n", p1, n->type->name);
2823 char*o2 = malloc(strlen(p2)+3);
2824 strcpy(o2, p2);strcat(o2, "| ");
2825 char*o3 = malloc(strlen(p2)+3);
2826 strcpy(o3, p2);strcat(o3, "+-");
2827 char*o4 = malloc(strlen(p2)+3);
2828 strcpy(o4, p2);strcat(o4, " ");
2830 for(t=0;t<n->num_children;t++) {
2831 fprintf(fi, "%s\n", o2);
2832 node_dump2(n->child[t], o3, t<n->num_children-1?o2:o4, fi);
2837 } else if(n->type == &node_const) {
2838 char*s = constant_tostring(n->value);
2839 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
2841 } else if(n->type == &node_code) {
2842 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, n->code.t?n->code.t->name:"*");
2843 code_dump2(n->code.c, 0, 0, (char*)p2, fi);
2845 fprintf(fi, "%s%s\n", p1, n->type->name);
2849 void node_dump(node_t*n)
2851 printf("------------VVVV---------------\n");
2852 node_dump2(n,"","",stdout);
2853 printf("-------------------------------\n");