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));
342 r.type = CONSTANT_UNKNOWN;
346 nodetype_t node_plus =
349 flags:NODE_HAS_CHILDREN,
351 write:node_plus_write,
356 // -------------------------- x - y -----------------------------------
358 typedcode_t node_minus_write(node_t*n)
360 syntaxerror("can't assign to this expression");
362 typedcode_t node_minus_read(node_t*n)
364 READ_HEADER_LEFTRIGHT;
365 c = code_append(left.c, right.c);
366 if(BOTH_INT(left.t,right.t)) {
367 c = abc_subtract_i(c);
375 code_t* node_minus_exec(node_t*n)
377 EXEC_HEADER_LEFTRIGHT;
378 return code_append(left, right);
380 constant_t node_minus_eval(node_t*n)
382 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
384 nodetype_t node_minus =
387 flags:NODE_HAS_CHILDREN,
388 eval: node_minus_eval,
389 write: node_minus_write,
390 read: node_minus_read,
391 exec: node_minus_exec
394 // ---------------------------- ++x -----------------------------------
396 typedcode_t node_lplusplus_write(node_t*n)
398 syntaxerror("can't assign to this expression");
400 typedcode_t node_lplusplus_read(node_t*n)
404 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
405 int nr = getlocalnr(x.c);
406 code_free(x.c);x.c=0;
407 if(TYPE_IS_INT(x.t)) {
408 c = abc_inclocal_i(c, nr);
409 c = abc_getlocal(c, nr);
410 } else if(TYPE_IS_NUMBER(x.t)) {
411 c = abc_inclocal(c, nr);
412 c = abc_getlocal(c, nr);
413 } else syntaxerror("internal error");
415 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
416 c = abc_increment_i(c);
419 c = abc_increment(c);
422 c = converttype(c, t, x.t);
423 c = toreadwrite(x.c, c, 0, 0, 1);
428 code_t* node_lplusplus_exec(node_t*n)
430 typedcode_t x = n->child[0]->type->read(n->child[0]);
432 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
433 int nr = getlocalnr(x.c);
434 code_free(x.c);x.c=0;
435 if(TYPE_IS_INT(x.t)) {
436 c = abc_inclocal_i(c, nr);
437 } else if(TYPE_IS_NUMBER(x.t)) {
438 c = abc_inclocal(c, nr);
439 } else syntaxerror("internal error");
442 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
443 c = abc_increment_i(c);
446 c = abc_increment(c);
449 c = converttype(c, t, x.t); //convert back to original type
450 c = toreadwrite(x.c, c, 0, 0, 0);
455 constant_t node_lplusplus_eval(node_t*n)
457 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
459 nodetype_t node_lplusplus =
462 flags:NODE_HAS_CHILDREN,
463 eval: node_lplusplus_eval,
464 write: node_lplusplus_write,
465 read: node_lplusplus_read,
466 exec: node_lplusplus_exec
470 // ---------------------------- --x -----------------------------------
472 typedcode_t node_lminusminus_write(node_t*n)
474 syntaxerror("can't assign to this expression");
476 typedcode_t node_lminusminus_read(node_t*n)
480 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
481 int nr = getlocalnr(x.c);
482 code_free(x.c);x.c=0;
483 if(TYPE_IS_INT(x.t)) {
484 c = abc_declocal_i(c, nr);
485 c = abc_getlocal(c, nr);
486 } else if(TYPE_IS_NUMBER(x.t)) {
487 c = abc_declocal(c, nr);
488 c = abc_getlocal(c, nr);
489 } else syntaxerror("internal error");
491 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
492 c = abc_decrement_i(c);
495 c = abc_decrement(c);
498 c = converttype(c, t, x.t);
499 c = toreadwrite(x.c, c, 0, 0, 1);
504 code_t* node_lminusminus_exec(node_t*n)
506 typedcode_t x = n->child[0]->type->read(n->child[0]);
508 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
509 int nr = getlocalnr(x.c);
510 code_free(x.c);x.c=0;
511 if(TYPE_IS_INT(x.t)) {
512 c = abc_declocal_i(c, nr);
513 } else if(TYPE_IS_NUMBER(x.t)) {
514 c = abc_declocal(c, nr);
515 } else syntaxerror("internal error");
518 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
519 c = abc_decrement_i(c);
522 c = abc_decrement(c);
525 c = converttype(c, t, x.t); //convert back to original type
526 c = toreadwrite(x.c, c, 0, 0, 0);
531 constant_t node_lminusminus_eval(node_t*n)
533 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
535 nodetype_t node_lminusminus =
538 flags:NODE_HAS_CHILDREN,
539 eval: node_lminusminus_eval,
540 write: node_lminusminus_write,
541 read: node_lminusminus_read,
542 exec: node_lminusminus_exec
547 // ---------------------------- x++ -----------------------------------
549 typedcode_t node_rplusplus_write(node_t*n)
551 syntaxerror("can't assign to this expression");
553 typedcode_t node_rplusplus_read(node_t*n)
557 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
558 int nr = getlocalnr(x.c);
559 code_free(x.c);x.c=0;
560 if(TYPE_IS_INT(x.t)) {
561 c = abc_getlocal(0, nr);
562 c = abc_inclocal_i(c, nr);
563 } else if(TYPE_IS_NUMBER(x.t)) {
564 c = abc_getlocal(0, nr);
565 c = abc_inclocal(c, nr);
566 } else syntaxerror("internal error");
568 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
569 c = abc_increment_i(c);
572 c = abc_increment(c);
575 c = converttype(c, t, x.t);
576 c = toreadwrite(x.c, c, 0, 1, 1);
581 code_t* node_rplusplus_exec(node_t*n)
583 typedcode_t x = n->child[0]->type->read(n->child[0]);
585 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
586 int nr = getlocalnr(x.c);
587 code_free(x.c);x.c=0;
588 if(TYPE_IS_INT(x.t)) {
589 c = abc_inclocal_i(c, nr);
590 } else if(TYPE_IS_NUMBER(x.t)) {
591 c = abc_inclocal(c, nr);
592 } else syntaxerror("internal error");
595 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
596 c = abc_increment_i(c);
599 c = abc_increment(c);
602 c = converttype(c, t, x.t); //convert back to original type
603 c = toreadwrite(x.c, c, 0, 1, 0);
608 constant_t node_rplusplus_eval(node_t*n)
610 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
612 nodetype_t node_rplusplus =
615 flags:NODE_HAS_CHILDREN,
616 eval: node_rplusplus_eval,
617 write: node_rplusplus_write,
618 read: node_rplusplus_read,
619 exec: node_rplusplus_exec
622 // ---------------------------- x-- -----------------------------------
624 typedcode_t node_rminusminus_write(node_t*n)
626 syntaxerror("can't assign to this expression");
628 typedcode_t node_rminusminus_read(node_t*n)
632 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
633 int nr = getlocalnr(x.c);
634 code_free(x.c);x.c=0;
635 if(TYPE_IS_INT(x.t)) {
636 c = abc_getlocal(0, nr);
637 c = abc_declocal_i(c, nr);
638 } else if(TYPE_IS_NUMBER(x.t)) {
639 c = abc_getlocal(0, nr);
640 c = abc_declocal(c, nr);
641 } else syntaxerror("internal error");
643 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
644 c = abc_decrement_i(c);
647 c = abc_decrement(c);
650 c = converttype(c, t, x.t);
651 c = toreadwrite(x.c, c, 0, 1, 1);
656 code_t* node_rminusminus_exec(node_t*n)
658 typedcode_t x = n->child[0]->type->read(n->child[0]);
660 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
661 int nr = getlocalnr(x.c);
662 code_free(x.c);x.c=0;
663 if(TYPE_IS_INT(x.t)) {
664 c = abc_declocal_i(c, nr);
665 } else if(TYPE_IS_NUMBER(x.t)) {
666 c = abc_declocal(c, nr);
667 } else syntaxerror("internal error");
670 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
671 c = abc_decrement_i(c);
674 c = abc_decrement(c);
677 c = converttype(c, t, x.t); //convert back to original type
678 c = toreadwrite(x.c, c, 0, 1, 0);
683 constant_t node_rminusminus_eval(node_t*n)
685 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
687 nodetype_t node_rminusminus =
690 flags:NODE_HAS_CHILDREN,
691 eval: node_rminusminus_eval,
692 write: node_rminusminus_write,
693 read: node_rminusminus_read,
694 exec: node_rminusminus_exec
697 // ---------------------------- x*y -----------------------------------
699 typedcode_t node_multiply_write(node_t*n)
701 syntaxerror("can't assign to this expression");
703 typedcode_t node_multiply_read(node_t*n)
705 READ_HEADER_LEFTRIGHT;
706 c = code_append(left.c,right.c);
707 if(BOTH_INT(left.t,right.t)) {
708 c = abc_multiply_i(c);
716 code_t* node_multiply_exec(node_t*n)
718 EXEC_HEADER_LEFTRIGHT;
719 return code_append(left, right);
721 constant_t node_multiply_eval(node_t*n)
723 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
725 nodetype_t node_multiply =
728 flags:NODE_HAS_CHILDREN,
729 eval: node_multiply_eval,
730 write: node_multiply_write,
731 read: node_multiply_read,
732 exec: node_multiply_exec
735 // ---------------------------- x/y -----------------------------------
737 typedcode_t node_div_write(node_t*n)
739 syntaxerror("can't assign to this expression");
741 typedcode_t node_div_read(node_t*n)
743 READ_HEADER_LEFTRIGHT;
744 c = code_append(left.c, right.c);
749 code_t* node_div_exec(node_t*n)
751 EXEC_HEADER_LEFTRIGHT;
752 return code_append(left, right);
754 constant_t node_div_eval(node_t*n)
756 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
758 nodetype_t node_div =
761 flags:NODE_HAS_CHILDREN,
763 write: node_div_write,
768 // ---------------------------- x%y -----------------------------------
770 typedcode_t node_mod_write(node_t*n)
772 syntaxerror("can't assign to this expression");
774 typedcode_t node_mod_read(node_t*n)
776 READ_HEADER_LEFTRIGHT;
777 c = code_append(left.c, right.c);
782 code_t* node_mod_exec(node_t*n)
784 EXEC_HEADER_LEFTRIGHT;
785 return code_append(left, right);
787 constant_t node_mod_eval(node_t*n)
789 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
791 nodetype_t node_mod =
794 flags:NODE_HAS_CHILDREN,
796 write: node_mod_write,
801 // ---------------------------- x<y -----------------------------------
803 typedcode_t node_lt_write(node_t*n)
805 syntaxerror("can't assign to this expression");
807 typedcode_t node_lt_read(node_t*n)
809 READ_HEADER_LEFTRIGHT;
810 c = code_append(left.c,right.c);
815 code_t* node_lt_exec(node_t*n)
817 EXEC_HEADER_LEFTRIGHT;
818 return code_append(left, right);
820 constant_t node_lt_eval(node_t*n)
822 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
827 flags:NODE_HAS_CHILDREN,
829 write: node_lt_write,
834 // ---------------------------- x>y -----------------------------------
836 typedcode_t node_gt_write(node_t*n)
838 syntaxerror("can't assign to this expression");
840 typedcode_t node_gt_read(node_t*n)
842 READ_HEADER_LEFTRIGHT;
843 c = code_append(left.c,right.c);
844 c = abc_greaterthan(c);
848 code_t* node_gt_exec(node_t*n)
850 EXEC_HEADER_LEFTRIGHT;
851 return code_append(left, right);
853 constant_t node_gt_eval(node_t*n)
855 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
860 flags:NODE_HAS_CHILDREN,
862 write: node_gt_write,
867 // ---------------------------- x<=y ----------------------------------
869 typedcode_t node_le_write(node_t*n)
871 syntaxerror("can't assign to this expression");
873 typedcode_t node_le_read(node_t*n)
875 READ_HEADER_LEFTRIGHT;
876 c = code_append(left.c,right.c);
877 c = abc_lessequals(c);
881 code_t* node_le_exec(node_t*n)
883 EXEC_HEADER_LEFTRIGHT;
884 return code_append(left, right);
886 constant_t node_le_eval(node_t*n)
888 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
890 nodetype_t node_le = //<=
893 flags:NODE_HAS_CHILDREN,
895 write: node_le_write,
900 // ---------------------------- x>=y ----------------------------------
902 typedcode_t node_ge_write(node_t*n)
904 syntaxerror("can't assign to this expression");
906 typedcode_t node_ge_read(node_t*n)
908 READ_HEADER_LEFTRIGHT;
909 c = code_append(left.c,right.c);
910 c = abc_greaterequals(c);
914 code_t* node_ge_exec(node_t*n)
916 EXEC_HEADER_LEFTRIGHT;
917 return code_append(left, right);
919 constant_t node_ge_eval(node_t*n)
921 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
923 nodetype_t node_ge = //>=
926 flags:NODE_HAS_CHILDREN,
928 write: node_ge_write,
933 // ---------------------------- x==y ----------------------------------
935 typedcode_t node_eqeq_write(node_t*n)
937 syntaxerror("can't assign to this expression");
939 typedcode_t node_eqeq_read(node_t*n)
941 READ_HEADER_LEFTRIGHT;
942 c = code_append(left.c,right.c);
947 code_t* node_eqeq_exec(node_t*n)
949 EXEC_HEADER_LEFTRIGHT;
950 return code_append(left, right);
952 constant_t node_eqeq_eval(node_t*n)
954 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
956 nodetype_t node_eqeq = //==
959 flags:NODE_HAS_CHILDREN,
960 eval: node_eqeq_eval,
961 write: node_eqeq_write,
962 read: node_eqeq_read,
966 // --------------------------- x===y ----------------------------------
968 typedcode_t node_eqeqeq_write(node_t*n)
970 syntaxerror("can't assign to this expression");
972 typedcode_t node_eqeqeq_read(node_t*n)
974 READ_HEADER_LEFTRIGHT;
975 c = code_append(left.c,right.c);
976 c = abc_strictequals(c);
980 code_t* node_eqeqeq_exec(node_t*n)
982 EXEC_HEADER_LEFTRIGHT;
983 return code_append(left, right);
985 constant_t node_eqeqeq_eval(node_t*n)
987 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
989 nodetype_t node_eqeqeq = //===
992 flags:NODE_HAS_CHILDREN,
993 eval: node_eqeqeq_eval,
994 write: node_eqeqeq_write,
995 read: node_eqeqeq_read,
996 exec: node_eqeqeq_exec
999 // --------------------------- x!==y ----------------------------------
1001 typedcode_t node_noteqeq_write(node_t*n)
1003 syntaxerror("can't assign to this expression");
1005 typedcode_t node_noteqeq_read(node_t*n)
1007 READ_HEADER_LEFTRIGHT;
1008 c = code_append(left.c,right.c);
1009 c = abc_strictequals(c);
1014 code_t* node_noteqeq_exec(node_t*n)
1016 EXEC_HEADER_LEFTRIGHT;
1017 return code_append(left, right);
1019 constant_t node_noteqeq_eval(node_t*n)
1021 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1023 nodetype_t node_noteqeq = //!==
1026 flags:NODE_HAS_CHILDREN,
1027 eval: node_noteqeq_eval,
1028 write: node_noteqeq_write,
1029 read: node_noteqeq_read,
1030 exec: node_noteqeq_exec
1033 // --------------------------- x!=y ----------------------------------
1035 typedcode_t node_noteq_write(node_t*n)
1037 syntaxerror("can't assign to this expression");
1039 typedcode_t node_noteq_read(node_t*n)
1041 READ_HEADER_LEFTRIGHT;
1042 c = code_append(left.c,right.c);
1048 code_t* node_noteq_exec(node_t*n)
1050 EXEC_HEADER_LEFTRIGHT;
1051 return code_append(left, right);
1053 constant_t node_noteq_eval(node_t*n)
1055 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1057 nodetype_t node_noteq = //!=
1060 flags:NODE_HAS_CHILDREN,
1061 eval: node_noteq_eval,
1062 write: node_noteq_write,
1063 read: node_noteq_read,
1064 exec: node_noteq_exec
1067 // --------------------------- x||y ----------------------------------
1069 typedcode_t node_oror_write(node_t*n)
1071 syntaxerror("can't assign to this expression");
1073 typedcode_t node_oror_read(node_t*n)
1075 READ_HEADER_LEFTRIGHT;
1076 t = join_types(left.t, right.t, n->type);
1078 c = converttype(c, left.t, t);
1080 code_t*jmp = c = abc_iftrue(c, 0);
1081 c = cut_last_push(c);
1082 c = code_append(c, right.c);
1083 c = converttype(c, right.t, t);
1084 code_t*label = c = abc_label(c);
1085 jmp->branch = label;
1088 code_t* node_oror_exec(node_t*n)
1090 typedcode_t left = n->child[0]->type->read(n->child[0]);
1091 code_t* right = n->child[1]->type->exec(n->child[1]);
1093 code_t*jmp = c = abc_iftrue(c, 0);
1094 c = code_append(c, right);
1095 code_t*label = c = abc_label(c);
1096 jmp->branch = label;
1099 constant_t node_oror_eval(node_t*n)
1101 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1103 nodetype_t node_oror = //||
1106 flags:NODE_HAS_CHILDREN,
1107 eval: node_oror_eval,
1108 write: node_oror_write,
1109 read: node_oror_read,
1110 exec: node_oror_exec
1113 // --------------------------- x&&y ----------------------------------
1115 typedcode_t node_andand_write(node_t*n)
1117 syntaxerror("can't assign to this expression");
1119 typedcode_t node_andand_read(node_t*n)
1121 READ_HEADER_LEFTRIGHT;
1122 t = join_types(left.t, right.t, &node_andand);
1124 c = converttype(c, left.t, t);
1126 code_t*jmp = c = abc_iffalse(c, 0);
1127 c = cut_last_push(c);
1128 c = code_append(c,right.c);
1129 c = converttype(c, right.t, t);
1130 code_t*label = c = abc_label(c);
1131 jmp->branch = label;
1134 code_t* node_andand_exec(node_t*n)
1136 typedcode_t left = n->child[0]->type->read(n->child[0]);\
1137 code_t* right = n->child[1]->type->exec(n->child[1]);\
1139 code_t*jmp = c = abc_iffalse(c, 0);
1140 c = code_append(c, right);
1141 code_t*label = c = abc_label(c);
1142 jmp->branch = label;
1145 constant_t node_andand_eval(node_t*n)
1147 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1149 nodetype_t node_andand = //&&
1152 flags:NODE_HAS_CHILDREN,
1153 eval: node_andand_eval,
1154 write: node_andand_write,
1155 read: node_andand_read,
1156 exec: node_andand_exec
1159 // ----------------------------- !x -----------------------------------
1161 typedcode_t node_not_write(node_t*n)
1163 syntaxerror("can't assign to this expression");
1165 typedcode_t node_not_read(node_t*n)
1173 code_t* node_not_exec(node_t*n)
1178 constant_t node_not_eval(node_t*n)
1180 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1182 nodetype_t node_not =
1185 flags:NODE_HAS_CHILDREN,
1186 eval: node_not_eval,
1187 write: node_not_write,
1188 read: node_not_read,
1192 // ----------------------------- ~x -----------------------------------
1194 typedcode_t node_bitnot_write(node_t*n)
1196 syntaxerror("can't assign to this expression");
1198 typedcode_t node_bitnot_read(node_t*n)
1206 code_t* node_bitnot_exec(node_t*n)
1211 constant_t node_bitnot_eval(node_t*n)
1213 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1215 nodetype_t node_bitnot =
1218 flags:NODE_HAS_CHILDREN,
1219 eval: node_bitnot_eval,
1220 write: node_bitnot_write,
1221 read: node_bitnot_read,
1222 exec: node_bitnot_exec
1225 // ----------------------------- x&y -----------------------------------
1227 typedcode_t node_bitand_write(node_t*n)
1229 syntaxerror("can't assign to this expression");
1231 typedcode_t node_bitand_read(node_t*n)
1233 READ_HEADER_LEFTRIGHT;
1234 c = code_append(left.c,right.c);
1239 code_t* node_bitand_exec(node_t*n)
1241 EXEC_HEADER_LEFTRIGHT;
1242 return code_append(left, right);
1244 constant_t node_bitand_eval(node_t*n)
1246 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1248 nodetype_t node_bitand =
1251 flags:NODE_HAS_CHILDREN,
1252 eval: node_bitand_eval,
1253 write: node_bitand_write,
1254 read: node_bitand_read,
1255 exec: node_bitand_exec
1258 // ----------------------------- x^y -----------------------------------
1260 typedcode_t node_bitxor_write(node_t*n)
1262 syntaxerror("can't assign to this expression");
1264 typedcode_t node_bitxor_read(node_t*n)
1266 READ_HEADER_LEFTRIGHT;
1267 c = code_append(left.c,right.c);
1272 code_t* node_bitxor_exec(node_t*n)
1274 EXEC_HEADER_LEFTRIGHT;
1275 return code_append(left, right);
1277 constant_t node_bitxor_eval(node_t*n)
1279 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1281 nodetype_t node_bitxor =
1284 flags:NODE_HAS_CHILDREN,
1285 eval: node_bitxor_eval,
1286 write: node_bitxor_write,
1287 read: node_bitxor_read,
1288 exec: node_bitxor_exec
1291 // ----------------------------- x|y -----------------------------------
1293 typedcode_t node_bitor_write(node_t*n)
1295 syntaxerror("can't assign to this expression");
1297 typedcode_t node_bitor_read(node_t*n)
1299 READ_HEADER_LEFTRIGHT;
1300 c = code_append(left.c,right.c);
1305 code_t* node_bitor_exec(node_t*n)
1307 EXEC_HEADER_LEFTRIGHT;
1308 return code_append(left, right);
1310 constant_t node_bitor_eval(node_t*n)
1312 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1314 nodetype_t node_bitor =
1317 flags:NODE_HAS_CHILDREN,
1318 eval: node_bitor_eval,
1319 write: node_bitor_write,
1320 read: node_bitor_read,
1321 exec: node_bitor_exec
1324 // ---------------------------- x>>y -----------------------------------
1326 typedcode_t node_shr_write(node_t*n)
1328 syntaxerror("can't assign to this expression");
1330 typedcode_t node_shr_read(node_t*n)
1332 READ_HEADER_LEFTRIGHT;
1333 c = code_append(left.c,right.c);
1338 code_t* node_shr_exec(node_t*n)
1340 EXEC_HEADER_LEFTRIGHT;
1341 return code_append(left, right);
1343 constant_t node_shr_eval(node_t*n)
1345 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1347 nodetype_t node_shr = //>>
1350 flags:NODE_HAS_CHILDREN,
1351 eval: node_shr_eval,
1352 write: node_shr_write,
1353 read: node_shr_read,
1357 // ---------------------------- x<<y -----------------------------------
1359 typedcode_t node_shl_write(node_t*n)
1361 syntaxerror("can't assign to this expression");
1363 typedcode_t node_shl_read(node_t*n)
1365 READ_HEADER_LEFTRIGHT;
1366 c = code_append(left.c,right.c);
1371 code_t* node_shl_exec(node_t*n)
1373 EXEC_HEADER_LEFTRIGHT;
1374 return code_append(left, right);
1376 constant_t node_shl_eval(node_t*n)
1378 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1380 nodetype_t node_shl = //<<
1383 flags:NODE_HAS_CHILDREN,
1384 eval: node_shl_eval,
1385 write: node_shl_write,
1386 read: node_shl_read,
1390 // ---------------------------- x>>>y -----------------------------------
1392 typedcode_t node_ushr_write(node_t*n)
1394 syntaxerror("can't assign to this expression");
1396 typedcode_t node_ushr_read(node_t*n)
1398 READ_HEADER_LEFTRIGHT;
1399 c = code_append(left.c,right.c);
1404 code_t* node_ushr_exec(node_t*n)
1406 EXEC_HEADER_LEFTRIGHT;
1407 return code_append(left, right);
1409 constant_t node_ushr_eval(node_t*n)
1411 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1413 nodetype_t node_ushr = //>>>
1416 flags:NODE_HAS_CHILDREN,
1417 eval: node_ushr_eval,
1418 write: node_ushr_write,
1419 read: node_ushr_read,
1420 exec: node_ushr_exec
1423 // ---------------------------- x in y ----------------------------------
1425 typedcode_t node_in_write(node_t*n)
1427 syntaxerror("can't assign to this expression");
1429 typedcode_t node_in_read(node_t*n)
1431 READ_HEADER_LEFTRIGHT;
1432 c = code_append(left.c,right.c);
1437 code_t* node_in_exec(node_t*n)
1439 EXEC_HEADER_LEFTRIGHT;
1440 return code_append(left, right);
1442 constant_t node_in_eval(node_t*n)
1444 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1446 nodetype_t node_in = //in
1449 flags:NODE_HAS_CHILDREN,
1451 write: node_in_write,
1456 // ---------------------------- x as y ----------------------------------
1458 typedcode_t node_as_write(node_t*n)
1461 syntaxerror("can't assign to this expression");
1463 typedcode_t node_as_read(node_t*n)
1465 READ_HEADER_LEFTRIGHT;
1466 c = code_append(left.c, right.c);
1467 c = abc_astypelate(c);
1468 if(TYPE_IS_CLASS(right.t) && right.t->data) {
1469 t = (classinfo_t*)right.t->data;
1475 code_t* node_as_exec(node_t*n)
1477 /* we assume here that "as" doesn't have side-effects (like
1478 early run time type checking) */
1479 EXEC_HEADER_LEFTRIGHT;
1480 return code_append(left, right);
1482 constant_t node_as_eval(node_t*n)
1484 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1486 nodetype_t node_as = //as
1489 flags:NODE_HAS_CHILDREN,
1491 write: node_as_write,
1496 // ------------------------- x instanceof y -----------------------------
1498 typedcode_t node_instanceof_write(node_t*n)
1500 syntaxerror("can't assign to this expression");
1502 typedcode_t node_instanceof_read(node_t*n)
1504 READ_HEADER_LEFTRIGHT;
1505 c = code_append(left.c, right.c);
1506 c = abc_instanceof(c);
1510 code_t* node_instanceof_exec(node_t*n)
1512 EXEC_HEADER_LEFTRIGHT;
1513 return code_append(left, right);
1515 constant_t node_instanceof_eval(node_t*n)
1517 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1519 nodetype_t node_instanceof = //instanceof
1522 flags:NODE_HAS_CHILDREN,
1523 eval: node_instanceof_eval,
1524 write: node_instanceof_write,
1525 read: node_instanceof_read,
1526 exec: node_instanceof_exec
1529 // ------------------------- x is y --------------------------------------
1531 typedcode_t node_is_write(node_t*n)
1533 syntaxerror("can't assign to this expression");
1535 typedcode_t node_is_read(node_t*n)
1537 READ_HEADER_LEFTRIGHT;
1538 c = code_append(left.c, right.c);
1539 c = abc_istypelate(c);
1543 code_t* node_is_exec(node_t*n)
1545 EXEC_HEADER_LEFTRIGHT;
1546 return code_append(left, right);
1548 constant_t node_is_eval(node_t*n)
1550 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1552 nodetype_t node_is = //is
1555 flags:NODE_HAS_CHILDREN,
1557 write: node_is_write,
1562 // ------------------------- x[y] --------------------------------------
1564 typedcode_t node_arraylookup_write(node_t*n)
1566 syntaxerror("not implemented yet");
1568 typedcode_t node_arraylookup_read(node_t*n)
1570 READ_HEADER_LEFTRIGHT;
1571 c = code_append(left.c, right.c);
1573 /* XXX not sure whether this access logic is correct */
1574 namespace_t ns = {left.t?left.t->access:ACCESS_PACKAGE, ""};
1575 namespace_set_t nsset;
1576 namespace_list_t l;l.next = 0;
1577 nsset.namespaces = &l;
1579 multiname_t m = {MULTINAMEL, 0, &nsset, 0};
1581 c = abc_getproperty2(c, &m);
1582 t = 0; // array elements have unknown type
1585 code_t* node_arraylookup_exec(node_t*n)
1587 EXEC_HEADER_LEFTRIGHT;
1588 return code_append(left, right);
1590 constant_t node_arraylookup_eval(node_t*n)
1592 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1594 nodetype_t node_arraylookup =
1596 name: "arraylookup",
1597 flags:NODE_HAS_CHILDREN,
1598 eval: node_arraylookup_eval,
1599 write: node_arraylookup_write,
1600 read: node_arraylookup_read,
1601 exec: node_arraylookup_exec
1604 // ------------------------- typeof(x) ------------------------------------
1606 typedcode_t node_typeof_write(node_t*n)
1608 syntaxerror("can't assign to this expression");
1610 typedcode_t node_typeof_read(node_t*n)
1618 code_t* node_typeof_exec(node_t*n)
1623 constant_t node_typeof_eval(node_t*n)
1625 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1627 nodetype_t node_typeof = //typeof
1630 flags:NODE_HAS_CHILDREN,
1631 eval: node_typeof_eval,
1632 write: node_typeof_write,
1633 read: node_typeof_read,
1634 exec: node_typeof_exec
1637 // ------------------------- (void)(x) ------------------------------------
1639 typedcode_t node_void_write(node_t*n)
1641 syntaxerror("can't assign to this expression");
1643 typedcode_t node_void_read(node_t*n)
1645 code_t*c = n->type->exec(n);
1646 c = abc_pushundefined(c);
1647 classinfo_t*t = TYPE_ANY;
1650 code_t* node_void_exec(node_t*n)
1655 constant_t node_void_eval(node_t*n)
1657 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1659 nodetype_t node_void = //void
1662 flags:NODE_HAS_CHILDREN,
1663 eval: node_void_eval,
1664 write: node_void_write,
1665 read: node_void_read,
1666 exec: node_void_exec
1669 // ---------------------------- -x ----------------------------------------
1671 typedcode_t node_neg_write(node_t*n)
1673 syntaxerror("can't assign to this expression");
1675 typedcode_t node_neg_read(node_t*n)
1680 c = abc_negate_i(c);
1688 code_t* node_neg_exec(node_t*n)
1693 constant_t node_neg_eval(node_t*n)
1695 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1697 nodetype_t node_neg = //-
1700 flags:NODE_HAS_CHILDREN,
1701 eval: node_neg_eval,
1702 write: node_neg_write,
1703 read: node_neg_read,
1707 // ---------------------------- x*=y ----------------------------------------
1709 typedcode_t node_muleq_write(node_t*n)
1711 syntaxerror("can't assign to this expression");
1713 typedcode_t node_muleq_read(node_t*n)
1715 READ_HEADER_LEFTRIGHT;
1718 if(BOTH_INT(left.t,right.t)) {
1719 c=abc_multiply_i(c);
1725 c=converttype(c, f, left.t);
1726 c = toreadwrite(left.c, c, 0, 0, 1);
1730 code_t* node_muleq_exec(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 return toreadwrite(left.c, c, 0, 0, 0);
1745 constant_t node_muleq_eval(node_t*n)
1747 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1749 nodetype_t node_muleq =
1752 flags:NODE_HAS_CHILDREN,
1753 eval: node_muleq_eval,
1754 write: node_muleq_write,
1755 read: node_muleq_read,
1756 exec: node_muleq_exec
1759 // ---------------------------- x%=y ----------------------------------------
1761 typedcode_t node_modeq_write(node_t*n)
1763 syntaxerror("can't assign to this expression");
1765 typedcode_t node_modeq_read(node_t*n)
1767 READ_HEADER_LEFTRIGHT;
1768 c = abc_modulo(right.c);
1769 c = converttype(c, TYPE_NUMBER, left.t);
1770 c = toreadwrite(left.c, c, 0, 0, 1);
1774 code_t* node_modeq_exec(node_t*n)
1776 READ_HEADER_LEFTRIGHT;
1777 c = abc_modulo(right.c);
1778 c = converttype(c, TYPE_NUMBER, left.t);
1779 return toreadwrite(left.c, c, 0, 0, 0);
1781 constant_t node_modeq_eval(node_t*n)
1783 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1785 nodetype_t node_modeq = //%=
1788 flags:NODE_HAS_CHILDREN,
1789 eval: node_modeq_eval,
1790 write: node_modeq_write,
1791 read: node_modeq_read,
1792 exec: node_modeq_exec
1795 // ---------------------------- x<<=y ----------------------------------------
1797 typedcode_t node_shleq_write(node_t*n)
1799 syntaxerror("can't assign to this expression");
1801 typedcode_t node_shleq_read(node_t*n)
1803 READ_HEADER_LEFTRIGHT;
1804 c = abc_lshift(right.c);
1805 c = converttype(c, TYPE_INT, left.t);
1806 c = toreadwrite(left.c, c, 0, 0, 1);
1810 code_t* node_shleq_exec(node_t*n)
1812 READ_HEADER_LEFTRIGHT;
1813 c = abc_lshift(right.c);
1814 c = converttype(c, TYPE_INT, left.t);
1815 return toreadwrite(left.c, c, 0, 0, 0);
1817 constant_t node_shleq_eval(node_t*n)
1819 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1821 nodetype_t node_shleq = //<<=
1824 flags:NODE_HAS_CHILDREN,
1825 eval: node_shleq_eval,
1826 write: node_shleq_write,
1827 read: node_shleq_read,
1828 exec: node_shleq_exec
1831 // ---------------------------- x>>=y ----------------------------------------
1833 typedcode_t node_shreq_write(node_t*n)
1835 syntaxerror("can't assign to this expression");
1837 typedcode_t node_shreq_read(node_t*n)
1839 READ_HEADER_LEFTRIGHT;
1840 c = abc_rshift(right.c);
1841 c = converttype(c, TYPE_INT, left.t);
1842 c = toreadwrite(left.c, c, 0, 0, 1);
1846 code_t* node_shreq_exec(node_t*n)
1848 READ_HEADER_LEFTRIGHT;
1849 c = abc_rshift(right.c);
1850 c = converttype(c, TYPE_INT, left.t);
1851 return toreadwrite(left.c, c, 0, 0, 0);
1853 constant_t node_shreq_eval(node_t*n)
1855 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1857 nodetype_t node_shreq = //>>=
1860 flags:NODE_HAS_CHILDREN,
1861 eval: node_shreq_eval,
1862 write: node_shreq_write,
1863 read: node_shreq_read,
1864 exec: node_shreq_exec
1867 // --------------------------- x>>>=y ----------------------------------------
1869 typedcode_t node_ushreq_write(node_t*n)
1871 syntaxerror("can't assign to this expression");
1873 typedcode_t node_ushreq_read(node_t*n)
1875 READ_HEADER_LEFTRIGHT;
1876 c = abc_urshift(right.c);
1877 c = converttype(c, TYPE_UINT, left.t);
1878 c = toreadwrite(left.c, c, 0, 0, 1);
1882 code_t* node_ushreq_exec(node_t*n)
1884 READ_HEADER_LEFTRIGHT;
1885 c = abc_urshift(right.c);
1886 c = converttype(c, TYPE_UINT, left.t);
1887 return toreadwrite(left.c, c, 0, 0, 0);
1889 constant_t node_ushreq_eval(node_t*n)
1891 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1893 nodetype_t node_ushreq = //>>>=
1896 flags:NODE_HAS_CHILDREN,
1897 eval: node_ushreq_eval,
1898 write: node_ushreq_write,
1899 read: node_ushreq_read,
1900 exec: node_ushreq_exec
1903 // --------------------------- x/=y ----------------------------------------
1905 typedcode_t node_diveq_write(node_t*n)
1907 syntaxerror("can't assign to this expression");
1909 typedcode_t node_diveq_read(node_t*n)
1911 READ_HEADER_LEFTRIGHT;
1912 c = abc_divide(right.c);
1913 c = converttype(c, TYPE_NUMBER, left.t);
1914 c = toreadwrite(left.c, c, 0, 0, 1);
1918 code_t* node_diveq_exec(node_t*n)
1920 READ_HEADER_LEFTRIGHT;
1921 c = abc_divide(right.c);
1922 c = converttype(c, TYPE_NUMBER, left.t);
1923 return toreadwrite(left.c, c, 0, 0, 0);
1925 constant_t node_diveq_eval(node_t*n)
1927 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1929 nodetype_t node_diveq =
1932 flags:NODE_HAS_CHILDREN,
1933 eval: node_diveq_eval,
1934 write: node_diveq_write,
1935 read: node_diveq_read,
1936 exec: node_diveq_exec
1939 // --------------------------- x|=y ----------------------------------------
1941 typedcode_t node_bitoreq_write(node_t*n)
1943 syntaxerror("can't assign to this expression");
1945 typedcode_t node_bitoreq_read(node_t*n)
1947 READ_HEADER_LEFTRIGHT;
1948 c = abc_bitor(right.c);
1949 c = converttype(c, TYPE_INT, left.t);
1950 c = toreadwrite(left.c, c, 0, 0, 1);
1954 code_t* node_bitoreq_exec(node_t*n)
1956 READ_HEADER_LEFTRIGHT;
1957 c = abc_bitor(right.c);
1958 c = converttype(c, TYPE_INT, left.t);
1959 return toreadwrite(left.c, c, 0, 0, 0);
1961 constant_t node_bitoreq_eval(node_t*n)
1963 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1965 nodetype_t node_bitoreq = //|=
1968 flags:NODE_HAS_CHILDREN,
1969 eval: node_bitoreq_eval,
1970 write: node_bitoreq_write,
1971 read: node_bitoreq_read,
1972 exec: node_bitoreq_exec
1975 // --------------------------- x^=y ----------------------------------------
1977 typedcode_t node_bitxoreq_write(node_t*n)
1979 syntaxerror("can't assign to this expression");
1981 typedcode_t node_bitxoreq_read(node_t*n)
1983 READ_HEADER_LEFTRIGHT;
1984 c = abc_bitxor(right.c);
1985 c = converttype(c, TYPE_INT, left.t);
1986 c = toreadwrite(left.c, c, 0, 0, 1);
1990 code_t* node_bitxoreq_exec(node_t*n)
1992 READ_HEADER_LEFTRIGHT;
1993 c = abc_bitxor(right.c);
1994 c = converttype(c, TYPE_INT, left.t);
1995 return toreadwrite(left.c, c, 0, 0, 0);
1997 constant_t node_bitxoreq_eval(node_t*n)
1999 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2001 nodetype_t node_bitxoreq = //^=
2004 flags:NODE_HAS_CHILDREN,
2005 eval: node_bitxoreq_eval,
2006 write: node_bitxoreq_write,
2007 read: node_bitxoreq_read,
2008 exec: node_bitxoreq_exec
2011 // --------------------------- x&=y ----------------------------------------
2013 typedcode_t node_bitandeq_write(node_t*n)
2015 syntaxerror("can't assign to this expression");
2017 typedcode_t node_bitandeq_read(node_t*n)
2019 READ_HEADER_LEFTRIGHT;
2020 c = abc_bitand(right.c);
2021 c = converttype(c, TYPE_INT, left.t);
2022 c = toreadwrite(left.c, c, 0, 0, 1);
2026 code_t* node_bitandeq_exec(node_t*n)
2028 READ_HEADER_LEFTRIGHT;
2029 c = abc_bitand(right.c);
2030 c = converttype(c, TYPE_INT, left.t);
2031 return toreadwrite(left.c, c, 0, 0, 0);
2033 constant_t node_bitandeq_eval(node_t*n)
2035 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2037 nodetype_t node_bitandeq = //^=
2040 flags:NODE_HAS_CHILDREN,
2041 eval: node_bitandeq_eval,
2042 write: node_bitandeq_write,
2043 read: node_bitandeq_read,
2044 exec: node_bitandeq_exec
2047 // --------------------------- x+=y ----------------------------------------
2049 typedcode_t node_pluseq_write(node_t*n)
2051 syntaxerror("can't assign to this expression");
2053 typedcode_t node_pluseq_read(node_t*n)
2055 READ_HEADER_LEFTRIGHT;
2057 if(TYPE_IS_INT(left.t)) {
2061 c = converttype(c, TYPE_NUMBER, left.t);
2063 c = toreadwrite(left.c, c, 0, 0, 1);
2067 code_t* node_pluseq_exec(node_t*n)
2069 READ_HEADER_LEFTRIGHT;
2071 if(TYPE_IS_INT(left.t)) {
2075 c = converttype(c, TYPE_NUMBER, left.t);
2077 return toreadwrite(left.c, c, 0, 0, 0);
2079 constant_t node_pluseq_eval(node_t*n)
2081 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2083 nodetype_t node_pluseq = //+=
2086 flags:NODE_HAS_CHILDREN,
2087 eval: node_pluseq_eval,
2088 write: node_pluseq_write,
2089 read: node_pluseq_read,
2090 exec: node_pluseq_exec
2093 // --------------------------- x-=y ----------------------------------------
2095 typedcode_t node_minuseq_write(node_t*n)
2097 syntaxerror("can't assign to this expression");
2099 typedcode_t node_minuseq_read(node_t*n)
2101 READ_HEADER_LEFTRIGHT;
2103 if(TYPE_IS_INT(left.t)) {
2104 c = abc_subtract_i(c);
2106 c = abc_subtract(c);
2107 c = converttype(c, TYPE_NUMBER, left.t);
2109 c = toreadwrite(left.c, c, 0, 0, 1);
2113 code_t* node_minuseq_exec(node_t*n)
2115 READ_HEADER_LEFTRIGHT;
2117 if(TYPE_IS_INT(left.t)) {
2118 c = abc_subtract_i(c);
2120 c = abc_subtract(c);
2121 c = converttype(c, TYPE_NUMBER, left.t);
2123 return toreadwrite(left.c, c, 0, 0, 0);
2125 constant_t node_minuseq_eval(node_t*n)
2127 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2129 nodetype_t node_minuseq = //-=
2132 flags:NODE_HAS_CHILDREN,
2133 eval: node_minuseq_eval,
2134 write: node_minuseq_write,
2135 read: node_minuseq_read,
2136 exec: node_minuseq_exec
2139 // --------------------------- x=y -----------------------------------------
2141 typedcode_t node_assign_write(node_t*n)
2143 syntaxerror("can't assign to this expression");
2145 typedcode_t node_assign_read(node_t*n)
2147 READ_HEADER_LEFTRIGHT;
2149 c = converttype(c, right.t, left.t);
2150 c = toreadwrite(left.c, c, 1, 0, 1);
2154 code_t* node_assign_exec(node_t*n)
2156 READ_HEADER_LEFTRIGHT;
2158 c = converttype(c, right.t, left.t);
2159 return toreadwrite(left.c, c, 1, 0, 0);
2161 constant_t node_assign_eval(node_t*n)
2163 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2165 nodetype_t node_assign =
2168 flags:NODE_HAS_CHILDREN,
2169 eval: node_assign_eval,
2170 write: node_assign_write,
2171 read: node_assign_read,
2172 exec: node_assign_exec
2175 // --------------------------- x?y1:y2 --------------------------------------
2177 typedcode_t node_tenary_write(node_t*n)
2179 /* TODO: this might actually be kinda useful.
2180 (global?global.x:this.x) = 3;
2182 syntaxerror("can't assign to this expression");
2184 typedcode_t node_tenary_read(node_t*n)
2186 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2187 typedcode_t left = n->child[1]->type->read(n->child[1]);
2188 typedcode_t right = n->child[2]->type->read(n->child[2]);
2189 classinfo_t*t = join_types(left.t,right.t,&node_tenary);
2191 code_t*j1 = c = abc_iffalse(c, 0);
2192 c = code_append(c, left.c);
2193 c = converttype(c, left.t, t);
2194 code_t*j2 = c = abc_jump(c, 0);
2195 c = j1->branch = abc_label(c);
2196 c = code_append(c, right.c);
2197 c = converttype(c, right.t, t);
2198 c = j2->branch = abc_label(c);
2201 code_t* node_tenary_exec(node_t*n)
2203 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2204 code_t* left = n->child[1]->type->exec(n->child[1]);
2205 code_t* right = n->child[2]->type->exec(n->child[2]);
2207 code_t*j1 = c = abc_iffalse(c, 0);
2208 c = code_append(c, left);
2209 code_t*j2 = c = abc_jump(c, 0);
2210 c = j1->branch = abc_label(c);
2211 c = code_append(c, right);
2212 c = j2->branch = abc_label(c);
2215 constant_t node_tenary_eval(node_t*n)
2217 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2219 nodetype_t node_tenary =
2222 flags:NODE_HAS_CHILDREN,
2223 eval: node_tenary_eval,
2224 write: node_tenary_write,
2225 read: node_tenary_read,
2226 exec: node_tenary_exec
2229 // ---------------------------- comma ----------------------------------------
2231 typedcode_t node_comma_write(node_t*n)
2233 syntaxerror("can't assign to this expression");
2235 typedcode_t node_comma_read(node_t*n)
2240 for(i=0;i<n->num_children-1;i++) {
2241 c = code_append(c, n->child[i]->type->exec(n->child[i]));
2243 typedcode_t o = n->child[i]->type->read(n->child[i]);
2244 c = code_append(c, o.c);
2248 code_t* node_comma_exec(node_t*n)
2252 for(t=0;t<n->num_children;t++) {
2253 c = code_append(c, n->child[t]->type->exec(n->child[t]));
2257 constant_t node_comma_eval(node_t*n)
2259 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2261 nodetype_t node_comma =
2264 flags: NODE_HAS_CHILDREN,
2265 eval: node_comma_eval,
2266 write: node_comma_write,
2267 read: node_comma_read,
2268 exec: node_comma_exec
2273 // -------------------------- new x -----------------------------------
2275 typedcode_t node_new_write(node_t*n)
2278 typedcode_t node_new_read(node_t*n)
2281 code_t* node_new_exec(node_t*n)
2284 constant_t node_new_eval(node_t*n)
2286 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2288 nodetype_t node_new = //new
2290 write: node_new_write,
2291 read: node_new_read,
2292 eval: node_new_eval,
2296 // ------------------------ delete x ----------------------------------
2298 typedcode_t node_delete_write(node_t*n)
2301 typedcode_t node_delete_read(node_t*n)
2304 code_t* node_delete_exec(node_t*n)
2307 constant_t node_delete_eval(node_t*n)
2309 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2311 nodetype_t node_delete = //delete
2313 write: node_delete_write,
2314 read: node_delete_read,
2315 eval: node_delete_eval,
2316 exec: node_delete_exec
2319 // ---------------------------- x.y -----------------------------------
2321 typedcode_t node_dot_write(node_t*n)
2324 typedcode_t node_dot_read(node_t*n)
2327 code_t* node_dot_exec(node_t*n)
2330 constant_t node_dot_eval(node_t*n)
2332 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2334 nodetype_t node_dot =
2336 write: node_dot_write,
2337 read: node_dot_read,
2338 eval: node_dot_eval,
2342 // --------------------------- x..y -----------------------------------
2344 typedcode_t node_dotdot_write(node_t*n)
2347 typedcode_t node_dotdot_read(node_t*n)
2350 code_t* node_dotdot_exec(node_t*n)
2354 constant_t node_dotdot_eval(node_t*n)
2356 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2358 nodetype_t node_dotdot = //..
2360 write: node_dotdot_write,
2361 read: node_dotdot_read,
2362 eval: node_dotdot_eval,
2363 exec: node_dotdot_exec
2366 // --------------------------- x.@y -----------------------------------
2368 typedcode_t node_dotat_write(node_t*n)
2371 typedcode_t node_dotat_read(node_t*n)
2374 code_t* node_dotat_exec(node_t*n)
2377 constant_t node_dotat_eval(node_t*n)
2379 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2381 nodetype_t node_dotat = //.@
2383 write: node_dotat_write,
2384 read: node_dotat_read,
2385 eval: node_dotat_eval,
2386 exec: node_dotat_exec
2389 // --------------------------- x.*y -----------------------------------
2391 typedcode_t node_dotstar_write(node_t*n)
2394 typedcode_t node_dotstar_read(node_t*n)
2397 code_t* node_dotstar_exec(node_t*n)
2400 constant_t node_dotstar_eval(node_t*n)
2402 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2404 nodetype_t node_dotstar = //.*
2406 write: node_dotstar_write,
2407 read: node_dotstar_read,
2408 eval: node_dotstar_eval,
2409 exec: node_dotstar_exec
2412 // -------------------------- x.(y) -----------------------------------
2414 typedcode_t node_filter_write(node_t*n)
2417 typedcode_t node_filter_read(node_t*n)
2420 code_t* node_filter_exec(node_t*n)
2423 constant_t node_filter_eval(node_t*n)
2425 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2427 nodetype_t node_filter = //.(
2429 write: node_filter_write,
2430 read: node_filter_read,
2431 eval: node_filter_eval,
2432 exec: node_filter_exec
2435 // ------------------------ x(y1,...,yn) ------------------------------
2437 typedcode_t node_call_write(node_t*n)
2440 typedcode_t node_call_read(node_t*n)
2443 code_t* node_call_exec(node_t*n)
2446 constant_t node_call_eval(node_t*n)
2448 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2450 nodetype_t node_call = //functioncall
2452 write: node_call_write,
2453 read: node_call_read,
2454 eval: node_call_eval,
2455 exec: node_call_exec
2458 // ------------------------------ @x ----------------------------------------
2460 typedcode_t node_at_write(node_t*n)
2463 typedcode_t node_at_read(node_t*n)
2466 code_t* node_at_exec(node_t*n)
2469 constant_t node_at_eval(node_t*n)
2471 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2473 nodetype_t node_at = //@
2475 write: node_at_write,
2481 // ---------------------------- x.ns::y ----------------------------------------
2483 typedcode_t node_dotns_write(node_t*n)
2486 typedcode_t node_dotns_read(node_t*n)
2489 code_t* node_dotns_exec(node_t*n)
2492 constant_t node_dotns_eval(node_t*n)
2494 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2496 nodetype_t node_dotns = //.::
2498 write: node_dotns_write,
2499 read: node_dotns_read,
2500 eval: node_dotns_eval,
2501 exec: node_dotns_exec
2505 // ------------------------ constant ------------------------------
2507 typedcode_t node_const_write(node_t*n)
2509 syntaxerror("can't assign a value to a constant");
2511 typedcode_t node_const_read(node_t*n)
2513 constant_t*v = n->value;
2518 if(v->i>-128 && v->i<128) {
2519 c = abc_pushbyte(0,v->i);
2520 } else if(v->i>=-32768 && v->i<32768) {
2521 c = abc_pushshort(0,v->i);
2523 c = abc_pushint(0,v->i);
2528 c = abc_pushuint(0,v->u);
2530 c = abc_pushbyte(0,v->u);
2531 } else if(v->u<32768) {
2532 c = abc_pushshort(0,v->u);
2534 c = abc_pushint(0,v->u);
2538 case CONSTANT_FLOAT:
2539 c = abc_pushdouble(0,v->f);
2543 c = abc_pushtrue(0);
2546 case CONSTANT_FALSE:
2547 c = abc_pushfalse(0);
2551 c = abc_pushnull(0);
2554 case CONSTANT_STRING:
2555 c = abc_pushstring2(0,v->s);
2558 case CONSTANT_UNDEFINED:
2559 c = abc_pushundefined(0);
2562 case CONSTANT_NAMESPACE:
2563 case CONSTANT_NAMESPACE_PACKAGE:
2564 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
2565 case CONSTANT_NAMESPACE_PROTECTED:
2566 case CONSTANT_NAMESPACE_EXPLICIT:
2567 case CONSTANT_NAMESPACE_STATICPROTECTED:
2568 case CONSTANT_NAMESPACE_PRIVATE:
2569 c = abc_pushnamespace(0, v->ns);
2571 case CONSTANT_UNKNOWN:
2572 syntaxerror("internal error: invalid constant");
2575 syntaxerror("invalid constant (%d)", v->type);
2581 code_t* node_const_exec(node_t*n)
2585 constant_t node_const_eval(node_t*n)
2587 constant_t*c = constant_clone(n->value);
2589 free(c); //shallow free
2592 nodetype_t node_const =
2596 eval: node_const_eval,
2597 write: node_const_write,
2598 read: node_const_read,
2599 exec: node_const_exec
2602 // ------------------------ code node ------------------------------
2604 typedcode_t node_code_write(node_t*n)
2606 syntaxerror("not implemented yet");
2608 typedcode_t node_code_read(node_t*n)
2616 code_t* node_code_exec(node_t*n)
2618 code_t*c = code_dup(n->code.c);
2619 c = cut_last_push(c);
2622 constant_t node_code_eval(node_t*n)
2624 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2626 nodetype_t node_code =
2630 eval: node_code_eval,
2631 write: node_code_write,
2632 read: node_code_read,
2633 exec: node_code_exec
2636 // ------------------------ dummy node ------------------------------
2638 typedcode_t node_dummy_write(node_t*n)
2640 syntaxerror("not implemented yet");
2642 typedcode_t node_dummy_read(node_t*n)
2645 t.c = abc_pushundefined(0);
2649 code_t* node_dummy_exec(node_t*n)
2653 constant_t node_dummy_eval(node_t*n)
2655 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2657 nodetype_t node_dummy =
2661 eval: node_dummy_eval,
2662 write: node_dummy_write,
2663 read: node_dummy_read,
2664 exec: node_dummy_exec
2667 // ======================== node handling ==============================
2669 node_t* mkdummynode()
2671 node_t*n = (node_t*)rfx_calloc(sizeof(node_t));
2672 n->type = &node_dummy;
2676 node_t* mkconstnode(constant_t*c)
2678 node_t*n = (node_t*)malloc(sizeof(node_t));
2679 n->type = &node_const;
2685 node_t* mkcodenode(typedcode_t c)
2687 node_t*n = (node_t*)malloc(sizeof(node_t));
2688 n->type = &node_code;
2694 node_t* mkmultinode(nodetype_t*t, node_t*one)
2696 node_t*n = (node_t*)malloc(sizeof(node_t));
2699 n->child = (node_t**)malloc(sizeof(node_t*)*1);
2701 n->num_children = 1;
2705 node_t* multinode_extend(node_t*n, node_t*add)
2707 n->child = realloc(n->child, (n->num_children+1)*sizeof(node_t*));
2708 n->child[n->num_children] = add;
2713 node_t* mknode1(nodetype_t*t, node_t*node)
2715 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*2);
2716 node_t**x = (node_t**)&n[1];
2720 n->num_children = 1;
2726 node_t* mknode2(nodetype_t*t, node_t*left, node_t*right)
2728 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*3);
2729 node_t**x = (node_t**)&n[1];
2733 n->num_children = 2;
2739 node_t* mknode3(nodetype_t*t, node_t*one, node_t*two, node_t*three)
2741 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*4);
2742 node_t**x = (node_t**)&n[1];
2746 n->num_children = 3;
2754 void node_free(node_t*n)
2757 if(n->type == &node_code) {
2759 code_free(n->code.c);n->code.c = 0;
2761 } else if(n->type == &node_const) {
2762 /* keep, this is not our reference */
2763 } else for(t=0;t<n->num_children;t++) {
2764 node_free(n->child[t]);n->child[t] = 0;
2769 typedcode_t node_read(node_t*n)
2771 typedcode_t t = n->type->read(n);
2775 code_t* node_exec(node_t*n)
2777 code_t*c = n->type->exec(n);
2781 constant_t node_eval(node_t*n)
2783 constant_t c = n->type->eval(n);
2801 void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
2803 if(n->type->flags&NODE_HAS_CHILDREN) {
2804 fprintf(fi, "%s%s\n", p1, n->type->name);
2806 char*o2 = malloc(strlen(p2)+3);
2807 strcpy(o2, p2);strcat(o2, "| ");
2808 char*o3 = malloc(strlen(p2)+3);
2809 strcpy(o3, p2);strcat(o3, "+-");
2810 char*o4 = malloc(strlen(p2)+3);
2811 strcpy(o4, p2);strcat(o4, " ");
2813 for(t=0;t<n->num_children;t++) {
2814 fprintf(fi, "%s\n", o2);
2815 node_dump2(n->child[t], o3, t<n->num_children-1?o2:o4, fi);
2820 } else if(n->type == &node_const) {
2821 char*s = constant_tostring(n->value);
2822 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
2824 } else if(n->type == &node_code) {
2825 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, n->code.t?n->code.t->name:"*");
2826 code_dump2(n->code.c, 0, 0, (char*)p2, fi);
2828 fprintf(fi, "%s%s\n", p1, n->type->name);
2832 void node_dump(node_t*n)
2834 printf("---------------------------VVVV\n");
2835 node_dump2(n,"","",stdout);
2836 printf("---------------------------^^^^\n");