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 ||
149 m->type == RTQNAME || m->type == RTQNAMEA) {
151 /* dupping two values on the stack requires 5 operations and one register-
152 couldn't adobe just have given us a dup2? */
153 int temp = gettempvar();
154 prefix = abc_setlocal(prefix, temp);
155 prefix = abc_dup(prefix);
156 prefix = abc_getlocal(prefix, temp);
157 prefix = abc_swap(prefix);
158 prefix = abc_getlocal(prefix, temp);
160 prefix = abc_kill(prefix, temp);
164 syntaxerror("illegal lvalue: can't assign a value to this expression (not a qname/multiname)");
166 } else if(r->opcode == OPCODE_GETSLOT) {
167 write->opcode = OPCODE_SETSLOT;
168 write->data[0] = r->data[0];
170 prefix = abc_dup(prefix); // we need the object, too
173 } else if(r->opcode == OPCODE_GETLOCAL) {
174 write->opcode = OPCODE_SETLOCAL;
175 write->data[0] = r->data[0];
176 } else if(r->opcode == OPCODE_GETLOCAL_0) {
177 write->opcode = OPCODE_SETLOCAL_0;
178 } else if(r->opcode == OPCODE_GETLOCAL_1) {
179 write->opcode = OPCODE_SETLOCAL_1;
180 } else if(r->opcode == OPCODE_GETLOCAL_2) {
181 write->opcode = OPCODE_SETLOCAL_2;
182 } else if(r->opcode == OPCODE_GETLOCAL_3) {
183 write->opcode = OPCODE_SETLOCAL_3;
184 } else if(r->opcode == OPCODE_GETSUPER) {
185 write->opcode = OPCODE_SETSUPER;
186 multiname_t*m = (multiname_t*)r->data[0];
187 write->data[0] = multiname_clone(m);
190 syntaxerror("illegal lvalue: can't assign a value to this expression");
197 /* with getproperty/getslot, we have to be extra careful not
198 to execute the read code twice, as it might have side-effects
199 (e.g. if the property is in fact a setter/getter combination)
201 So read the value, modify it, and write it again,
202 using prefix only once and making sure (by using a temporary
203 register) that the return value is what we just wrote */
205 c = code_append(c, prefix);
206 c = code_append(c, r);
207 if(pushvalue && readbefore) {
209 c = abc_setlocal(c, temp);
211 c = code_append(c, middlepart);
212 if(pushvalue && !readbefore) {
214 c = abc_setlocal(c, temp);
216 c = code_append(c, write);
218 c = abc_getlocal(c, temp);
219 c = abc_kill(c, temp);
222 /* if we're allowed to execute the read code twice *and*
223 the middlepart doesn't modify the code, things are easier.
225 //c = code_append(c, prefix);
226 if(prefix) syntaxerror("internal error (prefix)");
231 c = code_append(c, r);
232 c = code_append(c, middlepart);
233 c = code_append(c, write);
235 c = code_append(c, r2);
239 /* even smaller version: overwrite the value without reading
243 c = code_append(c, prefix);
246 c = code_append(c, middlepart);
247 c = code_append(c, write);
249 c = code_append(c, r);
255 c = code_append(c, prefix);
257 c = code_append(c, middlepart);
260 c = abc_setlocal(c, temp);
262 c = code_append(c, write);
264 c = abc_getlocal(c, temp);
265 c = abc_kill(c, temp);
272 typedcode_t push_constant(constant_t*v)
276 case CONSTANT_INT: t.c = abc_pushint(0, v->i);t.t = TYPE_INT;break;
277 case CONSTANT_UINT: t.c = abc_pushuint(0, v->u);t.t = TYPE_UINT;break;
278 case CONSTANT_FLOAT: t.c = abc_pushdouble(0, v->f);t.t = TYPE_FLOAT;break;
279 case CONSTANT_TRUE: t.c = abc_pushtrue(0);t.t = TYPE_BOOLEAN;break;
280 case CONSTANT_FALSE: t.c = abc_pushfalse(0);t.t = TYPE_BOOLEAN;break;
281 case CONSTANT_STRING: t.c = abc_pushstring2(0, v->s);t.t = TYPE_STRING;break;
282 case CONSTANT_NULL: t.c = abc_pushnull(0);t.t = TYPE_NULL;break;
283 case CONSTANT_UNDEFINED: t.c = abc_pushundefined(0);t.t = TYPE_ANY;break;
284 case CONSTANT_NAMESPACE:
285 case CONSTANT_NAMESPACE_PACKAGE:
286 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
287 case CONSTANT_NAMESPACE_PROTECTED:
288 case CONSTANT_NAMESPACE_EXPLICIT:
289 case CONSTANT_NAMESPACE_STATICPROTECTED:
290 case CONSTANT_NAMESPACE_PRIVATE:
291 t.c = abc_pushnamespace(0, v->ns);t.t = TYPE_NAMESPACE;break;
293 syntaxerror("internal error: bad constant");
298 code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to);
300 int constant_to_int(constant_t*c)
303 case CONSTANT_INT: return c->i;
304 case CONSTANT_UINT: return (int)c->u;
305 case CONSTANT_FLOAT: return c->f;
306 case CONSTANT_TRUE: return 1;
307 case CONSTANT_FALSE: return 0;
308 case CONSTANT_STRING: return atoi(c->s->str);
309 default: syntaxerror("can't convert this constant to an integer");
313 double constant_to_float(constant_t*c)
316 case CONSTANT_INT: return (double)c->i;
317 case CONSTANT_UINT: return (double)c->u;
318 case CONSTANT_FLOAT: return c->f;
319 case CONSTANT_TRUE: return (double)1;
320 case CONSTANT_FALSE: return (double)0;
321 case CONSTANT_STRING: return atof(c->s->str);
322 default: syntaxerror("can't convert this constant to a float");
326 // -------------------------- x + y -----------------------------------
328 typedcode_t node_plus_write(node_t*n)
330 syntaxerror("can't assign to this expression");
332 typedcode_t node_plus_read(node_t*n)
334 READ_HEADER_LEFTRIGHT;
335 c = code_append(left.c, right.c);
336 if(BOTH_INT(left.t, right.t)) {
341 t = join_types(left.t,right.t,n->type);
345 code_t* node_plus_exec(node_t*n)
347 EXEC_HEADER_LEFTRIGHT;
348 return code_append(left, right);
350 constant_t node_plus_eval(node_t*n)
352 EVAL_HEADER_LEFTRIGHT;
353 char left_int = left.type == CONSTANT_INT || left.type == CONSTANT_UINT;
354 if(left_int && (right.type == CONSTANT_INT || right.type == CONSTANT_UINT)) {
355 int i = constant_to_int(&left) + constant_to_int(&right);
356 r.type = CONSTANT_INT;
358 } else if(left_int && right.type == CONSTANT_FLOAT) {
359 double f = constant_to_int(&left) + constant_to_float(&right);
360 r.type = CONSTANT_FLOAT;
362 } else if(left.type == CONSTANT_STRING) {
363 char*add = constant_tostring(&right);
364 int l1 = left.s->len;
365 int l2 = strlen(add);
366 char*s = malloc(l1+l2+1);
367 memcpy(s, left.s->str, l1);
368 memcpy(s+l1, add, l2);
370 r.type = CONSTANT_STRING;
371 r.s = malloc(sizeof(string_t));
376 r.type = CONSTANT_UNKNOWN;
380 nodetype_t node_plus =
383 flags:NODE_HAS_CHILDREN,
385 write:node_plus_write,
390 // -------------------------- x - y -----------------------------------
392 typedcode_t node_minus_write(node_t*n)
394 syntaxerror("can't assign to this expression");
396 typedcode_t node_minus_read(node_t*n)
398 READ_HEADER_LEFTRIGHT;
399 c = code_append(left.c, right.c);
400 if(BOTH_INT(left.t,right.t)) {
401 c = abc_subtract_i(c);
409 code_t* node_minus_exec(node_t*n)
411 EXEC_HEADER_LEFTRIGHT;
412 return code_append(left, right);
414 constant_t node_minus_eval(node_t*n)
416 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
418 nodetype_t node_minus =
421 flags:NODE_HAS_CHILDREN,
422 eval: node_minus_eval,
423 write: node_minus_write,
424 read: node_minus_read,
425 exec: node_minus_exec
428 // ---------------------------- ++x -----------------------------------
430 typedcode_t node_lplusplus_write(node_t*n)
432 syntaxerror("can't assign to this expression");
434 typedcode_t node_lplusplus_read(node_t*n)
438 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
439 int nr = getlocalnr(x.c);
440 code_free(x.c);x.c=0;
441 if(TYPE_IS_INT(x.t)) {
442 c = abc_inclocal_i(c, nr);
443 c = abc_getlocal(c, nr);
444 } else if(TYPE_IS_NUMBER(x.t)) {
445 c = abc_inclocal(c, nr);
446 c = abc_getlocal(c, nr);
447 } else syntaxerror("internal error");
449 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
450 c = abc_increment_i(c);
453 c = abc_increment(c);
456 c = converttype(c, t, x.t);
457 c = toreadwrite(x.c, c, 0, 0, 1);
462 code_t* node_lplusplus_exec(node_t*n)
464 typedcode_t x = n->child[0]->type->read(n->child[0]);
466 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
467 int nr = getlocalnr(x.c);
468 code_free(x.c);x.c=0;
469 if(TYPE_IS_INT(x.t)) {
470 c = abc_inclocal_i(c, nr);
471 } else if(TYPE_IS_NUMBER(x.t)) {
472 c = abc_inclocal(c, nr);
473 } else syntaxerror("internal error");
476 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
477 c = abc_increment_i(c);
480 c = abc_increment(c);
483 c = converttype(c, t, x.t); //convert back to original type
484 c = toreadwrite(x.c, c, 0, 0, 0);
489 constant_t node_lplusplus_eval(node_t*n)
491 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
493 nodetype_t node_lplusplus =
496 flags:NODE_HAS_CHILDREN,
497 eval: node_lplusplus_eval,
498 write: node_lplusplus_write,
499 read: node_lplusplus_read,
500 exec: node_lplusplus_exec
504 // ---------------------------- --x -----------------------------------
506 typedcode_t node_lminusminus_write(node_t*n)
508 syntaxerror("can't assign to this expression");
510 typedcode_t node_lminusminus_read(node_t*n)
514 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
515 int nr = getlocalnr(x.c);
516 code_free(x.c);x.c=0;
517 if(TYPE_IS_INT(x.t)) {
518 c = abc_declocal_i(c, nr);
519 c = abc_getlocal(c, nr);
520 } else if(TYPE_IS_NUMBER(x.t)) {
521 c = abc_declocal(c, nr);
522 c = abc_getlocal(c, nr);
523 } else syntaxerror("internal error");
525 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
526 c = abc_decrement_i(c);
529 c = abc_decrement(c);
532 c = converttype(c, t, x.t);
533 c = toreadwrite(x.c, c, 0, 0, 1);
538 code_t* node_lminusminus_exec(node_t*n)
540 typedcode_t x = n->child[0]->type->read(n->child[0]);
542 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
543 int nr = getlocalnr(x.c);
544 code_free(x.c);x.c=0;
545 if(TYPE_IS_INT(x.t)) {
546 c = abc_declocal_i(c, nr);
547 } else if(TYPE_IS_NUMBER(x.t)) {
548 c = abc_declocal(c, nr);
549 } else syntaxerror("internal error");
552 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
553 c = abc_decrement_i(c);
556 c = abc_decrement(c);
559 c = converttype(c, t, x.t); //convert back to original type
560 c = toreadwrite(x.c, c, 0, 0, 0);
565 constant_t node_lminusminus_eval(node_t*n)
567 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
569 nodetype_t node_lminusminus =
572 flags:NODE_HAS_CHILDREN,
573 eval: node_lminusminus_eval,
574 write: node_lminusminus_write,
575 read: node_lminusminus_read,
576 exec: node_lminusminus_exec
581 // ---------------------------- x++ -----------------------------------
583 typedcode_t node_rplusplus_write(node_t*n)
585 syntaxerror("can't assign to this expression");
587 typedcode_t node_rplusplus_read(node_t*n)
591 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
592 int nr = getlocalnr(x.c);
593 code_free(x.c);x.c=0;
594 if(TYPE_IS_INT(x.t)) {
595 c = abc_getlocal(0, nr);
596 c = abc_inclocal_i(c, nr);
597 } else if(TYPE_IS_NUMBER(x.t)) {
598 c = abc_getlocal(0, nr);
599 c = abc_inclocal(c, nr);
600 } else syntaxerror("internal error");
602 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
603 c = abc_increment_i(c);
606 c = abc_increment(c);
609 c = converttype(c, t, x.t);
610 c = toreadwrite(x.c, c, 0, 1, 1);
615 code_t* node_rplusplus_exec(node_t*n)
617 typedcode_t x = n->child[0]->type->read(n->child[0]);
619 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
620 int nr = getlocalnr(x.c);
621 code_free(x.c);x.c=0;
622 if(TYPE_IS_INT(x.t)) {
623 c = abc_inclocal_i(c, nr);
624 } else if(TYPE_IS_NUMBER(x.t)) {
625 c = abc_inclocal(c, nr);
626 } else syntaxerror("internal error");
629 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
630 c = abc_increment_i(c);
633 c = abc_increment(c);
636 c = converttype(c, t, x.t); //convert back to original type
637 c = toreadwrite(x.c, c, 0, 1, 0);
642 constant_t node_rplusplus_eval(node_t*n)
644 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
646 nodetype_t node_rplusplus =
649 flags:NODE_HAS_CHILDREN,
650 eval: node_rplusplus_eval,
651 write: node_rplusplus_write,
652 read: node_rplusplus_read,
653 exec: node_rplusplus_exec
656 // ---------------------------- x-- -----------------------------------
658 typedcode_t node_rminusminus_write(node_t*n)
660 syntaxerror("can't assign to this expression");
662 typedcode_t node_rminusminus_read(node_t*n)
666 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
667 int nr = getlocalnr(x.c);
668 code_free(x.c);x.c=0;
669 if(TYPE_IS_INT(x.t)) {
670 c = abc_getlocal(0, nr);
671 c = abc_declocal_i(c, nr);
672 } else if(TYPE_IS_NUMBER(x.t)) {
673 c = abc_getlocal(0, nr);
674 c = abc_declocal(c, nr);
675 } else syntaxerror("internal error");
677 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
678 c = abc_decrement_i(c);
681 c = abc_decrement(c);
684 c = converttype(c, t, x.t);
685 c = toreadwrite(x.c, c, 0, 1, 1);
690 code_t* node_rminusminus_exec(node_t*n)
692 typedcode_t x = n->child[0]->type->read(n->child[0]);
694 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
695 int nr = getlocalnr(x.c);
696 code_free(x.c);x.c=0;
697 if(TYPE_IS_INT(x.t)) {
698 c = abc_declocal_i(c, nr);
699 } else if(TYPE_IS_NUMBER(x.t)) {
700 c = abc_declocal(c, nr);
701 } else syntaxerror("internal error");
704 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
705 c = abc_decrement_i(c);
708 c = abc_decrement(c);
711 c = converttype(c, t, x.t); //convert back to original type
712 c = toreadwrite(x.c, c, 0, 1, 0);
717 constant_t node_rminusminus_eval(node_t*n)
719 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
721 nodetype_t node_rminusminus =
724 flags:NODE_HAS_CHILDREN,
725 eval: node_rminusminus_eval,
726 write: node_rminusminus_write,
727 read: node_rminusminus_read,
728 exec: node_rminusminus_exec
731 // ---------------------------- x*y -----------------------------------
733 typedcode_t node_multiply_write(node_t*n)
735 syntaxerror("can't assign to this expression");
737 typedcode_t node_multiply_read(node_t*n)
739 READ_HEADER_LEFTRIGHT;
740 c = code_append(left.c,right.c);
741 if(BOTH_INT(left.t,right.t)) {
742 c = abc_multiply_i(c);
750 code_t* node_multiply_exec(node_t*n)
752 EXEC_HEADER_LEFTRIGHT;
753 return code_append(left, right);
755 constant_t node_multiply_eval(node_t*n)
757 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
759 nodetype_t node_multiply =
762 flags:NODE_HAS_CHILDREN,
763 eval: node_multiply_eval,
764 write: node_multiply_write,
765 read: node_multiply_read,
766 exec: node_multiply_exec
769 // ---------------------------- x/y -----------------------------------
771 typedcode_t node_div_write(node_t*n)
773 syntaxerror("can't assign to this expression");
775 typedcode_t node_div_read(node_t*n)
777 READ_HEADER_LEFTRIGHT;
778 c = code_append(left.c, right.c);
783 code_t* node_div_exec(node_t*n)
785 EXEC_HEADER_LEFTRIGHT;
786 return code_append(left, right);
788 constant_t node_div_eval(node_t*n)
790 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
792 nodetype_t node_div =
795 flags:NODE_HAS_CHILDREN,
797 write: node_div_write,
802 // ---------------------------- x%y -----------------------------------
804 typedcode_t node_mod_write(node_t*n)
806 syntaxerror("can't assign to this expression");
808 typedcode_t node_mod_read(node_t*n)
810 READ_HEADER_LEFTRIGHT;
811 c = code_append(left.c, right.c);
816 code_t* node_mod_exec(node_t*n)
818 EXEC_HEADER_LEFTRIGHT;
819 return code_append(left, right);
821 constant_t node_mod_eval(node_t*n)
823 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
825 nodetype_t node_mod =
828 flags:NODE_HAS_CHILDREN,
830 write: node_mod_write,
835 // ---------------------------- x<y -----------------------------------
837 typedcode_t node_lt_write(node_t*n)
839 syntaxerror("can't assign to this expression");
841 typedcode_t node_lt_read(node_t*n)
843 READ_HEADER_LEFTRIGHT;
844 c = code_append(left.c,right.c);
849 code_t* node_lt_exec(node_t*n)
851 EXEC_HEADER_LEFTRIGHT;
852 return code_append(left, right);
854 constant_t node_lt_eval(node_t*n)
856 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
861 flags:NODE_HAS_CHILDREN,
863 write: node_lt_write,
868 // ---------------------------- x>y -----------------------------------
870 typedcode_t node_gt_write(node_t*n)
872 syntaxerror("can't assign to this expression");
874 typedcode_t node_gt_read(node_t*n)
876 READ_HEADER_LEFTRIGHT;
877 c = code_append(left.c,right.c);
878 c = abc_greaterthan(c);
882 code_t* node_gt_exec(node_t*n)
884 EXEC_HEADER_LEFTRIGHT;
885 return code_append(left, right);
887 constant_t node_gt_eval(node_t*n)
889 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
894 flags:NODE_HAS_CHILDREN,
896 write: node_gt_write,
901 // ---------------------------- x<=y ----------------------------------
903 typedcode_t node_le_write(node_t*n)
905 syntaxerror("can't assign to this expression");
907 typedcode_t node_le_read(node_t*n)
909 READ_HEADER_LEFTRIGHT;
910 c = code_append(left.c,right.c);
911 c = abc_lessequals(c);
915 code_t* node_le_exec(node_t*n)
917 EXEC_HEADER_LEFTRIGHT;
918 return code_append(left, right);
920 constant_t node_le_eval(node_t*n)
922 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
924 nodetype_t node_le = //<=
927 flags:NODE_HAS_CHILDREN,
929 write: node_le_write,
934 // ---------------------------- x>=y ----------------------------------
936 typedcode_t node_ge_write(node_t*n)
938 syntaxerror("can't assign to this expression");
940 typedcode_t node_ge_read(node_t*n)
942 READ_HEADER_LEFTRIGHT;
943 c = code_append(left.c,right.c);
944 c = abc_greaterequals(c);
948 code_t* node_ge_exec(node_t*n)
950 EXEC_HEADER_LEFTRIGHT;
951 return code_append(left, right);
953 constant_t node_ge_eval(node_t*n)
955 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
957 nodetype_t node_ge = //>=
960 flags:NODE_HAS_CHILDREN,
962 write: node_ge_write,
967 // ---------------------------- x==y ----------------------------------
969 typedcode_t node_eqeq_write(node_t*n)
971 syntaxerror("can't assign to this expression");
973 typedcode_t node_eqeq_read(node_t*n)
975 READ_HEADER_LEFTRIGHT;
976 c = code_append(left.c,right.c);
981 code_t* node_eqeq_exec(node_t*n)
983 EXEC_HEADER_LEFTRIGHT;
984 return code_append(left, right);
986 constant_t node_eqeq_eval(node_t*n)
988 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
990 nodetype_t node_eqeq = //==
993 flags:NODE_HAS_CHILDREN,
994 eval: node_eqeq_eval,
995 write: node_eqeq_write,
996 read: node_eqeq_read,
1000 // --------------------------- x===y ----------------------------------
1002 typedcode_t node_eqeqeq_write(node_t*n)
1004 syntaxerror("can't assign to this expression");
1006 typedcode_t node_eqeqeq_read(node_t*n)
1008 READ_HEADER_LEFTRIGHT;
1009 c = code_append(left.c,right.c);
1010 c = abc_strictequals(c);
1014 code_t* node_eqeqeq_exec(node_t*n)
1016 EXEC_HEADER_LEFTRIGHT;
1017 return code_append(left, right);
1019 constant_t node_eqeqeq_eval(node_t*n)
1021 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1023 nodetype_t node_eqeqeq = //===
1026 flags:NODE_HAS_CHILDREN,
1027 eval: node_eqeqeq_eval,
1028 write: node_eqeqeq_write,
1029 read: node_eqeqeq_read,
1030 exec: node_eqeqeq_exec
1033 // --------------------------- x!==y ----------------------------------
1035 typedcode_t node_noteqeq_write(node_t*n)
1037 syntaxerror("can't assign to this expression");
1039 typedcode_t node_noteqeq_read(node_t*n)
1041 READ_HEADER_LEFTRIGHT;
1042 c = code_append(left.c,right.c);
1043 c = abc_strictequals(c);
1048 code_t* node_noteqeq_exec(node_t*n)
1050 EXEC_HEADER_LEFTRIGHT;
1051 return code_append(left, right);
1053 constant_t node_noteqeq_eval(node_t*n)
1055 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1057 nodetype_t node_noteqeq = //!==
1060 flags:NODE_HAS_CHILDREN,
1061 eval: node_noteqeq_eval,
1062 write: node_noteqeq_write,
1063 read: node_noteqeq_read,
1064 exec: node_noteqeq_exec
1067 // --------------------------- x!=y ----------------------------------
1069 typedcode_t node_noteq_write(node_t*n)
1071 syntaxerror("can't assign to this expression");
1073 typedcode_t node_noteq_read(node_t*n)
1075 READ_HEADER_LEFTRIGHT;
1076 c = code_append(left.c,right.c);
1082 code_t* node_noteq_exec(node_t*n)
1084 EXEC_HEADER_LEFTRIGHT;
1085 return code_append(left, right);
1087 constant_t node_noteq_eval(node_t*n)
1089 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1091 nodetype_t node_noteq = //!=
1094 flags:NODE_HAS_CHILDREN,
1095 eval: node_noteq_eval,
1096 write: node_noteq_write,
1097 read: node_noteq_read,
1098 exec: node_noteq_exec
1101 // --------------------------- x||y ----------------------------------
1103 typedcode_t node_oror_write(node_t*n)
1105 syntaxerror("can't assign to this expression");
1107 typedcode_t node_oror_read(node_t*n)
1109 READ_HEADER_LEFTRIGHT;
1110 t = join_types(left.t, right.t, n->type);
1112 c = converttype(c, left.t, t);
1114 code_t*jmp = c = abc_iftrue(c, 0);
1115 c = cut_last_push(c);
1116 c = code_append(c, right.c);
1117 c = converttype(c, right.t, t);
1118 code_t*label = c = abc_label(c);
1119 jmp->branch = label;
1122 code_t* node_oror_exec(node_t*n)
1124 typedcode_t left = n->child[0]->type->read(n->child[0]);
1125 code_t* right = n->child[1]->type->exec(n->child[1]);
1127 code_t*jmp = c = abc_iftrue(c, 0);
1128 c = code_append(c, right);
1129 code_t*label = c = abc_label(c);
1130 jmp->branch = label;
1133 constant_t node_oror_eval(node_t*n)
1135 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1137 nodetype_t node_oror = //||
1140 flags:NODE_HAS_CHILDREN,
1141 eval: node_oror_eval,
1142 write: node_oror_write,
1143 read: node_oror_read,
1144 exec: node_oror_exec
1147 // --------------------------- x&&y ----------------------------------
1149 typedcode_t node_andand_write(node_t*n)
1151 syntaxerror("can't assign to this expression");
1153 typedcode_t node_andand_read(node_t*n)
1155 READ_HEADER_LEFTRIGHT;
1156 t = join_types(left.t, right.t, &node_andand);
1158 c = converttype(c, left.t, t);
1160 code_t*jmp = c = abc_iffalse(c, 0);
1161 c = cut_last_push(c);
1162 c = code_append(c,right.c);
1163 c = converttype(c, right.t, t);
1164 code_t*label = c = abc_label(c);
1165 jmp->branch = label;
1168 code_t* node_andand_exec(node_t*n)
1170 typedcode_t left = n->child[0]->type->read(n->child[0]);\
1171 code_t* right = n->child[1]->type->exec(n->child[1]);\
1173 code_t*jmp = c = abc_iffalse(c, 0);
1174 c = code_append(c, right);
1175 code_t*label = c = abc_label(c);
1176 jmp->branch = label;
1179 constant_t node_andand_eval(node_t*n)
1181 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1183 nodetype_t node_andand = //&&
1186 flags:NODE_HAS_CHILDREN,
1187 eval: node_andand_eval,
1188 write: node_andand_write,
1189 read: node_andand_read,
1190 exec: node_andand_exec
1193 // ----------------------------- !x -----------------------------------
1195 typedcode_t node_not_write(node_t*n)
1197 syntaxerror("can't assign to this expression");
1199 typedcode_t node_not_read(node_t*n)
1207 code_t* node_not_exec(node_t*n)
1212 constant_t node_not_eval(node_t*n)
1214 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1216 nodetype_t node_not =
1219 flags:NODE_HAS_CHILDREN,
1220 eval: node_not_eval,
1221 write: node_not_write,
1222 read: node_not_read,
1226 // ----------------------------- ~x -----------------------------------
1228 typedcode_t node_bitnot_write(node_t*n)
1230 syntaxerror("can't assign to this expression");
1232 typedcode_t node_bitnot_read(node_t*n)
1240 code_t* node_bitnot_exec(node_t*n)
1245 constant_t node_bitnot_eval(node_t*n)
1247 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1249 nodetype_t node_bitnot =
1252 flags:NODE_HAS_CHILDREN,
1253 eval: node_bitnot_eval,
1254 write: node_bitnot_write,
1255 read: node_bitnot_read,
1256 exec: node_bitnot_exec
1259 // ----------------------------- x&y -----------------------------------
1261 typedcode_t node_bitand_write(node_t*n)
1263 syntaxerror("can't assign to this expression");
1265 typedcode_t node_bitand_read(node_t*n)
1267 READ_HEADER_LEFTRIGHT;
1268 c = code_append(left.c,right.c);
1273 code_t* node_bitand_exec(node_t*n)
1275 EXEC_HEADER_LEFTRIGHT;
1276 return code_append(left, right);
1278 constant_t node_bitand_eval(node_t*n)
1280 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1282 nodetype_t node_bitand =
1285 flags:NODE_HAS_CHILDREN,
1286 eval: node_bitand_eval,
1287 write: node_bitand_write,
1288 read: node_bitand_read,
1289 exec: node_bitand_exec
1292 // ----------------------------- x^y -----------------------------------
1294 typedcode_t node_bitxor_write(node_t*n)
1296 syntaxerror("can't assign to this expression");
1298 typedcode_t node_bitxor_read(node_t*n)
1300 READ_HEADER_LEFTRIGHT;
1301 c = code_append(left.c,right.c);
1306 code_t* node_bitxor_exec(node_t*n)
1308 EXEC_HEADER_LEFTRIGHT;
1309 return code_append(left, right);
1311 constant_t node_bitxor_eval(node_t*n)
1313 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1315 nodetype_t node_bitxor =
1318 flags:NODE_HAS_CHILDREN,
1319 eval: node_bitxor_eval,
1320 write: node_bitxor_write,
1321 read: node_bitxor_read,
1322 exec: node_bitxor_exec
1325 // ----------------------------- x|y -----------------------------------
1327 typedcode_t node_bitor_write(node_t*n)
1329 syntaxerror("can't assign to this expression");
1331 typedcode_t node_bitor_read(node_t*n)
1333 READ_HEADER_LEFTRIGHT;
1334 c = code_append(left.c,right.c);
1339 code_t* node_bitor_exec(node_t*n)
1341 EXEC_HEADER_LEFTRIGHT;
1342 return code_append(left, right);
1344 constant_t node_bitor_eval(node_t*n)
1346 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1348 nodetype_t node_bitor =
1351 flags:NODE_HAS_CHILDREN,
1352 eval: node_bitor_eval,
1353 write: node_bitor_write,
1354 read: node_bitor_read,
1355 exec: node_bitor_exec
1358 // ---------------------------- x>>y -----------------------------------
1360 typedcode_t node_shr_write(node_t*n)
1362 syntaxerror("can't assign to this expression");
1364 typedcode_t node_shr_read(node_t*n)
1366 READ_HEADER_LEFTRIGHT;
1367 c = code_append(left.c,right.c);
1372 code_t* node_shr_exec(node_t*n)
1374 EXEC_HEADER_LEFTRIGHT;
1375 return code_append(left, right);
1377 constant_t node_shr_eval(node_t*n)
1379 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1381 nodetype_t node_shr = //>>
1384 flags:NODE_HAS_CHILDREN,
1385 eval: node_shr_eval,
1386 write: node_shr_write,
1387 read: node_shr_read,
1391 // ---------------------------- x<<y -----------------------------------
1393 typedcode_t node_shl_write(node_t*n)
1395 syntaxerror("can't assign to this expression");
1397 typedcode_t node_shl_read(node_t*n)
1399 READ_HEADER_LEFTRIGHT;
1400 c = code_append(left.c,right.c);
1405 code_t* node_shl_exec(node_t*n)
1407 EXEC_HEADER_LEFTRIGHT;
1408 return code_append(left, right);
1410 constant_t node_shl_eval(node_t*n)
1412 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1414 nodetype_t node_shl = //<<
1417 flags:NODE_HAS_CHILDREN,
1418 eval: node_shl_eval,
1419 write: node_shl_write,
1420 read: node_shl_read,
1424 // ---------------------------- x>>>y -----------------------------------
1426 typedcode_t node_ushr_write(node_t*n)
1428 syntaxerror("can't assign to this expression");
1430 typedcode_t node_ushr_read(node_t*n)
1432 READ_HEADER_LEFTRIGHT;
1433 c = code_append(left.c,right.c);
1438 code_t* node_ushr_exec(node_t*n)
1440 EXEC_HEADER_LEFTRIGHT;
1441 return code_append(left, right);
1443 constant_t node_ushr_eval(node_t*n)
1445 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1447 nodetype_t node_ushr = //>>>
1450 flags:NODE_HAS_CHILDREN,
1451 eval: node_ushr_eval,
1452 write: node_ushr_write,
1453 read: node_ushr_read,
1454 exec: node_ushr_exec
1457 // ---------------------------- x in y ----------------------------------
1459 typedcode_t node_in_write(node_t*n)
1461 syntaxerror("can't assign to this expression");
1463 typedcode_t node_in_read(node_t*n)
1465 READ_HEADER_LEFTRIGHT;
1466 c = code_append(left.c,right.c);
1471 code_t* node_in_exec(node_t*n)
1473 EXEC_HEADER_LEFTRIGHT;
1474 return code_append(left, right);
1476 constant_t node_in_eval(node_t*n)
1478 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1480 nodetype_t node_in = //in
1483 flags:NODE_HAS_CHILDREN,
1485 write: node_in_write,
1490 // ---------------------------- x as y ----------------------------------
1492 typedcode_t node_as_write(node_t*n)
1495 syntaxerror("can't assign to this expression");
1497 typedcode_t node_as_read(node_t*n)
1499 READ_HEADER_LEFTRIGHT;
1500 c = code_append(left.c, right.c);
1501 c = abc_astypelate(c);
1502 if(TYPE_IS_CLASS(right.t) && right.t->data) {
1503 t = (classinfo_t*)right.t->data;
1509 code_t* node_as_exec(node_t*n)
1511 /* we assume here that "as" doesn't have side-effects (like
1512 early run time type checking) */
1513 EXEC_HEADER_LEFTRIGHT;
1514 return code_append(left, right);
1516 constant_t node_as_eval(node_t*n)
1518 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1520 nodetype_t node_as = //as
1523 flags:NODE_HAS_CHILDREN,
1525 write: node_as_write,
1530 // ------------------------- x instanceof y -----------------------------
1532 typedcode_t node_instanceof_write(node_t*n)
1534 syntaxerror("can't assign to this expression");
1536 typedcode_t node_instanceof_read(node_t*n)
1538 READ_HEADER_LEFTRIGHT;
1539 c = code_append(left.c, right.c);
1540 c = abc_instanceof(c);
1544 code_t* node_instanceof_exec(node_t*n)
1546 EXEC_HEADER_LEFTRIGHT;
1547 return code_append(left, right);
1549 constant_t node_instanceof_eval(node_t*n)
1551 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1553 nodetype_t node_instanceof = //instanceof
1556 flags:NODE_HAS_CHILDREN,
1557 eval: node_instanceof_eval,
1558 write: node_instanceof_write,
1559 read: node_instanceof_read,
1560 exec: node_instanceof_exec
1563 // ------------------------- x is y --------------------------------------
1565 typedcode_t node_is_write(node_t*n)
1567 syntaxerror("can't assign to this expression");
1569 typedcode_t node_is_read(node_t*n)
1571 READ_HEADER_LEFTRIGHT;
1572 c = code_append(left.c, right.c);
1573 c = abc_istypelate(c);
1577 code_t* node_is_exec(node_t*n)
1579 EXEC_HEADER_LEFTRIGHT;
1580 return code_append(left, right);
1582 constant_t node_is_eval(node_t*n)
1584 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1586 nodetype_t node_is = //is
1589 flags:NODE_HAS_CHILDREN,
1591 write: node_is_write,
1596 // ------------------------- x[y] --------------------------------------
1598 typedcode_t node_arraylookup_write(node_t*n)
1600 syntaxerror("not implemented yet");
1602 typedcode_t node_arraylookup_read(node_t*n)
1604 READ_HEADER_LEFTRIGHT;
1605 c = code_append(left.c, right.c);
1607 /* XXX not sure whether this access logic is correct */
1608 namespace_t ns = {left.t?left.t->access:ACCESS_PACKAGE, ""};
1609 namespace_set_t nsset;
1610 namespace_list_t l;l.next = 0;
1611 nsset.namespaces = &l;
1613 multiname_t m = {MULTINAMEL, 0, &nsset, 0};
1615 c = abc_getproperty2(c, &m);
1616 t = 0; // array elements have unknown type
1619 code_t* node_arraylookup_exec(node_t*n)
1621 EXEC_HEADER_LEFTRIGHT;
1622 return code_append(left, right);
1624 constant_t node_arraylookup_eval(node_t*n)
1626 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1628 nodetype_t node_arraylookup =
1630 name: "arraylookup",
1631 flags:NODE_HAS_CHILDREN,
1632 eval: node_arraylookup_eval,
1633 write: node_arraylookup_write,
1634 read: node_arraylookup_read,
1635 exec: node_arraylookup_exec
1638 // ------------------------- typeof(x) ------------------------------------
1640 typedcode_t node_typeof_write(node_t*n)
1642 syntaxerror("can't assign to this expression");
1644 typedcode_t node_typeof_read(node_t*n)
1652 code_t* node_typeof_exec(node_t*n)
1657 constant_t node_typeof_eval(node_t*n)
1659 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1661 nodetype_t node_typeof = //typeof
1664 flags:NODE_HAS_CHILDREN,
1665 eval: node_typeof_eval,
1666 write: node_typeof_write,
1667 read: node_typeof_read,
1668 exec: node_typeof_exec
1671 // ------------------------- (void)(x) ------------------------------------
1673 typedcode_t node_void_write(node_t*n)
1675 syntaxerror("can't assign to this expression");
1677 typedcode_t node_void_read(node_t*n)
1679 code_t*c = n->type->exec(n);
1680 c = abc_pushundefined(c);
1681 classinfo_t*t = TYPE_ANY;
1684 code_t* node_void_exec(node_t*n)
1689 constant_t node_void_eval(node_t*n)
1691 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1693 nodetype_t node_void = //void
1696 flags:NODE_HAS_CHILDREN,
1697 eval: node_void_eval,
1698 write: node_void_write,
1699 read: node_void_read,
1700 exec: node_void_exec
1703 // ---------------------------- -x ----------------------------------------
1705 typedcode_t node_neg_write(node_t*n)
1707 syntaxerror("can't assign to this expression");
1709 typedcode_t node_neg_read(node_t*n)
1714 c = abc_negate_i(c);
1722 code_t* node_neg_exec(node_t*n)
1727 constant_t node_neg_eval(node_t*n)
1729 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1731 nodetype_t node_neg = //-
1734 flags:NODE_HAS_CHILDREN,
1735 eval: node_neg_eval,
1736 write: node_neg_write,
1737 read: node_neg_read,
1741 // ---------------------------- x*=y ----------------------------------------
1743 typedcode_t node_muleq_write(node_t*n)
1745 syntaxerror("can't assign to this expression");
1747 typedcode_t node_muleq_read(node_t*n)
1749 READ_HEADER_LEFTRIGHT;
1752 if(BOTH_INT(left.t,right.t)) {
1753 c=abc_multiply_i(c);
1759 c=converttype(c, f, left.t);
1760 c = toreadwrite(left.c, c, 0, 0, 1);
1764 code_t* node_muleq_exec(node_t*n)
1766 READ_HEADER_LEFTRIGHT;
1769 if(BOTH_INT(left.t,right.t)) {
1770 c=abc_multiply_i(c);
1776 c = converttype(c, f, left.t);
1777 return toreadwrite(left.c, c, 0, 0, 0);
1779 constant_t node_muleq_eval(node_t*n)
1781 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1783 nodetype_t node_muleq =
1786 flags:NODE_HAS_CHILDREN,
1787 eval: node_muleq_eval,
1788 write: node_muleq_write,
1789 read: node_muleq_read,
1790 exec: node_muleq_exec
1793 // ---------------------------- x%=y ----------------------------------------
1795 typedcode_t node_modeq_write(node_t*n)
1797 syntaxerror("can't assign to this expression");
1799 typedcode_t node_modeq_read(node_t*n)
1801 READ_HEADER_LEFTRIGHT;
1802 c = abc_modulo(right.c);
1803 c = converttype(c, TYPE_NUMBER, left.t);
1804 c = toreadwrite(left.c, c, 0, 0, 1);
1808 code_t* node_modeq_exec(node_t*n)
1810 READ_HEADER_LEFTRIGHT;
1811 c = abc_modulo(right.c);
1812 c = converttype(c, TYPE_NUMBER, left.t);
1813 return toreadwrite(left.c, c, 0, 0, 0);
1815 constant_t node_modeq_eval(node_t*n)
1817 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1819 nodetype_t node_modeq = //%=
1822 flags:NODE_HAS_CHILDREN,
1823 eval: node_modeq_eval,
1824 write: node_modeq_write,
1825 read: node_modeq_read,
1826 exec: node_modeq_exec
1829 // ---------------------------- x<<=y ----------------------------------------
1831 typedcode_t node_shleq_write(node_t*n)
1833 syntaxerror("can't assign to this expression");
1835 typedcode_t node_shleq_read(node_t*n)
1837 READ_HEADER_LEFTRIGHT;
1838 c = abc_lshift(right.c);
1839 c = converttype(c, TYPE_INT, left.t);
1840 c = toreadwrite(left.c, c, 0, 0, 1);
1844 code_t* node_shleq_exec(node_t*n)
1846 READ_HEADER_LEFTRIGHT;
1847 c = abc_lshift(right.c);
1848 c = converttype(c, TYPE_INT, left.t);
1849 return toreadwrite(left.c, c, 0, 0, 0);
1851 constant_t node_shleq_eval(node_t*n)
1853 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1855 nodetype_t node_shleq = //<<=
1858 flags:NODE_HAS_CHILDREN,
1859 eval: node_shleq_eval,
1860 write: node_shleq_write,
1861 read: node_shleq_read,
1862 exec: node_shleq_exec
1865 // ---------------------------- x>>=y ----------------------------------------
1867 typedcode_t node_shreq_write(node_t*n)
1869 syntaxerror("can't assign to this expression");
1871 typedcode_t node_shreq_read(node_t*n)
1873 READ_HEADER_LEFTRIGHT;
1874 c = abc_rshift(right.c);
1875 c = converttype(c, TYPE_INT, left.t);
1876 c = toreadwrite(left.c, c, 0, 0, 1);
1880 code_t* node_shreq_exec(node_t*n)
1882 READ_HEADER_LEFTRIGHT;
1883 c = abc_rshift(right.c);
1884 c = converttype(c, TYPE_INT, left.t);
1885 return toreadwrite(left.c, c, 0, 0, 0);
1887 constant_t node_shreq_eval(node_t*n)
1889 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1891 nodetype_t node_shreq = //>>=
1894 flags:NODE_HAS_CHILDREN,
1895 eval: node_shreq_eval,
1896 write: node_shreq_write,
1897 read: node_shreq_read,
1898 exec: node_shreq_exec
1901 // --------------------------- x>>>=y ----------------------------------------
1903 typedcode_t node_ushreq_write(node_t*n)
1905 syntaxerror("can't assign to this expression");
1907 typedcode_t node_ushreq_read(node_t*n)
1909 READ_HEADER_LEFTRIGHT;
1910 c = abc_urshift(right.c);
1911 c = converttype(c, TYPE_UINT, left.t);
1912 c = toreadwrite(left.c, c, 0, 0, 1);
1916 code_t* node_ushreq_exec(node_t*n)
1918 READ_HEADER_LEFTRIGHT;
1919 c = abc_urshift(right.c);
1920 c = converttype(c, TYPE_UINT, left.t);
1921 return toreadwrite(left.c, c, 0, 0, 0);
1923 constant_t node_ushreq_eval(node_t*n)
1925 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1927 nodetype_t node_ushreq = //>>>=
1930 flags:NODE_HAS_CHILDREN,
1931 eval: node_ushreq_eval,
1932 write: node_ushreq_write,
1933 read: node_ushreq_read,
1934 exec: node_ushreq_exec
1937 // --------------------------- x/=y ----------------------------------------
1939 typedcode_t node_diveq_write(node_t*n)
1941 syntaxerror("can't assign to this expression");
1943 typedcode_t node_diveq_read(node_t*n)
1945 READ_HEADER_LEFTRIGHT;
1946 c = abc_divide(right.c);
1947 c = converttype(c, TYPE_NUMBER, left.t);
1948 c = toreadwrite(left.c, c, 0, 0, 1);
1952 code_t* node_diveq_exec(node_t*n)
1954 READ_HEADER_LEFTRIGHT;
1955 c = abc_divide(right.c);
1956 c = converttype(c, TYPE_NUMBER, left.t);
1957 return toreadwrite(left.c, c, 0, 0, 0);
1959 constant_t node_diveq_eval(node_t*n)
1961 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1963 nodetype_t node_diveq =
1966 flags:NODE_HAS_CHILDREN,
1967 eval: node_diveq_eval,
1968 write: node_diveq_write,
1969 read: node_diveq_read,
1970 exec: node_diveq_exec
1973 // --------------------------- x|=y ----------------------------------------
1975 typedcode_t node_bitoreq_write(node_t*n)
1977 syntaxerror("can't assign to this expression");
1979 typedcode_t node_bitoreq_read(node_t*n)
1981 READ_HEADER_LEFTRIGHT;
1982 c = abc_bitor(right.c);
1983 c = converttype(c, TYPE_INT, left.t);
1984 c = toreadwrite(left.c, c, 0, 0, 1);
1988 code_t* node_bitoreq_exec(node_t*n)
1990 READ_HEADER_LEFTRIGHT;
1991 c = abc_bitor(right.c);
1992 c = converttype(c, TYPE_INT, left.t);
1993 return toreadwrite(left.c, c, 0, 0, 0);
1995 constant_t node_bitoreq_eval(node_t*n)
1997 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
1999 nodetype_t node_bitoreq = //|=
2002 flags:NODE_HAS_CHILDREN,
2003 eval: node_bitoreq_eval,
2004 write: node_bitoreq_write,
2005 read: node_bitoreq_read,
2006 exec: node_bitoreq_exec
2009 // --------------------------- x^=y ----------------------------------------
2011 typedcode_t node_bitxoreq_write(node_t*n)
2013 syntaxerror("can't assign to this expression");
2015 typedcode_t node_bitxoreq_read(node_t*n)
2017 READ_HEADER_LEFTRIGHT;
2018 c = abc_bitxor(right.c);
2019 c = converttype(c, TYPE_INT, left.t);
2020 c = toreadwrite(left.c, c, 0, 0, 1);
2024 code_t* node_bitxoreq_exec(node_t*n)
2026 READ_HEADER_LEFTRIGHT;
2027 c = abc_bitxor(right.c);
2028 c = converttype(c, TYPE_INT, left.t);
2029 return toreadwrite(left.c, c, 0, 0, 0);
2031 constant_t node_bitxoreq_eval(node_t*n)
2033 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2035 nodetype_t node_bitxoreq = //^=
2038 flags:NODE_HAS_CHILDREN,
2039 eval: node_bitxoreq_eval,
2040 write: node_bitxoreq_write,
2041 read: node_bitxoreq_read,
2042 exec: node_bitxoreq_exec
2045 // --------------------------- x&=y ----------------------------------------
2047 typedcode_t node_bitandeq_write(node_t*n)
2049 syntaxerror("can't assign to this expression");
2051 typedcode_t node_bitandeq_read(node_t*n)
2053 READ_HEADER_LEFTRIGHT;
2054 c = abc_bitand(right.c);
2055 c = converttype(c, TYPE_INT, left.t);
2056 c = toreadwrite(left.c, c, 0, 0, 1);
2060 code_t* node_bitandeq_exec(node_t*n)
2062 READ_HEADER_LEFTRIGHT;
2063 c = abc_bitand(right.c);
2064 c = converttype(c, TYPE_INT, left.t);
2065 return toreadwrite(left.c, c, 0, 0, 0);
2067 constant_t node_bitandeq_eval(node_t*n)
2069 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2071 nodetype_t node_bitandeq = //^=
2074 flags:NODE_HAS_CHILDREN,
2075 eval: node_bitandeq_eval,
2076 write: node_bitandeq_write,
2077 read: node_bitandeq_read,
2078 exec: node_bitandeq_exec
2081 // --------------------------- x+=y ----------------------------------------
2083 typedcode_t node_pluseq_write(node_t*n)
2085 syntaxerror("can't assign to this expression");
2087 typedcode_t node_pluseq_read(node_t*n)
2089 READ_HEADER_LEFTRIGHT;
2091 if(TYPE_IS_INT(left.t)) {
2095 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2097 c = toreadwrite(left.c, c, 0, 0, 1);
2101 code_t* node_pluseq_exec(node_t*n)
2103 READ_HEADER_LEFTRIGHT;
2105 if(TYPE_IS_INT(left.t)) {
2109 c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
2111 return toreadwrite(left.c, c, 0, 0, 0);
2113 constant_t node_pluseq_eval(node_t*n)
2115 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2117 nodetype_t node_pluseq = //+=
2120 flags:NODE_HAS_CHILDREN,
2121 eval: node_pluseq_eval,
2122 write: node_pluseq_write,
2123 read: node_pluseq_read,
2124 exec: node_pluseq_exec
2127 // --------------------------- x-=y ----------------------------------------
2129 typedcode_t node_minuseq_write(node_t*n)
2131 syntaxerror("can't assign to this expression");
2133 typedcode_t node_minuseq_read(node_t*n)
2135 READ_HEADER_LEFTRIGHT;
2137 if(TYPE_IS_INT(left.t)) {
2138 c = abc_subtract_i(c);
2140 c = abc_subtract(c);
2141 c = converttype(c, TYPE_NUMBER, left.t);
2143 c = toreadwrite(left.c, c, 0, 0, 1);
2147 code_t* node_minuseq_exec(node_t*n)
2149 READ_HEADER_LEFTRIGHT;
2151 if(TYPE_IS_INT(left.t)) {
2152 c = abc_subtract_i(c);
2154 c = abc_subtract(c);
2155 c = converttype(c, TYPE_NUMBER, left.t);
2157 return toreadwrite(left.c, c, 0, 0, 0);
2159 constant_t node_minuseq_eval(node_t*n)
2161 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2163 nodetype_t node_minuseq = //-=
2166 flags:NODE_HAS_CHILDREN,
2167 eval: node_minuseq_eval,
2168 write: node_minuseq_write,
2169 read: node_minuseq_read,
2170 exec: node_minuseq_exec
2173 // --------------------------- x=y -----------------------------------------
2175 typedcode_t node_assign_write(node_t*n)
2177 syntaxerror("can't assign to this expression");
2179 typedcode_t node_assign_read(node_t*n)
2181 READ_HEADER_LEFTRIGHT;
2183 c = converttype(c, right.t, left.t);
2184 c = toreadwrite(left.c, c, 1, 0, 1);
2188 code_t* node_assign_exec(node_t*n)
2190 READ_HEADER_LEFTRIGHT;
2192 c = converttype(c, right.t, left.t);
2193 return toreadwrite(left.c, c, 1, 0, 0);
2195 constant_t node_assign_eval(node_t*n)
2197 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2199 nodetype_t node_assign =
2202 flags:NODE_HAS_CHILDREN,
2203 eval: node_assign_eval,
2204 write: node_assign_write,
2205 read: node_assign_read,
2206 exec: node_assign_exec
2209 // --------------------------- x?y1:y2 --------------------------------------
2211 typedcode_t node_tenary_write(node_t*n)
2213 /* TODO: this might actually be kinda useful.
2214 (global?global.x:this.x) = 3;
2216 syntaxerror("can't assign to this expression");
2218 typedcode_t node_tenary_read(node_t*n)
2220 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2221 typedcode_t left = n->child[1]->type->read(n->child[1]);
2222 typedcode_t right = n->child[2]->type->read(n->child[2]);
2223 classinfo_t*t = join_types(left.t,right.t,&node_tenary);
2225 code_t*j1 = c = abc_iffalse(c, 0);
2226 c = code_append(c, left.c);
2227 c = converttype(c, left.t, t);
2228 code_t*j2 = c = abc_jump(c, 0);
2229 c = j1->branch = abc_label(c);
2230 c = code_append(c, right.c);
2231 c = converttype(c, right.t, t);
2232 c = j2->branch = abc_label(c);
2235 code_t* node_tenary_exec(node_t*n)
2237 typedcode_t cond = n->child[0]->type->read(n->child[0]);
2238 code_t* left = n->child[1]->type->exec(n->child[1]);
2239 code_t* right = n->child[2]->type->exec(n->child[2]);
2241 code_t*j1 = c = abc_iffalse(c, 0);
2242 c = code_append(c, left);
2243 code_t*j2 = c = abc_jump(c, 0);
2244 c = j1->branch = abc_label(c);
2245 c = code_append(c, right);
2246 c = j2->branch = abc_label(c);
2249 constant_t node_tenary_eval(node_t*n)
2251 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2253 nodetype_t node_tenary =
2256 flags:NODE_HAS_CHILDREN,
2257 eval: node_tenary_eval,
2258 write: node_tenary_write,
2259 read: node_tenary_read,
2260 exec: node_tenary_exec
2263 // ---------------------------- comma ----------------------------------------
2265 typedcode_t node_comma_write(node_t*n)
2267 syntaxerror("can't assign to this expression");
2269 typedcode_t node_comma_read(node_t*n)
2274 for(i=0;i<n->num_children-1;i++) {
2275 c = code_append(c, n->child[i]->type->exec(n->child[i]));
2277 typedcode_t o = n->child[i]->type->read(n->child[i]);
2278 c = code_append(c, o.c);
2282 code_t* node_comma_exec(node_t*n)
2286 for(t=0;t<n->num_children;t++) {
2287 c = code_append(c, n->child[t]->type->exec(n->child[t]));
2291 constant_t node_comma_eval(node_t*n)
2293 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2295 nodetype_t node_comma =
2298 flags: NODE_HAS_CHILDREN,
2299 eval: node_comma_eval,
2300 write: node_comma_write,
2301 read: node_comma_read,
2302 exec: node_comma_exec
2307 // -------------------------- new x -----------------------------------
2309 typedcode_t node_new_write(node_t*n)
2312 typedcode_t node_new_read(node_t*n)
2315 code_t* node_new_exec(node_t*n)
2318 constant_t node_new_eval(node_t*n)
2320 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2322 nodetype_t node_new = //new
2324 write: node_new_write,
2325 read: node_new_read,
2326 eval: node_new_eval,
2330 // ------------------------ delete x ----------------------------------
2332 typedcode_t node_delete_write(node_t*n)
2335 typedcode_t node_delete_read(node_t*n)
2338 code_t* node_delete_exec(node_t*n)
2341 constant_t node_delete_eval(node_t*n)
2343 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2345 nodetype_t node_delete = //delete
2347 write: node_delete_write,
2348 read: node_delete_read,
2349 eval: node_delete_eval,
2350 exec: node_delete_exec
2353 // ---------------------------- x.y -----------------------------------
2355 typedcode_t node_dot_write(node_t*n)
2358 typedcode_t node_dot_read(node_t*n)
2361 code_t* node_dot_exec(node_t*n)
2364 constant_t node_dot_eval(node_t*n)
2366 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2368 nodetype_t node_dot =
2370 write: node_dot_write,
2371 read: node_dot_read,
2372 eval: node_dot_eval,
2376 // --------------------------- x..y -----------------------------------
2378 typedcode_t node_dotdot_write(node_t*n)
2381 typedcode_t node_dotdot_read(node_t*n)
2384 code_t* node_dotdot_exec(node_t*n)
2388 constant_t node_dotdot_eval(node_t*n)
2390 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2392 nodetype_t node_dotdot = //..
2394 write: node_dotdot_write,
2395 read: node_dotdot_read,
2396 eval: node_dotdot_eval,
2397 exec: node_dotdot_exec
2400 // --------------------------- x.@y -----------------------------------
2402 typedcode_t node_dotat_write(node_t*n)
2405 typedcode_t node_dotat_read(node_t*n)
2408 code_t* node_dotat_exec(node_t*n)
2411 constant_t node_dotat_eval(node_t*n)
2413 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2415 nodetype_t node_dotat = //.@
2417 write: node_dotat_write,
2418 read: node_dotat_read,
2419 eval: node_dotat_eval,
2420 exec: node_dotat_exec
2423 // --------------------------- x.*y -----------------------------------
2425 typedcode_t node_dotstar_write(node_t*n)
2428 typedcode_t node_dotstar_read(node_t*n)
2431 code_t* node_dotstar_exec(node_t*n)
2434 constant_t node_dotstar_eval(node_t*n)
2436 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2438 nodetype_t node_dotstar = //.*
2440 write: node_dotstar_write,
2441 read: node_dotstar_read,
2442 eval: node_dotstar_eval,
2443 exec: node_dotstar_exec
2446 // -------------------------- x.(y) -----------------------------------
2448 typedcode_t node_filter_write(node_t*n)
2451 typedcode_t node_filter_read(node_t*n)
2454 code_t* node_filter_exec(node_t*n)
2457 constant_t node_filter_eval(node_t*n)
2459 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2461 nodetype_t node_filter = //.(
2463 write: node_filter_write,
2464 read: node_filter_read,
2465 eval: node_filter_eval,
2466 exec: node_filter_exec
2469 // ------------------------ x(y1,...,yn) ------------------------------
2471 typedcode_t node_call_write(node_t*n)
2474 typedcode_t node_call_read(node_t*n)
2477 code_t* node_call_exec(node_t*n)
2480 constant_t node_call_eval(node_t*n)
2482 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2484 nodetype_t node_call = //functioncall
2486 write: node_call_write,
2487 read: node_call_read,
2488 eval: node_call_eval,
2489 exec: node_call_exec
2492 // ------------------------------ @x ----------------------------------------
2494 typedcode_t node_at_write(node_t*n)
2497 typedcode_t node_at_read(node_t*n)
2500 code_t* node_at_exec(node_t*n)
2503 constant_t node_at_eval(node_t*n)
2505 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2507 nodetype_t node_at = //@
2509 write: node_at_write,
2515 // ---------------------------- x.ns::y ----------------------------------------
2517 typedcode_t node_dotns_write(node_t*n)
2520 typedcode_t node_dotns_read(node_t*n)
2523 code_t* node_dotns_exec(node_t*n)
2526 constant_t node_dotns_eval(node_t*n)
2528 constant_t r;r.type=CONSTANT_UNKNOWN;return r;
2530 nodetype_t node_dotns = //.::
2532 write: node_dotns_write,
2533 read: node_dotns_read,
2534 eval: node_dotns_eval,
2535 exec: node_dotns_exec
2539 // ------------------------ constant ------------------------------
2541 typedcode_t node_const_write(node_t*n)
2543 syntaxerror("can't assign a value to a constant");
2545 typedcode_t node_const_read(node_t*n)
2547 constant_t*v = n->value;
2552 if(v->i>-128 && v->i<128) {
2553 c = abc_pushbyte(0,v->i);
2554 } else if(v->i>=-32768 && v->i<32768) {
2555 c = abc_pushshort(0,v->i);
2557 c = abc_pushint(0,v->i);
2562 c = abc_pushuint(0,v->u);
2564 c = abc_pushbyte(0,v->u);
2565 } else if(v->u<32768) {
2566 c = abc_pushshort(0,v->u);
2568 c = abc_pushint(0,v->u);
2572 case CONSTANT_FLOAT:
2573 c = abc_pushdouble(0,v->f);
2577 c = abc_pushtrue(0);
2580 case CONSTANT_FALSE:
2581 c = abc_pushfalse(0);
2585 c = abc_pushnull(0);
2588 case CONSTANT_STRING:
2589 c = abc_pushstring2(0,v->s);
2592 case CONSTANT_UNDEFINED:
2593 c = abc_pushundefined(0);
2596 case CONSTANT_NAMESPACE:
2597 case CONSTANT_NAMESPACE_PACKAGE:
2598 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
2599 case CONSTANT_NAMESPACE_PROTECTED:
2600 case CONSTANT_NAMESPACE_EXPLICIT:
2601 case CONSTANT_NAMESPACE_STATICPROTECTED:
2602 case CONSTANT_NAMESPACE_PRIVATE:
2603 c = abc_pushnamespace(0, v->ns);
2605 case CONSTANT_UNKNOWN:
2606 syntaxerror("internal error: invalid constant");
2609 syntaxerror("invalid constant (%d)", v->type);
2615 code_t* node_const_exec(node_t*n)
2619 constant_t node_const_eval(node_t*n)
2621 constant_t*c = constant_clone(n->value);
2623 free(c); //shallow free
2626 nodetype_t node_const =
2630 eval: node_const_eval,
2631 write: node_const_write,
2632 read: node_const_read,
2633 exec: node_const_exec
2636 // ------------------------ code node ------------------------------
2638 typedcode_t node_code_write(node_t*n)
2642 int tmp = gettempvar();
2643 t.c = abc_setlocal(t.c, tmp);
2644 code_t*w = toreadwrite(n->code.c, abc_getlocal(0,tmp), 1, 0, 0);
2645 t.c = code_append(t.c, w);
2646 t.c = abc_kill(t.c, tmp);
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 typedcode_t node_write(node_t*n)
2837 typedcode_t t = n->type->write(n);
2841 code_t* node_exec(node_t*n)
2843 code_t*c = n->type->exec(n);
2847 constant_t node_eval(node_t*n)
2849 constant_t c = n->type->eval(n);
2867 void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
2869 if(n->type->flags&NODE_HAS_CHILDREN) {
2870 fprintf(fi, "%s%s\n", p1, n->type->name);
2872 char*o2 = malloc(strlen(p2)+3);
2873 strcpy(o2, p2);strcat(o2, "| ");
2874 char*o3 = malloc(strlen(p2)+3);
2875 strcpy(o3, p2);strcat(o3, "+-");
2876 char*o4 = malloc(strlen(p2)+3);
2877 strcpy(o4, p2);strcat(o4, " ");
2879 for(t=0;t<n->num_children;t++) {
2880 fprintf(fi, "%s\n", o2);
2881 node_dump2(n->child[t], o3, t<n->num_children-1?o2:o4, fi);
2886 } else if(n->type == &node_const) {
2887 char*s = constant_tostring(n->value);
2888 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
2890 } else if(n->type == &node_code) {
2891 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, n->code.t?n->code.t->name:"*");
2892 code_dump2(n->code.c, 0, 0, (char*)p2, fi);
2894 fprintf(fi, "%s%s\n", p1, n->type->name);
2898 void node_dump(node_t*n)
2900 printf("------------VVVV---------------\n");
2901 node_dump2(n,"","",stdout);
2902 printf("-------------------------------\n");