6 #include "goomsl_private.h"
7 #include "goomsl_yacc.h"
9 /*#define TRACE_SCRIPT*/
11 /* {{{ definition of the instructions number */
12 #define INSTR_SETI_VAR_INTEGER 1
13 #define INSTR_SETI_VAR_VAR 2
14 #define INSTR_SETF_VAR_FLOAT 3
15 #define INSTR_SETF_VAR_VAR 4
17 /* #define INSTR_JUMP 6 */
18 #define INSTR_SETP_VAR_PTR 7
19 #define INSTR_SETP_VAR_VAR 8
20 #define INSTR_SUBI_VAR_INTEGER 9
21 #define INSTR_SUBI_VAR_VAR 10
22 #define INSTR_SUBF_VAR_FLOAT 11
23 #define INSTR_SUBF_VAR_VAR 12
24 #define INSTR_ISLOWERF_VAR_VAR 13
25 #define INSTR_ISLOWERF_VAR_FLOAT 14
26 #define INSTR_ISLOWERI_VAR_VAR 15
27 #define INSTR_ISLOWERI_VAR_INTEGER 16
28 #define INSTR_ADDI_VAR_INTEGER 17
29 #define INSTR_ADDI_VAR_VAR 18
30 #define INSTR_ADDF_VAR_FLOAT 19
31 #define INSTR_ADDF_VAR_VAR 20
32 #define INSTR_MULI_VAR_INTEGER 21
33 #define INSTR_MULI_VAR_VAR 22
34 #define INSTR_MULF_VAR_FLOAT 23
35 #define INSTR_MULF_VAR_VAR 24
36 #define INSTR_DIVI_VAR_INTEGER 25
37 #define INSTR_DIVI_VAR_VAR 26
38 #define INSTR_DIVF_VAR_FLOAT 27
39 #define INSTR_DIVF_VAR_VAR 28
40 /* #define INSTR_JZERO 29 */
41 #define INSTR_ISEQUALP_VAR_VAR 30
42 #define INSTR_ISEQUALP_VAR_PTR 31
43 #define INSTR_ISEQUALI_VAR_VAR 32
44 #define INSTR_ISEQUALI_VAR_INTEGER 33
45 #define INSTR_ISEQUALF_VAR_VAR 34
46 #define INSTR_ISEQUALF_VAR_FLOAT 35
47 /* #define INSTR_CALL 36 */
48 /* #define INSTR_RET 37 */
49 /* #define INSTR_EXT_CALL 38 */
50 #define INSTR_NOT_VAR 39
51 /* #define INSTR_JNZERO 40 */
52 #define INSTR_SETS_VAR_VAR 41
53 #define INSTR_ISEQUALS_VAR_VAR 42
54 #define INSTR_ADDS_VAR_VAR 43
55 #define INSTR_SUBS_VAR_VAR 44
56 #define INSTR_MULS_VAR_VAR 45
57 #define INSTR_DIVS_VAR_VAR 46
60 /* {{{ definition of the validation error types */
61 static const char *VALIDATE_OK = "ok";
63 #define VALIDATE_ERROR "error while validating "
64 #define VALIDATE_TODO "todo"
65 #define VALIDATE_SYNTHAX_ERROR "synthax error"
66 #define VALIDATE_NO_SUCH_INT "no such integer variable"
67 #define VALIDATE_NO_SUCH_VAR "no such variable"
68 #define VALIDATE_NO_SUCH_DEST_VAR "no such destination variable"
69 #define VALIDATE_NO_SUCH_SRC_VAR "no such src variable"
72 /***********************************/
73 /* PROTOTYPE OF INTERNAL FUNCTIONS */
74 /***********************************/
77 static void gsl_instr_free (Instruction * _this);
78 static const char *gsl_instr_validate (Instruction * _this);
79 static void gsl_instr_display (Instruction * _this);
81 static InstructionFlow *iflow_new (void);
82 static void iflow_add_instr (InstructionFlow * _this, Instruction * instr);
83 static void iflow_clean (InstructionFlow * _this);
84 static void iflow_free (InstructionFlow * _this);
85 static void iflow_execute (FastInstructionFlow * _this, GoomSL * gsl);
89 /************************************/
90 /* DEFINITION OF INTERNAL FUNCTIONS */
91 /************************************/
94 iflow_free (InstructionFlow * _this)
96 goom_hash_free (_this->labels);
97 free (_this); /*TODO: finir cette fonction */
101 iflow_clean (InstructionFlow * _this)
103 /* TODO: clean chaque instruction du flot */
105 goom_hash_free (_this->labels);
106 _this->labels = goom_hash_new ();
112 InstructionFlow *_this =
113 (InstructionFlow *) malloc (sizeof (InstructionFlow));
117 (Instruction **) malloc (_this->tabsize * sizeof (Instruction *));
118 _this->labels = goom_hash_new ();
124 iflow_add_instr (InstructionFlow * _this, Instruction * instr)
126 if (_this->number == _this->tabsize) {
129 (Instruction **) realloc (_this->instr,
130 _this->tabsize * sizeof (Instruction *));
132 _this->instr[_this->number] = instr;
133 instr->address = _this->number;
138 gsl_instr_set_namespace (Instruction * _this, GoomHash * ns)
140 if (_this->cur_param <= 0) {
141 fprintf (stderr, "ERROR: Line %d, No more params to instructions\n",
145 _this->vnamespace[_this->cur_param - 1] = ns;
149 gsl_instr_add_param (Instruction * instr, char *param, int type)
155 if (instr->cur_param == 0)
158 len = strlen (param);
159 instr->params[instr->cur_param] = (char *) malloc (len + 1);
160 strcpy (instr->params[instr->cur_param], param);
161 instr->types[instr->cur_param] = type;
162 if (instr->cur_param == 0) {
164 const char *result = gsl_instr_validate (instr);
166 if (result != VALIDATE_OK) {
167 printf ("ERROR: Line %d: ", instr->parent->num_lines + 1);
168 gsl_instr_display (instr);
169 printf ("... %s\n", result);
170 instr->parent->compilationOK = 0;
174 iflow_add_instr (instr->parent->iflow, instr);
176 if (instr->id != INSTR_NOP)
177 iflow_add_instr (instr->parent->iflow, instr);
179 gsl_instr_free (instr);
185 gsl_instr_init (GoomSL * parent, const char *name, int id, int nb_param,
188 Instruction *instr = (Instruction *) malloc (sizeof (Instruction));
189 instr->params = (char **) malloc (nb_param * sizeof (char *));
190 instr->vnamespace = (GoomHash **) malloc (nb_param * sizeof (GoomHash *));
191 instr->types = (int *) malloc (nb_param * sizeof (int));
192 instr->cur_param = instr->nb_param = nb_param;
193 instr->parent = parent;
196 instr->jump_label = NULL;
197 instr->line_number = line_number;
202 gsl_instr_free (Instruction * _this)
207 for (i = _this->cur_param; i < _this->nb_param; ++i)
208 free (_this->params[i]);
209 free (_this->params);
214 gsl_instr_display (Instruction * _this)
216 int i = _this->nb_param - 1;
218 printf ("%s", _this->name);
219 while (i >= _this->cur_param) {
220 printf (" %s", _this->params[i]);
225 /****************************************/
226 /* VALIDATION OF INSTRUCTION PARAMETERS */
227 /****************************************/
230 validate_v_v (Instruction * _this)
232 HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
233 HashValue *src = goom_hash_get (_this->vnamespace[0], _this->params[0]);
236 return VALIDATE_NO_SUCH_DEST_VAR;
239 return VALIDATE_NO_SUCH_SRC_VAR;
241 _this->data.udest.var = dest->ptr;
242 _this->data.usrc.var = src->ptr;
247 validate_v_i (Instruction * _this)
249 HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
251 _this->data.usrc.value_int = strtol (_this->params[0], NULL, 0);
254 return VALIDATE_NO_SUCH_INT;
256 _this->data.udest.var = dest->ptr;
261 validate_v_p (Instruction * _this)
263 HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
265 _this->data.usrc.value_ptr = strtol (_this->params[0], NULL, 0);
268 return VALIDATE_NO_SUCH_INT;
270 _this->data.udest.var = dest->ptr;
275 validate_v_f (Instruction * _this)
277 HashValue *dest = goom_hash_get (_this->vnamespace[1], _this->params[1]);
279 _this->data.usrc.value_float = atof (_this->params[0]);
282 return VALIDATE_NO_SUCH_VAR;
284 _this->data.udest.var = dest->ptr;
289 validate (Instruction * _this,
290 int vf_f_id, int vf_v_id,
291 int vi_i_id, int vi_v_id, int vp_p_id, int vp_v_id, int vs_v_id)
293 if ((_this->types[1] == TYPE_FVAR) && (_this->types[0] == TYPE_FLOAT)) {
295 return validate_v_f (_this);
296 } else if ((_this->types[1] == TYPE_FVAR) && (_this->types[0] == TYPE_FVAR)) {
298 return validate_v_v (_this);
299 } else if ((_this->types[1] == TYPE_IVAR)
300 && (_this->types[0] == TYPE_INTEGER)) {
302 return validate_v_i (_this);
303 } else if ((_this->types[1] == TYPE_IVAR) && (_this->types[0] == TYPE_IVAR)) {
305 return validate_v_v (_this);
306 } else if ((_this->types[1] == TYPE_PVAR) && (_this->types[0] == TYPE_PTR)) {
307 if (vp_p_id == INSTR_NOP)
308 return VALIDATE_ERROR;
310 return validate_v_p (_this);
311 } else if ((_this->types[1] == TYPE_PVAR) && (_this->types[0] == TYPE_PVAR)) {
313 if (vp_v_id == INSTR_NOP)
314 return VALIDATE_ERROR;
315 return validate_v_v (_this);
316 } else if ((_this->types[1] < FIRST_RESERVED) && (_this->types[1] >= 0)
317 && (_this->types[0] == _this->types[1])) {
319 if (vs_v_id == INSTR_NOP)
320 return "Impossible operation to perform between two structs";
321 return validate_v_v (_this);
323 return VALIDATE_ERROR;
327 gsl_instr_validate (Instruction * _this)
329 if (_this->id != INSTR_EXT_CALL) {
330 int i = _this->nb_param;
334 if (_this->types[i] == TYPE_VAR) {
335 int type = gsl_type_of_var (_this->vnamespace[i], _this->params[i]);
337 if (type == INSTR_INT)
338 _this->types[i] = TYPE_IVAR;
339 else if (type == INSTR_FLOAT)
340 _this->types[i] = TYPE_FVAR;
341 else if (type == INSTR_PTR)
342 _this->types[i] = TYPE_PVAR;
343 else if ((type >= 0) && (type < FIRST_RESERVED))
344 _this->types[i] = type;
346 fprintf (stderr, "WARNING: Line %d, %s has no namespace\n",
347 _this->line_number, _this->params[i]);
356 return validate (_this,
357 INSTR_SETF_VAR_FLOAT, INSTR_SETF_VAR_VAR,
358 INSTR_SETI_VAR_INTEGER, INSTR_SETI_VAR_VAR,
359 INSTR_SETP_VAR_PTR, INSTR_SETP_VAR_VAR, INSTR_SETS_VAR_VAR);
363 if (_this->types[0] == TYPE_VAR) {
365 goom_hash_get (_this->parent->functions, _this->params[0]);
367 _this->data.udest.external_function =
368 (struct _ExternalFunctionStruct *) fval->ptr;
372 return VALIDATE_ERROR;
376 if (_this->types[0] == TYPE_LABEL) {
377 _this->jump_label = _this->params[0];
380 return VALIDATE_ERROR;
389 if (_this->types[0] == TYPE_LABEL) {
390 _this->jump_label = _this->params[0];
393 return VALIDATE_ERROR;
399 if (_this->types[0] == TYPE_LABEL) {
400 _this->jump_label = _this->params[0];
403 return VALIDATE_ERROR;
408 if (_this->types[0] == TYPE_LABEL) {
409 _this->id = INSTR_NOP;
410 _this->nop_label = _this->params[0];
411 goom_hash_put_int (_this->parent->iflow->labels, _this->params[0],
412 _this->parent->iflow->number);
415 return VALIDATE_ERROR;
419 return validate (_this,
420 INSTR_ISEQUALF_VAR_FLOAT, INSTR_ISEQUALF_VAR_VAR,
421 INSTR_ISEQUALI_VAR_INTEGER, INSTR_ISEQUALI_VAR_VAR,
422 INSTR_ISEQUALP_VAR_PTR, INSTR_ISEQUALP_VAR_VAR,
423 INSTR_ISEQUALS_VAR_VAR);
427 _this->id = INSTR_NOT_VAR;
432 return validate (_this,
433 INSTR_ISLOWERF_VAR_FLOAT, INSTR_ISLOWERF_VAR_VAR,
434 INSTR_ISLOWERI_VAR_INTEGER, INSTR_ISLOWERI_VAR_VAR,
435 INSTR_NOP, INSTR_NOP, INSTR_NOP);
439 return validate (_this,
440 INSTR_ADDF_VAR_FLOAT, INSTR_ADDF_VAR_VAR,
441 INSTR_ADDI_VAR_INTEGER, INSTR_ADDI_VAR_VAR,
442 INSTR_NOP, INSTR_NOP, INSTR_ADDS_VAR_VAR);
446 return validate (_this,
447 INSTR_MULF_VAR_FLOAT, INSTR_MULF_VAR_VAR,
448 INSTR_MULI_VAR_INTEGER, INSTR_MULI_VAR_VAR,
449 INSTR_NOP, INSTR_NOP, INSTR_MULS_VAR_VAR);
453 return validate (_this,
454 INSTR_SUBF_VAR_FLOAT, INSTR_SUBF_VAR_VAR,
455 INSTR_SUBI_VAR_INTEGER, INSTR_SUBI_VAR_VAR,
456 INSTR_NOP, INSTR_NOP, INSTR_SUBS_VAR_VAR);
460 return validate (_this,
461 INSTR_DIVF_VAR_FLOAT, INSTR_DIVF_VAR_VAR,
462 INSTR_DIVI_VAR_INTEGER, INSTR_DIVI_VAR_VAR,
463 INSTR_NOP, INSTR_NOP, INSTR_DIVS_VAR_VAR);
466 return VALIDATE_TODO;
468 return VALIDATE_ERROR;
475 iflow_execute (FastInstructionFlow * _this, GoomSL * gsl)
479 FastInstruction *instr = _this->instr;
481 int stack_pointer = 0;
483 stack[stack_pointer++] = -1;
485 /* Quelques Macro pour rendre le code plus lisible */
486 #define pSRC_VAR instr[ip].data.usrc.var
487 #define SRC_VAR_INT *instr[ip].data.usrc.var_int
488 #define SRC_VAR_FLOAT *instr[ip].data.usrc.var_float
489 #define SRC_VAR_PTR *instr[ip].data.usrc.var_ptr
491 #define pDEST_VAR instr[ip].data.udest.var
492 #define DEST_VAR_INT *instr[ip].data.udest.var_int
493 #define DEST_VAR_FLOAT *instr[ip].data.udest.var_float
494 #define DEST_VAR_PTR *instr[ip].data.udest.var_ptr
496 #define VALUE_INT instr[ip].data.usrc.value_int
497 #define VALUE_FLOAT instr[ip].data.usrc.value_float
498 #define VALUE_PTR instr[ip].data.usrc.value_ptr
500 #define JUMP_OFFSET instr[ip].data.udest.jump_offset
502 #define SRC_STRUCT_ID instr[ip].data.usrc.var_int[-1]
503 #define DEST_STRUCT_ID instr[ip].data.udest.var_int[-1]
504 #define SRC_STRUCT_IBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i]
505 #define SRC_STRUCT_FBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i]
506 #define DEST_STRUCT_IBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i]
507 #define DEST_STRUCT_FBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i]
508 #define DEST_STRUCT_IBLOCK_VAR(i,j) \
509 ((int*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i].data))[j]
510 #define DEST_STRUCT_FBLOCK_VAR(i,j) \
511 ((float*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i].data))[j]
512 #define SRC_STRUCT_IBLOCK_VAR(i,j) \
513 ((int*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i].data))[j]
514 #define SRC_STRUCT_FBLOCK_VAR(i,j) \
515 ((float*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i].data))[j]
516 #define DEST_STRUCT_SIZE gsl->gsl_struct[DEST_STRUCT_ID]->size
523 gsl_instr_display (instr[ip].proto);
526 switch (instr[ip].id) {
529 case INSTR_SETI_VAR_INTEGER:
530 DEST_VAR_INT = VALUE_INT;
534 case INSTR_SETI_VAR_VAR:
535 DEST_VAR_INT = SRC_VAR_INT;
540 case INSTR_SETF_VAR_FLOAT:
541 DEST_VAR_FLOAT = VALUE_FLOAT;
545 case INSTR_SETF_VAR_VAR:
546 DEST_VAR_FLOAT = SRC_VAR_FLOAT;
551 case INSTR_SETP_VAR_VAR:
552 DEST_VAR_PTR = SRC_VAR_PTR;
556 case INSTR_SETP_VAR_PTR:
557 DEST_VAR_PTR = VALUE_PTR;
568 ip += (flag ? 1 : JUMP_OFFSET);
576 case INSTR_ISEQUALP_VAR_VAR:
577 flag = (DEST_VAR_PTR == SRC_VAR_PTR);
581 case INSTR_ISEQUALP_VAR_PTR:
582 flag = (DEST_VAR_PTR == VALUE_PTR);
587 case INSTR_ISEQUALI_VAR_VAR:
588 flag = (DEST_VAR_INT == SRC_VAR_INT);
592 case INSTR_ISEQUALI_VAR_INTEGER:
593 flag = (DEST_VAR_INT == VALUE_INT);
598 case INSTR_ISEQUALF_VAR_VAR:
599 flag = (DEST_VAR_FLOAT == SRC_VAR_FLOAT);
603 case INSTR_ISEQUALF_VAR_FLOAT:
604 flag = (DEST_VAR_FLOAT == VALUE_FLOAT);
609 case INSTR_ISLOWERI_VAR_VAR:
610 flag = (DEST_VAR_INT < SRC_VAR_INT);
614 case INSTR_ISLOWERI_VAR_INTEGER:
615 flag = (DEST_VAR_INT < VALUE_INT);
620 case INSTR_ISLOWERF_VAR_VAR:
621 flag = (DEST_VAR_FLOAT < SRC_VAR_FLOAT);
625 case INSTR_ISLOWERF_VAR_FLOAT:
626 flag = (DEST_VAR_FLOAT < VALUE_FLOAT);
631 case INSTR_ADDI_VAR_VAR:
632 DEST_VAR_INT += SRC_VAR_INT;
636 case INSTR_ADDI_VAR_INTEGER:
637 DEST_VAR_INT += VALUE_INT;
642 case INSTR_ADDF_VAR_VAR:
643 DEST_VAR_FLOAT += SRC_VAR_FLOAT;
647 case INSTR_ADDF_VAR_FLOAT:
648 DEST_VAR_FLOAT += VALUE_FLOAT;
653 case INSTR_MULI_VAR_VAR:
654 DEST_VAR_INT *= SRC_VAR_INT;
658 case INSTR_MULI_VAR_INTEGER:
659 DEST_VAR_INT *= VALUE_INT;
664 case INSTR_MULF_VAR_FLOAT:
665 DEST_VAR_FLOAT *= VALUE_FLOAT;
669 case INSTR_MULF_VAR_VAR:
670 DEST_VAR_FLOAT *= SRC_VAR_FLOAT;
675 case INSTR_DIVI_VAR_VAR:
676 DEST_VAR_INT /= SRC_VAR_INT;
680 case INSTR_DIVI_VAR_INTEGER:
681 DEST_VAR_INT /= VALUE_INT;
686 case INSTR_DIVF_VAR_FLOAT:
687 DEST_VAR_FLOAT /= VALUE_FLOAT;
691 case INSTR_DIVF_VAR_VAR:
692 DEST_VAR_FLOAT /= SRC_VAR_FLOAT;
697 case INSTR_SUBI_VAR_VAR:
698 DEST_VAR_INT -= SRC_VAR_INT;
702 case INSTR_SUBI_VAR_INTEGER:
703 DEST_VAR_INT -= VALUE_INT;
708 case INSTR_SUBF_VAR_FLOAT:
709 DEST_VAR_FLOAT -= VALUE_FLOAT;
713 case INSTR_SUBF_VAR_VAR:
714 DEST_VAR_FLOAT -= SRC_VAR_FLOAT;
720 stack[stack_pointer++] = ip + 1;
726 ip = stack[--stack_pointer];
733 instr[ip].data.udest.external_function->function (gsl, gsl->vars,
734 instr[ip].data.udest.external_function->vars);
746 ip += (flag ? JUMP_OFFSET : 1);
749 case INSTR_SETS_VAR_VAR:
750 memcpy (pDEST_VAR, pSRC_VAR, DEST_STRUCT_SIZE);
754 case INSTR_ISEQUALS_VAR_VAR:
757 case INSTR_ADDS_VAR_VAR:
758 /* process integers */
760 while (DEST_STRUCT_IBLOCK (i).size > 0) {
761 int j = DEST_STRUCT_IBLOCK (i).size;
764 DEST_STRUCT_IBLOCK_VAR (i, j) += SRC_STRUCT_IBLOCK_VAR (i, j);
770 while (DEST_STRUCT_FBLOCK (i).size > 0) {
771 int j = DEST_STRUCT_FBLOCK (i).size;
774 DEST_STRUCT_FBLOCK_VAR (i, j) += SRC_STRUCT_FBLOCK_VAR (i, j);
781 case INSTR_SUBS_VAR_VAR:
782 /* process integers */
784 while (DEST_STRUCT_IBLOCK (i).size > 0) {
785 int j = DEST_STRUCT_IBLOCK (i).size;
788 DEST_STRUCT_IBLOCK_VAR (i, j) -= SRC_STRUCT_IBLOCK_VAR (i, j);
794 while (DEST_STRUCT_FBLOCK (i).size > 0) {
795 int j = DEST_STRUCT_FBLOCK (i).size;
798 DEST_STRUCT_FBLOCK_VAR (i, j) -= SRC_STRUCT_FBLOCK_VAR (i, j);
805 case INSTR_MULS_VAR_VAR:
806 /* process integers */
808 while (DEST_STRUCT_IBLOCK (i).size > 0) {
809 int j = DEST_STRUCT_IBLOCK (i).size;
812 DEST_STRUCT_IBLOCK_VAR (i, j) *= SRC_STRUCT_IBLOCK_VAR (i, j);
818 while (DEST_STRUCT_FBLOCK (i).size > 0) {
819 int j = DEST_STRUCT_FBLOCK (i).size;
822 DEST_STRUCT_FBLOCK_VAR (i, j) *= SRC_STRUCT_FBLOCK_VAR (i, j);
829 case INSTR_DIVS_VAR_VAR:
830 /* process integers */
832 while (DEST_STRUCT_IBLOCK (i).size > 0) {
833 int j = DEST_STRUCT_IBLOCK (i).size;
836 DEST_STRUCT_IBLOCK_VAR (i, j) /= SRC_STRUCT_IBLOCK_VAR (i, j);
842 while (DEST_STRUCT_FBLOCK (i).size > 0) {
843 int j = DEST_STRUCT_FBLOCK (i).size;
846 DEST_STRUCT_FBLOCK_VAR (i, j) /= SRC_STRUCT_FBLOCK_VAR (i, j);
854 printf ("NOT IMPLEMENTED : %d\n", instr[ip].id);
862 gsl_malloc (GoomSL * _this, int size)
864 if (_this->nbPtr >= _this->ptrArraySize) {
865 _this->ptrArraySize *= 2;
867 (void **) realloc (_this->ptrArray,
868 sizeof (void *) * _this->ptrArraySize);
870 _this->ptrArray[_this->nbPtr] = malloc (size);
871 return _this->nbPtr++;
875 gsl_get_ptr (GoomSL * _this, int id)
877 if ((id >= 0) && (id < _this->nbPtr))
878 return _this->ptrArray[id];
879 fprintf (stderr, "INVALID GET PTR 0x%08x\n", id);
884 gsl_free_ptr (GoomSL * _this, int id)
886 if ((id >= 0) && (id < _this->nbPtr)) {
887 free (_this->ptrArray[id]);
888 _this->ptrArray[id] = 0;
893 gsl_enternamespace (const char *name)
895 HashValue *val = goom_hash_get (currentGoomSL->functions, name);
898 ExternalFunctionStruct *function = (ExternalFunctionStruct *) val->ptr;
900 currentGoomSL->currentNS++;
901 currentGoomSL->namespaces[currentGoomSL->currentNS] = function->vars;
903 fprintf (stderr, "ERROR: Line %d, Could not find namespace: %s\n",
904 currentGoomSL->num_lines, name);
910 gsl_reenternamespace (GoomHash * nsinfo)
912 currentGoomSL->currentNS++;
913 currentGoomSL->namespaces[currentGoomSL->currentNS] = nsinfo;
917 gsl_leavenamespace (void)
919 currentGoomSL->currentNS--;
920 return currentGoomSL->namespaces[currentGoomSL->currentNS + 1];
924 gsl_find_namespace (const char *name)
928 for (i = currentGoomSL->currentNS; i >= 0; --i) {
929 if (goom_hash_get (currentGoomSL->namespaces[i], name))
930 return currentGoomSL->namespaces[i];
936 gsl_declare_task (const char *name)
938 if (goom_hash_get (currentGoomSL->functions, name)) {
941 ExternalFunctionStruct *gef =
942 (ExternalFunctionStruct *) malloc (sizeof (ExternalFunctionStruct));
944 gef->vars = goom_hash_new ();
946 goom_hash_put_ptr (currentGoomSL->functions, name, (void *) gef);
951 gsl_declare_external_task (const char *name)
953 if (goom_hash_get (currentGoomSL->functions, name)) {
954 fprintf (stderr, "ERROR: Line %d, Duplicate declaration of %s\n",
955 currentGoomSL->num_lines, name);
958 ExternalFunctionStruct *gef =
959 (ExternalFunctionStruct *) malloc (sizeof (ExternalFunctionStruct));
961 gef->vars = goom_hash_new ();
963 goom_hash_put_ptr (currentGoomSL->functions, name, (void *) gef);
968 reset_scanner (GoomSL * gss)
972 iflow_clean (gss->iflow);
974 /* reset variables */
975 goom_hash_free (gss->vars);
976 gss->vars = goom_hash_new ();
978 gss->namespaces[0] = gss->vars;
980 goom_hash_free (gss->structIDS);
981 gss->structIDS = goom_hash_new ();
983 while (gss->nbStructID > 0) {
987 for (i = 0; i < gss->gsl_struct[gss->nbStructID]->nbFields; ++i)
988 free (gss->gsl_struct[gss->nbStructID]->fields[i]);
989 free (gss->gsl_struct[gss->nbStructID]);
992 gss->compilationOK = 1;
994 goom_heap_delete (gss->data_heap);
995 gss->data_heap = goom_heap_new ();
999 calculate_labels (InstructionFlow * iflow)
1003 while (i < iflow->number) {
1004 Instruction *instr = iflow->instr[i];
1006 if (instr->jump_label) {
1007 HashValue *label = goom_hash_get (iflow->labels, instr->jump_label);
1010 instr->data.udest.jump_offset = -instr->address + label->i;
1012 fprintf (stderr, "ERROR: Line %d, Could not find label %s\n",
1013 instr->line_number, instr->jump_label);
1014 instr->id = INSTR_NOP;
1015 instr->nop_label = 0;
1028 for (b = 0; b < 31; b++)
1034 /* Cree un flow d'instruction optimise */
1036 gsl_create_fast_iflow (void)
1038 int number = currentGoomSL->iflow->number;
1043 /* pour compatibilite avec les MACROS servant a execution */
1045 GoomSL *gsl = currentGoomSL;
1049 if (currentGoomSL->jitc != NULL)
1050 jitc_x86_delete (currentGoomSL->jitc);
1051 jitc = currentGoomSL->jitc = jitc_x86_env_new (0xffff);
1052 currentGoomSL->jitc_func = jitc_prepare_func (jitc);
1055 #define SRC_STRUCT_ID instr[ip].data.usrc.var_int[-1]
1056 #define DEST_STRUCT_ID instr[ip].data.udest.var_int[-1]
1057 #define SRC_STRUCT_IBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i]
1058 #define SRC_STRUCT_FBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i]
1059 #define DEST_STRUCT_IBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i]
1060 #define DEST_STRUCT_FBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i]
1061 #define DEST_STRUCT_IBLOCK_VAR(i,j) \
1062 ((int*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i].data))[j]
1063 #define DEST_STRUCT_FBLOCK_VAR(i,j) \
1064 ((float*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i].data))[j]
1065 #define SRC_STRUCT_IBLOCK_VAR(i,j) \
1066 ((int*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i].data))[j]
1067 #define SRC_STRUCT_FBLOCK_VAR(i,j) \
1068 ((float*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i].data))[j]
1069 #define DEST_STRUCT_SIZE gsl->gsl_struct[DEST_STRUCT_ID]->size
1072 JITC_JUMP_LABEL (jitc, "__very_end__");
1073 JITC_ADD_LABEL (jitc, "__very_start__");
1075 for (i = 0; i < number; ++i) {
1076 Instruction *instr = currentGoomSL->iflow->instr[i];
1078 switch (instr->id) {
1079 case INSTR_SETI_VAR_INTEGER:
1080 jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_int,
1081 instr->data.usrc.value_int);
1083 case INSTR_SETI_VAR_VAR:
1084 jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_int);
1085 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
1088 case INSTR_SETF_VAR_FLOAT:
1089 jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_float,
1090 *(int *) (&instr->data.usrc.value_float));
1092 case INSTR_SETF_VAR_VAR:
1093 jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_float);
1094 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_float);
1097 if (instr->nop_label != 0)
1098 JITC_ADD_LABEL (jitc, instr->nop_label);
1101 JITC_JUMP_LABEL (jitc, instr->jump_label);
1103 case INSTR_SETP_VAR_PTR:
1104 jitc_add (jitc, "mov [$d], $d", instr->data.udest.var_ptr,
1105 instr->data.usrc.value_ptr);
1107 case INSTR_SETP_VAR_VAR:
1108 jitc_add (jitc, "mov eax, [$d]", instr->data.usrc.var_ptr);
1109 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_ptr);
1111 case INSTR_SUBI_VAR_INTEGER:
1112 jitc_add (jitc, "add [$d], $d", instr->data.udest.var_int,
1113 -instr->data.usrc.value_int);
1115 case INSTR_SUBI_VAR_VAR:
1116 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1117 jitc_add (jitc, "sub eax, [$d]", instr->data.usrc.var_int);
1118 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
1120 case INSTR_SUBF_VAR_FLOAT:
1121 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1123 case INSTR_SUBF_VAR_VAR:
1124 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1126 case INSTR_ISLOWERF_VAR_VAR:
1127 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1129 case INSTR_ISLOWERF_VAR_FLOAT:
1130 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1132 case INSTR_ISLOWERI_VAR_VAR:
1133 jitc_add (jitc, "mov edx, [$d]", instr->data.udest.var_int);
1134 jitc_add (jitc, "sub edx, [$d]", instr->data.usrc.var_int);
1135 jitc_add (jitc, "shr edx, $d", 31);
1137 case INSTR_ISLOWERI_VAR_INTEGER:
1138 jitc_add (jitc, "mov edx, [$d]", instr->data.udest.var_int);
1139 jitc_add (jitc, "sub edx, $d", instr->data.usrc.value_int);
1140 jitc_add (jitc, "shr edx, $d", 31);
1142 case INSTR_ADDI_VAR_INTEGER:
1143 jitc_add (jitc, "add [$d], $d", instr->data.udest.var_int,
1144 instr->data.usrc.value_int);
1146 case INSTR_ADDI_VAR_VAR:
1147 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1148 jitc_add (jitc, "add eax, [$d]", instr->data.usrc.var_int);
1149 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
1151 case INSTR_ADDF_VAR_FLOAT:
1152 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1154 case INSTR_ADDF_VAR_VAR:
1155 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1157 case INSTR_MULI_VAR_INTEGER:
1158 if (instr->data.usrc.value_int != 1) {
1159 int po2 = powerOfTwo (instr->data.usrc.value_int);
1162 /* performs (V / 2^n) by doing V >> n */
1163 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1164 jitc_add (jitc, "sal eax, $d", po2);
1165 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
1167 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1168 jitc_add (jitc, "imul eax, $d", instr->data.usrc.value_int);
1169 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
1173 case INSTR_MULI_VAR_VAR:
1174 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1175 jitc_add (jitc, "imul eax, [$d]", instr->data.usrc.var_int);
1176 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
1178 case INSTR_MULF_VAR_FLOAT:
1179 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1181 case INSTR_MULF_VAR_VAR:
1182 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1184 case INSTR_DIVI_VAR_INTEGER:
1185 if ((instr->data.usrc.value_int != 1)
1186 && (instr->data.usrc.value_int != 0)) {
1187 int po2 = powerOfTwo (instr->data.usrc.value_int);
1190 /* performs (V / 2^n) by doing V >> n */
1191 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1192 jitc_add (jitc, "sar eax, $d", po2);
1193 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
1195 /* performs (V/n) by doing (V*(32^2/n)) */
1198 (double) 4294967296.0 / (double) instr->data.usrc.value_int;
1201 coef = (long) floor (dcoef);
1202 dcoef -= floor (dcoef);
1206 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1207 jitc_add (jitc, "mov edx, $d", coef);
1208 jitc_add (jitc, "imul edx");
1209 if (instr->data.usrc.value_int < 0)
1210 jitc_add (jitc, "neg edx");
1211 jitc_add (jitc, "mov [$d], edx", instr->data.udest.var_int);
1215 case INSTR_DIVI_VAR_VAR:
1216 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1217 jitc_add (jitc, "cdq"); /* sign extend eax into edx */
1218 jitc_add (jitc, "idiv [$d]", instr->data.usrc.var_int);
1219 jitc_add (jitc, "mov [$d], eax", instr->data.udest.var_int);
1221 case INSTR_DIVF_VAR_FLOAT:
1222 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1224 case INSTR_DIVF_VAR_VAR:
1225 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1228 jitc_add (jitc, "cmp edx, $d", 0);
1229 jitc_add (jitc, "je $s", instr->jump_label);
1231 case INSTR_ISEQUALP_VAR_VAR:
1232 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_ptr);
1233 jitc_add (jitc, "mov edx, $d", 0);
1234 jitc_add (jitc, "cmp eax, [$d]", instr->data.usrc.var_ptr);
1235 jitc_add (jitc, "jne $d", 1);
1236 jitc_add (jitc, "inc edx");
1238 case INSTR_ISEQUALP_VAR_PTR:
1239 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_ptr);
1240 jitc_add (jitc, "mov edx, $d", 0);
1241 jitc_add (jitc, "cmp eax, $d", instr->data.usrc.value_ptr);
1242 jitc_add (jitc, "jne $d", 1);
1243 jitc_add (jitc, "inc edx");
1245 case INSTR_ISEQUALI_VAR_VAR:
1246 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1247 jitc_add (jitc, "mov edx, $d", 0);
1248 jitc_add (jitc, "cmp eax, [$d]", instr->data.usrc.var_int);
1249 jitc_add (jitc, "jne $d", 1);
1250 jitc_add (jitc, "inc edx");
1252 case INSTR_ISEQUALI_VAR_INTEGER:
1253 jitc_add (jitc, "mov eax, [$d]", instr->data.udest.var_int);
1254 jitc_add (jitc, "mov edx, $d", 0);
1255 jitc_add (jitc, "cmp eax, $d", instr->data.usrc.value_int);
1256 jitc_add (jitc, "jne $d", 1);
1257 jitc_add (jitc, "inc edx");
1259 case INSTR_ISEQUALF_VAR_VAR:
1260 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1262 case INSTR_ISEQUALF_VAR_FLOAT:
1263 printf ("NOT IMPLEMENTED : %d\n", instr->id);
1266 jitc_add (jitc, "call $s", instr->jump_label);
1269 jitc_add (jitc, "ret");
1271 case INSTR_EXT_CALL:
1272 jitc_add (jitc, "mov eax, [$d]",
1273 &(instr->data.udest.external_function->vars));
1274 jitc_add (jitc, "push eax");
1275 jitc_add (jitc, "mov edx, [$d]", &(currentGoomSL->vars));
1276 jitc_add (jitc, "push edx");
1277 jitc_add (jitc, "mov eax, [$d]", &(currentGoomSL));
1278 jitc_add (jitc, "push eax");
1280 jitc_add (jitc, "mov eax, [$d]",
1281 &(instr->data.udest.external_function));
1282 jitc_add (jitc, "mov eax, [eax]");
1283 jitc_add (jitc, "call [eax]");
1284 jitc_add (jitc, "add esp, $d", 12);
1287 jitc_add (jitc, "mov eax, edx");
1288 jitc_add (jitc, "mov edx, $d", 1);
1289 jitc_add (jitc, "sub edx, eax");
1292 jitc_add (jitc, "cmp edx, $d", 0);
1293 jitc_add (jitc, "jne $s", instr->jump_label);
1295 case INSTR_SETS_VAR_VAR:
1297 int loop = DEST_STRUCT_SIZE / sizeof (int);
1298 int dst = (int) pDEST_VAR;
1299 int src = (int) pSRC_VAR;
1302 jitc_add (jitc, "mov eax, [$d]", src);
1303 jitc_add (jitc, "mov [$d], eax", dst);
1309 case INSTR_ISEQUALS_VAR_VAR:
1311 case INSTR_ADDS_VAR_VAR:
1313 /* process integers */
1316 while (DEST_STRUCT_IBLOCK (i).size > 0) {
1317 int j = DEST_STRUCT_IBLOCK (i).size;
1319 while (j--) { /* TODO interlace 2 */
1320 jitc_add (jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR (i, j));
1321 jitc_add (jitc, "add eax, [$d]", &SRC_STRUCT_IBLOCK_VAR (i, j));
1322 jitc_add (jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR (i, j));
1326 /* process floats */
1328 while (DEST_STRUCT_FBLOCK (i).size > 0) {
1329 int j = DEST_STRUCT_FBLOCK (i).size;
1332 /* DEST_STRUCT_FBLOCK_VAR(i,j) += SRC_STRUCT_FBLOCK_VAR(i,j); */
1339 case INSTR_SUBS_VAR_VAR:
1341 /* process integers */
1344 while (DEST_STRUCT_IBLOCK (i).size > 0) {
1345 int j = DEST_STRUCT_IBLOCK (i).size;
1348 jitc_add (jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR (i, j));
1349 jitc_add (jitc, "sub eax, [$d]", &SRC_STRUCT_IBLOCK_VAR (i, j));
1350 jitc_add (jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR (i, j));
1356 case INSTR_MULS_VAR_VAR:
1358 /* process integers */
1361 while (DEST_STRUCT_IBLOCK (i).size > 0) {
1362 int j = DEST_STRUCT_IBLOCK (i).size;
1365 jitc_add (jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR (i, j));
1366 jitc_add (jitc, "imul eax, [$d]", &SRC_STRUCT_IBLOCK_VAR (i, j));
1367 jitc_add (jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR (i, j));
1373 case INSTR_DIVS_VAR_VAR:
1375 /* process integers */
1378 while (DEST_STRUCT_IBLOCK (i).size > 0) {
1379 int j = DEST_STRUCT_IBLOCK (i).size;
1382 jitc_add (jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR (i, j));
1383 jitc_add (jitc, "cdq");
1384 jitc_add (jitc, "idiv [$d]", &SRC_STRUCT_IBLOCK_VAR (i, j));
1385 jitc_add (jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR (i, j));
1394 JITC_ADD_LABEL (jitc, "__very_end__");
1395 jitc_add (jitc, "call $s", "__very_start__");
1396 jitc_add (jitc, "mov eax, $d", 0);
1397 jitc_validate_func (jitc);
1399 InstructionFlow *iflow = currentGoomSL->iflow;
1400 FastInstructionFlow *fastiflow =
1401 (FastInstructionFlow *) malloc (sizeof (FastInstructionFlow));
1402 fastiflow->mallocedInstr = calloc (number * 16, sizeof (FastInstruction));
1403 /* fastiflow->instr = (FastInstruction*)(((int)fastiflow->mallocedInstr) + 16 - (((int)fastiflow->mallocedInstr)%16)); */
1404 fastiflow->instr = (FastInstruction *) fastiflow->mallocedInstr;
1405 fastiflow->number = number;
1406 for (i = 0; i < number; ++i) {
1407 fastiflow->instr[i].id = iflow->instr[i]->id;
1408 fastiflow->instr[i].data = iflow->instr[i]->data;
1409 fastiflow->instr[i].proto = iflow->instr[i];
1411 currentGoomSL->fastiflow = fastiflow;
1415 void yy_scan_string (const char *str);
1416 void yyparse (void);
1419 gsl_globals (GoomSL * _this)
1426 * Some native external functions
1429 ext_charAt (GoomSL * gsl, GoomHash * global, GoomHash * local)
1431 char *string = GSL_LOCAL_PTR (gsl, local, "value");
1432 int index = GSL_LOCAL_INT (gsl, local, "index");
1434 GSL_GLOBAL_INT (gsl, "charAt") = 0;
1435 if (string == NULL) {
1438 if (index < strlen (string))
1439 GSL_GLOBAL_INT (gsl, "charAt") = string[index];
1443 ext_i2f (GoomSL * gsl, GoomHash * global, GoomHash * local)
1445 int i = GSL_LOCAL_INT (gsl, local, "value");
1447 GSL_GLOBAL_FLOAT (gsl, "i2f") = i;
1451 ext_f2i (GoomSL * gsl, GoomHash * global, GoomHash * local)
1453 float f = GSL_LOCAL_FLOAT (gsl, local, "value");
1455 GSL_GLOBAL_INT (gsl, "f2i") = f;
1462 gsl_compile (GoomSL * _currentGoomSL, const char *script)
1464 char *script_and_externals;
1465 static const char *sBinds =
1466 "external <charAt: string value, int index> : int\n"
1467 "external <f2i: float value> : int\n"
1468 "external <i2f: int value> : float\n";
1471 printf ("\n=== Starting Compilation ===\n");
1474 script_and_externals = malloc (strlen (script) + strlen (sBinds) + 2);
1475 strcpy (script_and_externals, sBinds);
1476 strcat (script_and_externals, script);
1479 currentGoomSL = _currentGoomSL;
1480 reset_scanner (currentGoomSL);
1482 /* 1- create the syntaxic tree */
1483 yy_scan_string (script_and_externals);
1486 /* 2- generate code */
1487 gsl_commit_compilation ();
1489 /* 3- resolve symbols */
1490 calculate_labels (currentGoomSL->iflow);
1492 /* 4- optimize code */
1493 gsl_create_fast_iflow ();
1495 /* 5- bind a few internal functions */
1496 gsl_bind_function (currentGoomSL, "charAt", ext_charAt);
1497 gsl_bind_function (currentGoomSL, "f2i", ext_f2i);
1498 gsl_bind_function (currentGoomSL, "i2f", ext_i2f);
1499 free (script_and_externals);
1502 printf ("=== Compilation done. # of lines: %d. # of instr: %d ===\n",
1503 currentGoomSL->num_lines, currentGoomSL->iflow->number);
1508 gsl_execute (GoomSL * scanner)
1510 if (scanner->compilationOK) {
1512 scanner->jitc_func ();
1514 iflow_execute (scanner->fastiflow, scanner);
1522 GoomSL *gss = (GoomSL *) malloc (sizeof (GoomSL));
1524 gss->iflow = iflow_new ();
1525 gss->vars = goom_hash_new ();
1526 gss->functions = goom_hash_new ();
1527 gss->nbStructID = 0;
1528 gss->structIDS = goom_hash_new ();
1529 gss->gsl_struct_size = 32;
1531 (GSL_Struct **) malloc (gss->gsl_struct_size * sizeof (GSL_Struct *));
1533 gss->namespaces[0] = gss->vars;
1534 gss->data_heap = goom_heap_new ();
1536 reset_scanner (gss);
1538 gss->compilationOK = 0;
1540 gss->ptrArraySize = 256;
1541 gss->ptrArray = (void **) malloc (gss->ptrArraySize * sizeof (void *));
1549 gsl_bind_function (GoomSL * gss, const char *fname,
1550 GoomSL_ExternalFunction func)
1552 HashValue *val = goom_hash_get (gss->functions, fname);
1555 ExternalFunctionStruct *gef = (ExternalFunctionStruct *) val->ptr;
1557 gef->function = func;
1559 fprintf (stderr, "Unable to bind function %s\n", fname);
1563 gsl_is_compiled (GoomSL * gss)
1565 return gss->compilationOK;
1569 gsl_free (GoomSL * gss)
1571 iflow_free (gss->iflow);
1573 free (gss->functions);
1578 static int gsl_nb_import;
1579 static char gsl_already_imported[256][256];
1582 gsl_init_buffer (const char *fname)
1586 fbuffer = (char *) malloc (512);
1590 gsl_append_file_to_buffer (fname, &fbuffer);
1595 gsl_read_file (const char *fname)
1601 f = fopen (fname, "rt");
1603 fprintf (stderr, "ERROR: Could not load file %s\n", fname);
1606 fseek (f, 0, SEEK_END);
1609 buffer = (char *) malloc (fsize + 512);
1610 fread (buffer, 1, fsize, f);
1617 gsl_append_file_to_buffer (const char *fname, char **buffer)
1620 int size, fsize, i = 0;
1621 char reset_msg[256];
1623 /* look if the file have not been already imported */
1624 for (i = 0; i < gsl_nb_import; ++i) {
1625 if (strcmp (gsl_already_imported[i], fname) == 0)
1629 /* add fname to the already imported files. */
1630 strcpy (gsl_already_imported[gsl_nb_import++], fname);
1633 fbuffer = gsl_read_file (fname);
1634 fsize = strlen (fbuffer);
1636 /* look for #import */
1637 while (fbuffer[i]) {
1638 if ((fbuffer[i] == '#') && (fbuffer[i + 1] == 'i')) {
1642 while (fbuffer[i] && (fbuffer[i] != ' '))
1646 while (fbuffer[i] && (fbuffer[i] != '\n'))
1647 impName[j++] = fbuffer[i++];
1649 gsl_append_file_to_buffer (impName, buffer);
1654 sprintf (reset_msg, "\n#FILE %s#\n#RST_LINE#\n", fname);
1655 strcat (*buffer, reset_msg);
1656 size = strlen (*buffer);
1657 *buffer = (char *) realloc (*buffer, size + fsize + 256);
1658 strcat ((*buffer) + size, fbuffer);