PageRenderTime 138ms CodeModel.GetById 14ms app.highlight 108ms RepoModel.GetById 2ms app.codeStats 1ms

/xbmc/visualizations/Goom/goom2k4-0/src/goomsl_yacc.c

http://github.com/xbmc/xbmc
C | 2997 lines | 2309 code | 404 blank | 284 comment | 295 complexity | 6616b1b5b943d68f1012fa9618055aa8 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* A Bison parser, made by GNU Bison 1.875.  */
   2
   3/* Skeleton parser for Yacc-like parsing with Bison,
   4   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
   5
   6   This program is free software; you can redistribute it and/or modify
   7   it under the terms of the GNU General Public License as published by
   8   the Free Software Foundation; either version 2, or (at your option)
   9   any later version.
  10
  11   This program is distributed in the hope that it will be useful,
  12   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14   GNU General Public License for more details.
  15
  16   You should have received a copy of the GNU General Public License
  17   along with this program; if not, write to the Free Software
  18   Foundation, Inc., 59 Temple Place - Suite 330,
  19   Boston, MA 02111-1307, USA.  */
  20
  21/* As a special exception, when this file is copied by Bison into a
  22   Bison output file, you may use that output file without restriction.
  23   This special exception was added by the Free Software Foundation
  24   in version 1.24 of Bison.  */
  25
  26/* Written by Richard Stallman by simplifying the original so called
  27   ``semantic'' parser.  */
  28
  29/* All symbols defined below should begin with yy or YY, to avoid
  30   infringing on user name space.  This should be done even for local
  31   variables, as they might otherwise be expanded by user macros.
  32   There are some unavoidable exceptions within include files to
  33   define necessary library symbols; they are noted "INFRINGES ON
  34   USER NAME SPACE" below.  */
  35
  36/* Identify Bison output.  */
  37#define YYBISON 1
  38
  39/* Skeleton name.  */
  40#define YYSKELETON_NAME "yacc.c"
  41
  42/* Pure parsers.  */
  43#define YYPURE 0
  44
  45/* Using locations.  */
  46#define YYLSP_NEEDED 0
  47
  48
  49
  50/* Tokens.  */
  51#ifndef YYTOKENTYPE
  52# define YYTOKENTYPE
  53   /* Put the tokens into the symbol table, so that GDB and other debuggers
  54      know about them.  */
  55   enum yytokentype {
  56     LTYPE_INTEGER = 258,
  57     LTYPE_FLOAT = 259,
  58     LTYPE_VAR = 260,
  59     LTYPE_PTR = 261,
  60     PTR_TK = 262,
  61     INT_TK = 263,
  62     FLOAT_TK = 264,
  63     DECLARE = 265,
  64     EXTERNAL = 266,
  65     WHILE = 267,
  66     DO = 268,
  67     NOT = 269,
  68     PLUS_EQ = 270,
  69     SUB_EQ = 271,
  70     DIV_EQ = 272,
  71     MUL_EQ = 273,
  72     SUP_EQ = 274,
  73     LOW_EQ = 275,
  74     NOT_EQ = 276,
  75     STRUCT = 277,
  76     FOR = 278,
  77     IN = 279
  78   };
  79#endif
  80#define LTYPE_INTEGER 258
  81#define LTYPE_FLOAT 259
  82#define LTYPE_VAR 260
  83#define LTYPE_PTR 261
  84#define PTR_TK 262
  85#define INT_TK 263
  86#define FLOAT_TK 264
  87#define DECLARE 265
  88#define EXTERNAL 266
  89#define WHILE 267
  90#define DO 268
  91#define NOT 269
  92#define PLUS_EQ 270
  93#define SUB_EQ 271
  94#define DIV_EQ 272
  95#define MUL_EQ 273
  96#define SUP_EQ 274
  97#define LOW_EQ 275
  98#define NOT_EQ 276
  99#define STRUCT 277
 100#define FOR 278
 101#define IN 279
 102
 103
 104
 105
 106/* Copy the first part of user declarations.  */
 107#line 6 "goomsl_yacc.y"
 108
 109    #include <stdio.h>
 110    #include <stdlib.h>
 111    #include <string.h>
 112    #include "goomsl.h"
 113    #include "goomsl_private.h"
 114
 115#define STRUCT_ALIGNMENT 16
 116/* #define VERBOSE  */
 117
 118    int yylex(void);
 119    void yyerror(char *);
 120    extern GoomSL *currentGoomSL;
 121
 122    static NodeType *nodeNew(const char *str, int type, int line_number);
 123    static NodeType *nodeClone(NodeType *node);
 124    static void nodeFreeInternals(NodeType *node);
 125    static void nodeFree(NodeType *node);
 126
 127    static void commit_node(NodeType *node, int releaseIfTemp);
 128    static void precommit_node(NodeType *node);
 129
 130    static NodeType *new_constInt(const char *str, int line_number);
 131    static NodeType *new_constFloat(const char *str, int line_number);
 132    static NodeType *new_constPtr(const char *str, int line_number);
 133    static NodeType *new_var(const char *str, int line_number);
 134    static NodeType *new_nop(const char *str);
 135    static NodeType *new_op(const char *str, int type, int nbOp);
 136
 137    static int  allocateLabel();
 138    static int  allocateTemp();
 139    static void releaseTemp(int n);
 140    static void releaseAllTemps();
 141
 142    static int is_tmp_expr(NodeType *node) {
 143        if (node->str) {
 144            return (!strncmp(node->str,"_i_tmp_",7))
 145              || (!strncmp(node->str,"_f_tmp_",7))
 146              || (!strncmp(node->str,"_p_tmp",7));
 147        }
 148        return 0;
 149    }
 150    /* pre: is_tmp_expr(node); */
 151    static int get_tmp_id(NodeType *node)  { return atoi((node->str)+5); }
 152
 153    static int is_commutative_expr(int itype)
 154    { /* {{{ */
 155        return (itype == INSTR_ADD)
 156            || (itype == INSTR_MUL)
 157            || (itype == INSTR_ISEQUAL);
 158    } /* }}} */
 159
 160    static void GSL_PUT_LABEL(char *name, int line_number)
 161    { /* {{{ */
 162#ifdef VERBOSE
 163      printf("label %s\n", name);
 164#endif
 165      currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, line_number);
 166      gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
 167    } /* }}} */
 168    static void GSL_PUT_JUMP(char *name, int line_number)
 169    { /* {{{ */
 170#ifdef VERBOSE
 171      printf("jump %s\n", name);
 172#endif
 173      currentGoomSL->instr = gsl_instr_init(currentGoomSL, "jump", INSTR_JUMP, 1, line_number);
 174      gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
 175    } /* }}} */
 176
 177    static void GSL_PUT_JXXX(char *name, char *iname, int instr_id, int line_number)
 178    { /* {{{ */
 179#ifdef VERBOSE
 180      printf("%s %s\n", iname, name);
 181#endif
 182      currentGoomSL->instr = gsl_instr_init(currentGoomSL, iname, instr_id, 1, line_number);
 183      gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL);
 184    } /* }}} */
 185    static void GSL_PUT_JZERO(char *name,int line_number)
 186    { /* {{{ */
 187      GSL_PUT_JXXX(name,"jzero.i",INSTR_JZERO,line_number);
 188    } /* }}} */
 189    static void GSL_PUT_JNZERO(char *name, int line_number)
 190    { /* {{{ */
 191      GSL_PUT_JXXX(name,"jnzero.i",INSTR_JNZERO,line_number);
 192    } /* }}} */
 193
 194    /* Structures Management */
 195
 196#define ALIGN_ADDR(_addr,_align) {\
 197   if (_align>1) {\
 198       int _dec = (_addr%_align);\
 199       if (_dec != 0) _addr += _align - _dec;\
 200   }}
 201
 202    /* */
 203    void gsl_prepare_struct(GSL_Struct *s, int s_align, int i_align, int f_align)
 204    {
 205      int i;
 206      int consumed = 0;
 207      int iblk=0, fblk=0;
 208
 209      s->iBlock[0].size = 0;
 210      s->iBlock[0].data = 0;
 211      s->fBlock[0].size = 0;
 212      s->fBlock[0].data = 0;
 213
 214      /* Prepare sub-struct and calculate space needed for their storage */
 215      for (i = 0; i < s->nbFields; ++i)
 216      {
 217        if (s->fields[i]->type < FIRST_RESERVED)
 218        {
 219          int j=0;
 220          GSL_Struct *substruct = currentGoomSL->gsl_struct[s->fields[i]->type];
 221          consumed += sizeof(int); /* stocke le prefix */
 222          ALIGN_ADDR(consumed, s_align);
 223          s->fields[i]->offsetInStruct = consumed;
 224          gsl_prepare_struct(substruct, s_align, i_align, f_align);
 225          for(j=0;substruct->iBlock[j].size>0;++j) {
 226            s->iBlock[iblk].data = consumed + substruct->iBlock[j].data;
 227            s->iBlock[iblk].size = substruct->iBlock[j].size;
 228            iblk++;
 229          }
 230          for(j=0;substruct->fBlock[j].size>0;++j) {
 231            s->fBlock[fblk].data = consumed + substruct->fBlock[j].data;
 232            s->fBlock[fblk].size = substruct->fBlock[j].size;
 233            fblk++;
 234          }
 235          consumed += substruct->size;
 236        }
 237      }
 238
 239      /* Then prepare integers */
 240      ALIGN_ADDR(consumed, i_align);
 241      for (i = 0; i < s->nbFields; ++i)
 242      {
 243        if (s->fields[i]->type == INSTR_INT)
 244        {
 245          if (s->iBlock[iblk].size == 0) {
 246            s->iBlock[iblk].size = 1;
 247            s->iBlock[iblk].data = consumed;
 248          } else {
 249            s->iBlock[iblk].size += 1;
 250          }
 251          s->fields[i]->offsetInStruct = consumed;
 252          consumed += sizeof(int);
 253        }
 254      }
 255
 256      iblk++;
 257      s->iBlock[iblk].size = 0;
 258      s->iBlock[iblk].data = 0;
 259
 260      /* Then prepare floats */
 261      ALIGN_ADDR(consumed, f_align);
 262      for (i = 0; i < s->nbFields; ++i)
 263      {
 264        if (s->fields[i]->type == INSTR_FLOAT)
 265        {
 266          if (s->fBlock[fblk].size == 0) {
 267            s->fBlock[fblk].size = 1;
 268            s->fBlock[fblk].data = consumed;
 269          } else {
 270            s->fBlock[fblk].size += 1;
 271          }
 272          s->fields[i]->offsetInStruct = consumed;
 273          consumed += sizeof(int);
 274        }
 275      }
 276
 277      fblk++;
 278      s->fBlock[fblk].size = 0;
 279      s->fBlock[fblk].data = 0;
 280      
 281      /* Finally prepare pointers */
 282      ALIGN_ADDR(consumed, i_align);
 283      for (i = 0; i < s->nbFields; ++i)
 284      {
 285        if (s->fields[i]->type == INSTR_PTR)
 286        {
 287          s->fields[i]->offsetInStruct = consumed;
 288          consumed += sizeof(int);
 289        }
 290      }
 291      s->size = consumed;
 292    }
 293
 294    /* Returns the ID of a struct from its name */
 295    int gsl_get_struct_id(const char *name) /* {{{ */
 296    {
 297      HashValue *ret = goom_hash_get(currentGoomSL->structIDS, name);
 298      if (ret != NULL) return ret->i;
 299      return -1;
 300    } /* }}} */
 301
 302    /* Adds the definition of a struct */
 303    void gsl_add_struct(const char *name, GSL_Struct *gsl_struct) /* {{{ */
 304    {
 305      /* Prepare the struct: ie calculate internal storage format */
 306      gsl_prepare_struct(gsl_struct, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT);
 307      
 308      /* If the struct does not already exists */
 309      if (gsl_get_struct_id(name) < 0)
 310      {
 311        /* adds it */
 312        int id = currentGoomSL->nbStructID++;
 313        goom_hash_put_int(currentGoomSL->structIDS, name, id);
 314        if (currentGoomSL->gsl_struct_size <= id) {
 315          currentGoomSL->gsl_struct_size *= 2;
 316          currentGoomSL->gsl_struct = (GSL_Struct**)realloc(currentGoomSL->gsl_struct,
 317                                                            sizeof(GSL_Struct*) * currentGoomSL->gsl_struct_size);
 318        }
 319        currentGoomSL->gsl_struct[id] = gsl_struct;
 320      }
 321    } /* }}} */
 322    
 323    /* Creates a field for a struct */
 324    GSL_StructField *gsl_new_struct_field(const char *name, int type)
 325    {
 326      GSL_StructField *field = (GSL_StructField*)malloc(sizeof(GSL_StructField));
 327      strcpy(field->name, name);
 328      field->type = type;
 329      return field;
 330    }
 331    
 332    /* Create as field for a struct which will be a struct itself */
 333    GSL_StructField *gsl_new_struct_field_struct(const char *name, const char *type)
 334    {
 335      GSL_StructField *field = gsl_new_struct_field(name, gsl_get_struct_id(type));
 336      if (field->type < 0) {
 337        fprintf(stderr, "ERROR: Line %d, Unknown structure: '%s'\n",
 338                currentGoomSL->num_lines, type);
 339        exit(1);
 340      }
 341      return field;
 342    }
 343
 344    /* Creates a Struct */
 345    GSL_Struct *gsl_new_struct(GSL_StructField *field)
 346    {
 347      GSL_Struct *s = (GSL_Struct*)malloc(sizeof(GSL_Struct));
 348      s->nbFields = 1;
 349      s->fields[0] = field;
 350      return s;
 351    }
 352
 353    /* Adds a field to a struct */
 354    void gsl_add_struct_field(GSL_Struct *s, GSL_StructField *field)
 355    {
 356      s->fields[s->nbFields++] = field;
 357    }
 358
 359    int gsl_type_of_var(GoomHash *ns, const char *name)
 360    {
 361        char type_of[256];
 362        HashValue *hv;
 363        sprintf(type_of, "__type_of_%s", name);
 364        hv = goom_hash_get(ns, type_of);
 365        if (hv != NULL)
 366          return hv->i;
 367        fprintf(stderr, "ERROR: Unknown variable type: '%s'\n", name);
 368        return -1;
 369    }
 370
 371    static void gsl_declare_var(GoomHash *ns, const char *name, int type, void *space)
 372    {
 373        char type_of[256];
 374        if (name[0] == '@') { ns = currentGoomSL->vars; }
 375
 376        if (space == NULL) {
 377          switch (type) {
 378            case INSTR_INT:
 379            case INSTR_FLOAT:
 380            case INSTR_PTR:
 381              space = goom_heap_malloc_with_alignment(currentGoomSL->data_heap,
 382                  sizeof(int), sizeof(int));
 383            break;
 384            case -1:
 385              fprintf(stderr, "What the fuck!\n");
 386              exit(1);
 387            default: /* On a un struct_id */
 388              space = goom_heap_malloc_with_alignment_prefixed(currentGoomSL->data_heap,
 389                  currentGoomSL->gsl_struct[type]->size, STRUCT_ALIGNMENT, sizeof(int));
 390          }
 391        }
 392        goom_hash_put_ptr(ns, name, (void*)space);
 393        sprintf(type_of, "__type_of_%s", name);
 394        goom_hash_put_int(ns, type_of, type);
 395
 396        /* Ensuite le hack: on ajoute les champs en tant que variables. */
 397        if (type < FIRST_RESERVED)
 398        {
 399          int i;
 400          GSL_Struct *gsl_struct = currentGoomSL->gsl_struct[type];
 401          ((int*)space)[-1] = type; /* stockage du type dans le prefixe de structure */
 402          for (i = 0; i < gsl_struct->nbFields; ++i)
 403          {
 404            char full_name[256];
 405            char *cspace = (char*)space + gsl_struct->fields[i]->offsetInStruct;
 406            sprintf(full_name, "%s.%s", name, gsl_struct->fields[i]->name);
 407            gsl_declare_var(ns, full_name, gsl_struct->fields[i]->type, cspace);
 408          }
 409       }
 410    }
 411    
 412    /* Declare a variable which will be a struct */
 413    static void gsl_struct_decl(GoomHash *namespace, const char *struct_name, const char *name)
 414    {
 415        int  struct_id = gsl_get_struct_id(struct_name);
 416        gsl_declare_var(namespace, name, struct_id, NULL);
 417    }
 418
 419    static void gsl_float_decl_global(const char *name)
 420    {
 421        gsl_declare_var(currentGoomSL->vars, name, INSTR_FLOAT, NULL);
 422    }
 423    static void gsl_int_decl_global(const char *name)
 424    {
 425        gsl_declare_var(currentGoomSL->vars, name, INSTR_INT, NULL);
 426    }
 427    static void gsl_ptr_decl_global(const char *name)
 428    {
 429        gsl_declare_var(currentGoomSL->vars, name, INSTR_PTR, NULL);
 430    }
 431    static void gsl_struct_decl_global_from_id(const char *name, int id)
 432    {
 433        gsl_declare_var(currentGoomSL->vars, name, id, NULL);
 434    }
 435    
 436    /* FLOAT */
 437    static void gsl_float_decl_local(const char *name)
 438    {
 439        gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_FLOAT, NULL);
 440    }
 441    /* INT */
 442    static void gsl_int_decl_local(const char *name)
 443    {
 444        gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_INT, NULL);
 445    }
 446    /* PTR */
 447    static void gsl_ptr_decl_local(const char *name)
 448    {
 449        gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_PTR, NULL);
 450    }
 451    /* STRUCT */
 452    static void gsl_struct_decl_local(const char *struct_name, const char *name)
 453    {
 454        gsl_struct_decl(currentGoomSL->namespaces[currentGoomSL->currentNS],struct_name,name);
 455    }
 456
 457
 458    static void commit_test2(NodeType *set,const char *type, int instr);
 459    static NodeType *new_call(const char *name, NodeType *affect_list);
 460
 461    /* SETTER */
 462    static NodeType *new_set(NodeType *lvalue, NodeType *expression)
 463    { /* {{{ */
 464        NodeType *set = new_op("set", OPR_SET, 2);
 465        set->unode.opr.op[0] = lvalue;
 466        set->unode.opr.op[1] = expression;
 467        return set;
 468    } /* }}} */
 469    static void commit_set(NodeType *set)
 470    { /* {{{ */
 471      commit_test2(set,"set",INSTR_SET);
 472    } /* }}} */
 473
 474    /* PLUS_EQ */
 475    static NodeType *new_plus_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
 476    {
 477        NodeType *set = new_op("plus_eq", OPR_PLUS_EQ, 2);
 478        set->unode.opr.op[0] = lvalue;
 479        set->unode.opr.op[1] = expression;
 480        return set;
 481    }
 482    static void commit_plus_eq(NodeType *set)
 483    {
 484        precommit_node(set->unode.opr.op[1]);
 485#ifdef VERBOSE
 486        printf("add %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
 487#endif
 488        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "add", INSTR_ADD, 2, set->line_number);
 489        commit_node(set->unode.opr.op[0],0);
 490        commit_node(set->unode.opr.op[1],1);
 491    } /* }}} */
 492
 493    /* SUB_EQ */
 494    static NodeType *new_sub_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
 495    {
 496        NodeType *set = new_op("sub_eq", OPR_SUB_EQ, 2);
 497        set->unode.opr.op[0] = lvalue;
 498        set->unode.opr.op[1] = expression;
 499        return set;
 500    }
 501    static void commit_sub_eq(NodeType *set)
 502    {
 503        precommit_node(set->unode.opr.op[1]);
 504#ifdef VERBOSE
 505        printf("sub %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
 506#endif
 507        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "sub", INSTR_SUB, 2, set->line_number);
 508        commit_node(set->unode.opr.op[0],0);
 509        commit_node(set->unode.opr.op[1],1);
 510    } /* }}} */
 511
 512    /* MUL_EQ */
 513    static NodeType *new_mul_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
 514    {
 515        NodeType *set = new_op("mul_eq", OPR_MUL_EQ, 2);
 516        set->unode.opr.op[0] = lvalue;
 517        set->unode.opr.op[1] = expression;
 518        return set;
 519    }
 520    static void commit_mul_eq(NodeType *set)
 521    {
 522        precommit_node(set->unode.opr.op[1]);
 523#ifdef VERBOSE
 524        printf("mul %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
 525#endif
 526        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "mul", INSTR_MUL, 2, set->line_number);
 527        commit_node(set->unode.opr.op[0],0);
 528        commit_node(set->unode.opr.op[1],1);
 529    } /* }}} */
 530
 531    /* DIV_EQ */
 532    static NodeType *new_div_eq(NodeType *lvalue, NodeType *expression) /* {{{ */
 533    {
 534        NodeType *set = new_op("div_eq", OPR_DIV_EQ, 2);
 535        set->unode.opr.op[0] = lvalue;
 536        set->unode.opr.op[1] = expression;
 537        return set;
 538    }
 539    static void commit_div_eq(NodeType *set)
 540    {
 541        precommit_node(set->unode.opr.op[1]);
 542#ifdef VERBOSE
 543        printf("div %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);
 544#endif
 545        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "div", INSTR_DIV, 2, set->line_number);
 546        commit_node(set->unode.opr.op[0],0);
 547        commit_node(set->unode.opr.op[1],1);
 548    } /* }}} */
 549
 550    /* commodity method for add, mult, ... */
 551
 552    static void precommit_expr(NodeType *expr, const char *type, int instr_id)
 553    { /* {{{ */
 554        NodeType *tmp, *tmpcpy;
 555        int toAdd;
 556
 557        /* compute "left" and "right" */
 558        switch (expr->unode.opr.nbOp) {
 559        case 2:
 560          precommit_node(expr->unode.opr.op[1]);
 561        case 1:
 562          precommit_node(expr->unode.opr.op[0]);
 563        }
 564
 565        if (is_tmp_expr(expr->unode.opr.op[0])) {
 566            tmp = expr->unode.opr.op[0];
 567            toAdd = 1;
 568        }
 569        else if (is_commutative_expr(instr_id) && (expr->unode.opr.nbOp==2) && is_tmp_expr(expr->unode.opr.op[1])) {
 570            tmp = expr->unode.opr.op[1];
 571            toAdd = 0;
 572        }
 573        else {
 574            char stmp[256];
 575            /* declare a temporary variable to store the result */
 576            if (expr->unode.opr.op[0]->type == CONST_INT_NODE) {
 577                sprintf(stmp,"_i_tmp_%i",allocateTemp());
 578                gsl_int_decl_global(stmp);
 579            }
 580            else if (expr->unode.opr.op[0]->type == CONST_FLOAT_NODE) {
 581                sprintf(stmp,"_f_tmp%i",allocateTemp());
 582                gsl_float_decl_global(stmp);
 583            }
 584            else if (expr->unode.opr.op[0]->type == CONST_PTR_NODE) {
 585                sprintf(stmp,"_p_tmp%i",allocateTemp());
 586                gsl_ptr_decl_global(stmp);
 587            }
 588            else {
 589                int type = gsl_type_of_var(expr->unode.opr.op[0]->vnamespace, expr->unode.opr.op[0]->str);
 590                if (type == INSTR_FLOAT) {
 591                    sprintf(stmp,"_f_tmp_%i",allocateTemp());
 592                    gsl_float_decl_global(stmp);
 593                }
 594                else if (type == INSTR_PTR) {
 595                    sprintf(stmp,"_p_tmp_%i",allocateTemp());
 596                    gsl_ptr_decl_global(stmp);
 597                }
 598                else if (type == INSTR_INT) {
 599                    sprintf(stmp,"_i_tmp_%i",allocateTemp());
 600                    gsl_int_decl_global(stmp);
 601                }
 602                else if (type == -1) {
 603                    fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
 604                            expr->line_number, expr->unode.opr.op[0]->str);
 605                    exit(1);
 606                }
 607                else { /* type is a struct_id */
 608                    sprintf(stmp,"_s_tmp_%i",allocateTemp());
 609                    gsl_struct_decl_global_from_id(stmp,type);
 610                }
 611            }
 612            tmp = new_var(stmp,expr->line_number);
 613
 614            /* set the tmp to the value of "op1" */
 615            tmpcpy = nodeClone(tmp);
 616            commit_node(new_set(tmp,expr->unode.opr.op[0]),0);
 617            toAdd = 1;
 618
 619            tmp = tmpcpy;
 620        }
 621
 622        /* add op2 to tmp */
 623#ifdef VERBOSE
 624        if (expr->unode.opr.nbOp == 2)
 625          printf("%s %s %s\n", type, tmp->str, expr->unode.opr.op[toAdd]->str);
 626        else
 627          printf("%s %s\n", type, tmp->str);
 628#endif
 629        currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr_id, expr->unode.opr.nbOp, expr->line_number);
 630        tmpcpy = nodeClone(tmp);
 631        commit_node(tmp,0);
 632        if (expr->unode.opr.nbOp == 2) {
 633          commit_node(expr->unode.opr.op[toAdd],1);
 634        }
 635    
 636        /* redefine the ADD node now as the computed variable */
 637        nodeFreeInternals(expr);
 638        *expr = *tmpcpy;
 639        free(tmpcpy);
 640    } /* }}} */
 641
 642    static NodeType *new_expr1(const char *name, int id, NodeType *expr1)
 643    { /* {{{ */
 644        NodeType *add = new_op(name, id, 1);
 645        add->unode.opr.op[0] = expr1;
 646        return add;
 647    } /* }}} */
 648
 649    static NodeType *new_expr2(const char *name, int id, NodeType *expr1, NodeType *expr2)
 650    { /* {{{ */
 651        NodeType *add = new_op(name, id, 2);
 652        add->unode.opr.op[0] = expr1;
 653        add->unode.opr.op[1] = expr2;
 654        return add;
 655    } /* }}} */
 656
 657    /* ADD */
 658    static NodeType *new_add(NodeType *expr1, NodeType *expr2) { /* {{{ */
 659        return new_expr2("add", OPR_ADD, expr1, expr2);
 660    }
 661    static void precommit_add(NodeType *add) {
 662        precommit_expr(add,"add",INSTR_ADD);
 663    } /* }}} */
 664
 665    /* SUB */
 666    static NodeType *new_sub(NodeType *expr1, NodeType *expr2) { /* {{{ */
 667        return new_expr2("sub", OPR_SUB, expr1, expr2);
 668    }
 669    static void precommit_sub(NodeType *sub) {
 670        precommit_expr(sub,"sub",INSTR_SUB);
 671    } /* }}} */
 672
 673    /* NEG */
 674    static NodeType *new_neg(NodeType *expr) { /* {{{ */
 675        NodeType *zeroConst = NULL;
 676        if (expr->type == CONST_INT_NODE)
 677          zeroConst = new_constInt("0", currentGoomSL->num_lines);
 678        else if (expr->type == CONST_FLOAT_NODE)
 679          zeroConst = new_constFloat("0.0", currentGoomSL->num_lines);
 680        else if (expr->type == CONST_PTR_NODE) {
 681          fprintf(stderr, "ERROR: Line %d, Could not negate const pointer.\n",
 682            currentGoomSL->num_lines);
 683          exit(1);
 684        }
 685        else {
 686            int type = gsl_type_of_var(expr->vnamespace, expr->str);
 687            if (type == INSTR_FLOAT)
 688              zeroConst = new_constFloat("0.0", currentGoomSL->num_lines);
 689            else if (type == INSTR_PTR) {
 690              fprintf(stderr, "ERROR: Line %d, Could not negate pointer.\n",
 691                currentGoomSL->num_lines);
 692              exit(1);
 693            }
 694            else if (type == INSTR_INT)
 695              zeroConst = new_constInt("0", currentGoomSL->num_lines);
 696            else if (type == -1) {
 697                fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
 698                        expr->line_number, expr->unode.opr.op[0]->str);
 699                exit(1);
 700            }
 701            else { /* type is a struct_id */
 702                fprintf(stderr, "ERROR: Line %d, Could not negate struct '%s'\n",
 703                        expr->line_number, expr->str);
 704                exit(1);
 705            }
 706        }
 707        return new_expr2("sub", OPR_SUB, zeroConst, expr);
 708    }
 709    /* }}} */
 710
 711    /* MUL */
 712    static NodeType *new_mul(NodeType *expr1, NodeType *expr2) { /* {{{ */
 713        return new_expr2("mul", OPR_MUL, expr1, expr2);
 714    }
 715    static void precommit_mul(NodeType *mul) {
 716        precommit_expr(mul,"mul",INSTR_MUL);
 717    } /* }}} */
 718    
 719    /* DIV */
 720    static NodeType *new_div(NodeType *expr1, NodeType *expr2) { /* {{{ */
 721        return new_expr2("div", OPR_DIV, expr1, expr2);
 722    }
 723    static void precommit_div(NodeType *mul) {
 724        precommit_expr(mul,"div",INSTR_DIV);
 725    } /* }}} */
 726
 727    /* CALL EXPRESSION */
 728    static NodeType *new_call_expr(const char *name, NodeType *affect_list) { /* {{{ */
 729        NodeType *call = new_call(name,affect_list);
 730        NodeType *node = new_expr1(name, OPR_CALL_EXPR, call);
 731        node->vnamespace = gsl_find_namespace(name);
 732        if (node->vnamespace == NULL)
 733          fprintf(stderr, "ERROR: Line %d, No return type for: '%s'\n", currentGoomSL->num_lines, name);
 734        return node;
 735    }
 736    static void precommit_call_expr(NodeType *call) {
 737        char stmp[256];
 738        NodeType *tmp,*tmpcpy;
 739        int type = gsl_type_of_var(call->vnamespace, call->str);
 740        if (type == INSTR_FLOAT) {
 741          sprintf(stmp,"_f_tmp_%i",allocateTemp());
 742          gsl_float_decl_global(stmp);
 743        }
 744        else if (type == INSTR_PTR) {
 745          sprintf(stmp,"_p_tmp_%i",allocateTemp());
 746          gsl_ptr_decl_global(stmp);
 747        }
 748        else if (type == INSTR_INT) {
 749          sprintf(stmp,"_i_tmp_%i",allocateTemp());
 750          gsl_int_decl_global(stmp);
 751        }
 752        else if (type == -1) {
 753          fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n",
 754                  call->line_number, call->str);
 755          exit(1);
 756        }
 757        else { /* type is a struct_id */
 758          sprintf(stmp,"_s_tmp_%i",allocateTemp());
 759          gsl_struct_decl_global_from_id(stmp,type);
 760        }
 761        tmp = new_var(stmp,call->line_number);
 762        commit_node(call->unode.opr.op[0],0);
 763        tmpcpy = nodeClone(tmp);
 764        commit_node(new_set(tmp,new_var(call->str,call->line_number)),0);
 765        
 766        nodeFreeInternals(call);
 767        *call = *tmpcpy;
 768        free(tmpcpy);
 769    } /* }}} */
 770
 771    static void commit_test2(NodeType *set,const char *type, int instr)
 772    { /* {{{ */
 773        NodeType *tmp;
 774        char stmp[256];
 775        precommit_node(set->unode.opr.op[0]);
 776        precommit_node(set->unode.opr.op[1]);
 777        tmp = set->unode.opr.op[0];
 778        
 779        stmp[0] = 0;
 780        if (set->unode.opr.op[0]->type == CONST_INT_NODE) {
 781            sprintf(stmp,"_i_tmp_%i",allocateTemp());
 782            gsl_int_decl_global(stmp);
 783        }
 784        else if (set->unode.opr.op[0]->type == CONST_FLOAT_NODE) {
 785            sprintf(stmp,"_f_tmp%i",allocateTemp());
 786            gsl_float_decl_global(stmp);
 787        }
 788        else if (set->unode.opr.op[0]->type == CONST_PTR_NODE) {
 789            sprintf(stmp,"_p_tmp%i",allocateTemp());
 790            gsl_ptr_decl_global(stmp);
 791        }
 792        if (stmp[0]) {
 793            NodeType *tmpcpy;
 794            tmp = new_var(stmp, set->line_number);
 795            tmpcpy = nodeClone(tmp);
 796            commit_node(new_set(tmp,set->unode.opr.op[0]),0);
 797            tmp = tmpcpy;
 798        }
 799
 800#ifdef VERBOSE
 801        printf("%s %s %s\n", type, tmp->str, set->unode.opr.op[1]->str);
 802#endif
 803        currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr, 2, set->line_number);
 804        commit_node(tmp,instr!=INSTR_SET);
 805        commit_node(set->unode.opr.op[1],1);
 806    } /* }}} */
 807    
 808    /* NOT */
 809    static NodeType *new_not(NodeType *expr1) { /* {{{ */
 810        return new_expr1("not", OPR_NOT, expr1);
 811    }
 812    static void commit_not(NodeType *set)
 813    {
 814        commit_node(set->unode.opr.op[0],0);
 815#ifdef VERBOSE
 816        printf("not\n");
 817#endif
 818        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "not", INSTR_NOT, 1, set->line_number);
 819        gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
 820    } /* }}} */
 821    
 822    /* EQU */
 823    static NodeType *new_equ(NodeType *expr1, NodeType *expr2) { /* {{{ */
 824        return new_expr2("isequal", OPR_EQU, expr1, expr2);
 825    }
 826    static void commit_equ(NodeType *mul) {
 827        commit_test2(mul,"isequal",INSTR_ISEQUAL);
 828    } /* }}} */
 829    
 830    /* INF */
 831    static NodeType *new_low(NodeType *expr1, NodeType *expr2) { /* {{{ */
 832        return new_expr2("islower", OPR_LOW, expr1, expr2);
 833    }
 834    static void commit_low(NodeType *mul) {
 835        commit_test2(mul,"islower",INSTR_ISLOWER);
 836    } /* }}} */
 837
 838    /* WHILE */
 839    static NodeType *new_while(NodeType *expression, NodeType *instr) { /* {{{ */
 840        NodeType *node = new_op("while", OPR_WHILE, 2);
 841        node->unode.opr.op[0] = expression;
 842        node->unode.opr.op[1] = instr;
 843        return node;
 844    }
 845
 846    static void commit_while(NodeType *node)
 847    {
 848        int lbl = allocateLabel();
 849        char start_while[1024], test_while[1024];
 850        sprintf(start_while, "|start_while_%d|", lbl);
 851        sprintf(test_while, "|test_while_%d|", lbl);
 852       
 853        GSL_PUT_JUMP(test_while,node->line_number);
 854        GSL_PUT_LABEL(start_while,node->line_number);
 855
 856        /* code */
 857        commit_node(node->unode.opr.op[1],0);
 858
 859        GSL_PUT_LABEL(test_while,node->line_number);
 860        commit_node(node->unode.opr.op[0],0);
 861        GSL_PUT_JNZERO(start_while,node->line_number);
 862    } /* }}} */
 863
 864    /* FOR EACH */
 865    static NodeType *new_static_foreach(NodeType *var, NodeType *var_list, NodeType *instr) { /* {{{ */
 866        NodeType *node = new_op("for", OPR_FOREACH, 3);
 867        node->unode.opr.op[0] = var;
 868        node->unode.opr.op[1] = var_list;
 869        node->unode.opr.op[2] = instr;
 870        node->line_number = currentGoomSL->num_lines;
 871        return node;
 872    }
 873    static void commit_foreach(NodeType *node)
 874    {
 875        NodeType *cur = node->unode.opr.op[1];
 876        char tmp_func[256], tmp_loop[256];
 877        int lbl = allocateLabel();
 878        sprintf(tmp_func, "|foreach_func_%d|", lbl);
 879        sprintf(tmp_loop, "|foreach_loop_%d|", lbl);
 880
 881        GSL_PUT_JUMP(tmp_loop, node->line_number);
 882        GSL_PUT_LABEL(tmp_func, node->line_number);
 883
 884        precommit_node(node->unode.opr.op[2]);
 885        commit_node(node->unode.opr.op[2], 0);
 886
 887        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number);
 888        gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
 889#ifdef VERBOSE
 890        printf("ret\n");
 891#endif
 892        
 893        GSL_PUT_LABEL(tmp_loop, node->line_number);
 894        
 895        while (cur != NULL)
 896        {
 897          NodeType *x, *var;
 898
 899          /* 1: x=var */
 900          x   = nodeClone(node->unode.opr.op[0]);
 901          var = nodeClone(cur->unode.opr.op[0]);
 902          commit_node(new_set(x, var),0);
 903          
 904          /* 2: instr */
 905          currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number);
 906          gsl_instr_add_param(currentGoomSL->instr, tmp_func, TYPE_LABEL);
 907#ifdef VERBOSE
 908          printf("call %s\n", tmp_func);
 909#endif
 910          
 911          /* 3: var=x */
 912          x   = nodeClone(node->unode.opr.op[0]);
 913          var = cur->unode.opr.op[0];
 914          commit_node(new_set(var, x),0);
 915          cur = cur->unode.opr.op[1];
 916        }
 917        nodeFree(node->unode.opr.op[0]);
 918    } /* }}} */
 919
 920    /* IF */
 921    static NodeType *new_if(NodeType *expression, NodeType *instr) { /* {{{ */
 922        NodeType *node = new_op("if", OPR_IF, 2);
 923        node->unode.opr.op[0] = expression;
 924        node->unode.opr.op[1] = instr;
 925        return node;
 926    }
 927    static void commit_if(NodeType *node) {
 928
 929        char slab[1024];
 930        sprintf(slab, "|eif%d|", allocateLabel());
 931        commit_node(node->unode.opr.op[0],0);
 932        GSL_PUT_JZERO(slab,node->line_number);
 933        /* code */
 934        commit_node(node->unode.opr.op[1],0);
 935        GSL_PUT_LABEL(slab,node->line_number);
 936    } /* }}} */
 937
 938    /* BLOCK */
 939    static NodeType *new_block(NodeType *lastNode) { /* {{{ */
 940        NodeType *blk = new_op("block", OPR_BLOCK, 2);
 941        blk->unode.opr.op[0] = new_nop("start_of_block");
 942        blk->unode.opr.op[1] = lastNode;        
 943        return blk;
 944    }
 945    static void commit_block(NodeType *node) {
 946        commit_node(node->unode.opr.op[0]->unode.opr.next,0);
 947    } /* }}} */
 948
 949    /* FUNCTION INTRO */
 950    static NodeType *new_function_intro(const char *name) { /* {{{ */
 951        char stmp[256];
 952        if (strlen(name) < 200) {
 953           sprintf(stmp, "|__func_%s|", name);
 954        }
 955        return new_op(stmp, OPR_FUNC_INTRO, 0);
 956    }
 957    static void commit_function_intro(NodeType *node) {
 958        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, node->line_number);
 959        gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);
 960#ifdef VERBOSE
 961        printf("label %s\n", node->str);
 962#endif
 963    } /* }}} */
 964
 965    /* FUNCTION OUTRO */
 966    static NodeType *new_function_outro() { /* {{{ */
 967        return new_op("ret", OPR_FUNC_OUTRO, 0);
 968    }
 969    static void commit_function_outro(NodeType *node) {
 970        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number);
 971        gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);
 972        releaseAllTemps();
 973#ifdef VERBOSE
 974        printf("ret\n");
 975#endif
 976    } /* }}} */
 977    
 978    /* AFFECTATION LIST */
 979    static NodeType *new_affec_list(NodeType *set, NodeType *next) /* {{{ */
 980    {
 981      NodeType *node = new_op("affect_list", OPR_AFFECT_LIST, 2);
 982      node->unode.opr.op[0] = set;
 983      node->unode.opr.op[1] = next;
 984      return node;
 985    }
 986    static NodeType *new_affect_list_after(NodeType *affect_list)
 987    {
 988      NodeType *ret  = NULL;
 989      NodeType *cur  =  affect_list;
 990      while(cur != NULL) {
 991        NodeType *set  = cur->unode.opr.op[0];
 992        NodeType *next = cur->unode.opr.op[1];
 993        NodeType *lvalue     = set->unode.opr.op[0];
 994        NodeType *expression = set->unode.opr.op[1];
 995        if ((lvalue->str[0] == '&') && (expression->type == VAR_NODE)) {
 996          NodeType *nset = new_set(nodeClone(expression), nodeClone(lvalue));
 997          ret  = new_affec_list(nset, ret);
 998        }
 999        cur = next;
1000      }
1001      return ret;
1002    }
1003    static void commit_affect_list(NodeType *node)
1004    {
1005      NodeType *cur = node;
1006      while(cur != NULL) {
1007        NodeType *set = cur->unode.opr.op[0];
1008        precommit_node(set->unode.opr.op[0]);
1009        precommit_node(set->unode.opr.op[1]);
1010        cur = cur->unode.opr.op[1];
1011      }
1012      cur = node;
1013      while(cur != NULL) {
1014        NodeType *set = cur->unode.opr.op[0];
1015        commit_node(set,0);
1016        cur = cur->unode.opr.op[1];
1017      }
1018    } /* }}} */
1019
1020    /* VAR LIST */
1021    static NodeType *new_var_list(NodeType *var, NodeType *next) /* {{{ */
1022    {
1023      NodeType *node = new_op("var_list", OPR_VAR_LIST, 2);
1024      node->unode.opr.op[0] = var;
1025      node->unode.opr.op[1] = next;
1026      return node;
1027    }
1028    static void commit_var_list(NodeType *node)
1029    {
1030    } /* }}} */
1031
1032    /* FUNCTION CALL */
1033    static NodeType *new_call(const char *name, NodeType *affect_list) { /* {{{ */
1034        HashValue *fval;
1035        fval = goom_hash_get(currentGoomSL->functions, name);
1036        if (!fval) {
1037            gsl_declare_task(name);
1038            fval = goom_hash_get(currentGoomSL->functions, name);
1039        }
1040        if (!fval) {
1041            fprintf(stderr, "ERROR: Line %d, Could not find function %s\n", currentGoomSL->num_lines, name);
1042            exit(1);
1043            return NULL;
1044        }
1045        else {
1046            ExternalFunctionStruct *gef = (ExternalFunctionStruct*)fval->ptr;
1047            if (gef->is_extern) {
1048                NodeType *node =  new_op(name, OPR_EXT_CALL, 1);
1049                node->unode.opr.op[0] = affect_list;
1050                return node;
1051            }
1052            else {
1053                NodeType *node;
1054                char stmp[256];
1055                if (strlen(name) < 200) {
1056                    sprintf(stmp, "|__func_%s|", name);
1057                }
1058                node = new_op(stmp, OPR_CALL, 1);
1059                node->unode.opr.op[0] = affect_list;
1060                return node;
1061            }
1062        }
1063    }
1064    static void commit_ext_call(NodeType *node) {
1065        NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]);
1066        commit_node(node->unode.opr.op[0],0);
1067        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "extcall", INSTR_EXT_CALL, 1, node->line_number);
1068        gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR);
1069#ifdef VERBOSE
1070        printf("extcall %s\n", node->str);
1071#endif
1072        commit_node(alafter,0);
1073    }
1074    static void commit_call(NodeType *node) {
1075        NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]);
1076        commit_node(node->unode.opr.op[0],0);
1077        currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number);
1078        gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);
1079#ifdef VERBOSE
1080        printf("call %s\n", node->str);
1081#endif
1082        commit_node(alafter,0);
1083    } /* }}} */
1084
1085    /** **/
1086
1087    static NodeType *rootNode = 0; /* TODO: reinitialiser a chaque compilation. */
1088    static NodeType *lastNode = 0;
1089    static NodeType *gsl_append(NodeType *curNode) {
1090        if (curNode == 0) return 0; /* {{{ */
1091        if (lastNode)
1092            lastNode->unode.opr.next = curNode;
1093        lastNode = curNode;
1094        while(lastNode->unode.opr.next) lastNode = lastNode->unode.opr.next;
1095        if (rootNode == 0)
1096            rootNode = curNode;
1097        return curNode;
1098    } /* }}} */
1099
1100#if 1
1101    int allocateTemp() {
1102      return allocateLabel();
1103    }
1104    void releaseAllTemps() {}
1105    void releaseTemp(int n) {}
1106#else
1107    static int nbTemp = 0;
1108    static int *tempArray = 0;
1109    static int tempArraySize = 0;
1110    int allocateTemp() { /* TODO: allocateITemp, allocateFTemp */
1111        int i = 0; /* {{{ */
1112        if (tempArray == 0) {
1113          tempArraySize = 256;
1114          tempArray = (int*)malloc(tempArraySize * sizeof(int));
1115        }
1116        while (1) {
1117          int j;
1118          for (j=0;j<nbTemp;++j) {
1119            if (tempArray[j] == i) break;
1120          }
1121          if (j == nbTemp) {
1122            if (nbTemp == tempArraySize) {
1123              tempArraySize *= 2;
1124              tempArray = (int*)realloc(tempArray,tempArraySize * sizeof(int));
1125            }
1126            tempArray[nbTemp++] = i;
1127            return i;
1128          }
1129          i++;
1130        }
1131    } /* }}} */
1132    void releaseAllTemps() {
1133      nbTemp = 0; /* {{{ */
1134    } /* }}} */
1135    void releaseTemp(int n) {
1136      int j; /* {{{ */
1137      for (j=0;j<nbTemp;++j) {
1138        if (tempArray[j] == n) {
1139          tempArray[j] = tempArray[--nbTemp];
1140          break;
1141        }
1142      }
1143    } /* }}} */
1144#endif
1145
1146    static int lastLabel = 0;
1147    int allocateLabel() {
1148        return ++lastLabel; /* {{{ */
1149    } /* }}} */
1150
1151    void gsl_commit_compilation()
1152    { /* {{{ */
1153        commit_node(rootNode,0);
1154        rootNode = 0;
1155        lastNode = 0;
1156    } /* }}} */
1157    
1158    void precommit_node(NodeType *node)
1159    { /* {{{ */
1160        /* do here stuff for expression.. for exemple */
1161        if (node->type == OPR_NODE)
1162            switch(node->unode.opr.type) {
1163                case OPR_ADD: precommit_add(node); break;
1164                case OPR_SUB: precommit_sub(node); break;
1165                case OPR_MUL: precommit_mul(node); break;
1166                case OPR_DIV: precommit_div(node); break;
1167                case OPR_CALL_EXPR: precommit_call_expr(node); break;
1168            }
1169    } /* }}} */
1170    
1171    void commit_node(NodeType *node, int releaseIfTmp)
1172    { /* {{{ */
1173        if (node == 0) return;
1174        
1175        switch(node->type) {
1176            case OPR_NODE:
1177                switch(node->unode.opr.type) {
1178                    case OPR_SET:           commit_set(node); break;
1179                    case OPR_PLUS_EQ:       commit_plus_eq(node); break;
1180                    case OPR_SUB_EQ:        commit_sub_eq(node); break;
1181                    case OPR_MUL_EQ:        commit_mul_eq(node); break;
1182                    case OPR_DIV_EQ:        commit_div_eq(node); break;
1183                    case OPR_IF:            commit_if(node); break;
1184                    case OPR_WHILE:         commit_while(node); break;
1185                    case OPR_BLOCK:         commit_block(node); break;
1186                    case OPR_FUNC_INTRO:    commit_function_intro(node); break;
1187                    case OPR_FUNC_OUTRO:    commit_function_outro(node); break;
1188                    case OPR_CALL:          commit_call(node); break;
1189                    case OPR_EXT_CALL:      commit_ext_call(node); break;
1190                    case OPR_EQU:           commit_equ(node); break;
1191                    case OPR_LOW:           commit_low(node); break;
1192                    case OPR_NOT:           commit_not(node); break;
1193                    case OPR_AFFECT_LIST:   commit_affect_list(node); break;
1194                    case OPR_FOREACH:       commit_foreach(node); break;
1195                    case OPR_VAR_LIST:      commit_var_list(node); break;
1196#ifdef VERBOSE
1197                    case EMPTY_NODE:        printf("NOP\n"); break;
1198#endif
1199                }
1200
1201                commit_node(node->unode.opr.next,0); /* recursive for the moment, maybe better to do something iterative? */
1202                break;
1203
1204            case VAR_NODE:         gsl_instr_set_namespace(currentGoomSL->instr, node->vnamespace);
1205                                   gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR); break;
1206            case CONST_INT_NODE:   gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_INTEGER); break;
1207            case CONST_FLOAT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_FLOAT); break;
1208            case CONST_PTR_NODE:   gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_PTR); break;
1209        }
1210        if (releaseIfTmp && is_tmp_expr(node))
1211          releaseTemp(get_tmp_id(node));
1212        
1213        nodeFree(node);
1214    } /* }}} */
1215
1216    NodeType *nodeNew(const char *str, int type, int line_number) {
1217        NodeType *node = (NodeType*)malloc(sizeof(NodeType)); /* {{{ */
1218        node->type = type;
1219        node->str  = (char*)malloc(strlen(str)+1);
1220        node->vnamespace = NULL;
1221        node->line_number = line_number;
1222        strcpy(node->str, str);
1223        return node;
1224    } /* }}} */
1225    static NodeType *nodeClone(NodeType *node) {
1226        NodeType *ret = nodeNew(node->str, node->type, node->line_number); /* {{{ */
1227        ret->vnamespace = node->vnamespace;
1228        ret->unode = node->unode;
1229        return ret;
1230    } /* }}} */
1231
1232    void nodeFreeInternals(NodeType *node) {
1233        free(node->str); /* {{{ */
1234    } /* }}} */
1235    
1236    void nodeFree(NodeType *node) {
1237        nodeFreeInternals(node); /* {{{ */
1238        free(node);
1239    } /* }}} */
1240
1241    NodeType *new_constInt(const char *str, int line_number) {
1242        NodeType *node = nodeNew(str, CONST_INT_NODE, line_number); /* {{{ */
1243        node->unode.constInt.val = atoi(str);
1244        return node;
1245    } /* }}} */
1246
1247    NodeType *new_constPtr(const char *str, int line_number) {
1248        NodeType *node = nodeNew(str, CONST_PTR_NODE, line_number); /* {{{ */
1249        node->unode.constPtr.id = strtol(str,NULL,0);
1250        return node;
1251    } /* }}} */
1252
1253    NodeType *new_constFloat(const char *str, int line_number) {
1254        NodeType *node = nodeNew(str, CONST_FLOAT_NODE, line_number); /* {{{ */
1255        node->unode.constFloat.val = atof(str);
1256        return node;
1257    } /* }}} */
1258
1259    NodeType *new_var(const char *str, int line_number) {
1260        NodeType *node = nodeNew(str, VAR_NODE, line_number); /* {{{ */
1261        node->vnamespace = gsl_find_namespace(str);
1262        if (node->vnamespace == 0) {
1263            fprintf(stderr, "ERROR: Line %d, Variable not found: '%s'\n", line_number, str);
1264            exit(1);
1265        }
1266        return node;
1267    } /* }}} */
1268    
1269    NodeType *new_nop(const char *str) {
1270        NodeType *node = new_op(str, EMPTY_NODE, 0); /* {{{ */
1271        return node;
1272    } /* }}} */
1273    
1274    NodeType *new_op(const char *str, int type, int nbOp) {
1275        int i; /* {{{ */
1276        NodeType *node = nodeNew(str, OPR_NODE, currentGoomSL->num_lines);
1277        node->unode.opr.next = 0;
1278        node->unode.opr.type = type;
1279        node->unode.opr.nbOp = nbOp;
1280        for (i=0;i<nbOp;++i) node->unode.opr.op[i] = 0;
1281        return node;
1282    } /* }}} */
1283
1284
1285    void gsl_declare_global_variable(int type, char *name) {
1286      switch(type){
1287        case -1: break;
1288        case FLOAT_TK:gsl_float_decl_global(name);break;
1289        case INT_TK:  gsl_int_decl_global(name);break;
1290        case PTR_TK:  gsl_ptr_decl_global(name);break;
1291        default:
1292        {
1293          int id = type - 1000;
1294          gsl_struct_decl_global_from_id(name,id);
1295        }
1296      }
1297    }
1298
1299
1300
1301/* Enabling traces.  */
1302#ifndef YYDEBUG
1303# define YYDEBUG 0
1304#endif
1305
1306/* Enabling verbose error messages.  */
1307#ifdef YYERROR_VERBOSE
1308# undef YYERROR_VERBOSE
1309# define YYERROR_VERBOSE 1
1310#else
1311# define YYERROR_VERBOSE 0
1312#endif
1313
1314#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
1315#line 1199 "goomsl_yacc.y"
1316typedef union YYSTYPE {
1317    int intValue;
1318    float floatValue;
1319    char charValue;
1320    char strValue[2048];
1321    NodeType *nPtr;
1322    GoomHash *namespace;
1323    GSL_Struct *gsl_struct;
1324    GSL_StructField *gsl_struct_field;
1325  } YYSTYPE;
1326/* Line 191 of yacc.c.  */
1327#line 1327 "goomsl_yacc.c"
1328# define yystype YYSTYPE /* obsolescent; will be withdrawn */
1329# define YYSTYPE_IS_DECLARED 1
1330# define YYSTYPE_IS_TRIVIAL 1
1331#endif
1332
1333
1334
1335/* Copy the second part of user declarations.  */
1336
1337
1338/* Line 214 of yacc.c.  */
1339#line 1339 "goomsl_yacc.c"
1340
1341#if ! defined (yyoverflow) || YYERROR_VERBOSE
1342
1343/* The parser invokes alloca or malloc; define the necessary symbols.  */
1344
1345# if YYSTACK_USE_ALLOCA
1346#  define YYSTACK_ALLOC alloca
1347# else
1348#  ifndef YYSTACK_USE_ALLOCA
1349#   if defined (alloca) || defined (_ALLOCA_H)
1350#    define YYSTACK_ALLOC alloca
1351#   else
1352#    ifdef __GNUC__
1353#     define YYSTACK_ALLOC __builtin_alloca
1354#    endif
1355#   endif
1356#  endif
1357# endif
1358
1359# ifdef YYSTACK_ALLOC
1360   /* Pacify GCC's `empty if-body' warning. */
1361#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
1362# else
1363#  if defined (__STDC__) || defined (__cplusplus)
1364#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
1365#   define YYSIZE_T size_t
1366#  endif
1367#  define YYSTACK_ALLOC malloc
1368#  define YYSTACK_FREE free
1369# endif
1370#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
1371
1372
1373#if (! defined (yyoverflow) \
1374     && (! defined (__cplusplus) \
1375	 || (YYSTYPE_IS_TRIVIAL)))
1376
1377/* A type that is properly aligned for any stack member.  */
1378union yyalloc
1379{
1380  short yyss;
1381  YYSTYPE yyvs;
1382  };
1383
1384/* The size of the maximum gap between one aligned stack and the next.  */
1385# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
1386
1387/* The size of an array large to enough to hold all stacks, each with
1388   N elements.  */
1389# define YYSTACK_BYTES(N) \
1390     ((N) * (sizeof (short) + sizeof (YYSTYPE))				\
1391      + YYSTACK_GAP_MAXIMUM)
1392
1393/* Copy COUNT objects from FROM to TO.  The source and destination do
1394   not overlap.  */
1395# ifndef YYCOPY
1396#  if 1 < __GNUC__
1397#   define YYCOPY(To, From, Count) \
1398      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
1399#  else
1400#   define YYCOPY(To, From, Count)		\
1401      do					\
1402	{					\
1403	  register YYSIZE_T yyi;		\
1404	  for (yyi = 0; yyi < (Count); yyi++)	\
1405	    (To)[yyi] = (From)[yyi];		\
1406	}					\
1407      while (0)
1408#  endif
1409# endif
1410
1411/* Relocate STACK from its old location to the new one.  The
1412   local variables YYSIZE and YYSTACKSIZE give the old and new number of
1413   elements in the stack, and YYPTR gives the new location of the
1414   stack.  Advance YYPTR to a properly aligned location for the next
1415   stack.  */
1416# define YYSTACK_RELOCATE(Stack)					\
1417    do									\
1418      {									\
1419	YYSIZE_T yynewbytes;						\
1420	YYCOPY (&yyptr->Stack, Stack, yysize);				\
1421	Stack = &yyptr->Stack;						\
1422	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
1423	yyptr += yynewbytes / sizeof (*yyptr);				\
1424      }									\
1425    while (0)
1426
1427#endif
1428
1429#if defined (__STDC__) || defined (__cplusplus)
1430   typedef signed char yysigned_char;
1431#else
1432   typedef short yysigned_char;
1433#endif
1434
1435/* YYFINAL -- State number of the termination state. */
1436#define YYFINAL  3
1437/* YYLAST -- Last index in YYTABLE.  */
1438#define YYLAST   229
1439
1440/* YYNTOKENS -- Number of terminals. */
1441#define YYNTOKENS  42
1442/* YYNNTS -- Number of nonterminals. */
1443#define YYNNTS  30
1444/* YYNRULES -- Number of rules. */
1445#define YYNRULES  89
1446/* YYNRULES -- Number of states. */
1447#define YYNSTATES  217
1448
1449/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
1450#define YYUNDEFTOK  2
1451#define YYMAXUTOK   279
1452
1453#define YYTRANSLATE(YYX) 						\
1454  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
1455
1456/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
1457static const unsigned char yytranslate[] =
1458{
1459       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1460      25,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1461       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1462       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1463      35,    36,    32,    29,    34,    30,     2,    31,     2,     2,
1464       2,     2,     2,     2,     2,     2,     2,     2,    33,     2,
1465      27,    26,    28,    37,     2,     2,     2,     2,     2,     2,
1466       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1467       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1468       2,    40,     2,    41,     2,     2,     2,     2,     2,     2,
1469       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1470       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1471       2,     2,     2,    38,     2,    39,     2,     2,     2,     2,
1472       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1473       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1474       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1475       2,    

Large files files are truncated, but you can click here to view the full file