3 Extension module for the rfxswf library.
4 Part of the swftools package.
6 Copyright (c) 2009 Matthias Kramm <kramm@quiss.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
24 #include "tokenizer.h"
26 #define IS_INT(a) (TYPE_IS_INT((a)) || TYPE_IS_UINT((a)))
27 #define BOTH_INT(a,b) (IS_INT(a) && IS_INT(b))
29 #define READ_HEADER_LEFTRIGHT \
30 typedcode_t left = n->child[0]->type->read(n->child[0]);\
31 typedcode_t right = n->child[1]->type->read(n->child[1]);\
35 #define READ_HEADER_ONE \
36 typedcode_t x = n->child[0]->type->read(n->child[0]);\
40 #define EXEC_HEADER_ONE \
41 code_t* x = n->child[0]->type->exec(n->child[0]);\
45 #define EXEC_HEADER_LEFTRIGHT \
46 code_t* left = n->child[0]->type->exec(n->child[0]);\
47 code_t* right = n->child[1]->type->exec(n->child[1]);\
51 #define EVAL_HEADER_LEFTRIGHT \
52 constant_t left = n->child[0]->type->eval(n->child[0]);\
53 constant_t right = n->child[1]->type->eval(n->child[1]);\
55 if(left.type==CONSTANT_UNKNOWN || right.type==CONSTANT_UNKNOWN) {\
56 r.type = CONSTANT_UNKNOWN;return r; \
66 static classinfo_t*join_types(classinfo_t*type1, classinfo_t*type2, nodetype_t*t)
69 if((TYPE_IS_XMLLIST(type1) || TYPE_IS_XML(type1)) &&
70 (TYPE_IS_XMLLIST(type2) || TYPE_IS_XML(type2)))
72 if(BOTH_INT(type1, type2))
74 if(IS_NUMBER_OR_INT(type1) && IS_NUMBER_OR_INT(type2))
76 if(TYPE_IS_DATE(type1) || TYPE_IS_DATE(type2))
78 if(TYPE_IS_STRING(type1) || TYPE_IS_STRING(type2)) {
79 /* depending on where the strings come from, the result type
80 of an "add" might be an object or a string, depending on the
81 verifier's mood. So basically we just don't know the type. */
84 if(TYPE_IS_ANY(type1) || TYPE_IS_ANY(type2))
86 return TYPE_OBJECT; // e.g. array+array = object
93 static char is_getlocal(code_t*c)
95 if(!c || c->prev || c->next)
97 return(c->opcode == OPCODE_GETLOCAL
98 || c->opcode == OPCODE_GETLOCAL_0
99 || c->opcode == OPCODE_GETLOCAL_1
100 || c->opcode == OPCODE_GETLOCAL_2
101 || c->opcode == OPCODE_GETLOCAL_3);
103 static int getlocalnr(code_t*c)
105 if(c->opcode == OPCODE_GETLOCAL) {return (ptroff_t)c->data[0];}
106 else if(c->opcode == OPCODE_GETLOCAL_0) {return 0;}
107 else if(c->opcode == OPCODE_GETLOCAL_1) {return 1;}
108 else if(c->opcode == OPCODE_GETLOCAL_2) {return 2;}
109 else if(c->opcode == OPCODE_GETLOCAL_3) {return 3;}
110 else syntaxerror("Internal error: opcode %02x is not a getlocal call", c->opcode);
115 int gettempvar(); /* FIXME: we should use a function pointer here */
118 static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char readbefore, char pushvalue)
122 [prefix code] [read instruction]
126 [prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar]
128 if(in && in->opcode == OPCODE_COERCE_A) {
129 in = code_cutlast(in);
132 syntaxerror("internal error");
134 /* chop off read instruction */
138 prefix = r->prev;r->prev = 0;
144 char use_temp_var = readbefore;
146 /* generate the write instruction, and maybe append a dup to the prefix code */
147 code_t* write = abc_nop(0);
148 if(r->opcode == OPCODE_GETPROPERTY) {
149 write->opcode = OPCODE_SETPROPERTY;
150 multiname_t*m = (multiname_t*)r->data[0];
151 write->data[0] = multiname_clone(m);
152 if(m->type == QNAME || m->type == MULTINAME ||
153 m->type == QNAMEA || m->type == MULTINAMEA) {
155 prefix = abc_dup(prefix); // we need the object, too
158 } else if(m->type == MULTINAMEL || m->type == MULTINAMELA) {
160 /* dupping two values on the stack requires 5 operations and one register-
161 couldn't adobe just have given us a dup2? */
162 int temp = gettempvar();
163 prefix = abc_setlocal(prefix, temp);
164 prefix = abc_dup(prefix);
165 prefix = abc_getlocal(prefix, temp);
166 prefix = abc_swap(prefix);
167 prefix = abc_getlocal(prefix, temp);
169 prefix = abc_kill(prefix, temp);
173 syntaxerror("illegal lvalue: can't assign a value to this expression (not a qname/multiname)");
175 } else if(r->opcode == OPCODE_GETSLOT) {
176 write->opcode = OPCODE_SETSLOT;
177 write->data[0] = r->data[0];
179 prefix = abc_dup(prefix); // we need the object, too
182 } else if(r->opcode == OPCODE_GETLOCAL) {
183 write->opcode = OPCODE_SETLOCAL;
184 write->data[0] = r->data[0];
185 } else if(r->opcode == OPCODE_GETLOCAL_0) {
186 write->opcode = OPCODE_SETLOCAL_0;
187 } else if(r->opcode == OPCODE_GETLOCAL_1) {
188 write->opcode = OPCODE_SETLOCAL_1;
189 } else if(r->opcode == OPCODE_GETLOCAL_2) {
190 write->opcode = OPCODE_SETLOCAL_2;
191 } else if(r->opcode == OPCODE_GETLOCAL_3) {
192 write->opcode = OPCODE_SETLOCAL_3;
193 } else if(r->opcode == OPCODE_GETSUPER) {
194 write->opcode = OPCODE_SETSUPER;
195 multiname_t*m = (multiname_t*)r->data[0];
196 write->data[0] = multiname_clone(m);
199 syntaxerror("illegal lvalue: can't assign a value to this expression");
206 /* with getproperty/getslot, we have to be extra careful not
207 to execute the read code twice, as it might have side-effects
208 (e.g. if the property is in fact a setter/getter combination)
210 So read the value, modify it, and write it again,
211 using prefix only once and making sure (by using a temporary
212 register) that the return value is what we just wrote */
214 c = code_append(c, prefix);
215 c = code_append(c, r);
216 if(pushvalue && readbefore) {
218 c = abc_setlocal(c, temp);
220 c = code_append(c, middlepart);
221 if(pushvalue && !readbefore) {
223 c = abc_setlocal(c, temp);
225 c = code_append(c, write);
227 c = abc_getlocal(c, temp);
228 c = abc_kill(c, temp);
231 /* if we're allowed to execute the read code twice *and*
232 the middlepart doesn't modify the code, things are easier.
234 //c = code_append(c, prefix);
235 if(prefix) syntaxerror("internal error (prefix)");
240 c = code_append(c, r);
241 c = code_append(c, middlepart);
242 c = code_append(c, write);
244 c = code_append(c, r2);
248 /* even smaller version: overwrite the value without reading
252 c = code_append(c, prefix);
255 c = code_append(c, middlepart);
256 c = code_append(c, write);
258 c = code_append(c, r);
264 c = code_append(c, prefix);
266 c = code_append(c, middlepart);
269 c = abc_setlocal(c, temp);
271 c = code_append(c, write);
273 c = abc_getlocal(c, temp);
274 c = abc_kill(c, temp);
281 typedcode_t push_constant(constant_t*v)
285 case CONSTANT_INT: t.c = abc_pushint(0, v->i);t.t = TYPE_INT;break;
286 case CONSTANT_UINT: t.c = abc_pushuint(0, v->u);t.t = TYPE_UINT;break;
287 case CONSTANT_FLOAT: t.c = abc_pushdouble(0, v->f);t.t = TYPE_FLOAT;break;
288 case CONSTANT_TRUE: t.c = abc_pushtrue(0);t.t = TYPE_BOOLEAN;break;
289 case CONSTANT_FALSE: t.c = abc_pushfalse(0);t.t = TYPE_BOOLEAN;break;
290 case CONSTANT_STRING: t.c = abc_pushstring2(0, v->s);t.t = TYPE_STRING;break;
291 case CONSTANT_NULL: t.c = abc_pushnull(0);t.t = TYPE_NULL;break;
292 case CONSTANT_UNDEFINED: t.c = abc_pushundefined(0);t.t = TYPE_ANY;break;
293 case CONSTANT_NAMESPACE:
294 case CONSTANT_NAMESPACE_PACKAGE:
295 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
296 case CONSTANT_NAMESPACE_PROTECTED:
297 case CONSTANT_NAMESPACE_EXPLICIT:
298 case CONSTANT_NAMESPACE_STATICPROTECTED:
299 case CONSTANT_NAMESPACE_PRIVATE:
300 t.c = abc_pushnamespace(0, v->ns);t.t = TYPE_NAMESPACE;break;
302 syntaxerror("internal error: bad constant");
307 code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to);
309 int constant_to_int(constant_t*c)
312 case CONSTANT_INT: return c->i;
313 case CONSTANT_UINT: return (int)c->u;
314 case CONSTANT_FLOAT: return c->f;
315 case CONSTANT_TRUE: return 1;
316 case CONSTANT_FALSE: return 0;
317 case CONSTANT_STRING: return atoi(c->s->str);
318 default: syntaxerror("can't convert this constant to an integer");
322 double constant_to_float(constant_t*c)
325 case CONSTANT_INT: return (double)c->i;
326 case CONSTANT_UINT: return (double)c->u;
327 case CONSTANT_FLOAT: return c->f;
328 case CONSTANT_TRUE: return (double)1;
329 case CONSTANT_FALSE: return (double)0;
330 case CONSTANT_STRING: return atof(c->s->str);
331 default: syntaxerror("can't convert this constant to a float");
335 // -------------------------- x + y -----------------------------------
337 typedcode_t node_plus_write(node_t*n)
339 syntaxerror("can't assign to this expression");
341 typedcode_t node_plus_read(node_t*n)
343 READ_HEADER_LEFTRIGHT;
344 c = code_append(left.c, right.c);
345 if(BOTH_INT(left.t, right.t)) {
350 t = join_types(left.t,right.t,n->type);
354 code_t* node_plus_exec(node_t*n)
356 EXEC_HEADER_LEFTRIGHT;
357 return code_append(left, right);
359 constant_t node_plus_eval(node_t*n)
361 EVAL_HEADER_LEFTRIGHT;
362 char left_int = left.type == CONSTANT_INT || left.type == CONSTANT_UINT;
363 if(left_int && (right.type == CONSTANT_INT || right.type == CONSTANT_UINT)) {
364 int i = constant_to_int(&left) + constant_to_int(&right);
365 r.type = CONSTANT_INT;
367 } else if(left_int && right.type == CONSTANT_FLOAT) {
368 double f = constant_to_int(&left) + constant_to_float(&right);
369 r.type = CONSTANT_FLOAT;
371 } else if(left.type == CONSTANT_STRING) {
372 char*add = constant_tostring(&right);
373 int l1 = left.s->len;
374 int l2 = strlen(add);
375 char*s = malloc(l1+l2+1);
376 memcpy(s, left.s->str, l1);
377 memcpy(s+l1, add, l2);
379 r.type = CONSTANT_STRING;
380 r.s = malloc(sizeof(string_t));
385 r.type = CONSTANT_UNKNOWN;
389 nodetype_t node_plus =
392 flags:NODE_HAS_CHILDREN,
394 write:node_plus_write,
399 // -------------------------- x - y -----------------------------------
401 typedcode_t node_minus_write(node_t*n)
403 syntaxerror("can't assign to this expression");
405 typedcode_t node_minus_read(node_t*n)
407 READ_HEADER_LEFTRIGHT;
408 c = code_append(left.c, right.c);
409 if(BOTH_INT(left.t,right.t)) {
410 c = abc_subtract_i(c);
418 code_t* node_minus_exec(node_t*n)
420 EXEC_HEADER_LEFTRIGHT;
421 return code_append(left, right);
423 constant_t node_minus_eval(node_t*n)
425 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
427 nodetype_t node_minus =
430 flags:NODE_HAS_CHILDREN,
431 eval: node_minus_eval,
432 write: node_minus_write,
433 read: node_minus_read,
434 exec: node_minus_exec
437 // ---------------------------- ++x -----------------------------------
439 typedcode_t node_lplusplus_write(node_t*n)
441 syntaxerror("can't assign to this expression");
443 typedcode_t node_lplusplus_read(node_t*n)
447 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
448 int nr = getlocalnr(x.c);
449 code_free(x.c);x.c=0;
450 if(TYPE_IS_INT(x.t)) {
451 c = abc_inclocal_i(c, nr);
452 c = abc_getlocal(c, nr);
453 } else if(TYPE_IS_NUMBER(x.t)) {
454 c = abc_inclocal(c, nr);
455 c = abc_getlocal(c, nr);
456 } else syntaxerror("internal error");
458 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
459 c = abc_increment_i(c);
462 c = abc_increment(c);
465 c = converttype(c, t, x.t);
466 c = toreadwrite(x.c, c, 0, 0, 1);
471 code_t* node_lplusplus_exec(node_t*n)
473 typedcode_t x = n->child[0]->type->read(n->child[0]);
475 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
476 int nr = getlocalnr(x.c);
477 code_free(x.c);x.c=0;
478 if(TYPE_IS_INT(x.t)) {
479 c = abc_inclocal_i(c, nr);
480 } else if(TYPE_IS_NUMBER(x.t)) {
481 c = abc_inclocal(c, nr);
482 } else syntaxerror("internal error");
485 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
486 c = abc_increment_i(c);
489 c = abc_increment(c);
492 c = converttype(c, t, x.t); //convert back to original type
493 c = toreadwrite(x.c, c, 0, 0, 0);
498 constant_t node_lplusplus_eval(node_t*n)
500 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
502 nodetype_t node_lplusplus =
505 flags:NODE_HAS_CHILDREN,
506 eval: node_lplusplus_eval,
507 write: node_lplusplus_write,
508 read: node_lplusplus_read,
509 exec: node_lplusplus_exec
513 // ---------------------------- --x -----------------------------------
515 typedcode_t node_lminusminus_write(node_t*n)
517 syntaxerror("can't assign to this expression");
519 typedcode_t node_lminusminus_read(node_t*n)
523 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
524 int nr = getlocalnr(x.c);
525 code_free(x.c);x.c=0;
526 if(TYPE_IS_INT(x.t)) {
527 c = abc_declocal_i(c, nr);
528 c = abc_getlocal(c, nr);
529 } else if(TYPE_IS_NUMBER(x.t)) {
530 c = abc_declocal(c, nr);
531 c = abc_getlocal(c, nr);
532 } else syntaxerror("internal error");
534 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
535 c = abc_decrement_i(c);
538 c = abc_decrement(c);
541 c = converttype(c, t, x.t);
542 c = toreadwrite(x.c, c, 0, 0, 1);
547 code_t* node_lminusminus_exec(node_t*n)
549 typedcode_t x = n->child[0]->type->read(n->child[0]);
551 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
552 int nr = getlocalnr(x.c);
553 code_free(x.c);x.c=0;
554 if(TYPE_IS_INT(x.t)) {
555 c = abc_declocal_i(c, nr);
556 } else if(TYPE_IS_NUMBER(x.t)) {
557 c = abc_declocal(c, nr);
558 } else syntaxerror("internal error");
561 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
562 c = abc_decrement_i(c);
565 c = abc_decrement(c);
568 c = converttype(c, t, x.t); //convert back to original type
569 c = toreadwrite(x.c, c, 0, 0, 0);
574 constant_t node_lminusminus_eval(node_t*n)
576 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
578 nodetype_t node_lminusminus =
581 flags:NODE_HAS_CHILDREN,
582 eval: node_lminusminus_eval,
583 write: node_lminusminus_write,
584 read: node_lminusminus_read,
585 exec: node_lminusminus_exec
590 // ---------------------------- x++ -----------------------------------
592 typedcode_t node_rplusplus_write(node_t*n)
594 syntaxerror("can't assign to this expression");
596 typedcode_t node_rplusplus_read(node_t*n)
600 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
601 int nr = getlocalnr(x.c);
602 code_free(x.c);x.c=0;
603 if(TYPE_IS_INT(x.t)) {
604 c = abc_getlocal(0, nr);
605 c = abc_inclocal_i(c, nr);
606 } else if(TYPE_IS_NUMBER(x.t)) {
607 c = abc_getlocal(0, nr);
608 c = abc_inclocal(c, nr);
609 } else syntaxerror("internal error");
611 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
612 c = abc_increment_i(c);
615 c = abc_increment(c);
618 c = converttype(c, t, x.t);
619 c = toreadwrite(x.c, c, 0, 1, 1);
624 code_t* node_rplusplus_exec(node_t*n)
626 typedcode_t x = n->child[0]->type->read(n->child[0]);
628 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
629 int nr = getlocalnr(x.c);
630 code_free(x.c);x.c=0;
631 if(TYPE_IS_INT(x.t)) {
632 c = abc_inclocal_i(c, nr);
633 } else if(TYPE_IS_NUMBER(x.t)) {
634 c = abc_inclocal(c, nr);
635 } else syntaxerror("internal error");
638 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
639 c = abc_increment_i(c);
642 c = abc_increment(c);
645 c = converttype(c, t, x.t); //convert back to original type
646 c = toreadwrite(x.c, c, 0, 1, 0);
651 constant_t node_rplusplus_eval(node_t*n)
653 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
655 nodetype_t node_rplusplus =
658 flags:NODE_HAS_CHILDREN,
659 eval: node_rplusplus_eval,
660 write: node_rplusplus_write,
661 read: node_rplusplus_read,
662 exec: node_rplusplus_exec
665 // ---------------------------- x-- -----------------------------------
667 typedcode_t node_rminusminus_write(node_t*n)
669 syntaxerror("can't assign to this expression");
671 typedcode_t node_rminusminus_read(node_t*n)
675 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
676 int nr = getlocalnr(x.c);
677 code_free(x.c);x.c=0;
678 if(TYPE_IS_INT(x.t)) {
679 c = abc_getlocal(0, nr);
680 c = abc_declocal_i(c, nr);
681 } else if(TYPE_IS_NUMBER(x.t)) {
682 c = abc_getlocal(0, nr);
683 c = abc_declocal(c, nr);
684 } else syntaxerror("internal error");
686 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
687 c = abc_decrement_i(c);
690 c = abc_decrement(c);
693 c = converttype(c, t, x.t);
694 c = toreadwrite(x.c, c, 0, 1, 1);
699 code_t* node_rminusminus_exec(node_t*n)
701 typedcode_t x = n->child[0]->type->read(n->child[0]);
703 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
704 int nr = getlocalnr(x.c);
705 code_free(x.c);x.c=0;
706 if(TYPE_IS_INT(x.t)) {
707 c = abc_declocal_i(c, nr);
708 } else if(TYPE_IS_NUMBER(x.t)) {
709 c = abc_declocal(c, nr);
710 } else syntaxerror("internal error");
713 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
714 c = abc_decrement_i(c);
717 c = abc_decrement(c);
720 c = converttype(c, t, x.t); //convert back to original type
721 c = toreadwrite(x.c, c, 0, 1, 0);
726 constant_t node_rminusminus_eval(node_t*n)
728 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
730 nodetype_t node_rminusminus =
733 flags:NODE_HAS_CHILDREN,
734 eval: node_rminusminus_eval,
735 write: node_rminusminus_write,
736 read: node_rminusminus_read,
737 exec: node_rminusminus_exec
740 // ---------------------------- x*y -----------------------------------
742 typedcode_t node_multiply_write(node_t*n)
744 syntaxerror("can't assign to this expression");
746 typedcode_t node_multiply_read(node_t*n)
748 READ_HEADER_LEFTRIGHT;
749 c = code_append(left.c,right.c);
750 if(BOTH_INT(left.t,right.t)) {
751 c = abc_multiply_i(c);
759 code_t* node_multiply_exec(node_t*n)
761 EXEC_HEADER_LEFTRIGHT;
762 return code_append(left, right);
764 constant_t node_multiply_eval(node_t*n)
766 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
768 nodetype_t node_multiply =
771 flags:NODE_HAS_CHILDREN,
772 eval: node_multiply_eval,
773 write: node_multiply_write,
774 read: node_multiply_read,
775 exec: node_multiply_exec
778 // ---------------------------- x/y -----------------------------------
780 typedcode_t node_div_write(node_t*n)
782 syntaxerror("can't assign to this expression");
784 typedcode_t node_div_read(node_t*n)
786 READ_HEADER_LEFTRIGHT;
787 c = code_append(left.c, right.c);
792 code_t* node_div_exec(node_t*n)
794 EXEC_HEADER_LEFTRIGHT;
795 return code_append(left, right);
797 constant_t node_div_eval(node_t*n)
799 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
801 nodetype_t node_div =
804 flags:NODE_HAS_CHILDREN,
806 write: node_div_write,
811 // ---------------------------- x%y -----------------------------------
813 typedcode_t node_mod_write(node_t*n)
815 syntaxerror("can't assign to this expression");
817 typedcode_t node_mod_read(node_t*n)
819 READ_HEADER_LEFTRIGHT;
820 c = code_append(left.c, right.c);
825 code_t* node_mod_exec(node_t*n)
827 EXEC_HEADER_LEFTRIGHT;
828 return code_append(left, right);
830 constant_t node_mod_eval(node_t*n)
832 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
834 nodetype_t node_mod =
837 flags:NODE_HAS_CHILDREN,
839 write: node_mod_write,
844 // ---------------------------- x<y -----------------------------------
846 typedcode_t node_lt_write(node_t*n)
848 syntaxerror("can't assign to this expression");
850 typedcode_t node_lt_read(node_t*n)
852 READ_HEADER_LEFTRIGHT;
853 c = code_append(left.c,right.c);
858 code_t* node_lt_exec(node_t*n)
860 EXEC_HEADER_LEFTRIGHT;
861 return code_append(left, right);
863 constant_t node_lt_eval(node_t*n)
865 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
870 flags:NODE_HAS_CHILDREN,
872 write: node_lt_write,
877 // ---------------------------- x>y -----------------------------------
879 typedcode_t node_gt_write(node_t*n)
881 syntaxerror("can't assign to this expression");
883 typedcode_t node_gt_read(node_t*n)
885 READ_HEADER_LEFTRIGHT;
886 c = code_append(left.c,right.c);
887 c = abc_greaterthan(c);
891 code_t* node_gt_exec(node_t*n)
893 EXEC_HEADER_LEFTRIGHT;
894 return code_append(left, right);
896 constant_t node_gt_eval(node_t*n)
898 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
903 flags:NODE_HAS_CHILDREN,
905 write: node_gt_write,
910 // ---------------------------- x<=y ----------------------------------
912 typedcode_t node_le_write(node_t*n)
914 syntaxerror("can't assign to this expression");
916 typedcode_t node_le_read(node_t*n)
918 READ_HEADER_LEFTRIGHT;
919 c = code_append(left.c,right.c);
920 c = abc_lessequals(c);
924 code_t* node_le_exec(node_t*n)
926 EXEC_HEADER_LEFTRIGHT;
927 return code_append(left, right);
929 constant_t node_le_eval(node_t*n)
931 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
933 nodetype_t node_le = //<=
936 flags:NODE_HAS_CHILDREN,
938 write: node_le_write,
943 // ---------------------------- x>=y ----------------------------------
945 typedcode_t node_ge_write(node_t*n)
947 syntaxerror("can't assign to this expression");
949 typedcode_t node_ge_read(node_t*n)
951 READ_HEADER_LEFTRIGHT;
952 c = code_append(left.c,right.c);
953 c = abc_greaterequals(c);
957 code_t* node_ge_exec(node_t*n)
959 EXEC_HEADER_LEFTRIGHT;
960 return code_append(left, right);
962 constant_t node_ge_eval(node_t*n)
964 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
966 nodetype_t node_ge = //>=
969 flags:NODE_HAS_CHILDREN,
971 write: node_ge_write,
976 // ---------------------------- x==y ----------------------------------
978 typedcode_t node_eqeq_write(node_t*n)
980 syntaxerror("can't assign to this expression");
982 typedcode_t node_eqeq_read(node_t*n)
984 READ_HEADER_LEFTRIGHT;
985 c = code_append(left.c,right.c);
990 code_t* node_eqeq_exec(node_t*n)
992 EXEC_HEADER_LEFTRIGHT;
993 return code_append(left, right);
995 constant_t node_eqeq_eval(node_t*n)
997 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
999 nodetype_t node_eqeq = //==
1002 flags:NODE_HAS_CHILDREN,
1003 eval: node_eqeq_eval,
1004 write: node_eqeq_write,
1005 read: node_eqeq_read,
1006 exec: node_eqeq_exec
1009 // --------------------------- x===y ----------------------------------
1011 typedcode_t node_eqeqeq_write(node_t*n)
1013 syntaxerror("can't assign to this expression");
1015 typedcode_t node_eqeqeq_read(node_t*n)
1017 READ_HEADER_LEFTRIGHT;
1018 c = code_append(left.c,right.c);
1019 c = abc_strictequals(c);
1023 code_t* node_eqeqeq_exec(node_t*n)
1025 EXEC_HEADER_LEFTRIGHT;
1026 return code_append(left, right);
1028 constant_t node_eqeqeq_eval(node_t*n)
1030 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1032 nodetype_t node_eqeqeq = //===
1035 flags:NODE_HAS_CHILDREN,
1036 eval: node_eqeqeq_eval,
1037 write: node_eqeqeq_write,
1038 read: node_eqeqeq_read,
1039 exec: node_eqeqeq_exec
1042 // --------------------------- x!==y ----------------------------------
1044 typedcode_t node_noteqeq_write(node_t*n)
1046 syntaxerror("can't assign to this expression");
1048 typedcode_t node_noteqeq_read(node_t*n)
1050 READ_HEADER_LEFTRIGHT;
1051 c = code_append(left.c,right.c);
1052 c = abc_strictequals(c);
1057 code_t* node_noteqeq_exec(node_t*n)
1059 EXEC_HEADER_LEFTRIGHT;
1060 return code_append(left, right);
1062 constant_t node_noteqeq_eval(node_t*n)
1064 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1066 nodetype_t node_noteqeq = //!==
1069 flags:NODE_HAS_CHILDREN,
1070 eval: node_noteqeq_eval,
1071 write: node_noteqeq_write,
1072 read: node_noteqeq_read,
1073 exec: node_noteqeq_exec
1076 // --------------------------- x!=y ----------------------------------
1078 typedcode_t node_noteq_write(node_t*n)
1080 syntaxerror("can't assign to this expression");
1082 typedcode_t node_noteq_read(node_t*n)
1084 READ_HEADER_LEFTRIGHT;
1085 c = code_append(left.c,right.c);
1091 code_t* node_noteq_exec(node_t*n)
1093 EXEC_HEADER_LEFTRIGHT;
1094 return code_append(left, right);
1096 constant_t node_noteq_eval(node_t*n)
1098 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1100 nodetype_t node_noteq = //!=
1103 flags:NODE_HAS_CHILDREN,
1104 eval: node_noteq_eval,
1105 write: node_noteq_write,
1106 read: node_noteq_read,
1107 exec: node_noteq_exec
1110 // --------------------------- x||y ----------------------------------
1112 typedcode_t node_oror_write(node_t*n)
1114 syntaxerror("can't assign to this expression");
1116 typedcode_t node_oror_read(node_t*n)
1118 READ_HEADER_LEFTRIGHT;
1119 t = join_types(left.t, right.t, n->type);
1121 c = converttype(c, left.t, t);
1123 code_t*jmp = c = abc_iftrue(c, 0);
1124 c = cut_last_push(c);
1125 c = code_append(c, right.c);
1126 c = converttype(c, right.t, t);
1127 code_t*label = c = abc_label(c);
1128 jmp->branch = label;
1131 code_t* node_oror_exec(node_t*n)
1133 typedcode_t left = n->child[0]->type->read(n->child[0]);
1134 code_t* right = n->child[1]->type->exec(n->child[1]);
1136 code_t*jmp = c = abc_iftrue(c, 0);
1137 c = code_append(c, right);
1138 code_t*label = c = abc_label(c);
1139 jmp->branch = label;
1142 constant_t node_oror_eval(node_t*n)
1144 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1146 nodetype_t node_oror = //||
1149 flags:NODE_HAS_CHILDREN,
1150 eval: node_oror_eval,
1151 write: node_oror_write,
1152 read: node_oror_read,
1153 exec: node_oror_exec
1156 // --------------------------- x&&y ----------------------------------
1158 typedcode_t node_andand_write(node_t*n)
1160 syntaxerror("can't assign to this expression");
1162 typedcode_t node_andand_read(node_t*n)
1164 READ_HEADER_LEFTRIGHT;
1165 t = join_types(left.t, right.t, &node_andand);
1167 c = converttype(c, left.t, t);
1169 code_t*jmp = c = abc_iffalse(c, 0);
1170 c = cut_last_push(c);
1171 c = code_append(c,right.c);
1172 c = converttype(c, right.t, t);
1173 code_t*label = c = abc_label(c);
1174 jmp->branch = label;
1177 code_t* node_andand_exec(node_t*n)
1179 typedcode_t left = n->child[0]->type->read(n->child[0]);\
1180 code_t* right = n->child[1]->type->exec(n->child[1]);\
1182 code_t*jmp = c = abc_iffalse(c, 0);
1183 c = code_append(c, right);
1184 code_t*label = c = abc_label(c);
1185 jmp->branch = label;
1188 constant_t node_andand_eval(node_t*n)
1190 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1192 nodetype_t node_andand = //&&
1195 flags:NODE_HAS_CHILDREN,
1196 eval: node_andand_eval,
1197 write: node_andand_write,
1198 read: node_andand_read,
1199 exec: node_andand_exec
1202 // ----------------------------- !x -----------------------------------
1204 typedcode_t node_not_write(node_t*n)
1206 syntaxerror("can't assign to this expression");
1208 typedcode_t node_not_read(node_t*n)
1216 code_t* node_not_exec(node_t*n)
1221 constant_t node_not_eval(node_t*n)
1223 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1225 nodetype_t node_not =
1228 flags:NODE_HAS_CHILDREN,
1229 eval: node_not_eval,
1230 write: node_not_write,
1231 read: node_not_read,
1235 // ----------------------------- ~x -----------------------------------
1237 typedcode_t node_bitnot_write(node_t*n)
1239 syntaxerror("can't assign to this expression");
1241 typedcode_t node_bitnot_read(node_t*n)
1249 code_t* node_bitnot_exec(node_t*n)
1254 constant_t node_bitnot_eval(node_t*n)
1256 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1258 nodetype_t node_bitnot =
1261 flags:NODE_HAS_CHILDREN,
1262 eval: node_bitnot_eval,
1263 write: node_bitnot_write,
1264 read: node_bitnot_read,
1265 exec: node_bitnot_exec
1268 // ----------------------------- x&y -----------------------------------
1270 typedcode_t node_bitand_write(node_t*n)
1272 syntaxerror("can't assign to this expression");
1274 typedcode_t node_bitand_read(node_t*n)
1276 READ_HEADER_LEFTRIGHT;
1277 c = code_append(left.c,right.c);
1282 code_t* node_bitand_exec(node_t*n)
1284 EXEC_HEADER_LEFTRIGHT;
1285 return code_append(left, right);
1287 constant_t node_bitand_eval(node_t*n)
1289 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1291 nodetype_t node_bitand =
1294 flags:NODE_HAS_CHILDREN,
1295 eval: node_bitand_eval,
1296 write: node_bitand_write,
1297 read: node_bitand_read,
1298 exec: node_bitand_exec
1301 // ----------------------------- x^y -----------------------------------
1303 typedcode_t node_bitxor_write(node_t*n)
1305 syntaxerror("can't assign to this expression");
1307 typedcode_t node_bitxor_read(node_t*n)
1309 READ_HEADER_LEFTRIGHT;
1310 c = code_append(left.c,right.c);
1315 code_t* node_bitxor_exec(node_t*n)
1317 EXEC_HEADER_LEFTRIGHT;
1318 return code_append(left, right);
1320 constant_t node_bitxor_eval(node_t*n)
1322 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1324 nodetype_t node_bitxor =
1327 flags:NODE_HAS_CHILDREN,
1328 eval: node_bitxor_eval,
1329 write: node_bitxor_write,
1330 read: node_bitxor_read,
1331 exec: node_bitxor_exec
1334 // ----------------------------- x|y -----------------------------------
1336 typedcode_t node_bitor_write(node_t*n)
1338 syntaxerror("can't assign to this expression");
1340 typedcode_t node_bitor_read(node_t*n)
1342 READ_HEADER_LEFTRIGHT;
1343 c = code_append(left.c,right.c);
1348 code_t* node_bitor_exec(node_t*n)
1350 EXEC_HEADER_LEFTRIGHT;
1351 return code_append(left, right);
1353 constant_t node_bitor_eval(node_t*n)
1355 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1357 nodetype_t node_bitor =
1360 flags:NODE_HAS_CHILDREN,
1361 eval: node_bitor_eval,
1362 write: node_bitor_write,
1363 read: node_bitor_read,
1364 exec: node_bitor_exec
1367 // ---------------------------- x>>y -----------------------------------
1369 typedcode_t node_shr_write(node_t*n)
1371 syntaxerror("can't assign to this expression");
1373 typedcode_t node_shr_read(node_t*n)
1375 READ_HEADER_LEFTRIGHT;
1376 c = code_append(left.c,right.c);
1381 code_t* node_shr_exec(node_t*n)
1383 EXEC_HEADER_LEFTRIGHT;
1384 return code_append(left, right);
1386 constant_t node_shr_eval(node_t*n)
1388 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1390 nodetype_t node_shr = //>>
1393 flags:NODE_HAS_CHILDREN,
1394 eval: node_shr_eval,
1395 write: node_shr_write,
1396 read: node_shr_read,
1400 // ---------------------------- x<<y -----------------------------------
1402 typedcode_t node_shl_write(node_t*n)
1404 syntaxerror("can't assign to this expression");
1406 typedcode_t node_shl_read(node_t*n)
1408 READ_HEADER_LEFTRIGHT;
1409 c = code_append(left.c,right.c);
1414 code_t* node_shl_exec(node_t*n)
1416 EXEC_HEADER_LEFTRIGHT;
1417 return code_append(left, right);
1419 constant_t node_shl_eval(node_t*n)
1421 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1423 nodetype_t node_shl = //<<
1426 flags:NODE_HAS_CHILDREN,
1427 eval: node_shl_eval,
1428 write: node_shl_write,
1429 read: node_shl_read,
1433 // ---------------------------- x>>>y -----------------------------------
1435 typedcode_t node_ushr_write(node_t*n)
1437 syntaxerror("can't assign to this expression");
1439 typedcode_t node_ushr_read(node_t*n)
1441 READ_HEADER_LEFTRIGHT;
1442 c = code_append(left.c,right.c);
1447 code_t* node_ushr_exec(node_t*n)
1449 EXEC_HEADER_LEFTRIGHT;
1450 return code_append(left, right);
1452 constant_t node_ushr_eval(node_t*n)
1454 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1456 nodetype_t node_ushr = //>>>
1459 flags:NODE_HAS_CHILDREN,
1460 eval: node_ushr_eval,
1461 write: node_ushr_write,
1462 read: node_ushr_read,
1463 exec: node_ushr_exec
1466 // ---------------------------- x in y ----------------------------------
1468 typedcode_t node_in_write(node_t*n)
1470 syntaxerror("can't assign to this expression");
1472 typedcode_t node_in_read(node_t*n)
1474 READ_HEADER_LEFTRIGHT;
1475 c = code_append(left.c,right.c);
1480 code_t* node_in_exec(node_t*n)
1482 EXEC_HEADER_LEFTRIGHT;
1483 return code_append(left, right);
1485 constant_t node_in_eval(node_t*n)
1487 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1489 nodetype_t node_in = //in
1492 flags:NODE_HAS_CHILDREN,
1494 write: node_in_write,
1499 // ---------------------------- x as y ----------------------------------
1501 typedcode_t node_as_write(node_t*n)
1504 syntaxerror("can't assign to this expression");
1506 typedcode_t node_as_read(node_t*n)
1508 READ_HEADER_LEFTRIGHT;
1509 c = code_append(left.c, right.c);
1510 c = abc_astypelate(c);
1511 if(TYPE_IS_CLASS(right.t) && right.t->data) {
1512 t = (classinfo_t*)right.t->data;
1518 code_t* node_as_exec(node_t*n)
1520 /* we assume here that "as" doesn't have side-effects (like
1521 early run time type checking) */
1522 EXEC_HEADER_LEFTRIGHT;
1523 return code_append(left, right);
1525 constant_t node_as_eval(node_t*n)
1527 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1529 nodetype_t node_as = //as
1532 flags:NODE_HAS_CHILDREN,
1534 write: node_as_write,
1539 // ------------------------- x instanceof y -----------------------------
1541 typedcode_t node_instanceof_write(node_t*n)
1543 syntaxerror("can't assign to this expression");
1545 typedcode_t node_instanceof_read(node_t*n)
1547 READ_HEADER_LEFTRIGHT;
1548 c = code_append(left.c, right.c);
1549 c = abc_instanceof(c);
1553 code_t* node_instanceof_exec(node_t*n)
1555 EXEC_HEADER_LEFTRIGHT;
1556 return code_append(left, right);
1558 constant_t node_instanceof_eval(node_t*n)
1560 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1562 nodetype_t node_instanceof = //instanceof
1565 flags:NODE_HAS_CHILDREN,
1566 eval: node_instanceof_eval,
1567 write: node_instanceof_write,
1568 read: node_instanceof_read,
1569 exec: node_instanceof_exec
1572 // ------------------------- x is y --------------------------------------
1574 typedcode_t node_is_write(node_t*n)
1576 syntaxerror("can't assign to this expression");
1578 typedcode_t node_is_read(node_t*n)
1580 READ_HEADER_LEFTRIGHT;
1581 c = code_append(left.c, right.c);
1582 c = abc_istypelate(c);
1586 code_t* node_is_exec(node_t*n)
1588 EXEC_HEADER_LEFTRIGHT;
1589 return code_append(left, right);
1591 constant_t node_is_eval(node_t*n)
1593 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1595 nodetype_t node_is = //is
1598 flags:NODE_HAS_CHILDREN,
1600 write: node_is_write,
1605 // ------------------------- x[y] --------------------------------------
1607 typedcode_t node_arraylookup_write(node_t*n)
1609 syntaxerror("not implemented yet");
1611 typedcode_t node_arraylookup_read(node_t*n)
1613 READ_HEADER_LEFTRIGHT;
1614 c = code_append(left.c, right.c);
1616 /* XXX not sure whether this access logic is correct */
1617 namespace_t ns = {left.t?left.t->access:ACCESS_PACKAGE, ""};
1618 namespace_set_t nsset;
1619 namespace_list_t l;l.next = 0;
1620 nsset.namespaces = &l;
1622 multiname_t m = {MULTINAMEL, 0, &nsset, 0};
1624 c = abc_getproperty2(c, &m);
1625 t = 0; // array elements have unknown type
1628 code_t* node_arraylookup_exec(node_t*n)
1630 EXEC_HEADER_LEFTRIGHT;
1631 return code_append(left, right);
1633 constant_t node_arraylookup_eval(node_t*n)
1635 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1637 nodetype_t node_arraylookup =
1639 name: "arraylookup",
1640 flags:NODE_HAS_CHILDREN,
1641 eval: node_arraylookup_eval,
1642 write: node_arraylookup_write,
1643 read: node_arraylookup_read,
1644 exec: node_arraylookup_exec
1647 // ------------------------- typeof(x) ------------------------------------
1649 typedcode_t node_typeof_write(node_t*n)
1651 syntaxerror("can't assign to this expression");
1653 typedcode_t node_typeof_read(node_t*n)
1661 code_t* node_typeof_exec(node_t*n)
1666 constant_t node_typeof_eval(node_t*n)
1668 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1670 nodetype_t node_typeof = //typeof
1673 flags:NODE_HAS_CHILDREN,
1674 eval: node_typeof_eval,
1675 write: node_typeof_write,
1676 read: node_typeof_read,
1677 exec: node_typeof_exec
1680 // ------------------------- (void)(x) ------------------------------------
1682 typedcode_t node_void_write(node_t*n)
1684 syntaxerror("can't assign to this expression");
1686 typedcode_t node_void_read(node_t*n)
1688 code_t*c = n->type->exec(n);
1689 c = abc_pushundefined(c);
1690 classinfo_t*t = TYPE_ANY;
1693 code_t* node_void_exec(node_t*n)
1698 constant_t node_void_eval(node_t*n)
1700 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1702 nodetype_t node_void = //void
1705 flags:NODE_HAS_CHILDREN,
1706 eval: node_void_eval,
1707 write: node_void_write,
1708 read: node_void_read,
1709 exec: node_void_exec
1712 // ---------------------------- -x ----------------------------------------
1714 typedcode_t node_neg_write(node_t*n)
1716 syntaxerror("can't assign to this expression");
1718 typedcode_t node_neg_read(node_t*n)
1723 c = abc_negate_i(c);
1731 code_t* node_neg_exec(node_t*n)
1736 constant_t node_neg_eval(node_t*n)
1738 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1740 nodetype_t node_neg = //-
1743 flags:NODE_HAS_CHILDREN,
1744 eval: node_neg_eval,
1745 write: node_neg_write,
1746 read: node_neg_read,
1750 // ---------------------------- x*=y ----------------------------------------
1752 typedcode_t node_muleq_write(node_t*n)
1754 syntaxerror("can't assign to this expression");
1756 typedcode_t node_muleq_read(node_t*n)
1758 READ_HEADER_LEFTRIGHT;
1761 if(BOTH_INT(left.t,right.t)) {
1762 c=abc_multiply_i(c);
1768 c=converttype(c, f, left.t);
1769 c = toreadwrite(left.c, c, 0, 0, 1);
1773 code_t* node_muleq_exec(node_t*n)
1775 READ_HEADER_LEFTRIGHT;
1778 if(BOTH_INT(left.t,right.t)) {
1779 c=abc_multiply_i(c);
1785 c = converttype(c, f, left.t);
1786 return toreadwrite(left.c, c, 0, 0, 0);
1788 constant_t node_muleq_eval(node_t*n)
1790 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1792 nodetype_t node_muleq =
1795 flags:NODE_HAS_CHILDREN,
1796 eval: node_muleq_eval,
1797 write: node_muleq_write,
1798 read: node_muleq_read,
1799 exec: node_muleq_exec
1802 // ---------------------------- x%=y ----------------------------------------
1804 typedcode_t node_modeq_write(node_t*n)
1806 syntaxerror("can't assign to this expression");
1808 typedcode_t node_modeq_read(node_t*n)
1810 READ_HEADER_LEFTRIGHT;
1811 c = abc_modulo(right.c);
1812 c = converttype(c, TYPE_NUMBER, left.t);
1813 c = toreadwrite(left.c, c, 0, 0, 1);
1817 code_t* node_modeq_exec(node_t*n)
1819 READ_HEADER_LEFTRIGHT;
1820 c = abc_modulo(right.c);
1821 c = converttype(c, TYPE_NUMBER, left.t);
1822 return toreadwrite(left.c, c, 0, 0, 0);
1824 constant_t node_modeq_eval(node_t*n)
1826 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1828 nodetype_t node_modeq = //%=
1831 flags:NODE_HAS_CHILDREN,
1832 eval: node_modeq_eval,
1833 write: node_modeq_write,
1834 read: node_modeq_read,
1835 exec: node_modeq_exec
1838 // ---------------------------- x<<=y ----------------------------------------
1840 typedcode_t node_shleq_write(node_t*n)
1842 syntaxerror("can't assign to this expression");
1844 typedcode_t node_shleq_read(node_t*n)
1846 READ_HEADER_LEFTRIGHT;
1847 c = abc_lshift(right.c);
1848 c = converttype(c, TYPE_INT, left.t);
1849 c = toreadwrite(left.c, c, 0, 0, 1);
1853 code_t* node_shleq_exec(node_t*n)
1855 READ_HEADER_LEFTRIGHT;
1856 c = abc_lshift(right.c);
1857 c = converttype(c, TYPE_INT, left.t);
1858 return toreadwrite(left.c, c, 0, 0, 0);
1860 constant_t node_shleq_eval(node_t*n)
1862 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1864 nodetype_t node_shleq = //<<=
1867 flags:NODE_HAS_CHILDREN,
1868 eval: node_shleq_eval,
1869 write: node_shleq_write,
1870 read: node_shleq_read,
1871 exec: node_shleq_exec
1874 // ---------------------------- x>>=y ----------------------------------------
1876 typedcode_t node_shreq_write(node_t*n)
1878 syntaxerror("can't assign to this expression");
1880 typedcode_t node_shreq_read(node_t*n)
1882 READ_HEADER_LEFTRIGHT;
1883 c = abc_rshift(right.c);
1884 c = converttype(c, TYPE_INT, left.t);
1885 c = toreadwrite(left.c, c, 0, 0, 1);
1889 code_t* node_shreq_exec(node_t*n)
1891 READ_HEADER_LEFTRIGHT;
1892 c = abc_rshift(right.c);
1893 c = converttype(c, TYPE_INT, left.t);
1894 return toreadwrite(left.c, c, 0, 0, 0);
1896 constant_t node_shreq_eval(node_t*n)
1898 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1900 nodetype_t node_shreq = //>>=
1903 flags:NODE_HAS_CHILDREN,
1904 eval: node_shreq_eval,
1905 write: node_shreq_write,
1906 read: node_shreq_read,
1907 exec: node_shreq_exec
1910 // --------------------------- x>>>=y ----------------------------------------
1912 typedcode_t node_ushreq_write(node_t*n)
1914 syntaxerror("can't assign to this expression");
1916 typedcode_t node_ushreq_read(node_t*n)
1918 READ_HEADER_LEFTRIGHT;
1919 c = abc_urshift(right.c);
1920 c = converttype(c, TYPE_UINT, left.t);
1921 c = toreadwrite(left.c, c, 0, 0, 1);
1925 code_t* node_ushreq_exec(node_t*n)
1927 READ_HEADER_LEFTRIGHT;
1928 c = abc_urshift(right.c);
1929 c = converttype(c, TYPE_UINT, left.t);
1930 return toreadwrite(left.c, c, 0, 0, 0);
1932 constant_t node_ushreq_eval(node_t*n)
1934 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1936 nodetype_t node_ushreq = //>>>=
1939 flags:NODE_HAS_CHILDREN,
1940 eval: node_ushreq_eval,
1941 write: node_ushreq_write,
1942 read: node_ushreq_read,
1943 exec: node_ushreq_exec
1946 // --------------------------- x/=y ----------------------------------------
1948 typedcode_t node_diveq_write(node_t*n)
1950 syntaxerror("can't assign to this expression");
1952 typedcode_t node_diveq_read(node_t*n)
1954 READ_HEADER_LEFTRIGHT;
1955 c = abc_divide(right.c);
1956 c = converttype(c, TYPE_NUMBER, left.t);
1957 c = toreadwrite(left.c, c, 0, 0, 1);
1961 code_t* node_diveq_exec(node_t*n)
1963 READ_HEADER_LEFTRIGHT;
1964 c = abc_divide(right.c);
1965 c = converttype(c, TYPE_NUMBER, left.t);
1966 return toreadwrite(left.c, c, 0, 0, 0);
1968 constant_t node_diveq_eval(node_t*n)
1970 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1972 nodetype_t node_diveq =
1975 flags:NODE_HAS_CHILDREN,
1976 eval: node_diveq_eval,
1977 write: node_diveq_write,
1978 read: node_diveq_read,
1979 exec: node_diveq_exec
1982 // --------------------------- x|=y ----------------------------------------
1984 typedcode_t node_bitoreq_write(node_t*n)
1986 syntaxerror("can't assign to this expression");
1988 typedcode_t node_bitoreq_read(node_t*n)
1990 READ_HEADER_LEFTRIGHT;
1991 c = abc_bitor(right.c);
1992 c = converttype(c, TYPE_INT, left.t);
1993 c = toreadwrite(left.c, c, 0, 0, 1);
1997 code_t* node_bitoreq_exec(node_t*n)
1999 READ_HEADER_LEFTRIGHT;
2000 c = abc_bitor(right.c);
2001 c = converttype(c, TYPE_INT, left.t);
2002 return toreadwrite(left.c, c, 0, 0, 0);
2004 constant_t node_bitoreq_eval(node_t*n)
2006 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2008 nodetype_t node_bitoreq = //|=
2011 flags:NODE_HAS_CHILDREN,
2012 eval: node_bitoreq_eval,
2013 write: node_bitoreq_write,
2014 read: node_bitoreq_read,
2015 exec: node_bitoreq_exec
2018 // --------------------------- x^=y ----------------------------------------
2020 typedcode_t node_bitxoreq_write(node_t*n)
2022 syntaxerror("can't assign to this expression");
2024 typedcode_t node_bitxoreq_read(node_t*n)
2026 READ_HEADER_LEFTRIGHT;
2027 c = abc_bitxor(right.c);
2028 c = converttype(c, TYPE_INT, left.t);
2029 c = toreadwrite(left.c, c, 0, 0, 1);
2033 code_t* node_bitxoreq_exec(node_t*n)
2035 READ_HEADER_LEFTRIGHT;
2036 c = abc_bitxor(right.c);
2037 c = converttype(c, TYPE_INT, left.t);
2038 return toreadwrite(left.c, c, 0, 0, 0);
2040 constant_t node_bitxoreq_eval(node_t*n)
2042 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2044 nodetype_t node_bitxoreq = //^=
2047 flags:NODE_HAS_CHILDREN,
2048 eval: node_bitxoreq_eval,
2049 write: node_bitxoreq_write,
2050 read: node_bitxoreq_read,
2051 exec: node_bitxoreq_exec
2054 // --------------------------- x&=y ----------------------------------------
2056 typedcode_t node_bitandeq_write(node_t*n)
2058 syntaxerror("can't assign to this expression");
2060 typedcode_t node_bitandeq_read(node_t*n)
2062 READ_HEADER_LEFTRIGHT;
2063 c = abc_bitand(right.c);
2064 c = converttype(c, TYPE_INT, left.t);
2065 c = toreadwrite(left.c, c, 0, 0, 1);
2069 code_t* node_bitandeq_exec(node_t*n)
2071 READ_HEADER_LEFTRIGHT;
2072 c = abc_bitand(right.c);
2073 c = converttype(c, TYPE_INT, left.t);
2074 return toreadwrite(left.c, c, 0, 0, 0);
2076 constant_t node_bitandeq_eval(node_t*n)
2078 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2080 nodetype_t node_bitandeq = //^=
2083 flags:NODE_HAS_CHILDREN,
2084 eval: node_bitandeq_eval,
2085 write: node_bitandeq_write,
2086 read: node_bitandeq_read,
2087 exec: node_bitandeq_exec
2090 // --------------------------- x+=y ----------------------------------------
2092 typedcode_t node_pluseq_write(node_t*n)
2094 syntaxerror("can't assign to this expression");
2096 typedcode_t node_pluseq_read(node_t*n)
2098 READ_HEADER_LEFTRIGHT;
2100 if(TYPE_IS_INT(left.t)) {
2104 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2106 c = toreadwrite(left.c, c, 0, 0, 1);
2110 code_t* node_pluseq_exec(node_t*n)
2112 READ_HEADER_LEFTRIGHT;
2114 if(TYPE_IS_INT(left.t)) {
2118 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2120 return toreadwrite(left.c, c, 0, 0, 0);
2122 constant_t node_pluseq_eval(node_t*n)
2124 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2126 nodetype_t node_pluseq = //+=
2129 flags:NODE_HAS_CHILDREN,
2130 eval: node_pluseq_eval,
2131 write: node_pluseq_write,
2132 read: node_pluseq_read,
2133 exec: node_pluseq_exec
2136 // --------------------------- x-=y ----------------------------------------
2138 typedcode_t node_minuseq_write(node_t*n)
2140 syntaxerror("can't assign to this expression");
2142 typedcode_t node_minuseq_read(node_t*n)
2144 READ_HEADER_LEFTRIGHT;
2146 if(TYPE_IS_INT(left.t)) {
2147 c = abc_subtract_i(c);
2149 c = abc_subtract(c);
2150 c = converttype(c, TYPE_NUMBER, left.t);
2152 c = toreadwrite(left.c, c, 0, 0, 1);
2156 code_t* node_minuseq_exec(node_t*n)
2158 READ_HEADER_LEFTRIGHT;
2160 if(TYPE_IS_INT(left.t)) {
2161 c = abc_subtract_i(c);
2163 c = abc_subtract(c);
2164 c = converttype(c, TYPE_NUMBER, left.t);
2166 return toreadwrite(left.c, c, 0, 0, 0);
2168 constant_t node_minuseq_eval(node_t*n)
2170 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2172 nodetype_t node_minuseq = //-=
2175 flags:NODE_HAS_CHILDREN,
2176 eval: node_minuseq_eval,
2177 write: node_minuseq_write,
2178 read: node_minuseq_read,
2179 exec: node_minuseq_exec
2182 // --------------------------- x=y -----------------------------------------
2184 typedcode_t node_assign_write(node_t*n)
2186 syntaxerror("can't assign to this expression");
2188 typedcode_t node_assign_read(node_t*n)
2190 READ_HEADER_LEFTRIGHT;
2192 c = converttype(c, right.t, left.t);
2193 c = toreadwrite(left.c, c, 1, 0, 1);
2197 code_t* node_assign_exec(node_t*n)
2199 READ_HEADER_LEFTRIGHT;
2201 c = converttype(c, right.t, left.t);
2202 return toreadwrite(left.c, c, 1, 0, 0);
2204 constant_t node_assign_eval(node_t*n)
2206 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2208 nodetype_t node_assign =
2211 flags:NODE_HAS_CHILDREN,
2212 eval: node_assign_eval,
2213 write: node_assign_write,
2214 read: node_assign_read,
2215 exec: node_assign_exec
2218 // --------------------------- x?y1:y2 --------------------------------------
2220 typedcode_t node_tenary_write(node_t*n)
2222 /* TODO: this might actually be kinda useful.
2223 (global?global.x:this.x) = 3;
2225 syntaxerror("can't assign to this expression");
2227 typedcode_t node_tenary_read(node_t*n)
2229 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2230 typedcode_t left = n->child[1]->type->read(n->child[1]);
2231 typedcode_t right = n->child[2]->type->read(n->child[2]);
2232 classinfo_t*t = join_types(left.t,right.t,&node_tenary);
2234 code_t*j1 = c = abc_iffalse(c, 0);
2235 c = code_append(c, left.c);
2236 c = converttype(c, left.t, t);
2237 code_t*j2 = c = abc_jump(c, 0);
2238 c = j1->branch = abc_label(c);
2239 c = code_append(c, right.c);
2240 c = converttype(c, right.t, t);
2241 c = j2->branch = abc_label(c);
2244 code_t* node_tenary_exec(node_t*n)
2246 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2247 code_t* left = n->child[1]->type->exec(n->child[1]);
2248 code_t* right = n->child[2]->type->exec(n->child[2]);
2250 code_t*j1 = c = abc_iffalse(c, 0);
2251 c = code_append(c, left);
2252 code_t*j2 = c = abc_jump(c, 0);
2253 c = j1->branch = abc_label(c);
2254 c = code_append(c, right);
2255 c = j2->branch = abc_label(c);
2258 constant_t node_tenary_eval(node_t*n)
2260 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2262 nodetype_t node_tenary =
2265 flags:NODE_HAS_CHILDREN,
2266 eval: node_tenary_eval,
2267 write: node_tenary_write,
2268 read: node_tenary_read,
2269 exec: node_tenary_exec
2272 // ---------------------------- comma ----------------------------------------
2274 typedcode_t node_comma_write(node_t*n)
2276 syntaxerror("can't assign to this expression");
2278 typedcode_t node_comma_read(node_t*n)
2283 for(i=0;i<n->num_children-1;i++) {
2284 c = code_append(c, n->child[i]->type->exec(n->child[i]));
2286 typedcode_t o = n->child[i]->type->read(n->child[i]);
2287 c = code_append(c, o.c);
2291 code_t* node_comma_exec(node_t*n)
2295 for(t=0;t<n->num_children;t++) {
2296 c = code_append(c, n->child[t]->type->exec(n->child[t]));
2300 constant_t node_comma_eval(node_t*n)
2302 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2304 nodetype_t node_comma =
2307 flags: NODE_HAS_CHILDREN,
2308 eval: node_comma_eval,
2309 write: node_comma_write,
2310 read: node_comma_read,
2311 exec: node_comma_exec
2316 // -------------------------- new x -----------------------------------
2318 typedcode_t node_new_write(node_t*n)
2321 typedcode_t node_new_read(node_t*n)
2324 code_t* node_new_exec(node_t*n)
2327 constant_t node_new_eval(node_t*n)
2329 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2331 nodetype_t node_new = //new
2333 write: node_new_write,
2334 read: node_new_read,
2335 eval: node_new_eval,
2339 // ------------------------ delete x ----------------------------------
2341 typedcode_t node_delete_write(node_t*n)
2344 typedcode_t node_delete_read(node_t*n)
2347 code_t* node_delete_exec(node_t*n)
2350 constant_t node_delete_eval(node_t*n)
2352 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2354 nodetype_t node_delete = //delete
2356 write: node_delete_write,
2357 read: node_delete_read,
2358 eval: node_delete_eval,
2359 exec: node_delete_exec
2362 // ---------------------------- x.y -----------------------------------
2364 typedcode_t node_dot_write(node_t*n)
2367 typedcode_t node_dot_read(node_t*n)
2370 code_t* node_dot_exec(node_t*n)
2373 constant_t node_dot_eval(node_t*n)
2375 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2377 nodetype_t node_dot =
2379 write: node_dot_write,
2380 read: node_dot_read,
2381 eval: node_dot_eval,
2385 // --------------------------- x..y -----------------------------------
2387 typedcode_t node_dotdot_write(node_t*n)
2390 typedcode_t node_dotdot_read(node_t*n)
2393 code_t* node_dotdot_exec(node_t*n)
2397 constant_t node_dotdot_eval(node_t*n)
2399 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2401 nodetype_t node_dotdot = //..
2403 write: node_dotdot_write,
2404 read: node_dotdot_read,
2405 eval: node_dotdot_eval,
2406 exec: node_dotdot_exec
2409 // --------------------------- x.@y -----------------------------------
2411 typedcode_t node_dotat_write(node_t*n)
2414 typedcode_t node_dotat_read(node_t*n)
2417 code_t* node_dotat_exec(node_t*n)
2420 constant_t node_dotat_eval(node_t*n)
2422 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2424 nodetype_t node_dotat = //.@
2426 write: node_dotat_write,
2427 read: node_dotat_read,
2428 eval: node_dotat_eval,
2429 exec: node_dotat_exec
2432 // --------------------------- x.*y -----------------------------------
2434 typedcode_t node_dotstar_write(node_t*n)
2437 typedcode_t node_dotstar_read(node_t*n)
2440 code_t* node_dotstar_exec(node_t*n)
2443 constant_t node_dotstar_eval(node_t*n)
2445 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2447 nodetype_t node_dotstar = //.*
2449 write: node_dotstar_write,
2450 read: node_dotstar_read,
2451 eval: node_dotstar_eval,
2452 exec: node_dotstar_exec
2455 // -------------------------- x.(y) -----------------------------------
2457 typedcode_t node_filter_write(node_t*n)
2460 typedcode_t node_filter_read(node_t*n)
2463 code_t* node_filter_exec(node_t*n)
2466 constant_t node_filter_eval(node_t*n)
2468 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2470 nodetype_t node_filter = //.(
2472 write: node_filter_write,
2473 read: node_filter_read,
2474 eval: node_filter_eval,
2475 exec: node_filter_exec
2478 // ------------------------ x(y1,...,yn) ------------------------------
2480 typedcode_t node_call_write(node_t*n)
2483 typedcode_t node_call_read(node_t*n)
2486 code_t* node_call_exec(node_t*n)
2489 constant_t node_call_eval(node_t*n)
2491 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2493 nodetype_t node_call = //functioncall
2495 write: node_call_write,
2496 read: node_call_read,
2497 eval: node_call_eval,
2498 exec: node_call_exec
2501 // ------------------------------ @x ----------------------------------------
2503 typedcode_t node_at_write(node_t*n)
2506 typedcode_t node_at_read(node_t*n)
2509 code_t* node_at_exec(node_t*n)
2512 constant_t node_at_eval(node_t*n)
2514 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2516 nodetype_t node_at = //@
2518 write: node_at_write,
2524 // ---------------------------- x.ns::y ----------------------------------------
2526 typedcode_t node_dotns_write(node_t*n)
2529 typedcode_t node_dotns_read(node_t*n)
2532 code_t* node_dotns_exec(node_t*n)
2535 constant_t node_dotns_eval(node_t*n)
2537 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2539 nodetype_t node_dotns = //.::
2541 write: node_dotns_write,
2542 read: node_dotns_read,
2543 eval: node_dotns_eval,
2544 exec: node_dotns_exec
2548 // ------------------------ constant ------------------------------
2550 typedcode_t node_const_write(node_t*n)
2552 syntaxerror("can't assign a value to a constant");
2554 typedcode_t node_const_read(node_t*n)
2556 constant_t*v = n->value;
2561 if(v->i>-128 && v->i<128) {
2562 c = abc_pushbyte(0,v->i);
2563 } else if(v->i>=-32768 && v->i<32768) {
2564 c = abc_pushshort(0,v->i);
2566 c = abc_pushint(0,v->i);
2571 c = abc_pushuint(0,v->u);
2573 c = abc_pushbyte(0,v->u);
2574 } else if(v->u<32768) {
2575 c = abc_pushshort(0,v->u);
2577 c = abc_pushint(0,v->u);
2581 case CONSTANT_FLOAT:
2582 c = abc_pushdouble(0,v->f);
2586 c = abc_pushtrue(0);
2589 case CONSTANT_FALSE:
2590 c = abc_pushfalse(0);
2594 c = abc_pushnull(0);
2597 case CONSTANT_STRING:
2598 c = abc_pushstring2(0,v->s);
2601 case CONSTANT_UNDEFINED:
2602 c = abc_pushundefined(0);
2605 case CONSTANT_NAMESPACE:
2606 case CONSTANT_NAMESPACE_PACKAGE:
2607 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
2608 case CONSTANT_NAMESPACE_PROTECTED:
2609 case CONSTANT_NAMESPACE_EXPLICIT:
2610 case CONSTANT_NAMESPACE_STATICPROTECTED:
2611 case CONSTANT_NAMESPACE_PRIVATE:
2612 c = abc_pushnamespace(0, v->ns);
2614 case CONSTANT_UNKNOWN:
2615 syntaxerror("internal error: invalid constant");
2618 syntaxerror("invalid constant (%d)", v->type);
2624 code_t* node_const_exec(node_t*n)
2628 constant_t node_const_eval(node_t*n)
2630 constant_t*c = constant_clone(n->value);
2632 free(c); //shallow free
2635 nodetype_t node_const =
2639 eval: node_const_eval,
2640 write: node_const_write,
2641 read: node_const_read,
2642 exec: node_const_exec
2645 // ------------------------ code node ------------------------------
2647 typedcode_t node_code_write(node_t*n)
2649 syntaxerror("not implemented yet");
2651 typedcode_t node_code_read(node_t*n)
2659 code_t* node_code_exec(node_t*n)
2661 code_t*c = code_dup(n->code.c);
2662 c = cut_last_push(c);
2665 constant_t node_code_eval(node_t*n)
2667 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2669 nodetype_t node_code =
2673 eval: node_code_eval,
2674 write: node_code_write,
2675 read: node_code_read,
2676 exec: node_code_exec
2679 // ------------------------ dummy node ------------------------------
2681 typedcode_t node_dummy_write(node_t*n)
2683 syntaxerror("not implemented yet");
2685 typedcode_t node_dummy_read(node_t*n)
2688 t.c = abc_pushundefined(0);
2692 code_t* node_dummy_exec(node_t*n)
2696 constant_t node_dummy_eval(node_t*n)
2698 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2700 nodetype_t node_dummy =
2704 eval: node_dummy_eval,
2705 write: node_dummy_write,
2706 read: node_dummy_read,
2707 exec: node_dummy_exec
2710 // ======================== node handling ==============================
2712 node_t* mkdummynode()
2714 node_t*n = (node_t*)rfx_calloc(sizeof(node_t));
2715 n->type = &node_dummy;
2719 node_t* mkconstnode(constant_t*c)
2721 node_t*n = (node_t*)malloc(sizeof(node_t));
2722 n->type = &node_const;
2728 node_t* mkcodenode(typedcode_t c)
2730 node_t*n = (node_t*)malloc(sizeof(node_t));
2731 n->type = &node_code;
2737 node_t* mkmultinode(nodetype_t*t, node_t*one)
2739 node_t*n = (node_t*)malloc(sizeof(node_t));
2742 n->child = (node_t**)malloc(sizeof(node_t*)*1);
2744 n->num_children = 1;
2748 node_t* mkstringnode(const char*s)
2750 return mkconstnode(constant_new_string(s));
2753 node_t* mkaddnode(node_t*n1, node_t*n2)
2755 return mknode2(&node_plus, n1, n2);
2758 node_t* multinode_extend(node_t*n, node_t*add)
2760 n->child = realloc(n->child, (n->num_children+1)*sizeof(node_t*));
2761 n->child[n->num_children] = add;
2766 node_t* mknode1(nodetype_t*t, node_t*node)
2768 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*2);
2769 node_t**x = (node_t**)&n[1];
2773 n->num_children = 1;
2779 node_t* mknode2(nodetype_t*t, node_t*left, node_t*right)
2781 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*3);
2782 node_t**x = (node_t**)&n[1];
2786 n->num_children = 2;
2792 node_t* mknode3(nodetype_t*t, node_t*one, node_t*two, node_t*three)
2794 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*4);
2795 node_t**x = (node_t**)&n[1];
2799 n->num_children = 3;
2807 void node_free(node_t*n)
2810 if(n->type == &node_code) {
2812 code_free(n->code.c);n->code.c = 0;
2814 } else if(n->type == &node_const) {
2815 /* keep, this is not our reference */
2816 } else for(t=0;t<n->num_children;t++) {
2817 node_free(n->child[t]);n->child[t] = 0;
2822 typedcode_t node_read(node_t*n)
2824 constant_t c = n->type->eval(n);
2825 if(c.type == CONSTANT_UNKNOWN) {
2826 typedcode_t t = n->type->read(n);
2830 typedcode_t t = push_constant(&c);
2835 code_t* node_exec(node_t*n)
2837 code_t*c = n->type->exec(n);
2841 constant_t node_eval(node_t*n)
2843 constant_t c = n->type->eval(n);
2861 void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
2863 if(n->type->flags&NODE_HAS_CHILDREN) {
2864 fprintf(fi, "%s%s\n", p1, n->type->name);
2866 char*o2 = malloc(strlen(p2)+3);
2867 strcpy(o2, p2);strcat(o2, "| ");
2868 char*o3 = malloc(strlen(p2)+3);
2869 strcpy(o3, p2);strcat(o3, "+-");
2870 char*o4 = malloc(strlen(p2)+3);
2871 strcpy(o4, p2);strcat(o4, " ");
2873 for(t=0;t<n->num_children;t++) {
2874 fprintf(fi, "%s\n", o2);
2875 node_dump2(n->child[t], o3, t<n->num_children-1?o2:o4, fi);
2880 } else if(n->type == &node_const) {
2881 char*s = constant_tostring(n->value);
2882 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
2884 } else if(n->type == &node_code) {
2885 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, n->code.t?n->code.t->name:"*");
2886 code_dump2(n->code.c, 0, 0, (char*)p2, fi);
2888 fprintf(fi, "%s%s\n", p1, n->type->name);
2892 void node_dump(node_t*n)
2894 printf("------------VVVV---------------\n");
2895 node_dump2(n,"","",stdout);
2896 printf("-------------------------------\n");