2 * copyright 2004, Jean-Christophe Hoelt <jeko@ios-software.com>
4 * This program is released under the terms of the GNU Lesser General Public Licence.
12 #include "goomsl_private.h"
14 #define STRUCT_ALIGNMENT 16
19 extern GoomSL *currentGoomSL;
21 static NodeType *nodeNew(const char *str, int type, int line_number);
22 static NodeType *nodeClone(NodeType *node);
23 static void nodeFreeInternals(NodeType *node);
24 static void nodeFree(NodeType *node);
26 static void commit_node(NodeType *node, int releaseIfTemp);
27 static void precommit_node(NodeType *node);
29 static NodeType *new_constInt(const char *str, int line_number);
30 static NodeType *new_constFloat(const char *str, int line_number);
31 static NodeType *new_constPtr(const char *str, int line_number);
32 static NodeType *new_var(const char *str, int line_number);
33 static NodeType *new_nop(const char *str);
34 static NodeType *new_op(const char *str, int type, int nbOp);
36 static int allocateLabel();
37 static int allocateTemp();
38 static void releaseTemp(int n);
39 static void releaseAllTemps();
41 static int is_tmp_expr(NodeType *node) {
43 return (!strncmp(node->str,"_i_tmp_",7))
44 || (!strncmp(node->str,"_f_tmp_",7))
45 || (!strncmp(node->str,"_p_tmp",7));
49 /* pre: is_tmp_expr(node); */
50 static int get_tmp_id(NodeType *node) { return atoi((node->str)+5); }
52 static int is_commutative_expr(int itype)
54 return (itype == INSTR_ADD)
55 || (itype == INSTR_MUL)
56 || (itype == INSTR_ISEQUAL);
59 static void GSL_PUT_LABEL(char *name, int line_number)
62 printf("label %s\n", name);
64 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, line_number);
65 gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
67 static void GSL_PUT_JUMP(char *name, int line_number)
70 printf("jump %s\n", name);
72 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "jump", INSTR_JUMP, 1, line_number);
73 gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
76 static void GSL_PUT_JXXX(char *name, char *iname, int instr_id, int line_number)
79 printf("%s %s\n", iname, name);
81 currentGoomSL->instr = gsl_instr_init(currentGoomSL, iname, instr_id, 1, line_number);
82 gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
84 static void GSL_PUT_JZERO(char *name,int line_number)
86 GSL_PUT_JXXX(name,"jzero.i",INSTR_JZERO,line_number);
88 static void GSL_PUT_JNZERO(char *name, int line_number)
90 GSL_PUT_JXXX(name,"jnzero.i",INSTR_JNZERO,line_number);
93 /* Structures Management */
95 #define ALIGN_ADDR(_addr,_align) {\
97 int _dec = (_addr%_align);\
98 if (_dec != 0) _addr += _align - _dec;\
102 void gsl_prepare_struct(GSL_Struct *s, int s_align, int i_align, int f_align)
108 s->iBlock[0].size = 0;
109 s->iBlock[0].data = 0;
110 s->fBlock[0].size = 0;
111 s->fBlock[0].data = 0;
113 /* Prepare sub-struct and calculate space needed for their storage */
114 for (i = 0; i < s->nbFields; ++i)
116 if (s->fields[i]->type < FIRST_RESERVED)
119 GSL_Struct *substruct = currentGoomSL->gsl_struct[s->fields[i]->type];
120 consumed += sizeof(int); /* stocke le prefix */
121 ALIGN_ADDR(consumed, s_align);
122 s->fields[i]->offsetInStruct = consumed;
123 gsl_prepare_struct(substruct, s_align, i_align, f_align);
124 for(j=0;substruct->iBlock[j].size>0;++j) {
125 s->iBlock[iblk].data = consumed + substruct->iBlock[j].data;
126 s->iBlock[iblk].size = substruct->iBlock[j].size;
129 for(j=0;substruct->fBlock[j].size>0;++j) {
130 s->fBlock[fblk].data = consumed + substruct->fBlock[j].data;
131 s->fBlock[fblk].size = substruct->fBlock[j].size;
134 consumed += substruct->size;
138 /* Then prepare integers */
139 ALIGN_ADDR(consumed, i_align);
140 for (i = 0; i < s->nbFields; ++i)
142 if (s->fields[i]->type == INSTR_INT)
144 if (s->iBlock[iblk].size == 0) {
145 s->iBlock[iblk].size = 1;
146 s->iBlock[iblk].data = consumed;
148 s->iBlock[iblk].size += 1;
150 s->fields[i]->offsetInStruct = consumed;
151 consumed += sizeof(int);
156 s->iBlock[iblk].size = 0;
157 s->iBlock[iblk].data = 0;
159 /* Then prepare floats */
160 ALIGN_ADDR(consumed, f_align);
161 for (i = 0; i < s->nbFields; ++i)
163 if (s->fields[i]->type == INSTR_FLOAT)
165 if (s->fBlock[fblk].size == 0) {
166 s->fBlock[fblk].size = 1;
167 s->fBlock[fblk].data = consumed;
169 s->fBlock[fblk].size += 1;
171 s->fields[i]->offsetInStruct = consumed;
172 consumed += sizeof(int);
177 s->fBlock[fblk].size = 0;
178 s->fBlock[fblk].data = 0;
180 /* Finally prepare pointers */
181 ALIGN_ADDR(consumed, i_align);
182 for (i = 0; i < s->nbFields; ++i)
184 if (s->fields[i]->type == INSTR_PTR)
186 s->fields[i]->offsetInStruct = consumed;
187 consumed += sizeof(int);
193 /* Returns the ID of a struct from its name */
194 int gsl_get_struct_id(const char *name) /* {{{ */
196 HashValue *ret = goom_hash_get(currentGoomSL->structIDS, name);
197 if (ret != NULL) return ret->i;
201 /* Adds the definition of a struct */
202 void gsl_add_struct(const char *name, GSL_Struct *gsl_struct) /* {{{ */
204 /* Prepare the struct: ie calculate internal storage format */
205 gsl_prepare_struct(gsl_struct, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT);
207 /* If the struct does not already exists */
208 if (gsl_get_struct_id(name) < 0)
211 int id = currentGoomSL->nbStructID++;
212 goom_hash_put_int(currentGoomSL->structIDS, name, id);
213 if (currentGoomSL->gsl_struct_size <= id) {
214 currentGoomSL->gsl_struct_size *= 2;
215 currentGoomSL->gsl_struct = (GSL_Struct**)realloc(currentGoomSL->gsl_struct,
216 sizeof(GSL_Struct*) * currentGoomSL->gsl_struct_size);
218 currentGoomSL->gsl_struct[id] = gsl_struct;
222 /* Creates a field for a struct */
223 GSL_StructField *gsl_new_struct_field(const char *name, int type)
225 GSL_StructField *field = (GSL_StructField*)malloc(sizeof(GSL_StructField));
226 strcpy(field->name, name);
231 /* Create as field for a struct which will be a struct itself */
232 GSL_StructField *gsl_new_struct_field_struct(const char *name, const char *type)
234 GSL_StructField *field = gsl_new_struct_field(name, gsl_get_struct_id(type));
235 if (field->type < 0) {
236 g_assert_not_reached ();
238 fprintf(stderr, "ERROR: Line %d, Unknown structure: '%s'\n",
239 currentGoomSL->num_lines, type);
246 /* Creates a Struct */
247 GSL_Struct *gsl_new_struct(GSL_StructField *field)
249 GSL_Struct *s = (GSL_Struct*)malloc(sizeof(GSL_Struct));
251 s->fields[0] = field;
255 /* Adds a field to a struct */
256 void gsl_add_struct_field(GSL_Struct *s, GSL_StructField *field)
258 s->fields[s->nbFields++] = field;
261 int gsl_type_of_var(GoomHash *ns, const char *name)
265 sprintf(type_of, "__type_of_%s", name);
266 hv = goom_hash_get(ns, type_of);
269 fprintf(stderr, "ERROR: Unknown variable type: '%s'\n", name);
273 static void gsl_declare_var(GoomHash *ns, const char *name, int type, void *space)
276 if (name[0] == '@') { ns = currentGoomSL->vars; }
283 space = goom_heap_malloc_with_alignment(currentGoomSL->data_heap,
284 sizeof(int), sizeof(int));
288 fprintf(stderr, "What the fuck!\n");
291 default: /* On a un struct_id */
292 space = goom_heap_malloc_with_alignment_prefixed(currentGoomSL->data_heap,
293 currentGoomSL->gsl_struct[type]->size, STRUCT_ALIGNMENT, sizeof(int));
296 goom_hash_put_ptr(ns, name, (void*)space);
297 sprintf(type_of, "__type_of_%s", name);
298 goom_hash_put_int(ns, type_of, type);
300 /* Ensuite le hack: on ajoute les champs en tant que variables. */
301 if (type < FIRST_RESERVED)
304 GSL_Struct *gsl_struct = currentGoomSL->gsl_struct[type];
305 ((int*)space)[-1] = type; /* stockage du type dans le prefixe de structure */
306 for (i = 0; i < gsl_struct->nbFields; ++i)
309 char *cspace = (char*)space + gsl_struct->fields[i]->offsetInStruct;
310 sprintf(full_name, "%s.%s", name, gsl_struct->fields[i]->name);
311 gsl_declare_var(ns, full_name, gsl_struct->fields[i]->type, cspace);
316 /* Declare a variable which will be a struct */
317 static void gsl_struct_decl(GoomHash *namespace, const char *struct_name, const char *name)
319 int struct_id = gsl_get_struct_id(struct_name);
320 gsl_declare_var(namespace, name, struct_id, NULL);
323 static void gsl_float_decl_global(const char *name)
325 gsl_declare_var(currentGoomSL->vars, name, INSTR_FLOAT, NULL);
327 static void gsl_int_decl_global(const char *name)
329 gsl_declare_var(currentGoomSL->vars, name, INSTR_INT, NULL);
331 static void gsl_ptr_decl_global(const char *name)
333 gsl_declare_var(currentGoomSL->vars, name, INSTR_PTR, NULL);
335 static void gsl_struct_decl_global_from_id(const char *name, int id)
337 gsl_declare_var(currentGoomSL->vars, name, id, NULL);
341 static void gsl_float_decl_local(const char *name)
343 gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_FLOAT, NULL);
346 static void gsl_int_decl_local(const char *name)
348 gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_INT, NULL);
351 static void gsl_ptr_decl_local(const char *name)
353 gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_PTR, NULL);
356 static void gsl_struct_decl_local(const char *struct_name, const char *name)
358 gsl_struct_decl(currentGoomSL->namespaces[currentGoomSL->currentNS],struct_name,name);
362 static void commit_test2(NodeType *set,const char *type, int instr);
363 static NodeType *new_call(const char *name, NodeType *affect_list);
366 static NodeType *new_set(NodeType *lvalue, NodeType *expression)
368 NodeType *set = new_op("set", OPR_SET, 2);
369 set->unode.opr.op[0] = lvalue;
370 set->unode.opr.op[1] = expression;
373 static void commit_set(NodeType *set)
375 commit_test2(set,"set",INSTR_SET);
379 static NodeType *new_plus_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
381 NodeType *set = new_op("plus_eq", OPR_PLUS_EQ, 2);
382 set->unode.opr.op[0] = lvalue;
383 set->unode.opr.op[1] = expression;
386 static void commit_plus_eq(NodeType *set)
388 precommit_node(set->unode.opr.op[1]);
390 printf("add %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
392 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "add", INSTR_ADD, 2, set->line_number);
393 commit_node(set->unode.opr.op[0],0);
394 commit_node(set->unode.opr.op[1],1);
398 static NodeType *new_sub_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
400 NodeType *set = new_op("sub_eq", OPR_SUB_EQ, 2);
401 set->unode.opr.op[0] = lvalue;
402 set->unode.opr.op[1] = expression;
405 static void commit_sub_eq(NodeType *set)
407 precommit_node(set->unode.opr.op[1]);
409 printf("sub %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
411 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "sub", INSTR_SUB, 2, set->line_number);
412 commit_node(set->unode.opr.op[0],0);
413 commit_node(set->unode.opr.op[1],1);
417 static NodeType *new_mul_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
419 NodeType *set = new_op("mul_eq", OPR_MUL_EQ, 2);
420 set->unode.opr.op[0] = lvalue;
421 set->unode.opr.op[1] = expression;
424 static void commit_mul_eq(NodeType *set)
426 precommit_node(set->unode.opr.op[1]);
428 printf("mul %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
430 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "mul", INSTR_MUL, 2, set->line_number);
431 commit_node(set->unode.opr.op[0],0);
432 commit_node(set->unode.opr.op[1],1);
436 static NodeType *new_div_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
438 NodeType *set = new_op("div_eq", OPR_DIV_EQ, 2);
439 set->unode.opr.op[0] = lvalue;
440 set->unode.opr.op[1] = expression;
443 static void commit_div_eq(NodeType *set)
445 precommit_node(set->unode.opr.op[1]);
447 printf("div %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
449 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "div", INSTR_DIV, 2, set->line_number);
450 commit_node(set->unode.opr.op[0],0);
451 commit_node(set->unode.opr.op[1],1);
454 /* commodity method for add, mult, ... */
456 static void precommit_expr(NodeType *expr, const char *type, int instr_id)
458 NodeType *tmp, *tmpcpy;
461 /* compute "left" and "right" */
462 switch (expr->unode.opr.nbOp) {
464 precommit_node(expr->unode.opr.op[1]);
466 precommit_node(expr->unode.opr.op[0]);
469 if (is_tmp_expr(expr->unode.opr.op[0])) {
470 tmp = expr->unode.opr.op[0];
473 else if (is_commutative_expr(instr_id) && (expr->unode.opr.nbOp==2) && is_tmp_expr(expr->unode.opr.op[1])) {
474 tmp = expr->unode.opr.op[1];
479 /* declare a temporary variable to store the result */
480 if (expr->unode.opr.op[0]->type == CONST_INT_NODE) {
481 sprintf(stmp,"_i_tmp_%i",allocateTemp());
482 gsl_int_decl_global(stmp);
484 else if (expr->unode.opr.op[0]->type == CONST_FLOAT_NODE) {
485 sprintf(stmp,"_f_tmp%i",allocateTemp());
486 gsl_float_decl_global(stmp);
488 else if (expr->unode.opr.op[0]->type == CONST_PTR_NODE) {
489 sprintf(stmp,"_p_tmp%i",allocateTemp());
490 gsl_ptr_decl_global(stmp);
493 int type = gsl_type_of_var(expr->unode.opr.op[0]->vnamespace, expr->unode.opr.op[0]->str);
494 if (type == INSTR_FLOAT) {
495 sprintf(stmp,"_f_tmp_%i",allocateTemp());
496 gsl_float_decl_global(stmp);
498 else if (type == INSTR_PTR) {
499 sprintf(stmp,"_p_tmp_%i",allocateTemp());
500 gsl_ptr_decl_global(stmp);
502 else if (type == INSTR_INT) {
503 sprintf(stmp,"_i_tmp_%i",allocateTemp());
504 gsl_int_decl_global(stmp);
506 else if (type == -1) {
507 g_assert_not_reached ();
509 fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
510 expr->line_number, expr->unode.opr.op[0]->str);
514 else { /* type is a struct_id */
515 sprintf(stmp,"_s_tmp_%i",allocateTemp());
516 gsl_struct_decl_global_from_id(stmp,type);
519 tmp = new_var(stmp,expr->line_number);
521 /* set the tmp to the value of "op1" */
522 tmpcpy = nodeClone(tmp);
523 commit_node(new_set(tmp,expr->unode.opr.op[0]),0);
531 if (expr->unode.opr.nbOp == 2)
532 printf("%s %s %s\n", type, tmp->str, expr->unode.opr.op[toAdd]->str);
534 printf("%s %s\n", type, tmp->str);
536 currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr_id, expr->unode.opr.nbOp, expr->line_number);
537 tmpcpy = nodeClone(tmp);
539 if (expr->unode.opr.nbOp == 2) {
540 commit_node(expr->unode.opr.op[toAdd],1);
543 /* redefine the ADD node now as the computed variable */
544 nodeFreeInternals(expr);
549 static NodeType *new_expr1(const char *name, int id, NodeType *expr1)
551 NodeType *add = new_op(name, id, 1);
552 add->unode.opr.op[0] = expr1;
556 static NodeType *new_expr2(const char *name, int id, NodeType *expr1, NodeType *expr2)
558 NodeType *add = new_op(name, id, 2);
559 add->unode.opr.op[0] = expr1;
560 add->unode.opr.op[1] = expr2;
565 static NodeType *new_add(NodeType *expr1, NodeType *expr2) { /* {{{ */
566 return new_expr2("add", OPR_ADD, expr1, expr2);
568 static void precommit_add(NodeType *add) {
569 precommit_expr(add,"add",INSTR_ADD);
573 static NodeType *new_sub(NodeType *expr1, NodeType *expr2) { /* {{{ */
574 return new_expr2("sub", OPR_SUB, expr1, expr2);
576 static void precommit_sub(NodeType *sub) {
577 precommit_expr(sub,"sub",INSTR_SUB);
581 static NodeType *new_neg(NodeType *expr) { /* {{{ */
582 NodeType *zeroConst = NULL;
583 if (expr->type == CONST_INT_NODE)
584 zeroConst = new_constInt("0", currentGoomSL->num_lines);
585 else if (expr->type == CONST_FLOAT_NODE)
586 zeroConst = new_constFloat("0.0", currentGoomSL->num_lines);
587 else if (expr->type == CONST_PTR_NODE) {
588 g_assert_not_reached ();
590 fprintf(stderr, "ERROR: Line %d, Could not negate const pointer.\n",
591 currentGoomSL->num_lines);
596 int type = gsl_type_of_var(expr->vnamespace, expr->str);
597 if (type == INSTR_FLOAT)
598 zeroConst = new_constFloat("0.0", currentGoomSL->num_lines);
599 else if (type == INSTR_PTR) {
600 g_assert_not_reached ();
602 fprintf(stderr, "ERROR: Line %d, Could not negate pointer.\n",
603 currentGoomSL->num_lines);
607 else if (type == INSTR_INT)
608 zeroConst = new_constInt("0", currentGoomSL->num_lines);
609 else if (type == -1) {
610 g_assert_not_reached ();
612 fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
613 expr->line_number, expr->unode.opr.op[0]->str);
617 else { /* type is a struct_id */
618 g_assert_not_reached ();
620 fprintf(stderr, "ERROR: Line %d, Could not negate struct '%s'\n",
621 expr->line_number, expr->str);
626 return new_expr2("sub", OPR_SUB, zeroConst, expr);
631 static NodeType *new_mul(NodeType *expr1, NodeType *expr2) { /* {{{ */
632 return new_expr2("mul", OPR_MUL, expr1, expr2);
634 static void precommit_mul(NodeType *mul) {
635 precommit_expr(mul,"mul",INSTR_MUL);
639 static NodeType *new_div(NodeType *expr1, NodeType *expr2) { /* {{{ */
640 return new_expr2("div", OPR_DIV, expr1, expr2);
642 static void precommit_div(NodeType *mul) {
643 precommit_expr(mul,"div",INSTR_DIV);
646 /* CALL EXPRESSION */
647 static NodeType *new_call_expr(const char *name, NodeType *affect_list) { /* {{{ */
648 NodeType *call = new_call(name,affect_list);
649 NodeType *node = new_expr1(name, OPR_CALL_EXPR, call);
650 node->vnamespace = gsl_find_namespace(name);
651 if (node->vnamespace == NULL)
652 /* fprintf(stderr, "ERROR: Line %d, No return type for: '%s'\n", currentGoomSL->num_lines, name); */
655 static void precommit_call_expr(NodeType *call) {
657 NodeType *tmp,*tmpcpy;
658 int type = gsl_type_of_var(call->vnamespace, call->str);
659 if (type == INSTR_FLOAT) {
660 sprintf(stmp,"_f_tmp_%i",allocateTemp());
661 gsl_float_decl_global(stmp);
663 else if (type == INSTR_PTR) {
664 sprintf(stmp,"_p_tmp_%i",allocateTemp());
665 gsl_ptr_decl_global(stmp);
667 else if (type == INSTR_INT) {
668 sprintf(stmp,"_i_tmp_%i",allocateTemp());
669 gsl_int_decl_global(stmp);
671 else if (type == -1) {
672 g_assert_not_reached ();
674 fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
675 call->line_number, call->str);
679 else { /* type is a struct_id */
680 sprintf(stmp,"_s_tmp_%i",allocateTemp());
681 gsl_struct_decl_global_from_id(stmp,type);
683 tmp = new_var(stmp,call->line_number);
684 commit_node(call->unode.opr.op[0],0);
685 tmpcpy = nodeClone(tmp);
686 commit_node(new_set(tmp,new_var(call->str,call->line_number)),0);
688 nodeFreeInternals(call);
693 static void commit_test2(NodeType *set,const char *type, int instr)
697 precommit_node(set->unode.opr.op[0]);
698 precommit_node(set->unode.opr.op[1]);
699 tmp = set->unode.opr.op[0];
702 if (set->unode.opr.op[0]->type == CONST_INT_NODE) {
703 sprintf(stmp,"_i_tmp_%i",allocateTemp());
704 gsl_int_decl_global(stmp);
706 else if (set->unode.opr.op[0]->type == CONST_FLOAT_NODE) {
707 sprintf(stmp,"_f_tmp%i",allocateTemp());
708 gsl_float_decl_global(stmp);
710 else if (set->unode.opr.op[0]->type == CONST_PTR_NODE) {
711 sprintf(stmp,"_p_tmp%i",allocateTemp());
712 gsl_ptr_decl_global(stmp);
716 tmp = new_var(stmp, set->line_number);
717 tmpcpy = nodeClone(tmp);
718 commit_node(new_set(tmp,set->unode.opr.op[0]),0);
723 printf("%s %s %s\n", type, tmp->str, set->unode.opr.op[1]->str);
725 currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr, 2, set->line_number);
726 commit_node(tmp,instr!=INSTR_SET);
727 commit_node(set->unode.opr.op[1],1);
731 static NodeType *new_not(NodeType *expr1) { /* {{{ */
732 return new_expr1("not", OPR_NOT, expr1);
734 static void commit_not(NodeType *set)
736 commit_node(set->unode.opr.op[0],0);
740 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "not", INSTR_NOT, 1, set->line_number);
741 gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
745 static NodeType *new_equ(NodeType *expr1, NodeType *expr2) { /* {{{ */
746 return new_expr2("isequal", OPR_EQU, expr1, expr2);
748 static void commit_equ(NodeType *mul) {
749 commit_test2(mul,"isequal",INSTR_ISEQUAL);
753 static NodeType *new_low(NodeType *expr1, NodeType *expr2) { /* {{{ */
754 return new_expr2("islower", OPR_LOW, expr1, expr2);
756 static void commit_low(NodeType *mul) {
757 commit_test2(mul,"islower",INSTR_ISLOWER);
761 static NodeType *new_while(NodeType *expression, NodeType *instr) { /* {{{ */
762 NodeType *node = new_op("while", OPR_WHILE, 2);
763 node->unode.opr.op[0] = expression;
764 node->unode.opr.op[1] = instr;
768 static void commit_while(NodeType *node)
770 int lbl = allocateLabel();
771 char start_while[1024], test_while[1024];
772 sprintf(start_while, "|start_while_%d|", lbl);
773 sprintf(test_while, "|test_while_%d|", lbl);
775 GSL_PUT_JUMP(test_while,node->line_number);
776 GSL_PUT_LABEL(start_while,node->line_number);
779 commit_node(node->unode.opr.op[1],0);
781 GSL_PUT_LABEL(test_while,node->line_number);
782 commit_node(node->unode.opr.op[0],0);
783 GSL_PUT_JNZERO(start_while,node->line_number);
787 static NodeType *new_static_foreach(NodeType *var, NodeType *var_list, NodeType *instr) { /* {{{ */
788 NodeType *node = new_op("for", OPR_FOREACH, 3);
789 node->unode.opr.op[0] = var;
790 node->unode.opr.op[1] = var_list;
791 node->unode.opr.op[2] = instr;
792 node->line_number = currentGoomSL->num_lines;
795 static void commit_foreach(NodeType *node)
797 NodeType *cur = node->unode.opr.op[1];
798 char tmp_func[256], tmp_loop[256];
799 int lbl = allocateLabel();
800 sprintf(tmp_func, "|foreach_func_%d|", lbl);
801 sprintf(tmp_loop, "|foreach_loop_%d|", lbl);
803 GSL_PUT_JUMP(tmp_loop, node->line_number);
804 GSL_PUT_LABEL(tmp_func, node->line_number);
806 precommit_node(node->unode.opr.op[2]);
807 commit_node(node->unode.opr.op[2], 0);
809 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number);
810 gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
815 GSL_PUT_LABEL(tmp_loop, node->line_number);
822 x = nodeClone(node->unode.opr.op[0]);
823 var = nodeClone(cur->unode.opr.op[0]);
824 commit_node(new_set(x, var),0);
827 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number);
828 gsl_instr_add_param(currentGoomSL->instr, tmp_func, TYPE_LABEL);
830 printf("call %s\n", tmp_func);
834 x = nodeClone(node->unode.opr.op[0]);
835 var = cur->unode.opr.op[0];
836 commit_node(new_set(var, x),0);
837 cur = cur->unode.opr.op[1];
839 nodeFree(node->unode.opr.op[0]);
843 static NodeType *new_if(NodeType *expression, NodeType *instr) { /* {{{ */
844 NodeType *node = new_op("if", OPR_IF, 2);
845 node->unode.opr.op[0] = expression;
846 node->unode.opr.op[1] = instr;
849 static void commit_if(NodeType *node) {
852 sprintf(slab, "|eif%d|", allocateLabel());
853 commit_node(node->unode.opr.op[0],0);
854 GSL_PUT_JZERO(slab,node->line_number);
856 commit_node(node->unode.opr.op[1],0);
857 GSL_PUT_LABEL(slab,node->line_number);
861 static NodeType *new_block(NodeType *lastNode) { /* {{{ */
862 NodeType *blk = new_op("block", OPR_BLOCK, 2);
863 blk->unode.opr.op[0] = new_nop("start_of_block");
864 blk->unode.opr.op[1] = lastNode;
867 static void commit_block(NodeType *node) {
868 commit_node(node->unode.opr.op[0]->unode.opr.next,0);
872 static NodeType *new_function_intro(const char *name) { /* {{{ */
874 if (strlen(name) < 200) {
875 sprintf(stmp, "|__func_%s|", name);
877 return new_op(stmp, OPR_FUNC_INTRO, 0);
879 static void commit_function_intro(NodeType *node) {
880 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, node->line_number);
881 gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);
883 printf("label %s\n", node->str);
888 static NodeType *new_function_outro() { /* {{{ */
889 return new_op("ret", OPR_FUNC_OUTRO, 0);
891 static void commit_function_outro(NodeType *node) {
892 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number);
893 gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
900 /* AFFECTATION LIST */
901 static NodeType *new_affec_list(NodeType *set, NodeType *next) /* {{{ */
903 NodeType *node = new_op("affect_list", OPR_AFFECT_LIST, 2);
904 node->unode.opr.op[0] = set;
905 node->unode.opr.op[1] = next;
908 static NodeType *new_affect_list_after(NodeType *affect_list)
910 NodeType *ret = NULL;
911 NodeType *cur = affect_list;
913 NodeType *set = cur->unode.opr.op[0];
914 NodeType *next = cur->unode.opr.op[1];
915 NodeType *lvalue = set->unode.opr.op[0];
916 NodeType *expression = set->unode.opr.op[1];
917 if ((lvalue->str[0] == '&') && (expression->type == VAR_NODE)) {
918 NodeType *nset = new_set(nodeClone(expression), nodeClone(lvalue));
919 ret = new_affec_list(nset, ret);
925 static void commit_affect_list(NodeType *node)
927 NodeType *cur = node;
929 NodeType *set = cur->unode.opr.op[0];
930 precommit_node(set->unode.opr.op[0]);
931 precommit_node(set->unode.opr.op[1]);
932 cur = cur->unode.opr.op[1];
936 NodeType *set = cur->unode.opr.op[0];
938 cur = cur->unode.opr.op[1];
943 static NodeType *new_var_list(NodeType *var, NodeType *next) /* {{{ */
945 NodeType *node = new_op("var_list", OPR_VAR_LIST, 2);
946 node->unode.opr.op[0] = var;
947 node->unode.opr.op[1] = next;
950 static void commit_var_list(NodeType *node)
955 static NodeType *new_call(const char *name, NodeType *affect_list) { /* {{{ */
957 fval = goom_hash_get(currentGoomSL->functions, name);
959 gsl_declare_task(name);
960 fval = goom_hash_get(currentGoomSL->functions, name);
963 g_assert_not_reached ();
965 fprintf(stderr, "ERROR: Line %d, Could not find function %s\n", currentGoomSL->num_lines, name);
971 ExternalFunctionStruct *gef = (ExternalFunctionStruct*)fval->ptr;
972 if (gef->is_extern) {
973 NodeType *node = new_op(name, OPR_EXT_CALL, 1);
974 node->unode.opr.op[0] = affect_list;
980 if (strlen(name) < 200) {
981 sprintf(stmp, "|__func_%s|", name);
983 node = new_op(stmp, OPR_CALL, 1);
984 node->unode.opr.op[0] = affect_list;
989 static void commit_ext_call(NodeType *node) {
990 NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]);
991 commit_node(node->unode.opr.op[0],0);
992 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "extcall", INSTR_EXT_CALL, 1, node->line_number);
993 gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR);
995 printf("extcall %s\n", node->str);
997 commit_node(alafter,0);
999 static void commit_call(NodeType *node) {
1000 NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]);
1001 commit_node(node->unode.opr.op[0],0);
1002 currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number);
1003 gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);
1005 printf("call %s\n", node->str);
1007 commit_node(alafter,0);
1012 static NodeType *rootNode = 0; /* TODO: reinitialiser a chaque compilation. */
1013 static NodeType *lastNode = 0;
1014 static NodeType *gsl_append(NodeType *curNode) {
1015 if (curNode == 0) return 0; /* {{{ */
1017 lastNode->unode.opr.next = curNode;
1019 while(lastNode->unode.opr.next) lastNode = lastNode->unode.opr.next;
1026 int allocateTemp() {
1027 return allocateLabel();
1029 void releaseAllTemps() {}
1030 void releaseTemp(int n) {}
1032 static int nbTemp = 0;
1033 static int *tempArray = 0;
1034 static int tempArraySize = 0;
1035 int allocateTemp() { /* TODO: allocateITemp, allocateFTemp */
1036 int i = 0; /* {{{ */
1037 if (tempArray == 0) {
1038 tempArraySize = 256;
1039 tempArray = (int*)malloc(tempArraySize * sizeof(int));
1043 for (j=0;j<nbTemp;++j) {
1044 if (tempArray[j] == i) break;
1047 if (nbTemp == tempArraySize) {
1049 tempArray = (int*)realloc(tempArray,tempArraySize * sizeof(int));
1051 tempArray[nbTemp++] = i;
1057 void releaseAllTemps() {
1058 nbTemp = 0; /* {{{ */
1060 void releaseTemp(int n) {
1062 for (j=0;j<nbTemp;++j) {
1063 if (tempArray[j] == n) {
1064 tempArray[j] = tempArray[--nbTemp];
1071 static int lastLabel = 0;
1072 int allocateLabel() {
1073 return ++lastLabel; /* {{{ */
1076 void gsl_commit_compilation()
1078 commit_node(rootNode,0);
1083 void precommit_node(NodeType *node)
1085 /* do here stuff for expression.. for exemple */
1086 if (node->type == OPR_NODE)
1087 switch(node->unode.opr.type) {
1088 case OPR_ADD: precommit_add(node); break;
1089 case OPR_SUB: precommit_sub(node); break;
1090 case OPR_MUL: precommit_mul(node); break;
1091 case OPR_DIV: precommit_div(node); break;
1092 case OPR_CALL_EXPR: precommit_call_expr(node); break;
1096 void commit_node(NodeType *node, int releaseIfTmp)
1098 if (node == 0) return;
1100 switch(node->type) {
1102 switch(node->unode.opr.type) {
1103 case OPR_SET: commit_set(node); break;
1104 case OPR_PLUS_EQ: commit_plus_eq(node); break;
1105 case OPR_SUB_EQ: commit_sub_eq(node); break;
1106 case OPR_MUL_EQ: commit_mul_eq(node); break;
1107 case OPR_DIV_EQ: commit_div_eq(node); break;
1108 case OPR_IF: commit_if(node); break;
1109 case OPR_WHILE: commit_while(node); break;
1110 case OPR_BLOCK: commit_block(node); break;
1111 case OPR_FUNC_INTRO: commit_function_intro(node); break;
1112 case OPR_FUNC_OUTRO: commit_function_outro(node); break;
1113 case OPR_CALL: commit_call(node); break;
1114 case OPR_EXT_CALL: commit_ext_call(node); break;
1115 case OPR_EQU: commit_equ(node); break;
1116 case OPR_LOW: commit_low(node); break;
1117 case OPR_NOT: commit_not(node); break;
1118 case OPR_AFFECT_LIST: commit_affect_list(node); break;
1119 case OPR_FOREACH: commit_foreach(node); break;
1120 case OPR_VAR_LIST: commit_var_list(node); break;
1122 case EMPTY_NODE: printf("NOP\n"); break;
1126 commit_node(node->unode.opr.next,0); /* recursive for the moment, maybe better to do something iterative? */
1129 case VAR_NODE: gsl_instr_set_namespace(currentGoomSL->instr, node->vnamespace);
1130 gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR); break;
1131 case CONST_INT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_INTEGER); break;
1132 case CONST_FLOAT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_FLOAT); break;
1133 case CONST_PTR_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_PTR); break;
1135 if (releaseIfTmp && is_tmp_expr(node))
1136 releaseTemp(get_tmp_id(node));
1141 NodeType *nodeNew(const char *str, int type, int line_number) {
1142 NodeType *node = (NodeType*)malloc(sizeof(NodeType)); /* {{{ */
1144 node->str = (char*)malloc(strlen(str)+1);
1145 node->vnamespace = NULL;
1146 node->line_number = line_number;
1147 strcpy(node->str, str);
1150 static NodeType *nodeClone(NodeType *node) {
1151 NodeType *ret = nodeNew(node->str, node->type, node->line_number); /* {{{ */
1152 ret->vnamespace = node->vnamespace;
1153 ret->unode = node->unode;
1157 void nodeFreeInternals(NodeType *node) {
1158 free(node->str); /* {{{ */
1161 void nodeFree(NodeType *node) {
1162 nodeFreeInternals(node); /* {{{ */
1166 NodeType *new_constInt(const char *str, int line_number) {
1167 NodeType *node = nodeNew(str, CONST_INT_NODE, line_number); /* {{{ */
1168 node->unode.constInt.val = atoi(str);
1172 NodeType *new_constPtr(const char *str, int line_number) {
1173 NodeType *node = nodeNew(str, CONST_PTR_NODE, line_number); /* {{{ */
1174 node->unode.constPtr.id = strtol(str,NULL,0);
1178 NodeType *new_constFloat(const char *str, int line_number) {
1179 NodeType *node = nodeNew(str, CONST_FLOAT_NODE, line_number); /* {{{ */
1180 node->unode.constFloat.val = atof(str);
1184 NodeType *new_var(const char *str, int line_number) {
1185 NodeType *node = nodeNew(str, VAR_NODE, line_number); /* {{{ */
1186 node->vnamespace = gsl_find_namespace(str);
1187 if (node->vnamespace == 0) {
1188 g_assert_not_reached ();
1190 fprintf(stderr, "ERROR: Line %d, Variable not found: '%s'\n", line_number, str);
1197 NodeType *new_nop(const char *str) {
1198 NodeType *node = new_op(str, EMPTY_NODE, 0); /* {{{ */
1202 NodeType *new_op(const char *str, int type, int nbOp) {
1204 NodeType *node = nodeNew(str, OPR_NODE, currentGoomSL->num_lines);
1205 node->unode.opr.next = 0;
1206 node->unode.opr.type = type;
1207 node->unode.opr.nbOp = nbOp;
1208 for (i=0;i<nbOp;++i) node->unode.opr.op[i] = 0;
1213 void gsl_declare_global_variable(int type, char *name) {
1216 case FLOAT_TK:gsl_float_decl_global(name);break;
1217 case INT_TK: gsl_int_decl_global(name);break;
1218 case PTR_TK: gsl_ptr_decl_global(name);break;
1221 int id = type - 1000;
1222 gsl_struct_decl_global_from_id(name,id);
1233 char strValue[2048];
1235 GoomHash *namespace;
1236 GSL_Struct *gsl_struct;
1237 GSL_StructField *gsl_struct_field;
1240 %token <strValue> LTYPE_INTEGER
1241 %token <strValue> LTYPE_FLOAT
1242 %token <strValue> LTYPE_VAR
1243 %token <strValue> LTYPE_PTR
1245 %token PTR_TK INT_TK FLOAT_TK DECLARE EXTERNAL WHILE DO NOT PLUS_EQ SUB_EQ DIV_EQ MUL_EQ SUP_EQ LOW_EQ NOT_EQ STRUCT FOR IN
1247 %type <intValue> return_type
1248 %type <nPtr> expression constValue instruction test func_call func_call_expression
1249 %type <nPtr> start_block affectation_list affectation_in_list affectation declaration
1250 %type <nPtr> var_list_content var_list
1251 %type <strValue> task_name ext_task_name
1252 %type <namespace> leave_namespace
1253 %type <gsl_struct> struct_members
1254 %type <gsl_struct_field> struct_member
1256 %left PLUS_EQ SUB_EQ MUL_EQ DIV_EQ
1264 /* -------------- Global architechture of a GSL program ------------*/
1266 gsl: gsl_code function_outro gsl_def_functions ;
1268 gsl_code: gsl_code instruction { gsl_append($2); }
1269 | gsl_code EXTERNAL '<' ext_task_name '>' return_type '\n' leave_namespace { gsl_declare_global_variable($6,$4); }
1270 | gsl_code EXTERNAL '<' ext_task_name ':' arglist '>' return_type '\n' leave_namespace { gsl_declare_global_variable($8,$4); }
1271 | gsl_code DECLARE '<' task_name '>' return_type '\n' leave_namespace { gsl_declare_global_variable($6,$4); }
1272 | gsl_code DECLARE '<' task_name ':' arglist '>' return_type '\n' leave_namespace { gsl_declare_global_variable($8,$4); }
1273 | gsl_code struct_declaration
1278 /* ------------- Declaration of a structure ------------ */
1280 struct_declaration: STRUCT '<' LTYPE_VAR ':' struct_members '>' '\n' { gsl_add_struct($3, $5); }
1283 struct_members: opt_nl struct_member { $$ = gsl_new_struct($2); }
1284 | struct_members ',' opt_nl struct_member { $$ = $1; gsl_add_struct_field($1, $4); }
1287 struct_member: INT_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_INT); }
1288 | FLOAT_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_FLOAT); }
1289 | PTR_TK LTYPE_VAR { $$ = gsl_new_struct_field($2, INSTR_PTR); }
1290 | LTYPE_VAR LTYPE_VAR { $$ = gsl_new_struct_field_struct($2, $1); }
1293 /* ------------- Fonction declarations -------------- */
1295 ext_task_name: LTYPE_VAR { gsl_declare_external_task($1); gsl_enternamespace($1); strcpy($$,$1); }
1297 task_name: LTYPE_VAR { gsl_declare_task($1); gsl_enternamespace($1); strcpy($$,$1); strcpy($$,$1); }
1300 return_type: { $$=-1; }
1301 | ':' INT_TK { $$=INT_TK; }
1302 | ':' FLOAT_TK { $$=FLOAT_TK; }
1303 | ':' PTR_TK { $$=PTR_TK; }
1304 | ':' LTYPE_VAR { $$= 1000 + gsl_get_struct_id($2); }
1307 arglist: empty_declaration
1308 | empty_declaration ',' arglist
1311 /* ------------- Fonction definition -------------- */
1313 gsl_def_functions: gsl_def_functions function
1317 function: function_intro gsl_code function_outro { gsl_leavenamespace(); }
1319 function_intro: '<' task_name '>' return_type '\n' { gsl_append(new_function_intro($2));
1320 gsl_declare_global_variable($4,$2); }
1321 | '<' task_name ':' arglist '>' return_type '\n' { gsl_append(new_function_intro($2));
1322 gsl_declare_global_variable($6,$2); }
1324 function_outro: { gsl_append(new_function_outro()); } ;
1326 leave_namespace: { $$ = gsl_leavenamespace(); };
1328 /* ------------ Variable declaration ---------------- */
1330 declaration: FLOAT_TK LTYPE_VAR '=' expression { gsl_float_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
1331 | INT_TK LTYPE_VAR '=' expression { gsl_int_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
1332 | PTR_TK LTYPE_VAR '=' expression { gsl_ptr_decl_local($2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
1333 | LTYPE_VAR LTYPE_VAR '=' expression { gsl_struct_decl_local($1,$2); $$ = new_set(new_var($2,currentGoomSL->num_lines), $4); }
1334 | empty_declaration { $$ = 0; }
1337 empty_declaration: FLOAT_TK LTYPE_VAR { gsl_float_decl_local($2); }
1338 | INT_TK LTYPE_VAR { gsl_int_decl_local($2); }
1339 | PTR_TK LTYPE_VAR { gsl_ptr_decl_local($2); }
1340 | LTYPE_VAR LTYPE_VAR { gsl_struct_decl_local($1,$2); }
1343 /* -------------- Instructions and Expressions ------------------ */
1345 instruction: affectation '\n' { $$ = $1; }
1346 | declaration '\n' { $$ = $1; }
1347 | '(' test ')' '?' opt_nl instruction { $$ = new_if($2,$6); }
1348 | WHILE test opt_nl DO opt_nl instruction { $$ = new_while($2,$6); }
1349 | '{' '\n' start_block gsl_code '}' '\n' { lastNode = $3->unode.opr.op[1]; $$=$3; }
1350 | func_call { $$ = $1; }
1351 | LTYPE_VAR PLUS_EQ expression { $$ = new_plus_eq(new_var($1,currentGoomSL->num_lines),$3); }
1352 | LTYPE_VAR SUB_EQ expression { $$ = new_sub_eq(new_var($1,currentGoomSL->num_lines),$3); }
1353 | LTYPE_VAR MUL_EQ expression { $$ = new_mul_eq(new_var($1,currentGoomSL->num_lines),$3); }
1354 | LTYPE_VAR DIV_EQ expression { $$ = new_div_eq(new_var($1,currentGoomSL->num_lines),$3); }
1355 | FOR LTYPE_VAR IN var_list DO instruction { $$ = new_static_foreach(new_var($2, currentGoomSL->num_lines), $4, $6); }
1358 var_list: '(' var_list_content ')' { $$ = $2; }
1360 var_list_content: LTYPE_VAR { $$ = new_var_list(new_var($1,currentGoomSL->num_lines), NULL); }
1361 | LTYPE_VAR var_list_content { $$ = new_var_list(new_var($1,currentGoomSL->num_lines), $2); }
1364 affectation: LTYPE_VAR '=' expression { $$ = new_set(new_var($1,currentGoomSL->num_lines),$3); } ;
1366 start_block: { $$ = new_block(lastNode); lastNode = $$->unode.opr.op[0]; }
1369 expression: LTYPE_VAR { $$ = new_var($1,currentGoomSL->num_lines); }
1370 | constValue { $$ = $1; }
1371 | expression '*' expression { $$ = new_mul($1,$3); }
1372 | expression '/' expression { $$ = new_div($1,$3); }
1373 | expression '+' expression { $$ = new_add($1,$3); }
1374 | expression '-' expression { $$ = new_sub($1,$3); }
1375 | '-' expression { $$ = new_neg($2); }
1376 | '(' expression ')' { $$ = $2; }
1377 | func_call_expression { $$ = $1; }
1380 test: expression '=' expression { $$ = new_equ($1,$3); }
1381 | expression '<' expression { $$ = new_low($1,$3); }
1382 | expression '>' expression { $$ = new_low($3,$1); }
1383 | expression SUP_EQ expression { $$ = new_not(new_low($1,$3)); }
1384 | expression LOW_EQ expression { $$ = new_not(new_low($3,$1)); }
1385 | expression NOT_EQ expression { $$ = new_not(new_equ($1,$3)); }
1386 | NOT test { $$ = new_not($2); }
1389 constValue: LTYPE_FLOAT { $$ = new_constFloat($1,currentGoomSL->num_lines); }
1390 | LTYPE_INTEGER { $$ = new_constInt($1,currentGoomSL->num_lines); }
1391 | LTYPE_PTR { $$ = new_constPtr($1,currentGoomSL->num_lines); }
1394 /* ---------------- Function Calls ------------------ */
1396 func_call: task_name '\n' leave_namespace { $$ = new_call($1,NULL); }
1397 | task_name ':' affectation_list '\n' leave_namespace { $$ = new_call($1,$3); }
1398 | '[' task_name ']' '\n' leave_namespace { $$ = new_call($2,NULL); }
1399 | '[' task_name ':' affectation_list ']' '\n' leave_namespace { $$ = new_call($2,$4); }
1402 func_call_expression:
1403 '[' task_name leave_namespace ']' { $$ = new_call_expr($2,NULL); }
1404 | '[' task_name ':' affectation_list ']' leave_namespace { $$ = new_call_expr($2,$4); }
1407 affectation_list: affectation_in_list affectation_list { $$ = new_affec_list($1,$2); }
1408 | affectation_in_list { $$ = new_affec_list($1,NULL); }
1410 affectation_in_list: LTYPE_VAR '=' leave_namespace expression {
1411 gsl_reenternamespace($3);
1412 $$ = new_set(new_var($1,currentGoomSL->num_lines),$4);
1414 | ':' leave_namespace expression {
1415 gsl_reenternamespace($2);
1416 $$ = new_set(new_var("&this", currentGoomSL->num_lines),$3);
1421 /* ------------ Misc ---------- */
1429 void yyerror(char *str)
1431 g_assert_not_reached ();
1433 fprintf(stderr, "ERROR: Line %d, %s\n", currentGoomSL->num_lines, str);
1434 currentGoomSL->compilationOK = 0;