3 Extension module for the rfxswf library.
4 Part of the swftools package.
6 Copyright (c) 2009 Matthias Kramm <kramm@quiss.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
24 #include "tokenizer.h"
26 #define IS_INT(a) (TYPE_IS_INT((a)) || TYPE_IS_UINT((a)))
27 #define BOTH_INT(a,b) (IS_INT(a) && IS_INT(b))
29 #define READ_HEADER_LEFTRIGHT \
30 typedcode_t left = n->child[0]->type->read(n->child[0]);\
31 typedcode_t right = n->child[1]->type->read(n->child[1]);\
35 #define READ_HEADER_ONE \
36 typedcode_t x = n->child[0]->type->read(n->child[0]);\
40 #define EXEC_HEADER_ONE \
41 code_t* x = n->child[0]->type->exec(n->child[0]);\
45 #define EXEC_HEADER_LEFTRIGHT \
46 code_t* left = n->child[0]->type->exec(n->child[0]);\
47 code_t* right = n->child[1]->type->exec(n->child[1]);\
51 #define EVAL_HEADER_LEFTRIGHT \
52 constant_t left = n->child[0]->type->eval(n->child[0]);\
53 constant_t right = n->child[1]->type->eval(n->child[1]);\
55 if(left.type==CONSTANT_UNKNOWN || right.type==CONSTANT_UNKNOWN) {\
56 r.type = CONSTANT_UNKNOWN;return r; \
66 static classinfo_t*join_types(classinfo_t*type1, classinfo_t*type2, nodetype_t*t)
69 if((TYPE_IS_XMLLIST(type1) || TYPE_IS_XML(type1)) &&
70 (TYPE_IS_XMLLIST(type2) || TYPE_IS_XML(type2)))
72 if(BOTH_INT(type1, type2))
74 if(IS_NUMBER_OR_INT(type1) && IS_NUMBER_OR_INT(type2))
76 if(TYPE_IS_DATE(type1) || TYPE_IS_DATE(type2))
78 if(TYPE_IS_STRING(type1) || TYPE_IS_STRING(type2)) {
79 /* depending on where the strings come from, the result type
80 of an "add" might be an object or a string, depending on the
81 verifier's mood. So basically we just don't know the type. */
84 if(TYPE_IS_ANY(type1) || TYPE_IS_ANY(type2))
86 return TYPE_OBJECT; // e.g. array+array = object
93 static int getlocalnr(code_t*c)
95 if(c->opcode == OPCODE_GETLOCAL) {return (ptroff_t)c->data[0];}
96 else if(c->opcode == OPCODE_GETLOCAL_0) {return 0;}
97 else if(c->opcode == OPCODE_GETLOCAL_1) {return 1;}
98 else if(c->opcode == OPCODE_GETLOCAL_2) {return 2;}
99 else if(c->opcode == OPCODE_GETLOCAL_3) {return 3;}
100 else syntaxerror("Internal error: opcode %02x is not a getlocal call", c->opcode);
105 int gettempvar(); /* FIXME: we should use a function pointer here */
108 static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char readbefore, char pushvalue)
112 [prefix code] [read instruction]
116 [prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar]
118 if(in && in->opcode == OPCODE_COERCE_A) {
119 in = code_cutlast(in);
122 syntaxerror("internal error");
124 /* chop off read instruction */
128 prefix = r->prev;r->prev = 0;
134 char use_temp_var = readbefore;
136 /* generate the write instruction, and maybe append a dup to the prefix code */
137 code_t* write = abc_nop(0);
138 if(r->opcode == OPCODE_GETPROPERTY) {
139 write->opcode = OPCODE_SETPROPERTY;
140 multiname_t*m = (multiname_t*)r->data[0];
141 write->data[0] = multiname_clone(m);
142 if(m->type == QNAME || m->type == MULTINAME ||
143 m->type == QNAMEA || m->type == MULTINAMEA) {
145 prefix = abc_dup(prefix); // we need the object, too
148 } else if(m->type == MULTINAMEL || m->type == MULTINAMELA) {
150 /* dupping two values on the stack requires 5 operations and one register-
151 couldn't adobe just have given us a dup2? */
152 int temp = gettempvar();
153 prefix = abc_setlocal(prefix, temp);
154 prefix = abc_dup(prefix);
155 prefix = abc_getlocal(prefix, temp);
156 prefix = abc_swap(prefix);
157 prefix = abc_getlocal(prefix, temp);
159 prefix = abc_kill(prefix, temp);
163 syntaxerror("illegal lvalue: can't assign a value to this expression (not a qname/multiname)");
165 } else if(r->opcode == OPCODE_GETSLOT) {
166 write->opcode = OPCODE_SETSLOT;
167 write->data[0] = r->data[0];
169 prefix = abc_dup(prefix); // we need the object, too
172 } else if(r->opcode == OPCODE_GETLOCAL) {
173 write->opcode = OPCODE_SETLOCAL;
174 write->data[0] = r->data[0];
175 } else if(r->opcode == OPCODE_GETLOCAL_0) {
176 write->opcode = OPCODE_SETLOCAL_0;
177 } else if(r->opcode == OPCODE_GETLOCAL_1) {
178 write->opcode = OPCODE_SETLOCAL_1;
179 } else if(r->opcode == OPCODE_GETLOCAL_2) {
180 write->opcode = OPCODE_SETLOCAL_2;
181 } else if(r->opcode == OPCODE_GETLOCAL_3) {
182 write->opcode = OPCODE_SETLOCAL_3;
183 } else if(r->opcode == OPCODE_GETSUPER) {
184 write->opcode = OPCODE_SETSUPER;
185 multiname_t*m = (multiname_t*)r->data[0];
186 write->data[0] = multiname_clone(m);
189 syntaxerror("illegal lvalue: can't assign a value to this expression");
196 /* with getproperty/getslot, we have to be extra careful not
197 to execute the read code twice, as it might have side-effects
198 (e.g. if the property is in fact a setter/getter combination)
200 So read the value, modify it, and write it again,
201 using prefix only once and making sure (by using a temporary
202 register) that the return value is what we just wrote */
204 c = code_append(c, prefix);
205 c = code_append(c, r);
206 if(pushvalue && readbefore) {
208 c = abc_setlocal(c, temp);
210 c = code_append(c, middlepart);
211 if(pushvalue && !readbefore) {
213 c = abc_setlocal(c, temp);
215 c = code_append(c, write);
217 c = abc_getlocal(c, temp);
218 c = abc_kill(c, temp);
221 /* if we're allowed to execute the read code twice *and*
222 the middlepart doesn't modify the code, things are easier.
224 //c = code_append(c, prefix);
225 if(prefix) syntaxerror("internal error (prefix)");
230 c = code_append(c, r);
231 c = code_append(c, middlepart);
232 c = code_append(c, write);
234 c = code_append(c, r2);
238 /* even smaller version: overwrite the value without reading
242 c = code_append(c, prefix);
245 c = code_append(c, middlepart);
246 c = code_append(c, write);
248 c = code_append(c, r);
254 c = code_append(c, prefix);
256 c = code_append(c, middlepart);
259 c = abc_setlocal(c, temp);
261 c = code_append(c, write);
263 c = abc_getlocal(c, temp);
264 c = abc_kill(c, temp);
271 typedcode_t push_constant(constant_t*v)
275 case CONSTANT_INT: t.c = abc_pushint(0, v->i);t.t = TYPE_INT;break;
276 case CONSTANT_UINT: t.c = abc_pushuint(0, v->u);t.t = TYPE_UINT;break;
277 case CONSTANT_FLOAT: t.c = abc_pushdouble(0, v->f);t.t = TYPE_FLOAT;break;
278 case CONSTANT_TRUE: t.c = abc_pushtrue(0);t.t = TYPE_BOOLEAN;break;
279 case CONSTANT_FALSE: t.c = abc_pushfalse(0);t.t = TYPE_BOOLEAN;break;
280 case CONSTANT_STRING: t.c = abc_pushstring2(0, v->s);t.t = TYPE_STRING;break;
281 case CONSTANT_NULL: t.c = abc_pushnull(0);t.t = TYPE_NULL;break;
282 case CONSTANT_UNDEFINED: t.c = abc_pushundefined(0);t.t = TYPE_ANY;break;
283 case CONSTANT_NAMESPACE:
284 case CONSTANT_NAMESPACE_PACKAGE:
285 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
286 case CONSTANT_NAMESPACE_PROTECTED:
287 case CONSTANT_NAMESPACE_EXPLICIT:
288 case CONSTANT_NAMESPACE_STATICPROTECTED:
289 case CONSTANT_NAMESPACE_PRIVATE:
290 t.c = abc_pushnamespace(0, v->ns);t.t = TYPE_NAMESPACE;break;
292 syntaxerror("internal error: bad constant");
297 code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to);
299 int constant_to_int(constant_t*c)
302 case CONSTANT_INT: return c->i;
303 case CONSTANT_UINT: return (int)c->u;
304 case CONSTANT_FLOAT: return c->f;
305 case CONSTANT_TRUE: return 1;
306 case CONSTANT_FALSE: return 0;
307 case CONSTANT_STRING: return atoi(c->s->str);
308 default: syntaxerror("can't convert this constant to an integer");
312 double constant_to_float(constant_t*c)
315 case CONSTANT_INT: return (double)c->i;
316 case CONSTANT_UINT: return (double)c->u;
317 case CONSTANT_FLOAT: return c->f;
318 case CONSTANT_TRUE: return (double)1;
319 case CONSTANT_FALSE: return (double)0;
320 case CONSTANT_STRING: return atof(c->s->str);
321 default: syntaxerror("can't convert this constant to a float");
325 // -------------------------- x + y -----------------------------------
327 typedcode_t node_plus_write(node_t*n)
329 syntaxerror("can't assign to this expression");
331 typedcode_t node_plus_read(node_t*n)
333 READ_HEADER_LEFTRIGHT;
334 c = code_append(left.c, right.c);
335 if(BOTH_INT(left.t, right.t)) {
340 t = join_types(left.t,right.t,n->type);
344 code_t* node_plus_exec(node_t*n)
346 EXEC_HEADER_LEFTRIGHT;
347 return code_append(left, right);
349 constant_t node_plus_eval(node_t*n)
351 EVAL_HEADER_LEFTRIGHT;
352 char left_int = left.type == CONSTANT_INT || left.type == CONSTANT_UINT;
353 if(left_int && (right.type == CONSTANT_INT || right.type == CONSTANT_UINT)) {
354 int i = constant_to_int(&left) + constant_to_int(&right);
355 r.type = CONSTANT_INT;
357 } else if(left_int && right.type == CONSTANT_FLOAT) {
358 double f = constant_to_int(&left) + constant_to_float(&right);
359 r.type = CONSTANT_FLOAT;
361 } else if(left.type == CONSTANT_STRING) {
362 char*add = constant_tostring(&right);
363 int l1 = left.s->len;
364 int l2 = strlen(add);
365 char*s = malloc(l1+l2+1);
366 memcpy(s, left.s->str, l1);
367 memcpy(s+l1, add, l2);
369 r.type = CONSTANT_STRING;
370 r.s = malloc(sizeof(string_t));
375 r.type = CONSTANT_UNKNOWN;
379 nodetype_t node_plus =
382 flags:NODE_HAS_CHILDREN,
384 write:node_plus_write,
389 // -------------------------- x - y -----------------------------------
391 typedcode_t node_minus_write(node_t*n)
393 syntaxerror("can't assign to this expression");
395 typedcode_t node_minus_read(node_t*n)
397 READ_HEADER_LEFTRIGHT;
398 c = code_append(left.c, right.c);
399 if(BOTH_INT(left.t,right.t)) {
400 c = abc_subtract_i(c);
408 code_t* node_minus_exec(node_t*n)
410 EXEC_HEADER_LEFTRIGHT;
411 return code_append(left, right);
413 constant_t node_minus_eval(node_t*n)
415 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
417 nodetype_t node_minus =
420 flags:NODE_HAS_CHILDREN,
421 eval: node_minus_eval,
422 write: node_minus_write,
423 read: node_minus_read,
424 exec: node_minus_exec
427 // ---------------------------- ++x -----------------------------------
429 typedcode_t node_lplusplus_write(node_t*n)
431 syntaxerror("can't assign to this expression");
433 typedcode_t node_lplusplus_read(node_t*n)
437 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
438 int nr = getlocalnr(x.c);
439 code_free(x.c);x.c=0;
440 if(TYPE_IS_INT(x.t)) {
441 c = abc_inclocal_i(c, nr);
442 c = abc_getlocal(c, nr);
443 } else if(TYPE_IS_NUMBER(x.t)) {
444 c = abc_inclocal(c, nr);
445 c = abc_getlocal(c, nr);
446 } else syntaxerror("internal error");
448 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
449 c = abc_increment_i(c);
452 c = abc_increment(c);
455 c = converttype(c, t, x.t);
456 c = toreadwrite(x.c, c, 0, 0, 1);
461 code_t* node_lplusplus_exec(node_t*n)
463 typedcode_t x = n->child[0]->type->read(n->child[0]);
465 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
466 int nr = getlocalnr(x.c);
467 code_free(x.c);x.c=0;
468 if(TYPE_IS_INT(x.t)) {
469 c = abc_inclocal_i(c, nr);
470 } else if(TYPE_IS_NUMBER(x.t)) {
471 c = abc_inclocal(c, nr);
472 } else syntaxerror("internal error");
475 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
476 c = abc_increment_i(c);
479 c = abc_increment(c);
482 c = converttype(c, t, x.t); //convert back to original type
483 c = toreadwrite(x.c, c, 0, 0, 0);
488 constant_t node_lplusplus_eval(node_t*n)
490 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
492 nodetype_t node_lplusplus =
495 flags:NODE_HAS_CHILDREN,
496 eval: node_lplusplus_eval,
497 write: node_lplusplus_write,
498 read: node_lplusplus_read,
499 exec: node_lplusplus_exec
503 // ---------------------------- --x -----------------------------------
505 typedcode_t node_lminusminus_write(node_t*n)
507 syntaxerror("can't assign to this expression");
509 typedcode_t node_lminusminus_read(node_t*n)
513 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
514 int nr = getlocalnr(x.c);
515 code_free(x.c);x.c=0;
516 if(TYPE_IS_INT(x.t)) {
517 c = abc_declocal_i(c, nr);
518 c = abc_getlocal(c, nr);
519 } else if(TYPE_IS_NUMBER(x.t)) {
520 c = abc_declocal(c, nr);
521 c = abc_getlocal(c, nr);
522 } else syntaxerror("internal error");
524 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
525 c = abc_decrement_i(c);
528 c = abc_decrement(c);
531 c = converttype(c, t, x.t);
532 c = toreadwrite(x.c, c, 0, 0, 1);
537 code_t* node_lminusminus_exec(node_t*n)
539 typedcode_t x = n->child[0]->type->read(n->child[0]);
541 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
542 int nr = getlocalnr(x.c);
543 code_free(x.c);x.c=0;
544 if(TYPE_IS_INT(x.t)) {
545 c = abc_declocal_i(c, nr);
546 } else if(TYPE_IS_NUMBER(x.t)) {
547 c = abc_declocal(c, nr);
548 } else syntaxerror("internal error");
551 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
552 c = abc_decrement_i(c);
555 c = abc_decrement(c);
558 c = converttype(c, t, x.t); //convert back to original type
559 c = toreadwrite(x.c, c, 0, 0, 0);
564 constant_t node_lminusminus_eval(node_t*n)
566 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
568 nodetype_t node_lminusminus =
571 flags:NODE_HAS_CHILDREN,
572 eval: node_lminusminus_eval,
573 write: node_lminusminus_write,
574 read: node_lminusminus_read,
575 exec: node_lminusminus_exec
580 // ---------------------------- x++ -----------------------------------
582 typedcode_t node_rplusplus_write(node_t*n)
584 syntaxerror("can't assign to this expression");
586 typedcode_t node_rplusplus_read(node_t*n)
590 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
591 int nr = getlocalnr(x.c);
592 code_free(x.c);x.c=0;
593 if(TYPE_IS_INT(x.t)) {
594 c = abc_getlocal(0, nr);
595 c = abc_inclocal_i(c, nr);
596 } else if(TYPE_IS_NUMBER(x.t)) {
597 c = abc_getlocal(0, nr);
598 c = abc_inclocal(c, nr);
599 } else syntaxerror("internal error");
601 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
602 c = abc_increment_i(c);
605 c = abc_increment(c);
608 c = converttype(c, t, x.t);
609 c = toreadwrite(x.c, c, 0, 1, 1);
614 code_t* node_rplusplus_exec(node_t*n)
616 typedcode_t x = n->child[0]->type->read(n->child[0]);
618 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
619 int nr = getlocalnr(x.c);
620 code_free(x.c);x.c=0;
621 if(TYPE_IS_INT(x.t)) {
622 c = abc_inclocal_i(c, nr);
623 } else if(TYPE_IS_NUMBER(x.t)) {
624 c = abc_inclocal(c, nr);
625 } else syntaxerror("internal error");
628 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
629 c = abc_increment_i(c);
632 c = abc_increment(c);
635 c = converttype(c, t, x.t); //convert back to original type
636 c = toreadwrite(x.c, c, 0, 1, 0);
641 constant_t node_rplusplus_eval(node_t*n)
643 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
645 nodetype_t node_rplusplus =
648 flags:NODE_HAS_CHILDREN,
649 eval: node_rplusplus_eval,
650 write: node_rplusplus_write,
651 read: node_rplusplus_read,
652 exec: node_rplusplus_exec
655 // ---------------------------- x-- -----------------------------------
657 typedcode_t node_rminusminus_write(node_t*n)
659 syntaxerror("can't assign to this expression");
661 typedcode_t node_rminusminus_read(node_t*n)
665 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
666 int nr = getlocalnr(x.c);
667 code_free(x.c);x.c=0;
668 if(TYPE_IS_INT(x.t)) {
669 c = abc_getlocal(0, nr);
670 c = abc_declocal_i(c, nr);
671 } else if(TYPE_IS_NUMBER(x.t)) {
672 c = abc_getlocal(0, nr);
673 c = abc_declocal(c, nr);
674 } else syntaxerror("internal error");
676 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
677 c = abc_decrement_i(c);
680 c = abc_decrement(c);
683 c = converttype(c, t, x.t);
684 c = toreadwrite(x.c, c, 0, 1, 1);
689 code_t* node_rminusminus_exec(node_t*n)
691 typedcode_t x = n->child[0]->type->read(n->child[0]);
693 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
694 int nr = getlocalnr(x.c);
695 code_free(x.c);x.c=0;
696 if(TYPE_IS_INT(x.t)) {
697 c = abc_declocal_i(c, nr);
698 } else if(TYPE_IS_NUMBER(x.t)) {
699 c = abc_declocal(c, nr);
700 } else syntaxerror("internal error");
703 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
704 c = abc_decrement_i(c);
707 c = abc_decrement(c);
710 c = converttype(c, t, x.t); //convert back to original type
711 c = toreadwrite(x.c, c, 0, 1, 0);
716 constant_t node_rminusminus_eval(node_t*n)
718 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
720 nodetype_t node_rminusminus =
723 flags:NODE_HAS_CHILDREN,
724 eval: node_rminusminus_eval,
725 write: node_rminusminus_write,
726 read: node_rminusminus_read,
727 exec: node_rminusminus_exec
730 // ---------------------------- x*y -----------------------------------
732 typedcode_t node_multiply_write(node_t*n)
734 syntaxerror("can't assign to this expression");
736 typedcode_t node_multiply_read(node_t*n)
738 READ_HEADER_LEFTRIGHT;
739 c = code_append(left.c,right.c);
740 if(BOTH_INT(left.t,right.t)) {
741 c = abc_multiply_i(c);
749 code_t* node_multiply_exec(node_t*n)
751 EXEC_HEADER_LEFTRIGHT;
752 return code_append(left, right);
754 constant_t node_multiply_eval(node_t*n)
756 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
758 nodetype_t node_multiply =
761 flags:NODE_HAS_CHILDREN,
762 eval: node_multiply_eval,
763 write: node_multiply_write,
764 read: node_multiply_read,
765 exec: node_multiply_exec
768 // ---------------------------- x/y -----------------------------------
770 typedcode_t node_div_write(node_t*n)
772 syntaxerror("can't assign to this expression");
774 typedcode_t node_div_read(node_t*n)
776 READ_HEADER_LEFTRIGHT;
777 c = code_append(left.c, right.c);
782 code_t* node_div_exec(node_t*n)
784 EXEC_HEADER_LEFTRIGHT;
785 return code_append(left, right);
787 constant_t node_div_eval(node_t*n)
789 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
791 nodetype_t node_div =
794 flags:NODE_HAS_CHILDREN,
796 write: node_div_write,
801 // ---------------------------- x%y -----------------------------------
803 typedcode_t node_mod_write(node_t*n)
805 syntaxerror("can't assign to this expression");
807 typedcode_t node_mod_read(node_t*n)
809 READ_HEADER_LEFTRIGHT;
810 c = code_append(left.c, right.c);
815 code_t* node_mod_exec(node_t*n)
817 EXEC_HEADER_LEFTRIGHT;
818 return code_append(left, right);
820 constant_t node_mod_eval(node_t*n)
822 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
824 nodetype_t node_mod =
827 flags:NODE_HAS_CHILDREN,
829 write: node_mod_write,
834 // ---------------------------- x<y -----------------------------------
836 typedcode_t node_lt_write(node_t*n)
838 syntaxerror("can't assign to this expression");
840 typedcode_t node_lt_read(node_t*n)
842 READ_HEADER_LEFTRIGHT;
843 c = code_append(left.c,right.c);
848 code_t* node_lt_exec(node_t*n)
850 EXEC_HEADER_LEFTRIGHT;
851 return code_append(left, right);
853 constant_t node_lt_eval(node_t*n)
855 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
860 flags:NODE_HAS_CHILDREN,
862 write: node_lt_write,
867 // ---------------------------- x>y -----------------------------------
869 typedcode_t node_gt_write(node_t*n)
871 syntaxerror("can't assign to this expression");
873 typedcode_t node_gt_read(node_t*n)
875 READ_HEADER_LEFTRIGHT;
876 c = code_append(left.c,right.c);
877 c = abc_greaterthan(c);
881 code_t* node_gt_exec(node_t*n)
883 EXEC_HEADER_LEFTRIGHT;
884 return code_append(left, right);
886 constant_t node_gt_eval(node_t*n)
888 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
893 flags:NODE_HAS_CHILDREN,
895 write: node_gt_write,
900 // ---------------------------- x<=y ----------------------------------
902 typedcode_t node_le_write(node_t*n)
904 syntaxerror("can't assign to this expression");
906 typedcode_t node_le_read(node_t*n)
908 READ_HEADER_LEFTRIGHT;
909 c = code_append(left.c,right.c);
910 c = abc_lessequals(c);
914 code_t* node_le_exec(node_t*n)
916 EXEC_HEADER_LEFTRIGHT;
917 return code_append(left, right);
919 constant_t node_le_eval(node_t*n)
921 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
923 nodetype_t node_le = //<=
926 flags:NODE_HAS_CHILDREN,
928 write: node_le_write,
933 // ---------------------------- x>=y ----------------------------------
935 typedcode_t node_ge_write(node_t*n)
937 syntaxerror("can't assign to this expression");
939 typedcode_t node_ge_read(node_t*n)
941 READ_HEADER_LEFTRIGHT;
942 c = code_append(left.c,right.c);
943 c = abc_greaterequals(c);
947 code_t* node_ge_exec(node_t*n)
949 EXEC_HEADER_LEFTRIGHT;
950 return code_append(left, right);
952 constant_t node_ge_eval(node_t*n)
954 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
956 nodetype_t node_ge = //>=
959 flags:NODE_HAS_CHILDREN,
961 write: node_ge_write,
966 // ---------------------------- x==y ----------------------------------
968 typedcode_t node_eqeq_write(node_t*n)
970 syntaxerror("can't assign to this expression");
972 typedcode_t node_eqeq_read(node_t*n)
974 READ_HEADER_LEFTRIGHT;
975 c = code_append(left.c,right.c);
980 code_t* node_eqeq_exec(node_t*n)
982 EXEC_HEADER_LEFTRIGHT;
983 return code_append(left, right);
985 constant_t node_eqeq_eval(node_t*n)
987 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
989 nodetype_t node_eqeq = //==
992 flags:NODE_HAS_CHILDREN,
993 eval: node_eqeq_eval,
994 write: node_eqeq_write,
995 read: node_eqeq_read,
999 // --------------------------- x===y ----------------------------------
1001 typedcode_t node_eqeqeq_write(node_t*n)
1003 syntaxerror("can't assign to this expression");
1005 typedcode_t node_eqeqeq_read(node_t*n)
1007 READ_HEADER_LEFTRIGHT;
1008 c = code_append(left.c,right.c);
1009 c = abc_strictequals(c);
1013 code_t* node_eqeqeq_exec(node_t*n)
1015 EXEC_HEADER_LEFTRIGHT;
1016 return code_append(left, right);
1018 constant_t node_eqeqeq_eval(node_t*n)
1020 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1022 nodetype_t node_eqeqeq = //===
1025 flags:NODE_HAS_CHILDREN,
1026 eval: node_eqeqeq_eval,
1027 write: node_eqeqeq_write,
1028 read: node_eqeqeq_read,
1029 exec: node_eqeqeq_exec
1032 // --------------------------- x!==y ----------------------------------
1034 typedcode_t node_noteqeq_write(node_t*n)
1036 syntaxerror("can't assign to this expression");
1038 typedcode_t node_noteqeq_read(node_t*n)
1040 READ_HEADER_LEFTRIGHT;
1041 c = code_append(left.c,right.c);
1042 c = abc_strictequals(c);
1047 code_t* node_noteqeq_exec(node_t*n)
1049 EXEC_HEADER_LEFTRIGHT;
1050 return code_append(left, right);
1052 constant_t node_noteqeq_eval(node_t*n)
1054 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1056 nodetype_t node_noteqeq = //!==
1059 flags:NODE_HAS_CHILDREN,
1060 eval: node_noteqeq_eval,
1061 write: node_noteqeq_write,
1062 read: node_noteqeq_read,
1063 exec: node_noteqeq_exec
1066 // --------------------------- x!=y ----------------------------------
1068 typedcode_t node_noteq_write(node_t*n)
1070 syntaxerror("can't assign to this expression");
1072 typedcode_t node_noteq_read(node_t*n)
1074 READ_HEADER_LEFTRIGHT;
1075 c = code_append(left.c,right.c);
1081 code_t* node_noteq_exec(node_t*n)
1083 EXEC_HEADER_LEFTRIGHT;
1084 return code_append(left, right);
1086 constant_t node_noteq_eval(node_t*n)
1088 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1090 nodetype_t node_noteq = //!=
1093 flags:NODE_HAS_CHILDREN,
1094 eval: node_noteq_eval,
1095 write: node_noteq_write,
1096 read: node_noteq_read,
1097 exec: node_noteq_exec
1100 // --------------------------- x||y ----------------------------------
1102 typedcode_t node_oror_write(node_t*n)
1104 syntaxerror("can't assign to this expression");
1106 typedcode_t node_oror_read(node_t*n)
1108 READ_HEADER_LEFTRIGHT;
1109 t = join_types(left.t, right.t, n->type);
1111 c = converttype(c, left.t, t);
1113 code_t*jmp = c = abc_iftrue(c, 0);
1114 c = cut_last_push(c);
1115 c = code_append(c, right.c);
1116 c = converttype(c, right.t, t);
1117 code_t*label = c = abc_label(c);
1118 jmp->branch = label;
1121 code_t* node_oror_exec(node_t*n)
1123 typedcode_t left = n->child[0]->type->read(n->child[0]);
1124 code_t* right = n->child[1]->type->exec(n->child[1]);
1126 code_t*jmp = c = abc_iftrue(c, 0);
1127 c = code_append(c, right);
1128 code_t*label = c = abc_label(c);
1129 jmp->branch = label;
1132 constant_t node_oror_eval(node_t*n)
1134 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1136 nodetype_t node_oror = //||
1139 flags:NODE_HAS_CHILDREN,
1140 eval: node_oror_eval,
1141 write: node_oror_write,
1142 read: node_oror_read,
1143 exec: node_oror_exec
1146 // --------------------------- x&&y ----------------------------------
1148 typedcode_t node_andand_write(node_t*n)
1150 syntaxerror("can't assign to this expression");
1152 typedcode_t node_andand_read(node_t*n)
1154 READ_HEADER_LEFTRIGHT;
1155 t = join_types(left.t, right.t, &node_andand);
1157 c = converttype(c, left.t, t);
1159 code_t*jmp = c = abc_iffalse(c, 0);
1160 c = cut_last_push(c);
1161 c = code_append(c,right.c);
1162 c = converttype(c, right.t, t);
1163 code_t*label = c = abc_label(c);
1164 jmp->branch = label;
1167 code_t* node_andand_exec(node_t*n)
1169 typedcode_t left = n->child[0]->type->read(n->child[0]);\
1170 code_t* right = n->child[1]->type->exec(n->child[1]);\
1172 code_t*jmp = c = abc_iffalse(c, 0);
1173 c = code_append(c, right);
1174 code_t*label = c = abc_label(c);
1175 jmp->branch = label;
1178 constant_t node_andand_eval(node_t*n)
1180 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1182 nodetype_t node_andand = //&&
1185 flags:NODE_HAS_CHILDREN,
1186 eval: node_andand_eval,
1187 write: node_andand_write,
1188 read: node_andand_read,
1189 exec: node_andand_exec
1192 // ----------------------------- !x -----------------------------------
1194 typedcode_t node_not_write(node_t*n)
1196 syntaxerror("can't assign to this expression");
1198 typedcode_t node_not_read(node_t*n)
1206 code_t* node_not_exec(node_t*n)
1211 constant_t node_not_eval(node_t*n)
1213 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1215 nodetype_t node_not =
1218 flags:NODE_HAS_CHILDREN,
1219 eval: node_not_eval,
1220 write: node_not_write,
1221 read: node_not_read,
1225 // ----------------------------- ~x -----------------------------------
1227 typedcode_t node_bitnot_write(node_t*n)
1229 syntaxerror("can't assign to this expression");
1231 typedcode_t node_bitnot_read(node_t*n)
1239 code_t* node_bitnot_exec(node_t*n)
1244 constant_t node_bitnot_eval(node_t*n)
1246 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1248 nodetype_t node_bitnot =
1251 flags:NODE_HAS_CHILDREN,
1252 eval: node_bitnot_eval,
1253 write: node_bitnot_write,
1254 read: node_bitnot_read,
1255 exec: node_bitnot_exec
1258 // ----------------------------- x&y -----------------------------------
1260 typedcode_t node_bitand_write(node_t*n)
1262 syntaxerror("can't assign to this expression");
1264 typedcode_t node_bitand_read(node_t*n)
1266 READ_HEADER_LEFTRIGHT;
1267 c = code_append(left.c,right.c);
1272 code_t* node_bitand_exec(node_t*n)
1274 EXEC_HEADER_LEFTRIGHT;
1275 return code_append(left, right);
1277 constant_t node_bitand_eval(node_t*n)
1279 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1281 nodetype_t node_bitand =
1284 flags:NODE_HAS_CHILDREN,
1285 eval: node_bitand_eval,
1286 write: node_bitand_write,
1287 read: node_bitand_read,
1288 exec: node_bitand_exec
1291 // ----------------------------- x^y -----------------------------------
1293 typedcode_t node_bitxor_write(node_t*n)
1295 syntaxerror("can't assign to this expression");
1297 typedcode_t node_bitxor_read(node_t*n)
1299 READ_HEADER_LEFTRIGHT;
1300 c = code_append(left.c,right.c);
1305 code_t* node_bitxor_exec(node_t*n)
1307 EXEC_HEADER_LEFTRIGHT;
1308 return code_append(left, right);
1310 constant_t node_bitxor_eval(node_t*n)
1312 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1314 nodetype_t node_bitxor =
1317 flags:NODE_HAS_CHILDREN,
1318 eval: node_bitxor_eval,
1319 write: node_bitxor_write,
1320 read: node_bitxor_read,
1321 exec: node_bitxor_exec
1324 // ----------------------------- x|y -----------------------------------
1326 typedcode_t node_bitor_write(node_t*n)
1328 syntaxerror("can't assign to this expression");
1330 typedcode_t node_bitor_read(node_t*n)
1332 READ_HEADER_LEFTRIGHT;
1333 c = code_append(left.c,right.c);
1338 code_t* node_bitor_exec(node_t*n)
1340 EXEC_HEADER_LEFTRIGHT;
1341 return code_append(left, right);
1343 constant_t node_bitor_eval(node_t*n)
1345 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1347 nodetype_t node_bitor =
1350 flags:NODE_HAS_CHILDREN,
1351 eval: node_bitor_eval,
1352 write: node_bitor_write,
1353 read: node_bitor_read,
1354 exec: node_bitor_exec
1357 // ---------------------------- x>>y -----------------------------------
1359 typedcode_t node_shr_write(node_t*n)
1361 syntaxerror("can't assign to this expression");
1363 typedcode_t node_shr_read(node_t*n)
1365 READ_HEADER_LEFTRIGHT;
1366 c = code_append(left.c,right.c);
1371 code_t* node_shr_exec(node_t*n)
1373 EXEC_HEADER_LEFTRIGHT;
1374 return code_append(left, right);
1376 constant_t node_shr_eval(node_t*n)
1378 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1380 nodetype_t node_shr = //>>
1383 flags:NODE_HAS_CHILDREN,
1384 eval: node_shr_eval,
1385 write: node_shr_write,
1386 read: node_shr_read,
1390 // ---------------------------- x<<y -----------------------------------
1392 typedcode_t node_shl_write(node_t*n)
1394 syntaxerror("can't assign to this expression");
1396 typedcode_t node_shl_read(node_t*n)
1398 READ_HEADER_LEFTRIGHT;
1399 c = code_append(left.c,right.c);
1404 code_t* node_shl_exec(node_t*n)
1406 EXEC_HEADER_LEFTRIGHT;
1407 return code_append(left, right);
1409 constant_t node_shl_eval(node_t*n)
1411 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1413 nodetype_t node_shl = //<<
1416 flags:NODE_HAS_CHILDREN,
1417 eval: node_shl_eval,
1418 write: node_shl_write,
1419 read: node_shl_read,
1423 // ---------------------------- x>>>y -----------------------------------
1425 typedcode_t node_ushr_write(node_t*n)
1427 syntaxerror("can't assign to this expression");
1429 typedcode_t node_ushr_read(node_t*n)
1431 READ_HEADER_LEFTRIGHT;
1432 c = code_append(left.c,right.c);
1437 code_t* node_ushr_exec(node_t*n)
1439 EXEC_HEADER_LEFTRIGHT;
1440 return code_append(left, right);
1442 constant_t node_ushr_eval(node_t*n)
1444 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1446 nodetype_t node_ushr = //>>>
1449 flags:NODE_HAS_CHILDREN,
1450 eval: node_ushr_eval,
1451 write: node_ushr_write,
1452 read: node_ushr_read,
1453 exec: node_ushr_exec
1456 // ---------------------------- x in y ----------------------------------
1458 typedcode_t node_in_write(node_t*n)
1460 syntaxerror("can't assign to this expression");
1462 typedcode_t node_in_read(node_t*n)
1464 READ_HEADER_LEFTRIGHT;
1465 c = code_append(left.c,right.c);
1470 code_t* node_in_exec(node_t*n)
1472 EXEC_HEADER_LEFTRIGHT;
1473 return code_append(left, right);
1475 constant_t node_in_eval(node_t*n)
1477 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1479 nodetype_t node_in = //in
1482 flags:NODE_HAS_CHILDREN,
1484 write: node_in_write,
1489 // ---------------------------- x as y ----------------------------------
1491 typedcode_t node_as_write(node_t*n)
1494 syntaxerror("can't assign to this expression");
1496 typedcode_t node_as_read(node_t*n)
1498 READ_HEADER_LEFTRIGHT;
1499 c = code_append(left.c, right.c);
1500 c = abc_astypelate(c);
1501 if(TYPE_IS_CLASS(right.t) && right.t->data) {
1502 t = (classinfo_t*)right.t->data;
1508 code_t* node_as_exec(node_t*n)
1510 /* we assume here that "as" doesn't have side-effects (like
1511 early run time type checking) */
1512 EXEC_HEADER_LEFTRIGHT;
1513 return code_append(left, right);
1515 constant_t node_as_eval(node_t*n)
1517 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1519 nodetype_t node_as = //as
1522 flags:NODE_HAS_CHILDREN,
1524 write: node_as_write,
1529 // ------------------------- x instanceof y -----------------------------
1531 typedcode_t node_instanceof_write(node_t*n)
1533 syntaxerror("can't assign to this expression");
1535 typedcode_t node_instanceof_read(node_t*n)
1537 READ_HEADER_LEFTRIGHT;
1538 c = code_append(left.c, right.c);
1539 c = abc_instanceof(c);
1543 code_t* node_instanceof_exec(node_t*n)
1545 EXEC_HEADER_LEFTRIGHT;
1546 return code_append(left, right);
1548 constant_t node_instanceof_eval(node_t*n)
1550 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1552 nodetype_t node_instanceof = //instanceof
1555 flags:NODE_HAS_CHILDREN,
1556 eval: node_instanceof_eval,
1557 write: node_instanceof_write,
1558 read: node_instanceof_read,
1559 exec: node_instanceof_exec
1562 // ------------------------- x is y --------------------------------------
1564 typedcode_t node_is_write(node_t*n)
1566 syntaxerror("can't assign to this expression");
1568 typedcode_t node_is_read(node_t*n)
1570 READ_HEADER_LEFTRIGHT;
1571 c = code_append(left.c, right.c);
1572 c = abc_istypelate(c);
1576 code_t* node_is_exec(node_t*n)
1578 EXEC_HEADER_LEFTRIGHT;
1579 return code_append(left, right);
1581 constant_t node_is_eval(node_t*n)
1583 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1585 nodetype_t node_is = //is
1588 flags:NODE_HAS_CHILDREN,
1590 write: node_is_write,
1595 // ------------------------- x[y] --------------------------------------
1597 typedcode_t node_arraylookup_write(node_t*n)
1599 syntaxerror("not implemented yet");
1601 typedcode_t node_arraylookup_read(node_t*n)
1603 READ_HEADER_LEFTRIGHT;
1604 c = code_append(left.c, right.c);
1606 /* XXX not sure whether this access logic is correct */
1607 namespace_t ns = {left.t?left.t->access:ACCESS_PACKAGE, ""};
1608 namespace_set_t nsset;
1609 namespace_list_t l;l.next = 0;
1610 nsset.namespaces = &l;
1612 multiname_t m = {MULTINAMEL, 0, &nsset, 0};
1614 c = abc_getproperty2(c, &m);
1615 t = 0; // array elements have unknown type
1618 code_t* node_arraylookup_exec(node_t*n)
1620 EXEC_HEADER_LEFTRIGHT;
1621 return code_append(left, right);
1623 constant_t node_arraylookup_eval(node_t*n)
1625 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1627 nodetype_t node_arraylookup =
1629 name: "arraylookup",
1630 flags:NODE_HAS_CHILDREN,
1631 eval: node_arraylookup_eval,
1632 write: node_arraylookup_write,
1633 read: node_arraylookup_read,
1634 exec: node_arraylookup_exec
1637 // ------------------------- typeof(x) ------------------------------------
1639 typedcode_t node_typeof_write(node_t*n)
1641 syntaxerror("can't assign to this expression");
1643 typedcode_t node_typeof_read(node_t*n)
1651 code_t* node_typeof_exec(node_t*n)
1656 constant_t node_typeof_eval(node_t*n)
1658 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1660 nodetype_t node_typeof = //typeof
1663 flags:NODE_HAS_CHILDREN,
1664 eval: node_typeof_eval,
1665 write: node_typeof_write,
1666 read: node_typeof_read,
1667 exec: node_typeof_exec
1670 // ------------------------- (void)(x) ------------------------------------
1672 typedcode_t node_void_write(node_t*n)
1674 syntaxerror("can't assign to this expression");
1676 typedcode_t node_void_read(node_t*n)
1678 code_t*c = n->type->exec(n);
1679 c = abc_pushundefined(c);
1680 classinfo_t*t = TYPE_ANY;
1683 code_t* node_void_exec(node_t*n)
1688 constant_t node_void_eval(node_t*n)
1690 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1692 nodetype_t node_void = //void
1695 flags:NODE_HAS_CHILDREN,
1696 eval: node_void_eval,
1697 write: node_void_write,
1698 read: node_void_read,
1699 exec: node_void_exec
1702 // ---------------------------- -x ----------------------------------------
1704 typedcode_t node_neg_write(node_t*n)
1706 syntaxerror("can't assign to this expression");
1708 typedcode_t node_neg_read(node_t*n)
1713 c = abc_negate_i(c);
1721 code_t* node_neg_exec(node_t*n)
1726 constant_t node_neg_eval(node_t*n)
1728 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1730 nodetype_t node_neg = //-
1733 flags:NODE_HAS_CHILDREN,
1734 eval: node_neg_eval,
1735 write: node_neg_write,
1736 read: node_neg_read,
1740 // ---------------------------- x*=y ----------------------------------------
1742 typedcode_t node_muleq_write(node_t*n)
1744 syntaxerror("can't assign to this expression");
1746 typedcode_t node_muleq_read(node_t*n)
1748 READ_HEADER_LEFTRIGHT;
1751 if(BOTH_INT(left.t,right.t)) {
1752 c=abc_multiply_i(c);
1758 c=converttype(c, f, left.t);
1759 c = toreadwrite(left.c, c, 0, 0, 1);
1763 code_t* node_muleq_exec(node_t*n)
1765 READ_HEADER_LEFTRIGHT;
1768 if(BOTH_INT(left.t,right.t)) {
1769 c=abc_multiply_i(c);
1775 c = converttype(c, f, left.t);
1776 return toreadwrite(left.c, c, 0, 0, 0);
1778 constant_t node_muleq_eval(node_t*n)
1780 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1782 nodetype_t node_muleq =
1785 flags:NODE_HAS_CHILDREN,
1786 eval: node_muleq_eval,
1787 write: node_muleq_write,
1788 read: node_muleq_read,
1789 exec: node_muleq_exec
1792 // ---------------------------- x%=y ----------------------------------------
1794 typedcode_t node_modeq_write(node_t*n)
1796 syntaxerror("can't assign to this expression");
1798 typedcode_t node_modeq_read(node_t*n)
1800 READ_HEADER_LEFTRIGHT;
1801 c = abc_modulo(right.c);
1802 c = converttype(c, TYPE_NUMBER, left.t);
1803 c = toreadwrite(left.c, c, 0, 0, 1);
1807 code_t* node_modeq_exec(node_t*n)
1809 READ_HEADER_LEFTRIGHT;
1810 c = abc_modulo(right.c);
1811 c = converttype(c, TYPE_NUMBER, left.t);
1812 return toreadwrite(left.c, c, 0, 0, 0);
1814 constant_t node_modeq_eval(node_t*n)
1816 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1818 nodetype_t node_modeq = //%=
1821 flags:NODE_HAS_CHILDREN,
1822 eval: node_modeq_eval,
1823 write: node_modeq_write,
1824 read: node_modeq_read,
1825 exec: node_modeq_exec
1828 // ---------------------------- x<<=y ----------------------------------------
1830 typedcode_t node_shleq_write(node_t*n)
1832 syntaxerror("can't assign to this expression");
1834 typedcode_t node_shleq_read(node_t*n)
1836 READ_HEADER_LEFTRIGHT;
1837 c = abc_lshift(right.c);
1838 c = converttype(c, TYPE_INT, left.t);
1839 c = toreadwrite(left.c, c, 0, 0, 1);
1843 code_t* node_shleq_exec(node_t*n)
1845 READ_HEADER_LEFTRIGHT;
1846 c = abc_lshift(right.c);
1847 c = converttype(c, TYPE_INT, left.t);
1848 return toreadwrite(left.c, c, 0, 0, 0);
1850 constant_t node_shleq_eval(node_t*n)
1852 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1854 nodetype_t node_shleq = //<<=
1857 flags:NODE_HAS_CHILDREN,
1858 eval: node_shleq_eval,
1859 write: node_shleq_write,
1860 read: node_shleq_read,
1861 exec: node_shleq_exec
1864 // ---------------------------- x>>=y ----------------------------------------
1866 typedcode_t node_shreq_write(node_t*n)
1868 syntaxerror("can't assign to this expression");
1870 typedcode_t node_shreq_read(node_t*n)
1872 READ_HEADER_LEFTRIGHT;
1873 c = abc_rshift(right.c);
1874 c = converttype(c, TYPE_INT, left.t);
1875 c = toreadwrite(left.c, c, 0, 0, 1);
1879 code_t* node_shreq_exec(node_t*n)
1881 READ_HEADER_LEFTRIGHT;
1882 c = abc_rshift(right.c);
1883 c = converttype(c, TYPE_INT, left.t);
1884 return toreadwrite(left.c, c, 0, 0, 0);
1886 constant_t node_shreq_eval(node_t*n)
1888 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1890 nodetype_t node_shreq = //>>=
1893 flags:NODE_HAS_CHILDREN,
1894 eval: node_shreq_eval,
1895 write: node_shreq_write,
1896 read: node_shreq_read,
1897 exec: node_shreq_exec
1900 // --------------------------- x>>>=y ----------------------------------------
1902 typedcode_t node_ushreq_write(node_t*n)
1904 syntaxerror("can't assign to this expression");
1906 typedcode_t node_ushreq_read(node_t*n)
1908 READ_HEADER_LEFTRIGHT;
1909 c = abc_urshift(right.c);
1910 c = converttype(c, TYPE_UINT, left.t);
1911 c = toreadwrite(left.c, c, 0, 0, 1);
1915 code_t* node_ushreq_exec(node_t*n)
1917 READ_HEADER_LEFTRIGHT;
1918 c = abc_urshift(right.c);
1919 c = converttype(c, TYPE_UINT, left.t);
1920 return toreadwrite(left.c, c, 0, 0, 0);
1922 constant_t node_ushreq_eval(node_t*n)
1924 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1926 nodetype_t node_ushreq = //>>>=
1929 flags:NODE_HAS_CHILDREN,
1930 eval: node_ushreq_eval,
1931 write: node_ushreq_write,
1932 read: node_ushreq_read,
1933 exec: node_ushreq_exec
1936 // --------------------------- x/=y ----------------------------------------
1938 typedcode_t node_diveq_write(node_t*n)
1940 syntaxerror("can't assign to this expression");
1942 typedcode_t node_diveq_read(node_t*n)
1944 READ_HEADER_LEFTRIGHT;
1945 c = abc_divide(right.c);
1946 c = converttype(c, TYPE_NUMBER, left.t);
1947 c = toreadwrite(left.c, c, 0, 0, 1);
1951 code_t* node_diveq_exec(node_t*n)
1953 READ_HEADER_LEFTRIGHT;
1954 c = abc_divide(right.c);
1955 c = converttype(c, TYPE_NUMBER, left.t);
1956 return toreadwrite(left.c, c, 0, 0, 0);
1958 constant_t node_diveq_eval(node_t*n)
1960 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1962 nodetype_t node_diveq =
1965 flags:NODE_HAS_CHILDREN,
1966 eval: node_diveq_eval,
1967 write: node_diveq_write,
1968 read: node_diveq_read,
1969 exec: node_diveq_exec
1972 // --------------------------- x|=y ----------------------------------------
1974 typedcode_t node_bitoreq_write(node_t*n)
1976 syntaxerror("can't assign to this expression");
1978 typedcode_t node_bitoreq_read(node_t*n)
1980 READ_HEADER_LEFTRIGHT;
1981 c = abc_bitor(right.c);
1982 c = converttype(c, TYPE_INT, left.t);
1983 c = toreadwrite(left.c, c, 0, 0, 1);
1987 code_t* node_bitoreq_exec(node_t*n)
1989 READ_HEADER_LEFTRIGHT;
1990 c = abc_bitor(right.c);
1991 c = converttype(c, TYPE_INT, left.t);
1992 return toreadwrite(left.c, c, 0, 0, 0);
1994 constant_t node_bitoreq_eval(node_t*n)
1996 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1998 nodetype_t node_bitoreq = //|=
2001 flags:NODE_HAS_CHILDREN,
2002 eval: node_bitoreq_eval,
2003 write: node_bitoreq_write,
2004 read: node_bitoreq_read,
2005 exec: node_bitoreq_exec
2008 // --------------------------- x^=y ----------------------------------------
2010 typedcode_t node_bitxoreq_write(node_t*n)
2012 syntaxerror("can't assign to this expression");
2014 typedcode_t node_bitxoreq_read(node_t*n)
2016 READ_HEADER_LEFTRIGHT;
2017 c = abc_bitxor(right.c);
2018 c = converttype(c, TYPE_INT, left.t);
2019 c = toreadwrite(left.c, c, 0, 0, 1);
2023 code_t* node_bitxoreq_exec(node_t*n)
2025 READ_HEADER_LEFTRIGHT;
2026 c = abc_bitxor(right.c);
2027 c = converttype(c, TYPE_INT, left.t);
2028 return toreadwrite(left.c, c, 0, 0, 0);
2030 constant_t node_bitxoreq_eval(node_t*n)
2032 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2034 nodetype_t node_bitxoreq = //^=
2037 flags:NODE_HAS_CHILDREN,
2038 eval: node_bitxoreq_eval,
2039 write: node_bitxoreq_write,
2040 read: node_bitxoreq_read,
2041 exec: node_bitxoreq_exec
2044 // --------------------------- x&=y ----------------------------------------
2046 typedcode_t node_bitandeq_write(node_t*n)
2048 syntaxerror("can't assign to this expression");
2050 typedcode_t node_bitandeq_read(node_t*n)
2052 READ_HEADER_LEFTRIGHT;
2053 c = abc_bitand(right.c);
2054 c = converttype(c, TYPE_INT, left.t);
2055 c = toreadwrite(left.c, c, 0, 0, 1);
2059 code_t* node_bitandeq_exec(node_t*n)
2061 READ_HEADER_LEFTRIGHT;
2062 c = abc_bitand(right.c);
2063 c = converttype(c, TYPE_INT, left.t);
2064 return toreadwrite(left.c, c, 0, 0, 0);
2066 constant_t node_bitandeq_eval(node_t*n)
2068 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2070 nodetype_t node_bitandeq = //^=
2073 flags:NODE_HAS_CHILDREN,
2074 eval: node_bitandeq_eval,
2075 write: node_bitandeq_write,
2076 read: node_bitandeq_read,
2077 exec: node_bitandeq_exec
2080 // --------------------------- x+=y ----------------------------------------
2082 typedcode_t node_pluseq_write(node_t*n)
2084 syntaxerror("can't assign to this expression");
2086 typedcode_t node_pluseq_read(node_t*n)
2088 READ_HEADER_LEFTRIGHT;
2090 if(TYPE_IS_INT(left.t)) {
2094 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2096 c = toreadwrite(left.c, c, 0, 0, 1);
2100 code_t* node_pluseq_exec(node_t*n)
2102 READ_HEADER_LEFTRIGHT;
2104 if(TYPE_IS_INT(left.t)) {
2108 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2110 return toreadwrite(left.c, c, 0, 0, 0);
2112 constant_t node_pluseq_eval(node_t*n)
2114 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2116 nodetype_t node_pluseq = //+=
2119 flags:NODE_HAS_CHILDREN,
2120 eval: node_pluseq_eval,
2121 write: node_pluseq_write,
2122 read: node_pluseq_read,
2123 exec: node_pluseq_exec
2126 // --------------------------- x-=y ----------------------------------------
2128 typedcode_t node_minuseq_write(node_t*n)
2130 syntaxerror("can't assign to this expression");
2132 typedcode_t node_minuseq_read(node_t*n)
2134 READ_HEADER_LEFTRIGHT;
2136 if(TYPE_IS_INT(left.t)) {
2137 c = abc_subtract_i(c);
2139 c = abc_subtract(c);
2140 c = converttype(c, TYPE_NUMBER, left.t);
2142 c = toreadwrite(left.c, c, 0, 0, 1);
2146 code_t* node_minuseq_exec(node_t*n)
2148 READ_HEADER_LEFTRIGHT;
2150 if(TYPE_IS_INT(left.t)) {
2151 c = abc_subtract_i(c);
2153 c = abc_subtract(c);
2154 c = converttype(c, TYPE_NUMBER, left.t);
2156 return toreadwrite(left.c, c, 0, 0, 0);
2158 constant_t node_minuseq_eval(node_t*n)
2160 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2162 nodetype_t node_minuseq = //-=
2165 flags:NODE_HAS_CHILDREN,
2166 eval: node_minuseq_eval,
2167 write: node_minuseq_write,
2168 read: node_minuseq_read,
2169 exec: node_minuseq_exec
2172 // --------------------------- x=y -----------------------------------------
2174 typedcode_t node_assign_write(node_t*n)
2176 syntaxerror("can't assign to this expression");
2178 typedcode_t node_assign_read(node_t*n)
2180 READ_HEADER_LEFTRIGHT;
2182 c = converttype(c, right.t, left.t);
2183 c = toreadwrite(left.c, c, 1, 0, 1);
2187 code_t* node_assign_exec(node_t*n)
2189 READ_HEADER_LEFTRIGHT;
2191 c = converttype(c, right.t, left.t);
2192 return toreadwrite(left.c, c, 1, 0, 0);
2194 constant_t node_assign_eval(node_t*n)
2196 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2198 nodetype_t node_assign =
2201 flags:NODE_HAS_CHILDREN,
2202 eval: node_assign_eval,
2203 write: node_assign_write,
2204 read: node_assign_read,
2205 exec: node_assign_exec
2208 // --------------------------- x?y1:y2 --------------------------------------
2210 typedcode_t node_tenary_write(node_t*n)
2212 /* TODO: this might actually be kinda useful.
2213 (global?global.x:this.x) = 3;
2215 syntaxerror("can't assign to this expression");
2217 typedcode_t node_tenary_read(node_t*n)
2219 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2220 typedcode_t left = n->child[1]->type->read(n->child[1]);
2221 typedcode_t right = n->child[2]->type->read(n->child[2]);
2222 classinfo_t*t = join_types(left.t,right.t,&node_tenary);
2224 code_t*j1 = c = abc_iffalse(c, 0);
2225 c = code_append(c, left.c);
2226 c = converttype(c, left.t, t);
2227 code_t*j2 = c = abc_jump(c, 0);
2228 c = j1->branch = abc_label(c);
2229 c = code_append(c, right.c);
2230 c = converttype(c, right.t, t);
2231 c = j2->branch = abc_label(c);
2234 code_t* node_tenary_exec(node_t*n)
2236 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2237 code_t* left = n->child[1]->type->exec(n->child[1]);
2238 code_t* right = n->child[2]->type->exec(n->child[2]);
2240 code_t*j1 = c = abc_iffalse(c, 0);
2241 c = code_append(c, left);
2242 code_t*j2 = c = abc_jump(c, 0);
2243 c = j1->branch = abc_label(c);
2244 c = code_append(c, right);
2245 c = j2->branch = abc_label(c);
2248 constant_t node_tenary_eval(node_t*n)
2250 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2252 nodetype_t node_tenary =
2255 flags:NODE_HAS_CHILDREN,
2256 eval: node_tenary_eval,
2257 write: node_tenary_write,
2258 read: node_tenary_read,
2259 exec: node_tenary_exec
2262 // ---------------------------- comma ----------------------------------------
2264 typedcode_t node_comma_write(node_t*n)
2266 syntaxerror("can't assign to this expression");
2268 typedcode_t node_comma_read(node_t*n)
2273 for(i=0;i<n->num_children-1;i++) {
2274 c = code_append(c, n->child[i]->type->exec(n->child[i]));
2276 typedcode_t o = n->child[i]->type->read(n->child[i]);
2277 c = code_append(c, o.c);
2281 code_t* node_comma_exec(node_t*n)
2285 for(t=0;t<n->num_children;t++) {
2286 c = code_append(c, n->child[t]->type->exec(n->child[t]));
2290 constant_t node_comma_eval(node_t*n)
2292 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2294 nodetype_t node_comma =
2297 flags: NODE_HAS_CHILDREN,
2298 eval: node_comma_eval,
2299 write: node_comma_write,
2300 read: node_comma_read,
2301 exec: node_comma_exec
2306 // -------------------------- new x -----------------------------------
2308 typedcode_t node_new_write(node_t*n)
2311 typedcode_t node_new_read(node_t*n)
2314 code_t* node_new_exec(node_t*n)
2317 constant_t node_new_eval(node_t*n)
2319 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2321 nodetype_t node_new = //new
2323 write: node_new_write,
2324 read: node_new_read,
2325 eval: node_new_eval,
2329 // ------------------------ delete x ----------------------------------
2331 typedcode_t node_delete_write(node_t*n)
2334 typedcode_t node_delete_read(node_t*n)
2337 code_t* node_delete_exec(node_t*n)
2340 constant_t node_delete_eval(node_t*n)
2342 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2344 nodetype_t node_delete = //delete
2346 write: node_delete_write,
2347 read: node_delete_read,
2348 eval: node_delete_eval,
2349 exec: node_delete_exec
2352 // ---------------------------- x.y -----------------------------------
2354 typedcode_t node_dot_write(node_t*n)
2357 typedcode_t node_dot_read(node_t*n)
2360 code_t* node_dot_exec(node_t*n)
2363 constant_t node_dot_eval(node_t*n)
2365 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2367 nodetype_t node_dot =
2369 write: node_dot_write,
2370 read: node_dot_read,
2371 eval: node_dot_eval,
2375 // --------------------------- x..y -----------------------------------
2377 typedcode_t node_dotdot_write(node_t*n)
2380 typedcode_t node_dotdot_read(node_t*n)
2383 code_t* node_dotdot_exec(node_t*n)
2387 constant_t node_dotdot_eval(node_t*n)
2389 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2391 nodetype_t node_dotdot = //..
2393 write: node_dotdot_write,
2394 read: node_dotdot_read,
2395 eval: node_dotdot_eval,
2396 exec: node_dotdot_exec
2399 // --------------------------- x.@y -----------------------------------
2401 typedcode_t node_dotat_write(node_t*n)
2404 typedcode_t node_dotat_read(node_t*n)
2407 code_t* node_dotat_exec(node_t*n)
2410 constant_t node_dotat_eval(node_t*n)
2412 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2414 nodetype_t node_dotat = //.@
2416 write: node_dotat_write,
2417 read: node_dotat_read,
2418 eval: node_dotat_eval,
2419 exec: node_dotat_exec
2422 // --------------------------- x.*y -----------------------------------
2424 typedcode_t node_dotstar_write(node_t*n)
2427 typedcode_t node_dotstar_read(node_t*n)
2430 code_t* node_dotstar_exec(node_t*n)
2433 constant_t node_dotstar_eval(node_t*n)
2435 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2437 nodetype_t node_dotstar = //.*
2439 write: node_dotstar_write,
2440 read: node_dotstar_read,
2441 eval: node_dotstar_eval,
2442 exec: node_dotstar_exec
2445 // -------------------------- x.(y) -----------------------------------
2447 typedcode_t node_filter_write(node_t*n)
2450 typedcode_t node_filter_read(node_t*n)
2453 code_t* node_filter_exec(node_t*n)
2456 constant_t node_filter_eval(node_t*n)
2458 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2460 nodetype_t node_filter = //.(
2462 write: node_filter_write,
2463 read: node_filter_read,
2464 eval: node_filter_eval,
2465 exec: node_filter_exec
2468 // ------------------------ x(y1,...,yn) ------------------------------
2470 typedcode_t node_call_write(node_t*n)
2473 typedcode_t node_call_read(node_t*n)
2476 code_t* node_call_exec(node_t*n)
2479 constant_t node_call_eval(node_t*n)
2481 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2483 nodetype_t node_call = //functioncall
2485 write: node_call_write,
2486 read: node_call_read,
2487 eval: node_call_eval,
2488 exec: node_call_exec
2491 // ------------------------------ @x ----------------------------------------
2493 typedcode_t node_at_write(node_t*n)
2496 typedcode_t node_at_read(node_t*n)
2499 code_t* node_at_exec(node_t*n)
2502 constant_t node_at_eval(node_t*n)
2504 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2506 nodetype_t node_at = //@
2508 write: node_at_write,
2514 // ---------------------------- x.ns::y ----------------------------------------
2516 typedcode_t node_dotns_write(node_t*n)
2519 typedcode_t node_dotns_read(node_t*n)
2522 code_t* node_dotns_exec(node_t*n)
2525 constant_t node_dotns_eval(node_t*n)
2527 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2529 nodetype_t node_dotns = //.::
2531 write: node_dotns_write,
2532 read: node_dotns_read,
2533 eval: node_dotns_eval,
2534 exec: node_dotns_exec
2538 // ------------------------ constant ------------------------------
2540 typedcode_t node_const_write(node_t*n)
2542 syntaxerror("can't assign a value to a constant");
2544 typedcode_t node_const_read(node_t*n)
2546 constant_t*v = n->value;
2551 if(v->i>-128 && v->i<128) {
2552 c = abc_pushbyte(0,v->i);
2553 } else if(v->i>=-32768 && v->i<32768) {
2554 c = abc_pushshort(0,v->i);
2556 c = abc_pushint(0,v->i);
2561 c = abc_pushuint(0,v->u);
2563 c = abc_pushbyte(0,v->u);
2564 } else if(v->u<32768) {
2565 c = abc_pushshort(0,v->u);
2567 c = abc_pushint(0,v->u);
2571 case CONSTANT_FLOAT:
2572 c = abc_pushdouble(0,v->f);
2576 c = abc_pushtrue(0);
2579 case CONSTANT_FALSE:
2580 c = abc_pushfalse(0);
2584 c = abc_pushnull(0);
2587 case CONSTANT_STRING:
2588 c = abc_pushstring2(0,v->s);
2591 case CONSTANT_UNDEFINED:
2592 c = abc_pushundefined(0);
2595 case CONSTANT_NAMESPACE:
2596 case CONSTANT_NAMESPACE_PACKAGE:
2597 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
2598 case CONSTANT_NAMESPACE_PROTECTED:
2599 case CONSTANT_NAMESPACE_EXPLICIT:
2600 case CONSTANT_NAMESPACE_STATICPROTECTED:
2601 case CONSTANT_NAMESPACE_PRIVATE:
2602 c = abc_pushnamespace(0, v->ns);
2604 case CONSTANT_UNKNOWN:
2605 syntaxerror("internal error: invalid constant");
2608 syntaxerror("invalid constant (%d)", v->type);
2614 code_t* node_const_exec(node_t*n)
2618 constant_t node_const_eval(node_t*n)
2620 constant_t*c = constant_clone(n->value);
2622 free(c); //shallow free
2625 nodetype_t node_const =
2629 eval: node_const_eval,
2630 write: node_const_write,
2631 read: node_const_read,
2632 exec: node_const_exec
2635 // ------------------------ code node ------------------------------
2637 typedcode_t node_code_write(node_t*n)
2639 syntaxerror("not implemented yet");
2641 typedcode_t node_code_read(node_t*n)
2649 code_t* node_code_exec(node_t*n)
2651 code_t*c = code_dup(n->code.c);
2652 c = cut_last_push(c);
2655 constant_t node_code_eval(node_t*n)
2657 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2659 nodetype_t node_code =
2663 eval: node_code_eval,
2664 write: node_code_write,
2665 read: node_code_read,
2666 exec: node_code_exec
2669 // ------------------------ dummy node ------------------------------
2671 typedcode_t node_dummy_write(node_t*n)
2673 syntaxerror("not implemented yet");
2675 typedcode_t node_dummy_read(node_t*n)
2678 t.c = abc_pushundefined(0);
2682 code_t* node_dummy_exec(node_t*n)
2686 constant_t node_dummy_eval(node_t*n)
2688 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2690 nodetype_t node_dummy =
2694 eval: node_dummy_eval,
2695 write: node_dummy_write,
2696 read: node_dummy_read,
2697 exec: node_dummy_exec
2700 // ======================== node handling ==============================
2702 node_t* mkdummynode()
2704 node_t*n = (node_t*)rfx_calloc(sizeof(node_t));
2705 n->type = &node_dummy;
2709 node_t* mkconstnode(constant_t*c)
2711 node_t*n = (node_t*)malloc(sizeof(node_t));
2712 n->type = &node_const;
2718 node_t* mkcodenode(typedcode_t c)
2720 node_t*n = (node_t*)malloc(sizeof(node_t));
2721 n->type = &node_code;
2727 node_t* mkmultinode(nodetype_t*t, node_t*one)
2729 node_t*n = (node_t*)malloc(sizeof(node_t));
2732 n->child = (node_t**)malloc(sizeof(node_t*)*1);
2734 n->num_children = 1;
2738 node_t* mkstringnode(const char*s)
2740 return mkconstnode(constant_new_string(s));
2743 node_t* mkaddnode(node_t*n1, node_t*n2)
2745 return mknode2(&node_plus, n1, n2);
2748 node_t* multinode_extend(node_t*n, node_t*add)
2750 n->child = realloc(n->child, (n->num_children+1)*sizeof(node_t*));
2751 n->child[n->num_children] = add;
2756 node_t* mknode1(nodetype_t*t, node_t*node)
2758 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*2);
2759 node_t**x = (node_t**)&n[1];
2763 n->num_children = 1;
2769 node_t* mknode2(nodetype_t*t, node_t*left, node_t*right)
2771 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*3);
2772 node_t**x = (node_t**)&n[1];
2776 n->num_children = 2;
2782 node_t* mknode3(nodetype_t*t, node_t*one, node_t*two, node_t*three)
2784 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*4);
2785 node_t**x = (node_t**)&n[1];
2789 n->num_children = 3;
2797 void node_free(node_t*n)
2800 if(n->type == &node_code) {
2802 code_free(n->code.c);n->code.c = 0;
2804 } else if(n->type == &node_const) {
2805 /* keep, this is not our reference */
2806 } else for(t=0;t<n->num_children;t++) {
2807 node_free(n->child[t]);n->child[t] = 0;
2812 typedcode_t node_read(node_t*n)
2814 constant_t c = n->type->eval(n);
2815 if(c.type == CONSTANT_UNKNOWN) {
2816 typedcode_t t = n->type->read(n);
2820 typedcode_t t = push_constant(&c);
2825 code_t* node_exec(node_t*n)
2827 code_t*c = n->type->exec(n);
2831 constant_t node_eval(node_t*n)
2833 constant_t c = n->type->eval(n);
2851 void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
2853 if(n->type->flags&NODE_HAS_CHILDREN) {
2854 fprintf(fi, "%s%s\n", p1, n->type->name);
2856 char*o2 = malloc(strlen(p2)+3);
2857 strcpy(o2, p2);strcat(o2, "| ");
2858 char*o3 = malloc(strlen(p2)+3);
2859 strcpy(o3, p2);strcat(o3, "+-");
2860 char*o4 = malloc(strlen(p2)+3);
2861 strcpy(o4, p2);strcat(o4, " ");
2863 for(t=0;t<n->num_children;t++) {
2864 fprintf(fi, "%s\n", o2);
2865 node_dump2(n->child[t], o3, t<n->num_children-1?o2:o4, fi);
2870 } else if(n->type == &node_const) {
2871 char*s = constant_tostring(n->value);
2872 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
2874 } else if(n->type == &node_code) {
2875 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, n->code.t?n->code.t->name:"*");
2876 code_dump2(n->code.c, 0, 0, (char*)p2, fi);
2878 fprintf(fi, "%s%s\n", p1, n->type->name);
2882 void node_dump(node_t*n)
2884 printf("------------VVVV---------------\n");
2885 node_dump2(n,"","",stdout);
2886 printf("-------------------------------\n");