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)
70 if(TYPE_IS_ANY(type1) || TYPE_IS_ANY(type2))
76 static char is_getlocal(code_t*c)
78 if(!c || c->prev || c->next)
80 return(c->opcode == OPCODE_GETLOCAL
81 || c->opcode == OPCODE_GETLOCAL_0
82 || c->opcode == OPCODE_GETLOCAL_1
83 || c->opcode == OPCODE_GETLOCAL_2
84 || c->opcode == OPCODE_GETLOCAL_3);
86 static int getlocalnr(code_t*c)
88 if(c->opcode == OPCODE_GETLOCAL) {return (ptroff_t)c->data[0];}
89 else if(c->opcode == OPCODE_GETLOCAL_0) {return 0;}
90 else if(c->opcode == OPCODE_GETLOCAL_1) {return 1;}
91 else if(c->opcode == OPCODE_GETLOCAL_2) {return 2;}
92 else if(c->opcode == OPCODE_GETLOCAL_3) {return 3;}
93 else syntaxerror("Internal error: opcode %02x is not a getlocal call", c->opcode);
98 int gettempvar(); /* FIXME: we should use a function pointer here */
101 static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char readbefore, char pushvalue)
105 [prefix code] [read instruction]
109 [prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar]
111 if(in && in->opcode == OPCODE_COERCE_A) {
112 in = code_cutlast(in);
115 syntaxerror("internal error");
117 /* chop off read instruction */
121 prefix = r->prev;r->prev = 0;
127 char use_temp_var = readbefore;
129 /* generate the write instruction, and maybe append a dup to the prefix code */
130 code_t* write = abc_nop(0);
131 if(r->opcode == OPCODE_GETPROPERTY) {
132 write->opcode = OPCODE_SETPROPERTY;
133 multiname_t*m = (multiname_t*)r->data[0];
134 write->data[0] = multiname_clone(m);
135 if(m->type == QNAME || m->type == MULTINAME) {
137 prefix = abc_dup(prefix); // we need the object, too
140 } else if(m->type == MULTINAMEL) {
142 /* dupping two values on the stack requires 5 operations and one register-
143 couldn't adobe just have given us a dup2? */
144 int temp = gettempvar();
145 prefix = abc_setlocal(prefix, temp);
146 prefix = abc_dup(prefix);
147 prefix = abc_getlocal(prefix, temp);
148 prefix = abc_swap(prefix);
149 prefix = abc_getlocal(prefix, temp);
151 prefix = abc_kill(prefix, temp);
155 syntaxerror("illegal lvalue: can't assign a value to this expression (not a qname/multiname)");
157 } else if(r->opcode == OPCODE_GETSLOT) {
158 write->opcode = OPCODE_SETSLOT;
159 write->data[0] = r->data[0];
161 prefix = abc_dup(prefix); // we need the object, too
164 } else if(r->opcode == OPCODE_GETLOCAL) {
165 write->opcode = OPCODE_SETLOCAL;
166 write->data[0] = r->data[0];
167 } else if(r->opcode == OPCODE_GETLOCAL_0) {
168 write->opcode = OPCODE_SETLOCAL_0;
169 } else if(r->opcode == OPCODE_GETLOCAL_1) {
170 write->opcode = OPCODE_SETLOCAL_1;
171 } else if(r->opcode == OPCODE_GETLOCAL_2) {
172 write->opcode = OPCODE_SETLOCAL_2;
173 } else if(r->opcode == OPCODE_GETLOCAL_3) {
174 write->opcode = OPCODE_SETLOCAL_3;
175 } else if(r->opcode == OPCODE_GETSUPER) {
176 write->opcode = OPCODE_SETSUPER;
177 multiname_t*m = (multiname_t*)r->data[0];
178 write->data[0] = multiname_clone(m);
181 syntaxerror("illegal lvalue: can't assign a value to this expression");
188 /* with getproperty/getslot, we have to be extra careful not
189 to execute the read code twice, as it might have side-effects
190 (e.g. if the property is in fact a setter/getter combination)
192 So read the value, modify it, and write it again,
193 using prefix only once and making sure (by using a temporary
194 register) that the return value is what we just wrote */
196 c = code_append(c, prefix);
197 c = code_append(c, r);
198 if(pushvalue && readbefore) {
200 c = abc_setlocal(c, temp);
202 c = code_append(c, middlepart);
203 if(pushvalue && !readbefore) {
205 c = abc_setlocal(c, temp);
207 c = code_append(c, write);
209 c = abc_getlocal(c, temp);
210 c = abc_kill(c, temp);
213 /* if we're allowed to execute the read code twice *and*
214 the middlepart doesn't modify the code, things are easier.
216 //c = code_append(c, prefix);
217 if(prefix) syntaxerror("internal error (prefix)");
222 c = code_append(c, r);
223 c = code_append(c, middlepart);
224 c = code_append(c, write);
226 c = code_append(c, r2);
230 /* even smaller version: overwrite the value without reading
234 c = code_append(c, prefix);
237 c = code_append(c, middlepart);
238 c = code_append(c, write);
240 c = code_append(c, r);
246 c = code_append(c, prefix);
248 c = code_append(c, middlepart);
251 c = abc_setlocal(c, temp);
253 c = code_append(c, write);
255 c = abc_getlocal(c, temp);
256 c = abc_kill(c, temp);
263 code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to);
265 int constant_to_int(constant_t*c)
268 case CONSTANT_INT: return c->i;
269 case CONSTANT_UINT: return (int)c->u;
270 case CONSTANT_FLOAT: return c->f;
271 case CONSTANT_TRUE: return 1;
272 case CONSTANT_FALSE: return 0;
273 case CONSTANT_STRING: return atoi(c->s->str);
274 default: syntaxerror("can't convert this constant to an integer");
278 double constant_to_float(constant_t*c)
281 case CONSTANT_INT: return (double)c->i;
282 case CONSTANT_UINT: return (double)c->u;
283 case CONSTANT_FLOAT: return c->f;
284 case CONSTANT_TRUE: return (double)1;
285 case CONSTANT_FALSE: return (double)0;
286 case CONSTANT_STRING: return atof(c->s->str);
287 default: syntaxerror("can't convert this constant to a float");
291 // -------------------------- x + y -----------------------------------
293 typedcode_t node_plus_write(node_t*n)
295 syntaxerror("can't assign to this expression");
297 typedcode_t node_plus_read(node_t*n)
299 READ_HEADER_LEFTRIGHT;
300 c = code_append(left.c, right.c);
301 if(BOTH_INT(left.t, right.t)) {
306 t = join_types(left.t,right.t,n->type);
310 code_t* node_plus_exec(node_t*n)
312 EXEC_HEADER_LEFTRIGHT;
313 return code_append(left, right);
315 constant_t node_plus_eval(node_t*n)
317 EVAL_HEADER_LEFTRIGHT;
318 char left_int = left.type == CONSTANT_INT || left.type == CONSTANT_UINT;
319 if(left_int && (right.type == CONSTANT_INT || right.type == CONSTANT_UINT)) {
320 /* FIXME: what to do about signed/unsigned overflows? */
321 int i = constant_to_int(&left) + constant_to_int(&right);
322 r.type = CONSTANT_INT;
324 } else if(left_int && right.type == CONSTANT_FLOAT) {
325 double f = constant_to_int(&left) + constant_to_float(&right);
326 r.type = CONSTANT_FLOAT;
328 } else if(left.type == CONSTANT_STRING) {
329 char*add = constant_tostring(&right);
330 int l1 = left.s->len;
331 int l2 = strlen(add);
332 char*s = malloc(l1+l2+1);
333 memcpy(s, left.s->str, l1);
334 memcpy(s+l1, add, l2);
336 r.type = CONSTANT_STRING;
337 r.s = malloc(sizeof(string_t));
341 r.type = CONSTANT_UNKNOWN;
345 nodetype_t node_plus =
348 flags:NODE_HAS_CHILDREN,
350 write:node_plus_write,
355 // -------------------------- x - y -----------------------------------
357 typedcode_t node_minus_write(node_t*n)
359 syntaxerror("can't assign to this expression");
361 typedcode_t node_minus_read(node_t*n)
363 READ_HEADER_LEFTRIGHT;
364 c = code_append(left.c, right.c);
365 if(BOTH_INT(left.t,right.t)) {
366 c = abc_subtract_i(c);
374 code_t* node_minus_exec(node_t*n)
376 EXEC_HEADER_LEFTRIGHT;
377 return code_append(left, right);
379 constant_t node_minus_eval(node_t*n)
381 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
383 nodetype_t node_minus =
386 flags:NODE_HAS_CHILDREN,
387 eval: node_minus_eval,
388 write: node_minus_write,
389 read: node_minus_read,
390 exec: node_minus_exec
393 // ---------------------------- ++x -----------------------------------
395 typedcode_t node_lplusplus_write(node_t*n)
397 syntaxerror("can't assign to this expression");
399 typedcode_t node_lplusplus_read(node_t*n)
403 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
404 int nr = getlocalnr(x.c);
405 code_free(x.c);x.c=0;
406 if(TYPE_IS_INT(x.t)) {
407 c = abc_inclocal_i(c, nr);
408 c = abc_getlocal(c, nr);
409 } else if(TYPE_IS_NUMBER(x.t)) {
410 c = abc_inclocal(c, nr);
411 c = abc_getlocal(c, nr);
412 } else syntaxerror("internal error");
414 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
415 c = abc_increment_i(c);
418 c = abc_increment(c);
421 c = converttype(c, t, x.t);
422 c = toreadwrite(x.c, c, 0, 0, 1);
427 code_t* node_lplusplus_exec(node_t*n)
429 typedcode_t x = n->child[0]->type->read(n->child[0]);
431 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
432 int nr = getlocalnr(x.c);
433 code_free(x.c);x.c=0;
434 if(TYPE_IS_INT(x.t)) {
435 c = abc_inclocal_i(c, nr);
436 } else if(TYPE_IS_NUMBER(x.t)) {
437 c = abc_inclocal(c, nr);
438 } else syntaxerror("internal error");
441 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
442 c = abc_increment_i(c);
445 c = abc_increment(c);
448 c = converttype(c, t, x.t); //convert back to original type
449 c = toreadwrite(x.c, c, 0, 0, 0);
454 constant_t node_lplusplus_eval(node_t*n)
456 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
458 nodetype_t node_lplusplus =
461 flags:NODE_HAS_CHILDREN,
462 eval: node_lplusplus_eval,
463 write: node_lplusplus_write,
464 read: node_lplusplus_read,
465 exec: node_lplusplus_exec
469 // ---------------------------- --x -----------------------------------
471 typedcode_t node_lminusminus_write(node_t*n)
473 syntaxerror("can't assign to this expression");
475 typedcode_t node_lminusminus_read(node_t*n)
479 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
480 int nr = getlocalnr(x.c);
481 code_free(x.c);x.c=0;
482 if(TYPE_IS_INT(x.t)) {
483 c = abc_declocal_i(c, nr);
484 c = abc_getlocal(c, nr);
485 } else if(TYPE_IS_NUMBER(x.t)) {
486 c = abc_declocal(c, nr);
487 c = abc_getlocal(c, nr);
488 } else syntaxerror("internal error");
490 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
491 c = abc_decrement_i(c);
494 c = abc_decrement(c);
497 c = converttype(c, t, x.t);
498 c = toreadwrite(x.c, c, 0, 0, 1);
503 code_t* node_lminusminus_exec(node_t*n)
505 typedcode_t x = n->child[0]->type->read(n->child[0]);
507 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
508 int nr = getlocalnr(x.c);
509 code_free(x.c);x.c=0;
510 if(TYPE_IS_INT(x.t)) {
511 c = abc_declocal_i(c, nr);
512 } else if(TYPE_IS_NUMBER(x.t)) {
513 c = abc_declocal(c, nr);
514 } else syntaxerror("internal error");
517 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
518 c = abc_decrement_i(c);
521 c = abc_decrement(c);
524 c = converttype(c, t, x.t); //convert back to original type
525 c = toreadwrite(x.c, c, 0, 0, 0);
530 constant_t node_lminusminus_eval(node_t*n)
532 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
534 nodetype_t node_lminusminus =
537 flags:NODE_HAS_CHILDREN,
538 eval: node_lminusminus_eval,
539 write: node_lminusminus_write,
540 read: node_lminusminus_read,
541 exec: node_lminusminus_exec
546 // ---------------------------- x++ -----------------------------------
548 typedcode_t node_rplusplus_write(node_t*n)
550 syntaxerror("can't assign to this expression");
552 typedcode_t node_rplusplus_read(node_t*n)
556 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
557 int nr = getlocalnr(x.c);
558 code_free(x.c);x.c=0;
559 if(TYPE_IS_INT(x.t)) {
560 c = abc_getlocal(0, nr);
561 c = abc_inclocal_i(c, nr);
562 } else if(TYPE_IS_NUMBER(x.t)) {
563 c = abc_getlocal(0, nr);
564 c = abc_inclocal(c, nr);
565 } else syntaxerror("internal error");
567 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
568 c = abc_increment_i(c);
571 c = abc_increment(c);
574 c = converttype(c, t, x.t);
575 c = toreadwrite(x.c, c, 0, 1, 1);
580 code_t* node_rplusplus_exec(node_t*n)
582 typedcode_t x = n->child[0]->type->read(n->child[0]);
584 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
585 int nr = getlocalnr(x.c);
586 code_free(x.c);x.c=0;
587 if(TYPE_IS_INT(x.t)) {
588 c = abc_inclocal_i(c, nr);
589 } else if(TYPE_IS_NUMBER(x.t)) {
590 c = abc_inclocal(c, nr);
591 } else syntaxerror("internal error");
594 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
595 c = abc_increment_i(c);
598 c = abc_increment(c);
601 c = converttype(c, t, x.t); //convert back to original type
602 c = toreadwrite(x.c, c, 0, 1, 0);
607 constant_t node_rplusplus_eval(node_t*n)
609 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
611 nodetype_t node_rplusplus =
614 flags:NODE_HAS_CHILDREN,
615 eval: node_rplusplus_eval,
616 write: node_rplusplus_write,
617 read: node_rplusplus_read,
618 exec: node_rplusplus_exec
621 // ---------------------------- x-- -----------------------------------
623 typedcode_t node_rminusminus_write(node_t*n)
625 syntaxerror("can't assign to this expression");
627 typedcode_t node_rminusminus_read(node_t*n)
631 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
632 int nr = getlocalnr(x.c);
633 code_free(x.c);x.c=0;
634 if(TYPE_IS_INT(x.t)) {
635 c = abc_getlocal(0, nr);
636 c = abc_declocal_i(c, nr);
637 } else if(TYPE_IS_NUMBER(x.t)) {
638 c = abc_getlocal(0, nr);
639 c = abc_declocal(c, nr);
640 } else syntaxerror("internal error");
642 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
643 c = abc_decrement_i(c);
646 c = abc_decrement(c);
649 c = converttype(c, t, x.t);
650 c = toreadwrite(x.c, c, 0, 1, 1);
655 code_t* node_rminusminus_exec(node_t*n)
657 typedcode_t x = n->child[0]->type->read(n->child[0]);
659 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
660 int nr = getlocalnr(x.c);
661 code_free(x.c);x.c=0;
662 if(TYPE_IS_INT(x.t)) {
663 c = abc_declocal_i(c, nr);
664 } else if(TYPE_IS_NUMBER(x.t)) {
665 c = abc_declocal(c, nr);
666 } else syntaxerror("internal error");
669 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
670 c = abc_decrement_i(c);
673 c = abc_decrement(c);
676 c = converttype(c, t, x.t); //convert back to original type
677 c = toreadwrite(x.c, c, 0, 1, 0);
682 constant_t node_rminusminus_eval(node_t*n)
684 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
686 nodetype_t node_rminusminus =
689 flags:NODE_HAS_CHILDREN,
690 eval: node_rminusminus_eval,
691 write: node_rminusminus_write,
692 read: node_rminusminus_read,
693 exec: node_rminusminus_exec
696 // ---------------------------- x*y -----------------------------------
698 typedcode_t node_multiply_write(node_t*n)
700 syntaxerror("can't assign to this expression");
702 typedcode_t node_multiply_read(node_t*n)
704 READ_HEADER_LEFTRIGHT;
705 c = code_append(left.c,right.c);
706 if(BOTH_INT(left.t,right.t)) {
707 c = abc_multiply_i(c);
715 code_t* node_multiply_exec(node_t*n)
717 EXEC_HEADER_LEFTRIGHT;
718 return code_append(left, right);
720 constant_t node_multiply_eval(node_t*n)
722 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
724 nodetype_t node_multiply =
727 flags:NODE_HAS_CHILDREN,
728 eval: node_multiply_eval,
729 write: node_multiply_write,
730 read: node_multiply_read,
731 exec: node_multiply_exec
734 // ---------------------------- x/y -----------------------------------
736 typedcode_t node_div_write(node_t*n)
738 syntaxerror("can't assign to this expression");
740 typedcode_t node_div_read(node_t*n)
742 READ_HEADER_LEFTRIGHT;
743 c = code_append(left.c, right.c);
748 code_t* node_div_exec(node_t*n)
750 EXEC_HEADER_LEFTRIGHT;
751 return code_append(left, right);
753 constant_t node_div_eval(node_t*n)
755 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
757 nodetype_t node_div =
760 flags:NODE_HAS_CHILDREN,
762 write: node_div_write,
767 // ---------------------------- x%y -----------------------------------
769 typedcode_t node_mod_write(node_t*n)
771 syntaxerror("can't assign to this expression");
773 typedcode_t node_mod_read(node_t*n)
775 READ_HEADER_LEFTRIGHT;
776 c = code_append(left.c, right.c);
781 code_t* node_mod_exec(node_t*n)
783 EXEC_HEADER_LEFTRIGHT;
784 return code_append(left, right);
786 constant_t node_mod_eval(node_t*n)
788 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
790 nodetype_t node_mod =
793 flags:NODE_HAS_CHILDREN,
795 write: node_mod_write,
800 // ---------------------------- x<y -----------------------------------
802 typedcode_t node_lt_write(node_t*n)
804 syntaxerror("can't assign to this expression");
806 typedcode_t node_lt_read(node_t*n)
808 READ_HEADER_LEFTRIGHT;
809 c = code_append(left.c,right.c);
814 code_t* node_lt_exec(node_t*n)
816 EXEC_HEADER_LEFTRIGHT;
817 return code_append(left, right);
819 constant_t node_lt_eval(node_t*n)
821 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
826 flags:NODE_HAS_CHILDREN,
828 write: node_lt_write,
833 // ---------------------------- x>y -----------------------------------
835 typedcode_t node_gt_write(node_t*n)
837 syntaxerror("can't assign to this expression");
839 typedcode_t node_gt_read(node_t*n)
841 READ_HEADER_LEFTRIGHT;
842 c = code_append(left.c,right.c);
843 c = abc_greaterthan(c);
847 code_t* node_gt_exec(node_t*n)
849 EXEC_HEADER_LEFTRIGHT;
850 return code_append(left, right);
852 constant_t node_gt_eval(node_t*n)
854 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
859 flags:NODE_HAS_CHILDREN,
861 write: node_gt_write,
866 // ---------------------------- x<=y ----------------------------------
868 typedcode_t node_le_write(node_t*n)
870 syntaxerror("can't assign to this expression");
872 typedcode_t node_le_read(node_t*n)
874 READ_HEADER_LEFTRIGHT;
875 c = code_append(left.c,right.c);
876 c = abc_lessequals(c);
880 code_t* node_le_exec(node_t*n)
882 EXEC_HEADER_LEFTRIGHT;
883 return code_append(left, right);
885 constant_t node_le_eval(node_t*n)
887 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
889 nodetype_t node_le = //<=
892 flags:NODE_HAS_CHILDREN,
894 write: node_le_write,
899 // ---------------------------- x>=y ----------------------------------
901 typedcode_t node_ge_write(node_t*n)
903 syntaxerror("can't assign to this expression");
905 typedcode_t node_ge_read(node_t*n)
907 READ_HEADER_LEFTRIGHT;
908 c = code_append(left.c,right.c);
909 c = abc_greaterequals(c);
913 code_t* node_ge_exec(node_t*n)
915 EXEC_HEADER_LEFTRIGHT;
916 return code_append(left, right);
918 constant_t node_ge_eval(node_t*n)
920 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
922 nodetype_t node_ge = //>=
925 flags:NODE_HAS_CHILDREN,
927 write: node_ge_write,
932 // ---------------------------- x==y ----------------------------------
934 typedcode_t node_eqeq_write(node_t*n)
936 syntaxerror("can't assign to this expression");
938 typedcode_t node_eqeq_read(node_t*n)
940 READ_HEADER_LEFTRIGHT;
941 c = code_append(left.c,right.c);
946 code_t* node_eqeq_exec(node_t*n)
948 EXEC_HEADER_LEFTRIGHT;
949 return code_append(left, right);
951 constant_t node_eqeq_eval(node_t*n)
953 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
955 nodetype_t node_eqeq = //==
958 flags:NODE_HAS_CHILDREN,
959 eval: node_eqeq_eval,
960 write: node_eqeq_write,
961 read: node_eqeq_read,
965 // --------------------------- x===y ----------------------------------
967 typedcode_t node_eqeqeq_write(node_t*n)
969 syntaxerror("can't assign to this expression");
971 typedcode_t node_eqeqeq_read(node_t*n)
973 READ_HEADER_LEFTRIGHT;
974 c = code_append(left.c,right.c);
975 c = abc_strictequals(c);
979 code_t* node_eqeqeq_exec(node_t*n)
981 EXEC_HEADER_LEFTRIGHT;
982 return code_append(left, right);
984 constant_t node_eqeqeq_eval(node_t*n)
986 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
988 nodetype_t node_eqeqeq = //===
991 flags:NODE_HAS_CHILDREN,
992 eval: node_eqeqeq_eval,
993 write: node_eqeqeq_write,
994 read: node_eqeqeq_read,
995 exec: node_eqeqeq_exec
998 // --------------------------- x!==y ----------------------------------
1000 typedcode_t node_noteqeq_write(node_t*n)
1002 syntaxerror("can't assign to this expression");
1004 typedcode_t node_noteqeq_read(node_t*n)
1006 READ_HEADER_LEFTRIGHT;
1007 c = code_append(left.c,right.c);
1008 c = abc_strictequals(c);
1013 code_t* node_noteqeq_exec(node_t*n)
1015 EXEC_HEADER_LEFTRIGHT;
1016 return code_append(left, right);
1018 constant_t node_noteqeq_eval(node_t*n)
1020 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1022 nodetype_t node_noteqeq = //!==
1025 flags:NODE_HAS_CHILDREN,
1026 eval: node_noteqeq_eval,
1027 write: node_noteqeq_write,
1028 read: node_noteqeq_read,
1029 exec: node_noteqeq_exec
1032 // --------------------------- x!=y ----------------------------------
1034 typedcode_t node_noteq_write(node_t*n)
1036 syntaxerror("can't assign to this expression");
1038 typedcode_t node_noteq_read(node_t*n)
1040 READ_HEADER_LEFTRIGHT;
1041 c = code_append(left.c,right.c);
1047 code_t* node_noteq_exec(node_t*n)
1049 EXEC_HEADER_LEFTRIGHT;
1050 return code_append(left, right);
1052 constant_t node_noteq_eval(node_t*n)
1054 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1056 nodetype_t node_noteq = //!=
1059 flags:NODE_HAS_CHILDREN,
1060 eval: node_noteq_eval,
1061 write: node_noteq_write,
1062 read: node_noteq_read,
1063 exec: node_noteq_exec
1066 // --------------------------- x||y ----------------------------------
1068 typedcode_t node_oror_write(node_t*n)
1070 syntaxerror("can't assign to this expression");
1072 typedcode_t node_oror_read(node_t*n)
1074 READ_HEADER_LEFTRIGHT;
1075 t = join_types(left.t, right.t, n->type);
1077 c = converttype(c, left.t, t);
1079 code_t*jmp = c = abc_iftrue(c, 0);
1080 c = cut_last_push(c);
1081 c = code_append(c, right.c);
1082 c = converttype(c, right.t, t);
1083 code_t*label = c = abc_label(c);
1084 jmp->branch = label;
1087 code_t* node_oror_exec(node_t*n)
1089 typedcode_t left = n->child[0]->type->read(n->child[0]);
1090 code_t* right = n->child[1]->type->exec(n->child[1]);
1092 code_t*jmp = c = abc_iftrue(c, 0);
1093 c = code_append(c, right);
1094 code_t*label = c = abc_label(c);
1095 jmp->branch = label;
1098 constant_t node_oror_eval(node_t*n)
1100 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1102 nodetype_t node_oror = //||
1105 flags:NODE_HAS_CHILDREN,
1106 eval: node_oror_eval,
1107 write: node_oror_write,
1108 read: node_oror_read,
1109 exec: node_oror_exec
1112 // --------------------------- x&&y ----------------------------------
1114 typedcode_t node_andand_write(node_t*n)
1116 syntaxerror("can't assign to this expression");
1118 typedcode_t node_andand_read(node_t*n)
1120 READ_HEADER_LEFTRIGHT;
1121 t = join_types(left.t, right.t, &node_andand);
1123 c = converttype(c, left.t, t);
1125 code_t*jmp = c = abc_iffalse(c, 0);
1126 c = cut_last_push(c);
1127 c = code_append(c,right.c);
1128 c = converttype(c, right.t, t);
1129 code_t*label = c = abc_label(c);
1130 jmp->branch = label;
1133 code_t* node_andand_exec(node_t*n)
1135 typedcode_t left = n->child[0]->type->read(n->child[0]);\
1136 code_t* right = n->child[1]->type->exec(n->child[1]);\
1138 code_t*jmp = c = abc_iffalse(c, 0);
1139 c = code_append(c, right);
1140 code_t*label = c = abc_label(c);
1141 jmp->branch = label;
1144 constant_t node_andand_eval(node_t*n)
1146 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1148 nodetype_t node_andand = //&&
1151 flags:NODE_HAS_CHILDREN,
1152 eval: node_andand_eval,
1153 write: node_andand_write,
1154 read: node_andand_read,
1155 exec: node_andand_exec
1158 // ----------------------------- !x -----------------------------------
1160 typedcode_t node_not_write(node_t*n)
1162 syntaxerror("can't assign to this expression");
1164 typedcode_t node_not_read(node_t*n)
1172 code_t* node_not_exec(node_t*n)
1177 constant_t node_not_eval(node_t*n)
1179 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1181 nodetype_t node_not =
1184 flags:NODE_HAS_CHILDREN,
1185 eval: node_not_eval,
1186 write: node_not_write,
1187 read: node_not_read,
1191 // ----------------------------- ~x -----------------------------------
1193 typedcode_t node_bitnot_write(node_t*n)
1195 syntaxerror("can't assign to this expression");
1197 typedcode_t node_bitnot_read(node_t*n)
1205 code_t* node_bitnot_exec(node_t*n)
1210 constant_t node_bitnot_eval(node_t*n)
1212 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1214 nodetype_t node_bitnot =
1217 flags:NODE_HAS_CHILDREN,
1218 eval: node_bitnot_eval,
1219 write: node_bitnot_write,
1220 read: node_bitnot_read,
1221 exec: node_bitnot_exec
1224 // ----------------------------- x&y -----------------------------------
1226 typedcode_t node_bitand_write(node_t*n)
1228 syntaxerror("can't assign to this expression");
1230 typedcode_t node_bitand_read(node_t*n)
1232 READ_HEADER_LEFTRIGHT;
1233 c = code_append(left.c,right.c);
1238 code_t* node_bitand_exec(node_t*n)
1240 EXEC_HEADER_LEFTRIGHT;
1241 return code_append(left, right);
1243 constant_t node_bitand_eval(node_t*n)
1245 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1247 nodetype_t node_bitand =
1250 flags:NODE_HAS_CHILDREN,
1251 eval: node_bitand_eval,
1252 write: node_bitand_write,
1253 read: node_bitand_read,
1254 exec: node_bitand_exec
1257 // ----------------------------- x^y -----------------------------------
1259 typedcode_t node_bitxor_write(node_t*n)
1261 syntaxerror("can't assign to this expression");
1263 typedcode_t node_bitxor_read(node_t*n)
1265 READ_HEADER_LEFTRIGHT;
1266 c = code_append(left.c,right.c);
1271 code_t* node_bitxor_exec(node_t*n)
1273 EXEC_HEADER_LEFTRIGHT;
1274 return code_append(left, right);
1276 constant_t node_bitxor_eval(node_t*n)
1278 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1280 nodetype_t node_bitxor =
1283 flags:NODE_HAS_CHILDREN,
1284 eval: node_bitxor_eval,
1285 write: node_bitxor_write,
1286 read: node_bitxor_read,
1287 exec: node_bitxor_exec
1290 // ----------------------------- x|y -----------------------------------
1292 typedcode_t node_bitor_write(node_t*n)
1294 syntaxerror("can't assign to this expression");
1296 typedcode_t node_bitor_read(node_t*n)
1298 READ_HEADER_LEFTRIGHT;
1299 c = code_append(left.c,right.c);
1304 code_t* node_bitor_exec(node_t*n)
1306 EXEC_HEADER_LEFTRIGHT;
1307 return code_append(left, right);
1309 constant_t node_bitor_eval(node_t*n)
1311 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1313 nodetype_t node_bitor =
1316 flags:NODE_HAS_CHILDREN,
1317 eval: node_bitor_eval,
1318 write: node_bitor_write,
1319 read: node_bitor_read,
1320 exec: node_bitor_exec
1323 // ---------------------------- x>>y -----------------------------------
1325 typedcode_t node_shr_write(node_t*n)
1327 syntaxerror("can't assign to this expression");
1329 typedcode_t node_shr_read(node_t*n)
1331 READ_HEADER_LEFTRIGHT;
1332 c = code_append(left.c,right.c);
1337 code_t* node_shr_exec(node_t*n)
1339 EXEC_HEADER_LEFTRIGHT;
1340 return code_append(left, right);
1342 constant_t node_shr_eval(node_t*n)
1344 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1346 nodetype_t node_shr = //>>
1349 flags:NODE_HAS_CHILDREN,
1350 eval: node_shr_eval,
1351 write: node_shr_write,
1352 read: node_shr_read,
1356 // ---------------------------- x<<y -----------------------------------
1358 typedcode_t node_shl_write(node_t*n)
1360 syntaxerror("can't assign to this expression");
1362 typedcode_t node_shl_read(node_t*n)
1364 READ_HEADER_LEFTRIGHT;
1365 c = code_append(left.c,right.c);
1370 code_t* node_shl_exec(node_t*n)
1372 EXEC_HEADER_LEFTRIGHT;
1373 return code_append(left, right);
1375 constant_t node_shl_eval(node_t*n)
1377 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1379 nodetype_t node_shl = //<<
1382 flags:NODE_HAS_CHILDREN,
1383 eval: node_shl_eval,
1384 write: node_shl_write,
1385 read: node_shl_read,
1389 // ---------------------------- x>>>y -----------------------------------
1391 typedcode_t node_ushr_write(node_t*n)
1393 syntaxerror("can't assign to this expression");
1395 typedcode_t node_ushr_read(node_t*n)
1397 READ_HEADER_LEFTRIGHT;
1398 c = code_append(left.c,right.c);
1403 code_t* node_ushr_exec(node_t*n)
1405 EXEC_HEADER_LEFTRIGHT;
1406 return code_append(left, right);
1408 constant_t node_ushr_eval(node_t*n)
1410 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1412 nodetype_t node_ushr = //>>>
1415 flags:NODE_HAS_CHILDREN,
1416 eval: node_ushr_eval,
1417 write: node_ushr_write,
1418 read: node_ushr_read,
1419 exec: node_ushr_exec
1422 // ---------------------------- x in y ----------------------------------
1424 typedcode_t node_in_write(node_t*n)
1426 syntaxerror("can't assign to this expression");
1428 typedcode_t node_in_read(node_t*n)
1430 READ_HEADER_LEFTRIGHT;
1431 c = code_append(left.c,right.c);
1436 code_t* node_in_exec(node_t*n)
1438 EXEC_HEADER_LEFTRIGHT;
1439 return code_append(left, right);
1441 constant_t node_in_eval(node_t*n)
1443 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1445 nodetype_t node_in = //in
1448 flags:NODE_HAS_CHILDREN,
1450 write: node_in_write,
1455 // ---------------------------- x as y ----------------------------------
1457 typedcode_t node_as_write(node_t*n)
1460 syntaxerror("can't assign to this expression");
1462 typedcode_t node_as_read(node_t*n)
1464 READ_HEADER_LEFTRIGHT;
1465 c = code_append(left.c, right.c);
1466 c = abc_astypelate(c);
1470 code_t* node_as_exec(node_t*n)
1472 /* we assume here that "as" doesn't have side-effects (like
1473 early run time type checking) */
1474 EXEC_HEADER_LEFTRIGHT;
1475 return code_append(left, right);
1477 constant_t node_as_eval(node_t*n)
1479 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1481 nodetype_t node_as = //as
1484 flags:NODE_HAS_CHILDREN,
1486 write: node_as_write,
1491 // ------------------------- x instanceof y -----------------------------
1493 typedcode_t node_instanceof_write(node_t*n)
1495 syntaxerror("can't assign to this expression");
1497 typedcode_t node_instanceof_read(node_t*n)
1499 READ_HEADER_LEFTRIGHT;
1500 c = code_append(left.c, right.c);
1501 c = abc_instanceof(c);
1505 code_t* node_instanceof_exec(node_t*n)
1507 EXEC_HEADER_LEFTRIGHT;
1508 return code_append(left, right);
1510 constant_t node_instanceof_eval(node_t*n)
1512 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1514 nodetype_t node_instanceof = //instanceof
1517 flags:NODE_HAS_CHILDREN,
1518 eval: node_instanceof_eval,
1519 write: node_instanceof_write,
1520 read: node_instanceof_read,
1521 exec: node_instanceof_exec
1524 // ------------------------- x is y --------------------------------------
1526 typedcode_t node_is_write(node_t*n)
1528 syntaxerror("can't assign to this expression");
1530 typedcode_t node_is_read(node_t*n)
1532 READ_HEADER_LEFTRIGHT;
1533 c = code_append(left.c, right.c);
1534 c = abc_istypelate(c);
1538 code_t* node_is_exec(node_t*n)
1540 EXEC_HEADER_LEFTRIGHT;
1541 return code_append(left, right);
1543 constant_t node_is_eval(node_t*n)
1545 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1547 nodetype_t node_is = //is
1550 flags:NODE_HAS_CHILDREN,
1552 write: node_is_write,
1557 // ------------------------- x[y] --------------------------------------
1559 typedcode_t node_arraylookup_write(node_t*n)
1561 syntaxerror("not implemented yet");
1563 typedcode_t node_arraylookup_read(node_t*n)
1565 READ_HEADER_LEFTRIGHT;
1566 c = code_append(left.c, right.c);
1568 /* XXX not sure whether this access logic is correct */
1569 namespace_t ns = {left.t?left.t->access:ACCESS_PACKAGE, ""};
1570 namespace_set_t nsset;
1571 namespace_list_t l;l.next = 0;
1572 nsset.namespaces = &l;
1574 multiname_t m = {MULTINAMEL, 0, &nsset, 0};
1576 c = abc_getproperty2(c, &m);
1577 t = 0; // array elements have unknown type
1580 code_t* node_arraylookup_exec(node_t*n)
1582 EXEC_HEADER_LEFTRIGHT;
1583 return code_append(left, right);
1585 constant_t node_arraylookup_eval(node_t*n)
1587 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1589 nodetype_t node_arraylookup =
1591 name: "arraylookup",
1592 flags:NODE_HAS_CHILDREN,
1593 eval: node_arraylookup_eval,
1594 write: node_arraylookup_write,
1595 read: node_arraylookup_read,
1596 exec: node_arraylookup_exec
1599 // ------------------------- typeof(x) ------------------------------------
1601 typedcode_t node_typeof_write(node_t*n)
1603 syntaxerror("can't assign to this expression");
1605 typedcode_t node_typeof_read(node_t*n)
1613 code_t* node_typeof_exec(node_t*n)
1618 constant_t node_typeof_eval(node_t*n)
1620 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1622 nodetype_t node_typeof = //typeof
1625 flags:NODE_HAS_CHILDREN,
1626 eval: node_typeof_eval,
1627 write: node_typeof_write,
1628 read: node_typeof_read,
1629 exec: node_typeof_exec
1632 // ------------------------- (void)(x) ------------------------------------
1634 typedcode_t node_void_write(node_t*n)
1636 syntaxerror("can't assign to this expression");
1638 typedcode_t node_void_read(node_t*n)
1640 code_t*c = n->type->exec(n);
1641 c = abc_pushundefined(c);
1642 classinfo_t*t = TYPE_ANY;
1645 code_t* node_void_exec(node_t*n)
1650 constant_t node_void_eval(node_t*n)
1652 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1654 nodetype_t node_void = //void
1657 flags:NODE_HAS_CHILDREN,
1658 eval: node_void_eval,
1659 write: node_void_write,
1660 read: node_void_read,
1661 exec: node_void_exec
1664 // ---------------------------- -x ----------------------------------------
1666 typedcode_t node_neg_write(node_t*n)
1668 syntaxerror("can't assign to this expression");
1670 typedcode_t node_neg_read(node_t*n)
1675 c = abc_negate_i(c);
1683 code_t* node_neg_exec(node_t*n)
1688 constant_t node_neg_eval(node_t*n)
1690 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1692 nodetype_t node_neg = //-
1695 flags:NODE_HAS_CHILDREN,
1696 eval: node_neg_eval,
1697 write: node_neg_write,
1698 read: node_neg_read,
1702 // ---------------------------- x*=y ----------------------------------------
1704 typedcode_t node_muleq_write(node_t*n)
1706 syntaxerror("can't assign to this expression");
1708 typedcode_t node_muleq_read(node_t*n)
1710 READ_HEADER_LEFTRIGHT;
1713 if(BOTH_INT(left.t,right.t)) {
1714 c=abc_multiply_i(c);
1720 c=converttype(c, f, left.t);
1721 c = toreadwrite(left.c, c, 0, 0, 1);
1725 code_t* node_muleq_exec(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 return toreadwrite(left.c, c, 0, 0, 0);
1740 constant_t node_muleq_eval(node_t*n)
1742 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1744 nodetype_t node_muleq =
1747 flags:NODE_HAS_CHILDREN,
1748 eval: node_muleq_eval,
1749 write: node_muleq_write,
1750 read: node_muleq_read,
1751 exec: node_muleq_exec
1754 // ---------------------------- x%=y ----------------------------------------
1756 typedcode_t node_modeq_write(node_t*n)
1758 syntaxerror("can't assign to this expression");
1760 typedcode_t node_modeq_read(node_t*n)
1762 READ_HEADER_LEFTRIGHT;
1763 c = abc_modulo(right.c);
1764 c = converttype(c, TYPE_NUMBER, left.t);
1765 c = toreadwrite(left.c, c, 0, 0, 1);
1769 code_t* node_modeq_exec(node_t*n)
1771 READ_HEADER_LEFTRIGHT;
1772 c = abc_modulo(right.c);
1773 c = converttype(c, TYPE_NUMBER, left.t);
1774 return toreadwrite(left.c, c, 0, 0, 0);
1776 constant_t node_modeq_eval(node_t*n)
1778 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1780 nodetype_t node_modeq = //%=
1783 flags:NODE_HAS_CHILDREN,
1784 eval: node_modeq_eval,
1785 write: node_modeq_write,
1786 read: node_modeq_read,
1787 exec: node_modeq_exec
1790 // ---------------------------- x<<=y ----------------------------------------
1792 typedcode_t node_shleq_write(node_t*n)
1794 syntaxerror("can't assign to this expression");
1796 typedcode_t node_shleq_read(node_t*n)
1798 READ_HEADER_LEFTRIGHT;
1799 c = abc_lshift(right.c);
1800 c = converttype(c, TYPE_INT, left.t);
1801 c = toreadwrite(left.c, c, 0, 0, 1);
1805 code_t* node_shleq_exec(node_t*n)
1807 READ_HEADER_LEFTRIGHT;
1808 c = abc_lshift(right.c);
1809 c = converttype(c, TYPE_INT, left.t);
1810 return toreadwrite(left.c, c, 0, 0, 0);
1812 constant_t node_shleq_eval(node_t*n)
1814 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1816 nodetype_t node_shleq = //<<=
1819 flags:NODE_HAS_CHILDREN,
1820 eval: node_shleq_eval,
1821 write: node_shleq_write,
1822 read: node_shleq_read,
1823 exec: node_shleq_exec
1826 // ---------------------------- x>>=y ----------------------------------------
1828 typedcode_t node_shreq_write(node_t*n)
1830 syntaxerror("can't assign to this expression");
1832 typedcode_t node_shreq_read(node_t*n)
1834 READ_HEADER_LEFTRIGHT;
1835 c = abc_rshift(right.c);
1836 c = converttype(c, TYPE_INT, left.t);
1837 c = toreadwrite(left.c, c, 0, 0, 1);
1841 code_t* node_shreq_exec(node_t*n)
1843 READ_HEADER_LEFTRIGHT;
1844 c = abc_rshift(right.c);
1845 c = converttype(c, TYPE_INT, left.t);
1846 return toreadwrite(left.c, c, 0, 0, 0);
1848 constant_t node_shreq_eval(node_t*n)
1850 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1852 nodetype_t node_shreq = //>>=
1855 flags:NODE_HAS_CHILDREN,
1856 eval: node_shreq_eval,
1857 write: node_shreq_write,
1858 read: node_shreq_read,
1859 exec: node_shreq_exec
1862 // --------------------------- x>>>=y ----------------------------------------
1864 typedcode_t node_ushreq_write(node_t*n)
1866 syntaxerror("can't assign to this expression");
1868 typedcode_t node_ushreq_read(node_t*n)
1870 READ_HEADER_LEFTRIGHT;
1871 c = abc_urshift(right.c);
1872 c = converttype(c, TYPE_UINT, left.t);
1873 c = toreadwrite(left.c, c, 0, 0, 1);
1877 code_t* node_ushreq_exec(node_t*n)
1879 READ_HEADER_LEFTRIGHT;
1880 c = abc_urshift(right.c);
1881 c = converttype(c, TYPE_UINT, left.t);
1882 return toreadwrite(left.c, c, 0, 0, 0);
1884 constant_t node_ushreq_eval(node_t*n)
1886 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1888 nodetype_t node_ushreq = //>>>=
1891 flags:NODE_HAS_CHILDREN,
1892 eval: node_ushreq_eval,
1893 write: node_ushreq_write,
1894 read: node_ushreq_read,
1895 exec: node_ushreq_exec
1898 // --------------------------- x/=y ----------------------------------------
1900 typedcode_t node_diveq_write(node_t*n)
1902 syntaxerror("can't assign to this expression");
1904 typedcode_t node_diveq_read(node_t*n)
1906 READ_HEADER_LEFTRIGHT;
1907 c = abc_divide(right.c);
1908 c = converttype(c, TYPE_NUMBER, left.t);
1909 c = toreadwrite(left.c, c, 0, 0, 1);
1913 code_t* node_diveq_exec(node_t*n)
1915 READ_HEADER_LEFTRIGHT;
1916 c = abc_divide(right.c);
1917 c = converttype(c, TYPE_NUMBER, left.t);
1918 return toreadwrite(left.c, c, 0, 0, 0);
1920 constant_t node_diveq_eval(node_t*n)
1922 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1924 nodetype_t node_diveq =
1927 flags:NODE_HAS_CHILDREN,
1928 eval: node_diveq_eval,
1929 write: node_diveq_write,
1930 read: node_diveq_read,
1931 exec: node_diveq_exec
1934 // --------------------------- x|=y ----------------------------------------
1936 typedcode_t node_bitoreq_write(node_t*n)
1938 syntaxerror("can't assign to this expression");
1940 typedcode_t node_bitoreq_read(node_t*n)
1942 READ_HEADER_LEFTRIGHT;
1943 c = abc_bitor(right.c);
1944 c = converttype(c, TYPE_INT, left.t);
1945 c = toreadwrite(left.c, c, 0, 0, 1);
1949 code_t* node_bitoreq_exec(node_t*n)
1951 READ_HEADER_LEFTRIGHT;
1952 c = abc_bitor(right.c);
1953 c = converttype(c, TYPE_INT, left.t);
1954 return toreadwrite(left.c, c, 0, 0, 0);
1956 constant_t node_bitoreq_eval(node_t*n)
1958 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1960 nodetype_t node_bitoreq = //|=
1963 flags:NODE_HAS_CHILDREN,
1964 eval: node_bitoreq_eval,
1965 write: node_bitoreq_write,
1966 read: node_bitoreq_read,
1967 exec: node_bitoreq_exec
1970 // --------------------------- x^=y ----------------------------------------
1972 typedcode_t node_bitxoreq_write(node_t*n)
1974 syntaxerror("can't assign to this expression");
1976 typedcode_t node_bitxoreq_read(node_t*n)
1978 READ_HEADER_LEFTRIGHT;
1979 c = abc_bitxor(right.c);
1980 c = converttype(c, TYPE_INT, left.t);
1981 c = toreadwrite(left.c, c, 0, 0, 1);
1985 code_t* node_bitxoreq_exec(node_t*n)
1987 READ_HEADER_LEFTRIGHT;
1988 c = abc_bitxor(right.c);
1989 c = converttype(c, TYPE_INT, left.t);
1990 return toreadwrite(left.c, c, 0, 0, 0);
1992 constant_t node_bitxoreq_eval(node_t*n)
1994 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1996 nodetype_t node_bitxoreq = //^=
1999 flags:NODE_HAS_CHILDREN,
2000 eval: node_bitxoreq_eval,
2001 write: node_bitxoreq_write,
2002 read: node_bitxoreq_read,
2003 exec: node_bitxoreq_exec
2006 // --------------------------- x&=y ----------------------------------------
2008 typedcode_t node_bitandeq_write(node_t*n)
2010 syntaxerror("can't assign to this expression");
2012 typedcode_t node_bitandeq_read(node_t*n)
2014 READ_HEADER_LEFTRIGHT;
2015 c = abc_bitand(right.c);
2016 c = converttype(c, TYPE_INT, left.t);
2017 c = toreadwrite(left.c, c, 0, 0, 1);
2021 code_t* node_bitandeq_exec(node_t*n)
2023 READ_HEADER_LEFTRIGHT;
2024 c = abc_bitand(right.c);
2025 c = converttype(c, TYPE_INT, left.t);
2026 return toreadwrite(left.c, c, 0, 0, 0);
2028 constant_t node_bitandeq_eval(node_t*n)
2030 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2032 nodetype_t node_bitandeq = //^=
2035 flags:NODE_HAS_CHILDREN,
2036 eval: node_bitandeq_eval,
2037 write: node_bitandeq_write,
2038 read: node_bitandeq_read,
2039 exec: node_bitandeq_exec
2042 // --------------------------- x+=y ----------------------------------------
2044 typedcode_t node_pluseq_write(node_t*n)
2046 syntaxerror("can't assign to this expression");
2048 typedcode_t node_pluseq_read(node_t*n)
2050 READ_HEADER_LEFTRIGHT;
2052 if(TYPE_IS_INT(left.t)) {
2056 c = converttype(c, TYPE_NUMBER, left.t);
2058 c = toreadwrite(left.c, c, 0, 0, 1);
2062 code_t* node_pluseq_exec(node_t*n)
2064 READ_HEADER_LEFTRIGHT;
2066 if(TYPE_IS_INT(left.t)) {
2070 c = converttype(c, TYPE_NUMBER, left.t);
2072 return toreadwrite(left.c, c, 0, 0, 0);
2074 constant_t node_pluseq_eval(node_t*n)
2076 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2078 nodetype_t node_pluseq = //+=
2081 flags:NODE_HAS_CHILDREN,
2082 eval: node_pluseq_eval,
2083 write: node_pluseq_write,
2084 read: node_pluseq_read,
2085 exec: node_pluseq_exec
2088 // --------------------------- x-=y ----------------------------------------
2090 typedcode_t node_minuseq_write(node_t*n)
2092 syntaxerror("can't assign to this expression");
2094 typedcode_t node_minuseq_read(node_t*n)
2096 READ_HEADER_LEFTRIGHT;
2098 if(TYPE_IS_INT(left.t)) {
2099 c = abc_subtract_i(c);
2101 c = abc_subtract(c);
2102 c = converttype(c, TYPE_NUMBER, left.t);
2104 c = toreadwrite(left.c, c, 0, 0, 1);
2108 code_t* node_minuseq_exec(node_t*n)
2110 READ_HEADER_LEFTRIGHT;
2112 if(TYPE_IS_INT(left.t)) {
2113 c = abc_subtract_i(c);
2115 c = abc_subtract(c);
2116 c = converttype(c, TYPE_NUMBER, left.t);
2118 return toreadwrite(left.c, c, 0, 0, 0);
2120 constant_t node_minuseq_eval(node_t*n)
2122 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2124 nodetype_t node_minuseq = //-=
2127 flags:NODE_HAS_CHILDREN,
2128 eval: node_minuseq_eval,
2129 write: node_minuseq_write,
2130 read: node_minuseq_read,
2131 exec: node_minuseq_exec
2134 // --------------------------- x=y -----------------------------------------
2136 typedcode_t node_assign_write(node_t*n)
2138 syntaxerror("can't assign to this expression");
2140 typedcode_t node_assign_read(node_t*n)
2142 READ_HEADER_LEFTRIGHT;
2144 c = converttype(c, right.t, left.t);
2145 c = toreadwrite(left.c, c, 1, 0, 1);
2149 code_t* node_assign_exec(node_t*n)
2151 READ_HEADER_LEFTRIGHT;
2153 c = converttype(c, right.t, left.t);
2154 return toreadwrite(left.c, c, 1, 0, 0);
2156 constant_t node_assign_eval(node_t*n)
2158 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2160 nodetype_t node_assign =
2163 flags:NODE_HAS_CHILDREN,
2164 eval: node_assign_eval,
2165 write: node_assign_write,
2166 read: node_assign_read,
2167 exec: node_assign_exec
2170 // --------------------------- x?y1:y2 --------------------------------------
2172 typedcode_t node_tenary_write(node_t*n)
2174 /* TODO: this might actually be kinda useful.
2175 (global?global.x:this.x) = 3;
2177 syntaxerror("can't assign to this expression");
2179 typedcode_t node_tenary_read(node_t*n)
2181 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2182 typedcode_t left = n->child[1]->type->read(n->child[1]);
2183 typedcode_t right = n->child[2]->type->read(n->child[2]);
2184 classinfo_t*t = join_types(left.t,right.t,&node_tenary);
2186 code_t*j1 = c = abc_iffalse(c, 0);
2187 c = code_append(c, left.c);
2188 c = converttype(c, left.t, t);
2189 code_t*j2 = c = abc_jump(c, 0);
2190 c = j1->branch = abc_label(c);
2191 c = code_append(c, right.c);
2192 c = converttype(c, right.t, t);
2193 c = j2->branch = abc_label(c);
2196 code_t* node_tenary_exec(node_t*n)
2198 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2199 code_t* left = n->child[1]->type->exec(n->child[1]);
2200 code_t* right = n->child[2]->type->exec(n->child[2]);
2202 code_t*j1 = c = abc_iffalse(c, 0);
2203 c = code_append(c, left);
2204 code_t*j2 = c = abc_jump(c, 0);
2205 c = j1->branch = abc_label(c);
2206 c = code_append(c, right);
2207 c = j2->branch = abc_label(c);
2210 constant_t node_tenary_eval(node_t*n)
2212 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2214 nodetype_t node_tenary =
2217 flags:NODE_HAS_CHILDREN,
2218 eval: node_tenary_eval,
2219 write: node_tenary_write,
2220 read: node_tenary_read,
2221 exec: node_tenary_exec
2224 // ---------------------------- comma ----------------------------------------
2226 typedcode_t node_comma_write(node_t*n)
2228 syntaxerror("can't assign to this expression");
2230 typedcode_t node_comma_read(node_t*n)
2235 for(i=0;i<n->num_children-1;i++) {
2236 c = code_append(c, n->child[i]->type->exec(n->child[i]));
2238 typedcode_t o = n->child[i]->type->read(n->child[i]);
2239 c = code_append(c, o.c);
2243 code_t* node_comma_exec(node_t*n)
2247 for(t=0;t<n->num_children;t++) {
2248 c = code_append(c, n->child[t]->type->exec(n->child[t]));
2252 constant_t node_comma_eval(node_t*n)
2254 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2256 nodetype_t node_comma =
2259 flags: NODE_HAS_CHILDREN,
2260 eval: node_comma_eval,
2261 write: node_comma_write,
2262 read: node_comma_read,
2263 exec: node_comma_exec
2268 // -------------------------- new x -----------------------------------
2270 typedcode_t node_new_write(node_t*n)
2273 typedcode_t node_new_read(node_t*n)
2276 code_t* node_new_exec(node_t*n)
2279 constant_t node_new_eval(node_t*n)
2281 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2283 nodetype_t node_new = //new
2285 write: node_new_write,
2286 read: node_new_read,
2287 eval: node_new_eval,
2291 // ------------------------ delete x ----------------------------------
2293 typedcode_t node_delete_write(node_t*n)
2296 typedcode_t node_delete_read(node_t*n)
2299 code_t* node_delete_exec(node_t*n)
2302 constant_t node_delete_eval(node_t*n)
2304 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2306 nodetype_t node_delete = //delete
2308 write: node_delete_write,
2309 read: node_delete_read,
2310 eval: node_delete_eval,
2311 exec: node_delete_exec
2314 // ---------------------------- x.y -----------------------------------
2316 typedcode_t node_dot_write(node_t*n)
2319 typedcode_t node_dot_read(node_t*n)
2322 code_t* node_dot_exec(node_t*n)
2325 constant_t node_dot_eval(node_t*n)
2327 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2329 nodetype_t node_dot =
2331 write: node_dot_write,
2332 read: node_dot_read,
2333 eval: node_dot_eval,
2337 // --------------------------- x..y -----------------------------------
2339 typedcode_t node_dotdot_write(node_t*n)
2342 typedcode_t node_dotdot_read(node_t*n)
2345 code_t* node_dotdot_exec(node_t*n)
2349 constant_t node_dotdot_eval(node_t*n)
2351 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2353 nodetype_t node_dotdot = //..
2355 write: node_dotdot_write,
2356 read: node_dotdot_read,
2357 eval: node_dotdot_eval,
2358 exec: node_dotdot_exec
2361 // --------------------------- x.@y -----------------------------------
2363 typedcode_t node_dotat_write(node_t*n)
2366 typedcode_t node_dotat_read(node_t*n)
2369 code_t* node_dotat_exec(node_t*n)
2372 constant_t node_dotat_eval(node_t*n)
2374 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2376 nodetype_t node_dotat = //.@
2378 write: node_dotat_write,
2379 read: node_dotat_read,
2380 eval: node_dotat_eval,
2381 exec: node_dotat_exec
2384 // --------------------------- x.*y -----------------------------------
2386 typedcode_t node_dotstar_write(node_t*n)
2389 typedcode_t node_dotstar_read(node_t*n)
2392 code_t* node_dotstar_exec(node_t*n)
2395 constant_t node_dotstar_eval(node_t*n)
2397 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2399 nodetype_t node_dotstar = //.*
2401 write: node_dotstar_write,
2402 read: node_dotstar_read,
2403 eval: node_dotstar_eval,
2404 exec: node_dotstar_exec
2407 // -------------------------- x.(y) -----------------------------------
2409 typedcode_t node_filter_write(node_t*n)
2412 typedcode_t node_filter_read(node_t*n)
2415 code_t* node_filter_exec(node_t*n)
2418 constant_t node_filter_eval(node_t*n)
2420 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2422 nodetype_t node_filter = //.(
2424 write: node_filter_write,
2425 read: node_filter_read,
2426 eval: node_filter_eval,
2427 exec: node_filter_exec
2430 // ------------------------ x(y1,...,yn) ------------------------------
2432 typedcode_t node_call_write(node_t*n)
2435 typedcode_t node_call_read(node_t*n)
2438 code_t* node_call_exec(node_t*n)
2441 constant_t node_call_eval(node_t*n)
2443 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2445 nodetype_t node_call = //functioncall
2447 write: node_call_write,
2448 read: node_call_read,
2449 eval: node_call_eval,
2450 exec: node_call_exec
2453 // ------------------------------ @x ----------------------------------------
2455 typedcode_t node_at_write(node_t*n)
2458 typedcode_t node_at_read(node_t*n)
2461 code_t* node_at_exec(node_t*n)
2464 constant_t node_at_eval(node_t*n)
2466 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2468 nodetype_t node_at = //@
2470 write: node_at_write,
2476 // ---------------------------- x.ns::y ----------------------------------------
2478 typedcode_t node_dotns_write(node_t*n)
2481 typedcode_t node_dotns_read(node_t*n)
2484 code_t* node_dotns_exec(node_t*n)
2487 constant_t node_dotns_eval(node_t*n)
2489 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2491 nodetype_t node_dotns = //.::
2493 write: node_dotns_write,
2494 read: node_dotns_read,
2495 eval: node_dotns_eval,
2496 exec: node_dotns_exec
2500 // ------------------------ constant ------------------------------
2502 typedcode_t node_const_write(node_t*n)
2504 syntaxerror("can't assign a value to a constant");
2506 typedcode_t node_const_read(node_t*n)
2508 constant_t*v = n->value;
2513 if(v->i>-128 && v->i<128) {
2514 c = abc_pushbyte(0,v->i);
2515 } else if(v->i>=-32768 && v->i<32768) {
2516 c = abc_pushshort(0,v->i);
2518 c = abc_pushint(0,v->i);
2523 c = abc_pushuint(0,v->u);
2525 c = abc_pushbyte(0,v->u);
2526 } else if(v->u<32768) {
2527 c = abc_pushshort(0,v->u);
2529 c = abc_pushint(0,v->u);
2533 case CONSTANT_FLOAT:
2534 c = abc_pushdouble(0,v->f);
2538 c = abc_pushtrue(0);
2541 case CONSTANT_FALSE:
2542 c = abc_pushfalse(0);
2546 c = abc_pushnull(0);
2549 case CONSTANT_STRING:
2550 c = abc_pushstring2(0,v->s);
2553 case CONSTANT_UNDEFINED:
2554 c = abc_pushundefined(0);
2557 case CONSTANT_NAMESPACE:
2558 case CONSTANT_NAMESPACE_PACKAGE:
2559 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
2560 case CONSTANT_NAMESPACE_PROTECTED:
2561 case CONSTANT_NAMESPACE_EXPLICIT:
2562 case CONSTANT_NAMESPACE_STATICPROTECTED:
2563 case CONSTANT_NAMESPACE_PRIVATE:
2564 c = abc_pushnamespace(0, v->ns);
2566 default: syntaxerror("invalid constant");
2571 code_t* node_const_exec(node_t*n)
2575 constant_t node_const_eval(node_t*n)
2577 constant_t*c = constant_clone(n->value);
2579 free(c); //shallow free
2582 nodetype_t node_const =
2586 eval: node_const_eval,
2587 write: node_const_write,
2588 read: node_const_read,
2589 exec: node_const_exec
2592 // ------------------------ code node ------------------------------
2594 typedcode_t node_code_write(node_t*n)
2596 syntaxerror("not implemented yet");
2598 typedcode_t node_code_read(node_t*n)
2600 /* TODO: this dup might be unnecessary- n->code.c is only read out once */
2602 t.c = code_dup(n->code.c);
2606 code_t* node_code_exec(node_t*n)
2608 code_t*c = code_dup(n->code.c);
2609 c = cut_last_push(c);
2612 constant_t node_code_eval(node_t*n)
2614 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2616 nodetype_t node_code =
2620 eval: node_code_eval,
2621 write: node_code_write,
2622 read: node_code_read,
2623 exec: node_code_exec
2626 // ------------------------ dummy node ------------------------------
2628 typedcode_t node_dummy_write(node_t*n)
2630 syntaxerror("not implemented yet");
2632 typedcode_t node_dummy_read(node_t*n)
2635 t.c = abc_pushundefined(0);
2639 code_t* node_dummy_exec(node_t*n)
2643 constant_t node_dummy_eval(node_t*n)
2645 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2647 nodetype_t node_dummy =
2651 eval: node_dummy_eval,
2652 write: node_dummy_write,
2653 read: node_dummy_read,
2654 exec: node_dummy_exec
2657 // ======================== node handling ==============================
2659 node_t* mkdummynode()
2661 node_t*n = (node_t*)rfx_calloc(sizeof(node_t));
2662 n->type = &node_dummy;
2666 node_t* mkconstnode(constant_t*c)
2668 node_t*n = (node_t*)malloc(sizeof(node_t));
2669 n->type = &node_const;
2675 node_t* mkcodenode(typedcode_t c)
2677 node_t*n = (node_t*)malloc(sizeof(node_t));
2678 n->type = &node_code;
2684 node_t* mkmultinode(nodetype_t*t, node_t*one)
2686 node_t*n = (node_t*)malloc(sizeof(node_t));
2689 n->child = (node_t**)malloc(sizeof(node_t*)*1);
2691 n->num_children = 1;
2695 node_t* multinode_extend(node_t*n, node_t*add)
2697 n->child = realloc(n->child, (n->num_children+1)*sizeof(node_t*));
2698 n->child[n->num_children] = add;
2703 node_t* mknode1(nodetype_t*t, node_t*node)
2705 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*2);
2706 node_t**x = (node_t**)&n[1];
2710 n->num_children = 1;
2716 node_t* mknode2(nodetype_t*t, node_t*left, node_t*right)
2718 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*3);
2719 node_t**x = (node_t**)&n[1];
2723 n->num_children = 2;
2729 node_t* mknode3(nodetype_t*t, node_t*one, node_t*two, node_t*three)
2731 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*4);
2732 node_t**x = (node_t**)&n[1];
2736 n->num_children = 3;
2744 void node_free(node_t*n)
2747 if(n->type == &node_const) {
2748 constant_free(n->value);n->value = 0;
2750 else if(n->type == &node_code) {
2751 code_free(n->code.c);n->code.c = 0;
2753 else for(t=0;t<n->num_children;t++) {
2754 node_free(n->child[t]);n->child[t] = 0;
2759 typedcode_t node_read(node_t*n)
2761 typedcode_t t = n->type->read(n);
2765 code_t* node_exec(node_t*n)
2767 code_t*c = n->type->exec(n);
2771 constant_t node_eval(node_t*n)
2773 constant_t c = n->type->eval(n);
2791 void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
2793 if(n->type->flags&NODE_HAS_CHILDREN) {
2794 fprintf(fi, "%s%s\n", p1, n->type->name);
2796 char*o2 = malloc(strlen(p2)+3);
2797 strcpy(o2, p2);strcat(o2, "| ");
2798 char*o3 = malloc(strlen(p2)+3);
2799 strcpy(o3, p2);strcat(o3, "+-");
2800 char*o4 = malloc(strlen(p2)+3);
2801 strcpy(o4, p2);strcat(o4, " ");
2803 for(t=0;t<n->num_children;t++) {
2804 fprintf(fi, "%s\n", o2);
2805 node_dump2(n->child[t], o3, t<n->num_children-1?o2:o4, fi);
2810 } else if(n->type == &node_const) {
2811 char*s = constant_tostring(n->value);
2812 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
2814 } else if(n->type == &node_code) {
2815 fprintf(fi, "%s%s\n", p1, n->type->name);
2816 code_dump2(n->code.c, 0, 0, (char*)p2, fi);
2818 fprintf(fi, "%s%s\n", p1, n->type->name);
2822 void node_dump(node_t*n)
2824 printf("---------------------------VVVV\n");
2825 node_dump2(n,"","",stdout);
2826 printf("---------------------------^^^^\n");