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]);\
57 static classinfo_t*join_types(classinfo_t*type1, classinfo_t*type2, nodetype_t*t)
60 return registry_getanytype();
61 if(TYPE_IS_ANY(type1) || TYPE_IS_ANY(type2))
62 return registry_getanytype();
65 return registry_getanytype();
67 static char is_getlocal(code_t*c)
69 if(!c || c->prev || c->next)
71 return(c->opcode == OPCODE_GETLOCAL
72 || c->opcode == OPCODE_GETLOCAL_0
73 || c->opcode == OPCODE_GETLOCAL_1
74 || c->opcode == OPCODE_GETLOCAL_2
75 || c->opcode == OPCODE_GETLOCAL_3);
77 static int getlocalnr(code_t*c)
79 if(c->opcode == OPCODE_GETLOCAL) {return (ptroff_t)c->data[0];}
80 else if(c->opcode == OPCODE_GETLOCAL_0) {return 0;}
81 else if(c->opcode == OPCODE_GETLOCAL_1) {return 1;}
82 else if(c->opcode == OPCODE_GETLOCAL_2) {return 2;}
83 else if(c->opcode == OPCODE_GETLOCAL_3) {return 3;}
84 else syntaxerror("Internal error: opcode %02x is not a getlocal call", c->opcode);
89 int gettempvar(); /* FIXME: we should use a function pointer here */
92 static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char readbefore, char pushvalue)
96 [prefix code] [read instruction]
100 [prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar]
102 if(in && in->opcode == OPCODE_COERCE_A) {
103 in = code_cutlast(in);
106 syntaxerror("internal error");
108 /* chop off read instruction */
112 prefix = r->prev;r->prev = 0;
118 char use_temp_var = readbefore;
120 /* generate the write instruction, and maybe append a dup to the prefix code */
121 code_t* write = abc_nop(0);
122 if(r->opcode == OPCODE_GETPROPERTY) {
123 write->opcode = OPCODE_SETPROPERTY;
124 multiname_t*m = (multiname_t*)r->data[0];
125 write->data[0] = multiname_clone(m);
126 if(m->type == QNAME || m->type == MULTINAME) {
128 prefix = abc_dup(prefix); // we need the object, too
131 } else if(m->type == MULTINAMEL) {
133 /* dupping two values on the stack requires 5 operations and one register-
134 couldn't adobe just have given us a dup2? */
135 int temp = gettempvar();
136 prefix = abc_setlocal(prefix, temp);
137 prefix = abc_dup(prefix);
138 prefix = abc_getlocal(prefix, temp);
139 prefix = abc_swap(prefix);
140 prefix = abc_getlocal(prefix, temp);
142 prefix = abc_kill(prefix, temp);
146 syntaxerror("illegal lvalue: can't assign a value to this expression (not a qname/multiname)");
148 } else if(r->opcode == OPCODE_GETSLOT) {
149 write->opcode = OPCODE_SETSLOT;
150 write->data[0] = r->data[0];
152 prefix = abc_dup(prefix); // we need the object, too
155 } else if(r->opcode == OPCODE_GETLOCAL) {
156 write->opcode = OPCODE_SETLOCAL;
157 write->data[0] = r->data[0];
158 } else if(r->opcode == OPCODE_GETLOCAL_0) {
159 write->opcode = OPCODE_SETLOCAL_0;
160 } else if(r->opcode == OPCODE_GETLOCAL_1) {
161 write->opcode = OPCODE_SETLOCAL_1;
162 } else if(r->opcode == OPCODE_GETLOCAL_2) {
163 write->opcode = OPCODE_SETLOCAL_2;
164 } else if(r->opcode == OPCODE_GETLOCAL_3) {
165 write->opcode = OPCODE_SETLOCAL_3;
166 } else if(r->opcode == OPCODE_GETSUPER) {
167 write->opcode = OPCODE_SETSUPER;
168 multiname_t*m = (multiname_t*)r->data[0];
169 write->data[0] = multiname_clone(m);
172 syntaxerror("illegal lvalue: can't assign a value to this expression");
179 /* with getproperty/getslot, we have to be extra careful not
180 to execute the read code twice, as it might have side-effects
181 (e.g. if the property is in fact a setter/getter combination)
183 So read the value, modify it, and write it again,
184 using prefix only once and making sure (by using a temporary
185 register) that the return value is what we just wrote */
187 c = code_append(c, prefix);
188 c = code_append(c, r);
189 if(pushvalue && readbefore) {
191 c = abc_setlocal(c, temp);
193 c = code_append(c, middlepart);
194 if(pushvalue && !readbefore) {
196 c = abc_setlocal(c, temp);
198 c = code_append(c, write);
200 c = abc_getlocal(c, temp);
201 c = abc_kill(c, temp);
204 /* if we're allowed to execute the read code twice *and*
205 the middlepart doesn't modify the code, things are easier.
207 //c = code_append(c, prefix);
208 if(prefix) syntaxerror("internal error (prefix)");
213 c = code_append(c, r);
214 c = code_append(c, middlepart);
215 c = code_append(c, write);
217 c = code_append(c, r2);
221 /* even smaller version: overwrite the value without reading
225 c = code_append(c, prefix);
228 c = code_append(c, middlepart);
229 c = code_append(c, write);
231 c = code_append(c, r);
237 c = code_append(c, prefix);
239 c = code_append(c, middlepart);
242 c = abc_setlocal(c, temp);
244 c = code_append(c, write);
246 c = abc_getlocal(c, temp);
247 c = abc_kill(c, temp);
254 code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to);
256 // -------------------------- x + y -----------------------------------
258 typedcode_t node_plus_write(node_t*n)
260 syntaxerror("can't assign to this expression");
262 typedcode_t node_plus_read(node_t*n)
264 READ_HEADER_LEFTRIGHT;
265 c = code_append(left.c, right.c);
266 if(BOTH_INT(left.t, right.t)) {
271 t = join_types(left.t,right.t,n->type);
275 code_t* node_plus_exec(node_t*n)
277 EXEC_HEADER_LEFTRIGHT;
278 return code_append(left, right);
280 nodetype_t node_plus =
283 flags:NODE_HAS_CHILDREN,
284 write:node_plus_write,
289 // -------------------------- x - y -----------------------------------
291 typedcode_t node_minus_write(node_t*n)
293 syntaxerror("can't assign to this expression");
295 typedcode_t node_minus_read(node_t*n)
297 READ_HEADER_LEFTRIGHT;
298 c = code_append(left.c, right.c);
299 if(BOTH_INT(left.t,right.t)) {
300 c = abc_subtract_i(c);
308 code_t* node_minus_exec(node_t*n)
310 EXEC_HEADER_LEFTRIGHT;
311 return code_append(left, right);
313 nodetype_t node_minus =
316 flags:NODE_HAS_CHILDREN,
317 write: node_minus_write,
318 read: node_minus_read,
319 exec: node_minus_exec
322 // ---------------------------- ++x -----------------------------------
324 typedcode_t node_lplusplus_write(node_t*n)
326 syntaxerror("can't assign to this expression");
328 typedcode_t node_lplusplus_read(node_t*n)
332 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
333 int nr = getlocalnr(x.c);
334 code_free(x.c);x.c=0;
335 if(TYPE_IS_INT(x.t)) {
336 c = abc_inclocal_i(c, nr);
337 c = abc_getlocal(c, nr);
338 } else if(TYPE_IS_NUMBER(x.t)) {
339 c = abc_inclocal(c, nr);
340 c = abc_getlocal(c, nr);
341 } else syntaxerror("internal error");
343 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
344 c = abc_increment_i(c);
347 c = abc_increment(c);
350 c = converttype(c, t, x.t);
351 c = toreadwrite(x.c, c, 0, 0, 1);
356 code_t* node_lplusplus_exec(node_t*n)
358 typedcode_t x = n->child[0]->type->read(n->child[0]);
360 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
361 int nr = getlocalnr(x.c);
362 code_free(x.c);x.c=0;
363 if(TYPE_IS_INT(x.t)) {
364 c = abc_inclocal_i(c, nr);
365 } else if(TYPE_IS_NUMBER(x.t)) {
366 c = abc_inclocal(c, nr);
367 } else syntaxerror("internal error");
370 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
371 c = abc_increment_i(c);
374 c = abc_increment(c);
377 c = converttype(c, t, x.t); //convert back to original type
378 c = toreadwrite(x.c, c, 0, 0, 0);
383 nodetype_t node_lplusplus =
386 flags:NODE_HAS_CHILDREN,
387 write: node_lplusplus_write,
388 read: node_lplusplus_read,
389 exec: node_lplusplus_exec
393 // ---------------------------- --x -----------------------------------
395 typedcode_t node_lminusminus_write(node_t*n)
397 syntaxerror("can't assign to this expression");
399 typedcode_t node_lminusminus_read(node_t*n)
403 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
404 int nr = getlocalnr(x.c);
405 code_free(x.c);x.c=0;
406 if(TYPE_IS_INT(x.t)) {
407 c = abc_declocal_i(c, nr);
408 c = abc_getlocal(c, nr);
409 } else if(TYPE_IS_NUMBER(x.t)) {
410 c = abc_declocal(c, nr);
411 c = abc_getlocal(c, nr);
412 } else syntaxerror("internal error");
414 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
415 c = abc_decrement_i(c);
418 c = abc_decrement(c);
421 c = converttype(c, t, x.t);
422 c = toreadwrite(x.c, c, 0, 0, 1);
427 code_t* node_lminusminus_exec(node_t*n)
429 typedcode_t x = n->child[0]->type->read(n->child[0]);
431 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
432 int nr = getlocalnr(x.c);
433 code_free(x.c);x.c=0;
434 if(TYPE_IS_INT(x.t)) {
435 c = abc_declocal_i(c, nr);
436 } else if(TYPE_IS_NUMBER(x.t)) {
437 c = abc_declocal(c, nr);
438 } else syntaxerror("internal error");
441 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
442 c = abc_decrement_i(c);
445 c = abc_decrement(c);
448 c = converttype(c, t, x.t); //convert back to original type
449 c = toreadwrite(x.c, c, 0, 0, 0);
454 nodetype_t node_lminusminus =
457 flags:NODE_HAS_CHILDREN,
458 write: node_lminusminus_write,
459 read: node_lminusminus_read,
460 exec: node_lminusminus_exec
465 // ---------------------------- x++ -----------------------------------
467 typedcode_t node_rplusplus_write(node_t*n)
469 syntaxerror("can't assign to this expression");
471 typedcode_t node_rplusplus_read(node_t*n)
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_getlocal(0, nr);
480 c = abc_inclocal_i(c, nr);
481 } else if(TYPE_IS_NUMBER(x.t)) {
482 c = abc_getlocal(0, nr);
483 c = abc_inclocal(c, nr);
484 } else syntaxerror("internal error");
486 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
487 c = abc_increment_i(c);
490 c = abc_increment(c);
493 c = converttype(c, t, x.t);
494 c = toreadwrite(x.c, c, 0, 1, 1);
499 code_t* node_rplusplus_exec(node_t*n)
501 typedcode_t x = n->child[0]->type->read(n->child[0]);
503 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
504 int nr = getlocalnr(x.c);
505 code_free(x.c);x.c=0;
506 if(TYPE_IS_INT(x.t)) {
507 c = abc_inclocal_i(c, nr);
508 } else if(TYPE_IS_NUMBER(x.t)) {
509 c = abc_inclocal(c, nr);
510 } else syntaxerror("internal error");
513 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
514 c = abc_increment_i(c);
517 c = abc_increment(c);
520 c = converttype(c, t, x.t); //convert back to original type
521 c = toreadwrite(x.c, c, 0, 1, 0);
526 nodetype_t node_rplusplus =
529 flags:NODE_HAS_CHILDREN,
530 write: node_rplusplus_write,
531 read: node_rplusplus_read,
532 exec: node_rplusplus_exec
535 // ---------------------------- x-- -----------------------------------
537 typedcode_t node_rminusminus_write(node_t*n)
539 syntaxerror("can't assign to this expression");
541 typedcode_t node_rminusminus_read(node_t*n)
545 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
546 int nr = getlocalnr(x.c);
547 code_free(x.c);x.c=0;
548 if(TYPE_IS_INT(x.t)) {
549 c = abc_getlocal(0, nr);
550 c = abc_declocal_i(c, nr);
551 } else if(TYPE_IS_NUMBER(x.t)) {
552 c = abc_getlocal(0, nr);
553 c = abc_declocal(c, nr);
554 } else syntaxerror("internal error");
556 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
557 c = abc_decrement_i(c);
560 c = abc_decrement(c);
563 c = converttype(c, t, x.t);
564 c = toreadwrite(x.c, c, 0, 1, 1);
569 code_t* node_rminusminus_exec(node_t*n)
571 typedcode_t x = n->child[0]->type->read(n->child[0]);
573 if(is_getlocal(x.c) && (TYPE_IS_INT(x.t) || TYPE_IS_NUMBER(x.t))) {
574 int nr = getlocalnr(x.c);
575 code_free(x.c);x.c=0;
576 if(TYPE_IS_INT(x.t)) {
577 c = abc_declocal_i(c, nr);
578 } else if(TYPE_IS_NUMBER(x.t)) {
579 c = abc_declocal(c, nr);
580 } else syntaxerror("internal error");
583 if(TYPE_IS_INT(x.t) || TYPE_IS_UINT(x.t)) {
584 c = abc_decrement_i(c);
587 c = abc_decrement(c);
590 c = converttype(c, t, x.t); //convert back to original type
591 c = toreadwrite(x.c, c, 0, 1, 0);
596 nodetype_t node_rminusminus =
599 flags:NODE_HAS_CHILDREN,
600 write: node_rminusminus_write,
601 read: node_rminusminus_read,
602 exec: node_rminusminus_exec
605 // ---------------------------- x*y -----------------------------------
607 typedcode_t node_multiply_write(node_t*n)
609 syntaxerror("can't assign to this expression");
611 typedcode_t node_multiply_read(node_t*n)
613 READ_HEADER_LEFTRIGHT;
614 c = code_append(left.c,right.c);
615 if(BOTH_INT(left.t,right.t)) {
616 c = abc_multiply_i(c);
624 code_t* node_multiply_exec(node_t*n)
626 EXEC_HEADER_LEFTRIGHT;
627 return code_append(left, right);
629 nodetype_t node_multiply =
632 flags:NODE_HAS_CHILDREN,
633 write: node_multiply_write,
634 read: node_multiply_read,
635 exec: node_multiply_exec
638 // ---------------------------- x/y -----------------------------------
640 typedcode_t node_div_write(node_t*n)
642 syntaxerror("can't assign to this expression");
644 typedcode_t node_div_read(node_t*n)
646 READ_HEADER_LEFTRIGHT;
647 c = code_append(left.c, right.c);
652 code_t* node_div_exec(node_t*n)
654 EXEC_HEADER_LEFTRIGHT;
655 return code_append(left, right);
657 nodetype_t node_div =
660 flags:NODE_HAS_CHILDREN,
661 write: node_div_write,
666 // ---------------------------- x%y -----------------------------------
668 typedcode_t node_mod_write(node_t*n)
670 syntaxerror("can't assign to this expression");
672 typedcode_t node_mod_read(node_t*n)
674 READ_HEADER_LEFTRIGHT;
675 c = code_append(left.c, right.c);
680 code_t* node_mod_exec(node_t*n)
682 EXEC_HEADER_LEFTRIGHT;
683 return code_append(left, right);
685 nodetype_t node_mod =
688 flags:NODE_HAS_CHILDREN,
689 write: node_mod_write,
694 // ---------------------------- x<y -----------------------------------
696 typedcode_t node_lt_write(node_t*n)
698 syntaxerror("can't assign to this expression");
700 typedcode_t node_lt_read(node_t*n)
702 READ_HEADER_LEFTRIGHT;
703 c = code_append(left.c,right.c);
708 code_t* node_lt_exec(node_t*n)
710 EXEC_HEADER_LEFTRIGHT;
711 return code_append(left, right);
716 flags:NODE_HAS_CHILDREN,
717 write: node_lt_write,
722 // ---------------------------- x>y -----------------------------------
724 typedcode_t node_gt_write(node_t*n)
726 syntaxerror("can't assign to this expression");
728 typedcode_t node_gt_read(node_t*n)
730 READ_HEADER_LEFTRIGHT;
731 c = code_append(left.c,right.c);
732 c = abc_greaterthan(c);
736 code_t* node_gt_exec(node_t*n)
738 EXEC_HEADER_LEFTRIGHT;
739 return code_append(left, right);
744 flags:NODE_HAS_CHILDREN,
745 write: node_gt_write,
750 // ---------------------------- x<=y ----------------------------------
752 typedcode_t node_le_write(node_t*n)
754 syntaxerror("can't assign to this expression");
756 typedcode_t node_le_read(node_t*n)
758 READ_HEADER_LEFTRIGHT;
759 c = code_append(left.c,right.c);
760 c = abc_lessequals(c);
764 code_t* node_le_exec(node_t*n)
766 EXEC_HEADER_LEFTRIGHT;
767 return code_append(left, right);
769 nodetype_t node_le = //<=
772 flags:NODE_HAS_CHILDREN,
773 write: node_le_write,
778 // ---------------------------- x>=y ----------------------------------
780 typedcode_t node_ge_write(node_t*n)
782 syntaxerror("can't assign to this expression");
784 typedcode_t node_ge_read(node_t*n)
786 READ_HEADER_LEFTRIGHT;
787 c = code_append(left.c,right.c);
788 c = abc_greaterequals(c);
792 code_t* node_ge_exec(node_t*n)
794 EXEC_HEADER_LEFTRIGHT;
795 return code_append(left, right);
797 nodetype_t node_ge = //>=
800 flags:NODE_HAS_CHILDREN,
801 write: node_ge_write,
806 // ---------------------------- x==y ----------------------------------
808 typedcode_t node_eqeq_write(node_t*n)
810 syntaxerror("can't assign to this expression");
812 typedcode_t node_eqeq_read(node_t*n)
814 READ_HEADER_LEFTRIGHT;
815 c = code_append(left.c,right.c);
820 code_t* node_eqeq_exec(node_t*n)
822 EXEC_HEADER_LEFTRIGHT;
823 return code_append(left, right);
825 nodetype_t node_eqeq = //==
828 flags:NODE_HAS_CHILDREN,
829 write: node_eqeq_write,
830 read: node_eqeq_read,
834 // --------------------------- x===y ----------------------------------
836 typedcode_t node_eqeqeq_write(node_t*n)
838 syntaxerror("can't assign to this expression");
840 typedcode_t node_eqeqeq_read(node_t*n)
842 READ_HEADER_LEFTRIGHT;
843 c = code_append(left.c,right.c);
844 c = abc_strictequals(c);
848 code_t* node_eqeqeq_exec(node_t*n)
850 EXEC_HEADER_LEFTRIGHT;
851 return code_append(left, right);
853 nodetype_t node_eqeqeq = //===
856 flags:NODE_HAS_CHILDREN,
857 write: node_eqeqeq_write,
858 read: node_eqeqeq_read,
859 exec: node_eqeqeq_exec
862 // --------------------------- x!==y ----------------------------------
864 typedcode_t node_noteqeq_write(node_t*n)
866 syntaxerror("can't assign to this expression");
868 typedcode_t node_noteqeq_read(node_t*n)
870 READ_HEADER_LEFTRIGHT;
871 c = code_append(left.c,right.c);
872 c = abc_strictequals(c);
877 code_t* node_noteqeq_exec(node_t*n)
879 EXEC_HEADER_LEFTRIGHT;
880 return code_append(left, right);
882 nodetype_t node_noteqeq = //!==
885 flags:NODE_HAS_CHILDREN,
886 write: node_noteqeq_write,
887 read: node_noteqeq_read,
888 exec: node_noteqeq_exec
891 // --------------------------- x!=y ----------------------------------
893 typedcode_t node_noteq_write(node_t*n)
895 syntaxerror("can't assign to this expression");
897 typedcode_t node_noteq_read(node_t*n)
899 READ_HEADER_LEFTRIGHT;
900 c = code_append(left.c,right.c);
906 code_t* node_noteq_exec(node_t*n)
908 EXEC_HEADER_LEFTRIGHT;
909 return code_append(left, right);
911 nodetype_t node_noteq = //!=
914 flags:NODE_HAS_CHILDREN,
915 write: node_noteq_write,
916 read: node_noteq_read,
917 exec: node_noteq_exec
920 // --------------------------- x||y ----------------------------------
922 typedcode_t node_oror_write(node_t*n)
924 syntaxerror("can't assign to this expression");
926 typedcode_t node_oror_read(node_t*n)
928 READ_HEADER_LEFTRIGHT;
929 t = join_types(left.t, right.t, n->type);
931 c = converttype(c, left.t, t);
933 code_t*jmp = c = abc_iftrue(c, 0);
934 c = cut_last_push(c);
935 c = code_append(c, right.c);
936 c = converttype(c, right.t, t);
937 code_t*label = c = abc_label(c);
941 code_t* node_oror_exec(node_t*n)
943 typedcode_t left = n->child[0]->type->read(n->child[0]);
944 code_t* right = n->child[1]->type->exec(n->child[1]);
946 code_t*jmp = c = abc_iftrue(c, 0);
947 c = code_append(c, right);
948 code_t*label = c = abc_label(c);
952 nodetype_t node_oror = //||
955 flags:NODE_HAS_CHILDREN,
956 write: node_oror_write,
957 read: node_oror_read,
961 // --------------------------- x&&y ----------------------------------
963 typedcode_t node_andand_write(node_t*n)
965 syntaxerror("can't assign to this expression");
967 typedcode_t node_andand_read(node_t*n)
969 READ_HEADER_LEFTRIGHT;
970 t = join_types(left.t, right.t, &node_andand);
972 c = converttype(c, left.t, t);
974 code_t*jmp = c = abc_iffalse(c, 0);
975 c = cut_last_push(c);
976 c = code_append(c,right.c);
977 c = converttype(c, right.t, t);
978 code_t*label = c = abc_label(c);
982 code_t* node_andand_exec(node_t*n)
984 typedcode_t left = n->child[0]->type->read(n->child[0]);\
985 code_t* right = n->child[1]->type->exec(n->child[1]);\
987 code_t*jmp = c = abc_iffalse(c, 0);
988 c = code_append(c, right);
989 code_t*label = c = abc_label(c);
993 nodetype_t node_andand = //&&
996 flags:NODE_HAS_CHILDREN,
997 write: node_andand_write,
998 read: node_andand_read,
999 exec: node_andand_exec
1002 // ----------------------------- !x -----------------------------------
1004 typedcode_t node_not_write(node_t*n)
1006 syntaxerror("can't assign to this expression");
1008 typedcode_t node_not_read(node_t*n)
1016 code_t* node_not_exec(node_t*n)
1021 nodetype_t node_not =
1024 flags:NODE_HAS_CHILDREN,
1025 write: node_not_write,
1026 read: node_not_read,
1030 // ----------------------------- ~x -----------------------------------
1032 typedcode_t node_bitnot_write(node_t*n)
1034 syntaxerror("can't assign to this expression");
1036 typedcode_t node_bitnot_read(node_t*n)
1044 code_t* node_bitnot_exec(node_t*n)
1049 nodetype_t node_bitnot =
1052 flags:NODE_HAS_CHILDREN,
1053 write: node_bitnot_write,
1054 read: node_bitnot_read,
1055 exec: node_bitnot_exec
1058 // ----------------------------- x&y -----------------------------------
1060 typedcode_t node_bitand_write(node_t*n)
1062 syntaxerror("can't assign to this expression");
1064 typedcode_t node_bitand_read(node_t*n)
1066 READ_HEADER_LEFTRIGHT;
1067 c = code_append(left.c,right.c);
1072 code_t* node_bitand_exec(node_t*n)
1074 EXEC_HEADER_LEFTRIGHT;
1075 return code_append(left, right);
1077 nodetype_t node_bitand =
1080 flags:NODE_HAS_CHILDREN,
1081 write: node_bitand_write,
1082 read: node_bitand_read,
1083 exec: node_bitand_exec
1086 // ----------------------------- x^y -----------------------------------
1088 typedcode_t node_bitxor_write(node_t*n)
1090 syntaxerror("can't assign to this expression");
1092 typedcode_t node_bitxor_read(node_t*n)
1094 READ_HEADER_LEFTRIGHT;
1095 c = code_append(left.c,right.c);
1100 code_t* node_bitxor_exec(node_t*n)
1102 EXEC_HEADER_LEFTRIGHT;
1103 return code_append(left, right);
1105 nodetype_t node_bitxor =
1108 flags:NODE_HAS_CHILDREN,
1109 write: node_bitxor_write,
1110 read: node_bitxor_read,
1111 exec: node_bitxor_exec
1114 // ----------------------------- x|y -----------------------------------
1116 typedcode_t node_bitor_write(node_t*n)
1118 syntaxerror("can't assign to this expression");
1120 typedcode_t node_bitor_read(node_t*n)
1122 READ_HEADER_LEFTRIGHT;
1123 c = code_append(left.c,right.c);
1128 code_t* node_bitor_exec(node_t*n)
1130 EXEC_HEADER_LEFTRIGHT;
1131 return code_append(left, right);
1133 nodetype_t node_bitor =
1136 flags:NODE_HAS_CHILDREN,
1137 write: node_bitor_write,
1138 read: node_bitor_read,
1139 exec: node_bitor_exec
1142 // ---------------------------- x>>y -----------------------------------
1144 typedcode_t node_shr_write(node_t*n)
1146 syntaxerror("can't assign to this expression");
1148 typedcode_t node_shr_read(node_t*n)
1150 READ_HEADER_LEFTRIGHT;
1151 c = code_append(left.c,right.c);
1156 code_t* node_shr_exec(node_t*n)
1158 EXEC_HEADER_LEFTRIGHT;
1159 return code_append(left, right);
1161 nodetype_t node_shr = //>>
1164 flags:NODE_HAS_CHILDREN,
1165 write: node_shr_write,
1166 read: node_shr_read,
1170 // ---------------------------- x<<y -----------------------------------
1172 typedcode_t node_shl_write(node_t*n)
1174 syntaxerror("can't assign to this expression");
1176 typedcode_t node_shl_read(node_t*n)
1178 READ_HEADER_LEFTRIGHT;
1179 c = code_append(left.c,right.c);
1184 code_t* node_shl_exec(node_t*n)
1186 EXEC_HEADER_LEFTRIGHT;
1187 return code_append(left, right);
1189 nodetype_t node_shl = //<<
1192 flags:NODE_HAS_CHILDREN,
1193 write: node_shl_write,
1194 read: node_shl_read,
1198 // ---------------------------- x>>>y -----------------------------------
1200 typedcode_t node_ushr_write(node_t*n)
1202 syntaxerror("can't assign to this expression");
1204 typedcode_t node_ushr_read(node_t*n)
1206 READ_HEADER_LEFTRIGHT;
1207 c = code_append(left.c,right.c);
1212 code_t* node_ushr_exec(node_t*n)
1214 EXEC_HEADER_LEFTRIGHT;
1215 return code_append(left, right);
1217 nodetype_t node_ushr = //>>>
1220 flags:NODE_HAS_CHILDREN,
1221 write: node_ushr_write,
1222 read: node_ushr_read,
1223 exec: node_ushr_exec
1226 // ---------------------------- x in y ----------------------------------
1228 typedcode_t node_in_write(node_t*n)
1230 syntaxerror("can't assign to this expression");
1232 typedcode_t node_in_read(node_t*n)
1234 READ_HEADER_LEFTRIGHT;
1235 c = code_append(left.c,right.c);
1240 code_t* node_in_exec(node_t*n)
1242 EXEC_HEADER_LEFTRIGHT;
1243 return code_append(left, right);
1245 nodetype_t node_in = //in
1248 flags:NODE_HAS_CHILDREN,
1249 write: node_in_write,
1254 // ---------------------------- x as y ----------------------------------
1256 typedcode_t node_as_write(node_t*n)
1259 syntaxerror("can't assign to this expression");
1261 typedcode_t node_as_read(node_t*n)
1263 READ_HEADER_LEFTRIGHT;
1264 c = code_append(left.c, right.c);
1265 c = abc_astypelate(c);
1269 code_t* node_as_exec(node_t*n)
1271 /* we assume here that "as" doesn't have side-effects (like
1272 early run time type checking) */
1273 EXEC_HEADER_LEFTRIGHT;
1274 return code_append(left, right);
1276 nodetype_t node_as = //as
1279 flags:NODE_HAS_CHILDREN,
1280 write: node_as_write,
1285 // ------------------------- x instanceof y -----------------------------
1287 typedcode_t node_instanceof_write(node_t*n)
1289 syntaxerror("can't assign to this expression");
1291 typedcode_t node_instanceof_read(node_t*n)
1293 READ_HEADER_LEFTRIGHT;
1294 c = code_append(left.c, right.c);
1295 c = abc_instanceof(c);
1299 code_t* node_instanceof_exec(node_t*n)
1301 EXEC_HEADER_LEFTRIGHT;
1302 return code_append(left, right);
1304 nodetype_t node_instanceof = //instanceof
1307 flags:NODE_HAS_CHILDREN,
1308 write: node_instanceof_write,
1309 read: node_instanceof_read,
1310 exec: node_instanceof_exec
1313 // ------------------------- x is y --------------------------------------
1315 typedcode_t node_is_write(node_t*n)
1317 syntaxerror("can't assign to this expression");
1319 typedcode_t node_is_read(node_t*n)
1321 READ_HEADER_LEFTRIGHT;
1322 c = code_append(left.c, right.c);
1323 c = abc_istypelate(c);
1327 code_t* node_is_exec(node_t*n)
1329 EXEC_HEADER_LEFTRIGHT;
1330 return code_append(left, right);
1332 nodetype_t node_is = //is
1335 flags:NODE_HAS_CHILDREN,
1336 write: node_is_write,
1341 // ------------------------- x[y] --------------------------------------
1343 typedcode_t node_arraylookup_write(node_t*n)
1345 syntaxerror("not implemented yet");
1347 typedcode_t node_arraylookup_read(node_t*n)
1349 READ_HEADER_LEFTRIGHT;
1350 c = code_append(left.c, right.c);
1352 /* XXX not sure whether this access logic is correct */
1353 namespace_t ns = {left.t?left.t->access:ACCESS_PACKAGE, ""};
1354 namespace_set_t nsset;
1355 namespace_list_t l;l.next = 0;
1356 nsset.namespaces = &l;
1358 multiname_t m = {MULTINAMEL, 0, &nsset, 0};
1360 c = abc_getproperty2(c, &m);
1361 t = 0; // array elements have unknown type
1364 code_t* node_arraylookup_exec(node_t*n)
1366 EXEC_HEADER_LEFTRIGHT;
1367 return code_append(left, right);
1369 nodetype_t node_arraylookup =
1371 name: "arraylookup",
1372 flags:NODE_HAS_CHILDREN,
1373 write: node_arraylookup_write,
1374 read: node_arraylookup_read,
1375 exec: node_arraylookup_exec
1378 // ------------------------- typeof(x) ------------------------------------
1380 typedcode_t node_typeof_write(node_t*n)
1382 syntaxerror("can't assign to this expression");
1384 typedcode_t node_typeof_read(node_t*n)
1392 code_t* node_typeof_exec(node_t*n)
1397 nodetype_t node_typeof = //typeof
1400 flags:NODE_HAS_CHILDREN,
1401 write: node_typeof_write,
1402 read: node_typeof_read,
1403 exec: node_typeof_exec
1406 // ------------------------- (void)(x) ------------------------------------
1408 typedcode_t node_void_write(node_t*n)
1410 syntaxerror("can't assign to this expression");
1412 typedcode_t node_void_read(node_t*n)
1414 code_t*c = n->type->exec(n);
1415 c = abc_pushundefined(c);
1416 classinfo_t*t = TYPE_ANY;
1419 code_t* node_void_exec(node_t*n)
1424 nodetype_t node_void = //void
1427 flags:NODE_HAS_CHILDREN,
1428 write: node_void_write,
1429 read: node_void_read,
1430 exec: node_void_exec
1433 // ---------------------------- -x ----------------------------------------
1435 typedcode_t node_neg_write(node_t*n)
1437 syntaxerror("can't assign to this expression");
1439 typedcode_t node_neg_read(node_t*n)
1444 c = abc_negate_i(c);
1452 code_t* node_neg_exec(node_t*n)
1457 nodetype_t node_neg = //-
1460 flags:NODE_HAS_CHILDREN,
1461 write: node_neg_write,
1462 read: node_neg_read,
1466 // ---------------------------- x*=y ----------------------------------------
1468 typedcode_t node_muleq_write(node_t*n)
1470 syntaxerror("can't assign to this expression");
1472 typedcode_t node_muleq_read(node_t*n)
1474 READ_HEADER_LEFTRIGHT;
1477 if(BOTH_INT(left.t,right.t)) {
1478 c=abc_multiply_i(c);
1484 c=converttype(c, f, left.t);
1485 c = toreadwrite(left.c, c, 0, 0, 1);
1489 code_t* node_muleq_exec(node_t*n)
1491 READ_HEADER_LEFTRIGHT;
1494 if(BOTH_INT(left.t,right.t)) {
1495 c=abc_multiply_i(c);
1501 c = converttype(c, f, left.t);
1502 return toreadwrite(left.c, c, 0, 0, 0);
1504 nodetype_t node_muleq =
1507 flags:NODE_HAS_CHILDREN,
1508 write: node_muleq_write,
1509 read: node_muleq_read,
1510 exec: node_muleq_exec
1513 // ---------------------------- x%=y ----------------------------------------
1515 typedcode_t node_modeq_write(node_t*n)
1517 syntaxerror("can't assign to this expression");
1519 typedcode_t node_modeq_read(node_t*n)
1521 READ_HEADER_LEFTRIGHT;
1522 c = abc_modulo(right.c);
1523 c = converttype(c, TYPE_NUMBER, left.t);
1524 c = toreadwrite(left.c, c, 0, 0, 1);
1528 code_t* node_modeq_exec(node_t*n)
1530 READ_HEADER_LEFTRIGHT;
1531 c = abc_modulo(right.c);
1532 c = converttype(c, TYPE_NUMBER, left.t);
1533 return toreadwrite(left.c, c, 0, 0, 0);
1535 nodetype_t node_modeq = //%=
1538 flags:NODE_HAS_CHILDREN,
1539 write: node_modeq_write,
1540 read: node_modeq_read,
1541 exec: node_modeq_exec
1544 // ---------------------------- x<<=y ----------------------------------------
1546 typedcode_t node_shleq_write(node_t*n)
1548 syntaxerror("can't assign to this expression");
1550 typedcode_t node_shleq_read(node_t*n)
1552 READ_HEADER_LEFTRIGHT;
1553 c = abc_lshift(right.c);
1554 c = converttype(c, TYPE_INT, left.t);
1555 c = toreadwrite(left.c, c, 0, 0, 1);
1559 code_t* node_shleq_exec(node_t*n)
1561 READ_HEADER_LEFTRIGHT;
1562 c = abc_lshift(right.c);
1563 c = converttype(c, TYPE_INT, left.t);
1564 return toreadwrite(left.c, c, 0, 0, 0);
1566 nodetype_t node_shleq = //<<=
1569 flags:NODE_HAS_CHILDREN,
1570 write: node_shleq_write,
1571 read: node_shleq_read,
1572 exec: node_shleq_exec
1575 // ---------------------------- x>>=y ----------------------------------------
1577 typedcode_t node_shreq_write(node_t*n)
1579 syntaxerror("can't assign to this expression");
1581 typedcode_t node_shreq_read(node_t*n)
1583 READ_HEADER_LEFTRIGHT;
1584 c = abc_rshift(right.c);
1585 c = converttype(c, TYPE_INT, left.t);
1586 c = toreadwrite(left.c, c, 0, 0, 1);
1590 code_t* node_shreq_exec(node_t*n)
1592 READ_HEADER_LEFTRIGHT;
1593 c = abc_rshift(right.c);
1594 c = converttype(c, TYPE_INT, left.t);
1595 return toreadwrite(left.c, c, 0, 0, 0);
1597 nodetype_t node_shreq = //>>=
1600 flags:NODE_HAS_CHILDREN,
1601 write: node_shreq_write,
1602 read: node_shreq_read,
1603 exec: node_shreq_exec
1606 // --------------------------- x>>>=y ----------------------------------------
1608 typedcode_t node_ushreq_write(node_t*n)
1610 syntaxerror("can't assign to this expression");
1612 typedcode_t node_ushreq_read(node_t*n)
1614 READ_HEADER_LEFTRIGHT;
1615 c = abc_urshift(right.c);
1616 c = converttype(c, TYPE_UINT, left.t);
1617 c = toreadwrite(left.c, c, 0, 0, 1);
1621 code_t* node_ushreq_exec(node_t*n)
1623 READ_HEADER_LEFTRIGHT;
1624 c = abc_urshift(right.c);
1625 c = converttype(c, TYPE_UINT, left.t);
1626 return toreadwrite(left.c, c, 0, 0, 0);
1628 nodetype_t node_ushreq = //>>>=
1631 flags:NODE_HAS_CHILDREN,
1632 write: node_ushreq_write,
1633 read: node_ushreq_read,
1634 exec: node_ushreq_exec
1637 // --------------------------- x/=y ----------------------------------------
1639 typedcode_t node_diveq_write(node_t*n)
1641 syntaxerror("can't assign to this expression");
1643 typedcode_t node_diveq_read(node_t*n)
1645 READ_HEADER_LEFTRIGHT;
1646 c = abc_divide(right.c);
1647 c = converttype(c, TYPE_NUMBER, left.t);
1648 c = toreadwrite(left.c, c, 0, 0, 1);
1652 code_t* node_diveq_exec(node_t*n)
1654 READ_HEADER_LEFTRIGHT;
1655 c = abc_divide(right.c);
1656 c = converttype(c, TYPE_NUMBER, left.t);
1657 return toreadwrite(left.c, c, 0, 0, 0);
1659 nodetype_t node_diveq =
1662 flags:NODE_HAS_CHILDREN,
1663 write: node_diveq_write,
1664 read: node_diveq_read,
1665 exec: node_diveq_exec
1668 // --------------------------- x|=y ----------------------------------------
1670 typedcode_t node_bitoreq_write(node_t*n)
1672 syntaxerror("can't assign to this expression");
1674 typedcode_t node_bitoreq_read(node_t*n)
1676 READ_HEADER_LEFTRIGHT;
1677 c = abc_bitor(right.c);
1678 c = converttype(c, TYPE_INT, left.t);
1679 c = toreadwrite(left.c, c, 0, 0, 1);
1683 code_t* node_bitoreq_exec(node_t*n)
1685 READ_HEADER_LEFTRIGHT;
1686 c = abc_bitor(right.c);
1687 c = converttype(c, TYPE_INT, left.t);
1688 return toreadwrite(left.c, c, 0, 0, 0);
1690 nodetype_t node_bitoreq = //|=
1693 flags:NODE_HAS_CHILDREN,
1694 write: node_bitoreq_write,
1695 read: node_bitoreq_read,
1696 exec: node_bitoreq_exec
1699 // --------------------------- x^=y ----------------------------------------
1701 typedcode_t node_bitxoreq_write(node_t*n)
1703 syntaxerror("can't assign to this expression");
1705 typedcode_t node_bitxoreq_read(node_t*n)
1707 READ_HEADER_LEFTRIGHT;
1708 c = abc_bitxor(right.c);
1709 c = converttype(c, TYPE_INT, left.t);
1710 c = toreadwrite(left.c, c, 0, 0, 1);
1714 code_t* node_bitxoreq_exec(node_t*n)
1716 READ_HEADER_LEFTRIGHT;
1717 c = abc_bitxor(right.c);
1718 c = converttype(c, TYPE_INT, left.t);
1719 return toreadwrite(left.c, c, 0, 0, 0);
1721 nodetype_t node_bitxoreq = //^=
1724 flags:NODE_HAS_CHILDREN,
1725 write: node_bitxoreq_write,
1726 read: node_bitxoreq_read,
1727 exec: node_bitxoreq_exec
1730 // --------------------------- x&=y ----------------------------------------
1732 typedcode_t node_bitandeq_write(node_t*n)
1734 syntaxerror("can't assign to this expression");
1736 typedcode_t node_bitandeq_read(node_t*n)
1738 READ_HEADER_LEFTRIGHT;
1739 c = abc_bitand(right.c);
1740 c = converttype(c, TYPE_INT, left.t);
1741 c = toreadwrite(left.c, c, 0, 0, 1);
1745 code_t* node_bitandeq_exec(node_t*n)
1747 READ_HEADER_LEFTRIGHT;
1748 c = abc_bitand(right.c);
1749 c = converttype(c, TYPE_INT, left.t);
1750 return toreadwrite(left.c, c, 0, 0, 0);
1752 nodetype_t node_bitandeq = //^=
1755 flags:NODE_HAS_CHILDREN,
1756 write: node_bitandeq_write,
1757 read: node_bitandeq_read,
1758 exec: node_bitandeq_exec
1761 // --------------------------- x+=y ----------------------------------------
1763 typedcode_t node_pluseq_write(node_t*n)
1765 syntaxerror("can't assign to this expression");
1767 typedcode_t node_pluseq_read(node_t*n)
1769 READ_HEADER_LEFTRIGHT;
1771 if(TYPE_IS_INT(left.t)) {
1775 c = converttype(c, TYPE_NUMBER, left.t);
1777 c = toreadwrite(left.c, c, 0, 0, 1);
1781 code_t* node_pluseq_exec(node_t*n)
1783 READ_HEADER_LEFTRIGHT;
1785 if(TYPE_IS_INT(left.t)) {
1789 c = converttype(c, TYPE_NUMBER, left.t);
1791 return toreadwrite(left.c, c, 0, 0, 0);
1793 nodetype_t node_pluseq = //+=
1796 flags:NODE_HAS_CHILDREN,
1797 write: node_pluseq_write,
1798 read: node_pluseq_read,
1799 exec: node_pluseq_exec
1802 // --------------------------- x-=y ----------------------------------------
1804 typedcode_t node_minuseq_write(node_t*n)
1806 syntaxerror("can't assign to this expression");
1808 typedcode_t node_minuseq_read(node_t*n)
1810 READ_HEADER_LEFTRIGHT;
1812 if(TYPE_IS_INT(left.t)) {
1813 c = abc_subtract_i(c);
1815 c = abc_subtract(c);
1816 c = converttype(c, TYPE_NUMBER, left.t);
1818 c = toreadwrite(left.c, c, 0, 0, 1);
1822 code_t* node_minuseq_exec(node_t*n)
1824 READ_HEADER_LEFTRIGHT;
1826 if(TYPE_IS_INT(left.t)) {
1827 c = abc_subtract_i(c);
1829 c = abc_subtract(c);
1830 c = converttype(c, TYPE_NUMBER, left.t);
1832 return toreadwrite(left.c, c, 0, 0, 0);
1834 nodetype_t node_minuseq = //-=
1837 flags:NODE_HAS_CHILDREN,
1838 write: node_minuseq_write,
1839 read: node_minuseq_read,
1840 exec: node_minuseq_exec
1843 // --------------------------- x=y -----------------------------------------
1845 typedcode_t node_assign_write(node_t*n)
1847 syntaxerror("can't assign to this expression");
1849 typedcode_t node_assign_read(node_t*n)
1851 READ_HEADER_LEFTRIGHT;
1853 c = converttype(c, right.t, left.t);
1854 c = toreadwrite(left.c, c, 1, 0, 1);
1858 code_t* node_assign_exec(node_t*n)
1860 READ_HEADER_LEFTRIGHT;
1862 c = converttype(c, right.t, left.t);
1863 return toreadwrite(left.c, c, 1, 0, 0);
1865 nodetype_t node_assign =
1868 flags:NODE_HAS_CHILDREN,
1869 write: node_assign_write,
1870 read: node_assign_read,
1871 exec: node_assign_exec
1874 // --------------------------- x?y1:y2 --------------------------------------
1876 typedcode_t node_tenary_write(node_t*n)
1878 /* TODO: this might actually be kinda useful.
1879 (global?global.x:this.x) = 3;
1881 syntaxerror("can't assign to this expression");
1883 typedcode_t node_tenary_read(node_t*n)
1885 typedcode_t cond = n->child[0]->type->read(n->child[0]);
1886 typedcode_t left = n->child[1]->type->read(n->child[1]);
1887 typedcode_t right = n->child[2]->type->read(n->child[2]);
1888 classinfo_t*t = join_types(left.t,right.t,&node_tenary);
1890 code_t*j1 = c = abc_iffalse(c, 0);
1891 c = code_append(c, left.c);
1892 c = converttype(c, left.t, t);
1893 code_t*j2 = c = abc_jump(c, 0);
1894 c = j1->branch = abc_label(c);
1895 c = code_append(c, right.c);
1896 c = converttype(c, right.t, t);
1897 c = j2->branch = abc_label(c);
1900 code_t* node_tenary_exec(node_t*n)
1902 typedcode_t cond = n->child[0]->type->read(n->child[0]);
1903 code_t* left = n->child[1]->type->exec(n->child[1]);
1904 code_t* right = n->child[2]->type->exec(n->child[2]);
1906 code_t*j1 = c = abc_iffalse(c, 0);
1907 c = code_append(c, left);
1908 code_t*j2 = c = abc_jump(c, 0);
1909 c = j1->branch = abc_label(c);
1910 c = code_append(c, right);
1911 c = j2->branch = abc_label(c);
1914 nodetype_t node_tenary =
1917 flags:NODE_HAS_CHILDREN,
1918 write: node_tenary_write,
1919 read: node_tenary_read,
1920 exec: node_tenary_exec
1923 // ---------------------------- comma ----------------------------------------
1925 typedcode_t node_comma_write(node_t*n)
1927 syntaxerror("can't assign to this expression");
1929 typedcode_t node_comma_read(node_t*n)
1934 for(i=0;i<n->num_children-1;i++) {
1935 c = code_append(c, n->child[i]->type->exec(n->child[i]));
1937 typedcode_t o = n->child[i]->type->read(n->child[i]);
1938 c = code_append(c, o.c);
1942 code_t* node_comma_exec(node_t*n)
1946 for(t=0;t<n->num_children;t++) {
1947 c = code_append(c, n->child[t]->type->exec(n->child[t]));
1951 nodetype_t node_comma =
1954 flags: NODE_HAS_CHILDREN,
1955 write: node_comma_write,
1956 read: node_comma_read,
1957 exec: node_comma_exec
1962 // -------------------------- new x -----------------------------------
1964 typedcode_t node_new_write(node_t*n)
1967 typedcode_t node_new_read(node_t*n)
1970 code_t* node_new_exec(node_t*n)
1973 nodetype_t node_new = //new
1975 write: node_new_write,
1976 read: node_new_read,
1980 // ------------------------ delete x ----------------------------------
1982 typedcode_t node_delete_write(node_t*n)
1985 typedcode_t node_delete_read(node_t*n)
1988 code_t* node_delete_exec(node_t*n)
1991 nodetype_t node_delete = //delete
1993 write: node_delete_write,
1994 read: node_delete_read,
1995 exec: node_delete_exec
1998 // ---------------------------- x.y -----------------------------------
2000 typedcode_t node_dot_write(node_t*n)
2003 typedcode_t node_dot_read(node_t*n)
2006 code_t* node_dot_exec(node_t*n)
2009 nodetype_t node_dot =
2011 write: node_dot_write,
2012 read: node_dot_read,
2016 // --------------------------- x..y -----------------------------------
2018 typedcode_t node_dotdot_write(node_t*n)
2021 typedcode_t node_dotdot_read(node_t*n)
2024 code_t* node_dotdot_exec(node_t*n)
2028 nodetype_t node_dotdot = //..
2030 write: node_dotdot_write,
2031 read: node_dotdot_read,
2032 exec: node_dotdot_exec
2035 // --------------------------- x.@y -----------------------------------
2037 typedcode_t node_dotat_write(node_t*n)
2040 typedcode_t node_dotat_read(node_t*n)
2043 code_t* node_dotat_exec(node_t*n)
2046 nodetype_t node_dotat = //.@
2048 write: node_dotat_write,
2049 read: node_dotat_read,
2050 exec: node_dotat_exec
2053 // --------------------------- x.*y -----------------------------------
2055 typedcode_t node_dotstar_write(node_t*n)
2058 typedcode_t node_dotstar_read(node_t*n)
2061 code_t* node_dotstar_exec(node_t*n)
2064 nodetype_t node_dotstar = //.*
2066 write: node_dotstar_write,
2067 read: node_dotstar_read,
2068 exec: node_dotstar_exec
2071 // -------------------------- x.(y) -----------------------------------
2073 typedcode_t node_filter_write(node_t*n)
2076 typedcode_t node_filter_read(node_t*n)
2079 code_t* node_filter_exec(node_t*n)
2082 nodetype_t node_filter = //.(
2084 write: node_filter_write,
2085 read: node_filter_read,
2086 exec: node_filter_exec
2089 // ------------------------ x(y1,...,yn) ------------------------------
2091 typedcode_t node_call_write(node_t*n)
2094 typedcode_t node_call_read(node_t*n)
2097 code_t* node_call_exec(node_t*n)
2100 nodetype_t node_call = //functioncall
2102 write: node_call_write,
2103 read: node_call_read,
2104 exec: node_call_exec
2107 // ------------------------------ @x ----------------------------------------
2109 typedcode_t node_at_write(node_t*n)
2112 typedcode_t node_at_read(node_t*n)
2115 code_t* node_at_exec(node_t*n)
2118 nodetype_t node_at = //@
2120 write: node_at_write,
2125 // ---------------------------- x.ns::y ----------------------------------------
2127 typedcode_t node_dotns_write(node_t*n)
2130 typedcode_t node_dotns_read(node_t*n)
2133 code_t* node_dotns_exec(node_t*n)
2136 nodetype_t node_dotns = //.::
2138 write: node_dotns_write,
2139 read: node_dotns_read,
2140 exec: node_dotns_exec
2144 // ------------------------ constant ------------------------------
2146 typedcode_t node_const_write(node_t*n)
2148 syntaxerror("can't assign a value to a constant");
2150 typedcode_t node_const_read(node_t*n)
2152 constant_t*v = n->value;
2157 if(v->i>-128 && v->i<128) {
2158 c = abc_pushbyte(0,v->i);
2159 } else if(v->i>=-32768 && v->i<32768) {
2160 c = abc_pushshort(0,v->i);
2162 c = abc_pushint(0,v->i);
2167 c = abc_pushuint(0,v->u);
2169 c = abc_pushbyte(0,v->u);
2170 } else if(v->u<32768) {
2171 c = abc_pushshort(0,v->u);
2173 c = abc_pushint(0,v->u);
2177 case CONSTANT_FLOAT:
2178 c = abc_pushdouble(0,v->f);
2182 c = abc_pushtrue(0);
2185 case CONSTANT_FALSE:
2186 c = abc_pushfalse(0);
2190 c = abc_pushnull(0);
2193 case CONSTANT_STRING:
2194 c = abc_pushstring2(0,v->s);
2197 case CONSTANT_UNDEFINED:
2198 c = abc_pushundefined(0);
2201 case CONSTANT_NAMESPACE:
2202 case CONSTANT_NAMESPACE_PACKAGE:
2203 case CONSTANT_NAMESPACE_PACKAGEINTERNAL:
2204 case CONSTANT_NAMESPACE_PROTECTED:
2205 case CONSTANT_NAMESPACE_EXPLICIT:
2206 case CONSTANT_NAMESPACE_STATICPROTECTED:
2207 case CONSTANT_NAMESPACE_PRIVATE:
2208 c = abc_pushnamespace(0, v->ns);
2210 default: syntaxerror("invalid constant");
2215 code_t* node_const_exec(node_t*n)
2219 nodetype_t node_const =
2223 write: node_const_write,
2224 read: node_const_read,
2225 exec: node_const_exec
2228 // ------------------------ code node ------------------------------
2230 typedcode_t node_code_write(node_t*n)
2232 syntaxerror("not implemented yet");
2234 typedcode_t node_code_read(node_t*n)
2236 /* TODO: this dup might be unnecessary- n->code.c is only read out once */
2238 t.c = code_dup(n->code.c);
2242 code_t* node_code_exec(node_t*n)
2244 code_t*c = code_dup(n->code.c);
2245 c = cut_last_push(c);
2248 nodetype_t node_code =
2252 write: node_code_write,
2253 read: node_code_read,
2254 exec: node_code_exec
2257 // ------------------------ code node ------------------------------
2259 typedcode_t node_dummy_write(node_t*n)
2261 syntaxerror("not implemented yet");
2263 typedcode_t node_dummy_read(node_t*n)
2266 t.c = abc_pushundefined(0);
2270 code_t* node_dummy_exec(node_t*n)
2274 nodetype_t node_dummy =
2278 write: node_dummy_write,
2279 read: node_dummy_read,
2280 exec: node_dummy_exec
2283 // ======================== node handling ==============================
2285 node_t* mkdummynode()
2287 node_t*n = (node_t*)rfx_calloc(sizeof(node_t));
2288 n->type = &node_dummy;
2292 node_t* mkconstnode(constant_t*c)
2294 node_t*n = (node_t*)malloc(sizeof(node_t));
2295 n->type = &node_const;
2301 node_t* mkcodenode(typedcode_t c)
2303 node_t*n = (node_t*)malloc(sizeof(node_t));
2304 n->type = &node_code;
2310 node_t* mkmultinode(nodetype_t*t, node_t*one)
2312 node_t*n = (node_t*)malloc(sizeof(node_t));
2315 n->child = (node_t**)malloc(sizeof(node_t*)*1);
2317 n->num_children = 1;
2321 node_t* multinode_extend(node_t*n, node_t*add)
2323 n->child = realloc(n->child, (n->num_children+1)*sizeof(node_t*));
2324 n->child[n->num_children] = add;
2329 node_t* mknode1(nodetype_t*t, node_t*node)
2331 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*2);
2332 node_t**x = (node_t**)&n[1];
2336 n->num_children = 1;
2342 node_t* mknode2(nodetype_t*t, node_t*left, node_t*right)
2344 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*3);
2345 node_t**x = (node_t**)&n[1];
2349 n->num_children = 2;
2355 node_t* mknode3(nodetype_t*t, node_t*one, node_t*two, node_t*three)
2357 node_t*n = (node_t*)malloc(sizeof(node_t)+sizeof(node_t*)*4);
2358 node_t**x = (node_t**)&n[1];
2362 n->num_children = 3;
2370 void node_free(node_t*n)
2373 if(n->type == &node_const) {
2374 constant_free(n->value);n->value = 0;
2376 else if(n->type == &node_code) {
2377 code_free(n->code.c);n->code.c = 0;
2379 else for(t=0;t<n->num_children;t++) {
2380 node_free(n->child[t]);n->child[t] = 0;
2385 typedcode_t node_read(node_t*n)
2387 typedcode_t t = n->type->read(n);
2391 code_t* node_exec(node_t*n)
2393 code_t*c = n->type->exec(n);
2411 void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
2413 if(n->type->flags&NODE_HAS_CHILDREN) {
2414 fprintf(fi, "%s%s\n", p1, n->type->name);
2416 char*o2 = malloc(strlen(p2)+3);
2417 strcpy(o2, p2);strcat(o2, "| ");
2418 char*o3 = malloc(strlen(p2)+3);
2419 strcpy(o3, p2);strcat(o3, "+-");
2420 char*o4 = malloc(strlen(p2)+3);
2421 strcpy(o4, p2);strcat(o4, " ");
2423 for(t=0;t<n->num_children;t++) {
2424 fprintf(fi, "%s\n", o2);
2425 node_dump2(n->child[t], o3, t<n->num_children-1?o2:o4, fi);
2430 } else if(n->type == &node_const) {
2431 char*s = constant_tostring(n->value);
2432 fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
2434 } else if(n->type == &node_code) {
2435 fprintf(fi, "%s%s\n", p1, n->type->name);
2436 code_dump2(n->code.c, 0, 0, (char*)p2, fi);
2438 fprintf(fi, "%s%s\n", p1, n->type->name);
2442 void node_dump(node_t*n)
2444 printf("---------------------------VVVV\n");
2445 node_dump2(n,"","",stdout);
2446 printf("---------------------------^^^^\n");