Restructure how we look for Read files slightly.
[fvwm.git] / modules / FvwmScript / script.y
blob3841dec9c70dc44a886e5445b2b187b6967050e2
1 %{
2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 #include "config.h"
17 #include "types.h"
18 #include "libs/FGettext.h"
20 #define MAX_VARS 5120
21 extern int numligne;
22 ScriptProp *scriptprop;
23 int nbobj=-1; /* Nombre d'objets */
24 int HasPosition,HasType=0;
25 TabObj *tabobj; /* Tableau d'objets, limite=1000 */
26 int TabIdObj[1001]; /* Tableau d'indice des objets */
27 Bloc **TabIObj; /* TabIObj[Obj][Case] -> bloc attache au case */
28 Bloc *PileBloc[10]; /* Au maximum 10 imbrications de boucle conditionnelle */
29 int TopPileB=0; /* Sommet de la pile des blocs */
30 CaseObj *TabCObj; /* Struct pour enregistrer les valeurs des cases et leur nb */
31 int CurrCase;
32 int i;
33 char **TabNVar; /* Tableau des noms de variables */
34 char **TabVVar; /* Tableau des valeurs de variables */
35 int NbVar;
36 long BuffArg[6][20]; /* Les arguments s'ajoute par couche pour chaque fonction imbriquee */
37 int NbArg[6]; /* Tableau: nb d'args pour chaque couche */
38 int SPileArg; /* Taille de la pile d'arguments */
39 long l;
40 extern char* ScriptName;
42 /* Initialisation globale */
43 void InitVarGlob(void)
45 scriptprop=(ScriptProp*) safecalloc(1,sizeof(ScriptProp));
46 scriptprop->x=-1;
47 scriptprop->y=-1;
48 scriptprop->colorset = -1;
49 scriptprop->initbloc=NULL;
51 tabobj=(TabObj*) safecalloc(1,sizeof(TabObj));
52 for (i=0;i<1001;i++)
53 TabIdObj[i]=-1;
54 TabNVar=NULL;
55 TabVVar=NULL;
56 NbVar=-1;
58 SPileArg=-1;
59 scriptprop->usegettext = False;
60 scriptprop->periodictasks=NULL;
61 scriptprop->quitfunc=NULL;
64 /* Initialisation pour un objet */
65 void InitObjTabCase(int HasMainLoop)
67 if (nbobj==0)
69 TabIObj=(Bloc**)safecalloc(1,sizeof(long));
70 TabCObj=(CaseObj*)safecalloc(1,sizeof(CaseObj));
72 else
74 TabIObj=(Bloc**)realloc(TabIObj,sizeof(long)*(nbobj+1));
75 TabCObj=(CaseObj*)realloc(TabCObj,sizeof(CaseObj)*(nbobj+1));
78 if (!HasMainLoop)
79 TabIObj[nbobj]=NULL;
80 CurrCase=-1;
81 TabCObj[nbobj].NbCase=-1;
84 /* Ajout d'un case dans la table TabCase */
85 /* Initialisation d'un case of: agrandissement de la table */
86 void InitCase(int cond)
88 CurrCase++;
90 /* On enregistre la condition du case */
91 TabCObj[nbobj].NbCase++;
92 if (TabCObj[nbobj].NbCase==0)
93 TabCObj[nbobj].LstCase=(int*)safecalloc(1,sizeof(int));
94 else
95 TabCObj[nbobj].LstCase=(int*)realloc(TabCObj[nbobj].LstCase,sizeof(int)*(CurrCase+1));
96 TabCObj[nbobj].LstCase[CurrCase]=cond;
98 if (CurrCase==0)
99 TabIObj[nbobj]=(Bloc*)safecalloc(1,sizeof(Bloc));
100 else
101 TabIObj[nbobj]=(Bloc*)realloc(TabIObj[nbobj],sizeof(Bloc)*(CurrCase+1));
103 TabIObj[nbobj][CurrCase].NbInstr=-1;
104 TabIObj[nbobj][CurrCase].TabInstr=NULL;
106 /* Ce case correspond au bloc courant d'instruction: on l'empile */
107 PileBloc[0]=&TabIObj[nbobj][CurrCase];
108 TopPileB=0;
111 /* Enleve un niveau d'args dans la pile BuffArg */
112 void RmLevelBufArg(void)
114 SPileArg--;
117 /* Fonction de concatenation des n derniers etage de la pile */
118 /* Retourne les elts trie et depile et la taille */
119 long *Depile(int NbLevelArg, int *s)
121 long *Temp;
122 int j;
123 int i;
124 int size;
126 if (NbLevelArg>0)
128 Temp=(long*)safecalloc(1,sizeof(long));
129 size=0;
130 for (i=SPileArg-NbLevelArg+1;i<=SPileArg;i++)
132 size=NbArg[i]+size+1;
133 Temp=(long*)realloc (Temp,sizeof(long)*size);
134 for (j=0;j<=NbArg[i];j++)
136 Temp[j+size-NbArg[i]-1]=BuffArg[i][j];
139 *s=size;
140 for (i=0;i<NbLevelArg;i++) /* On depile les couches d'arguments */
141 RmLevelBufArg();
142 return Temp;
144 else
146 *s=0;
147 return NULL;
151 /* Ajout d'une commande */
152 void AddCom(int Type, int NbLevelArg)
154 int CurrInstr;
157 PileBloc[TopPileB]->NbInstr++;
158 CurrInstr=PileBloc[TopPileB]->NbInstr;
160 if (CurrInstr==0)
161 PileBloc[TopPileB]->TabInstr=(Instr*)safecalloc(1,sizeof(Instr)*(CurrInstr+1));
162 else
163 PileBloc[TopPileB]->TabInstr=(Instr*)realloc(PileBloc[TopPileB]->TabInstr,
164 sizeof(Instr)*(CurrInstr+1));
165 /* Rangement des instructions dans le bloc */
166 PileBloc[TopPileB]->TabInstr[CurrInstr].Type=Type;
167 /* On enleve la derniere couche d'argument et on la range dans la commande */
169 PileBloc[TopPileB]->TabInstr[CurrInstr].TabArg=Depile(NbLevelArg,
170 &PileBloc[TopPileB]->TabInstr[CurrInstr].NbArg);
173 /* Initialisation du buffer contenant les arguments de la commande courante */
174 /* Ajout d'une couche d'argument dans la pile*/
175 void AddLevelBufArg(void)
177 /* Agrandissment de la pile */
178 SPileArg++;
179 NbArg[SPileArg]=-1;
182 /* Ajout d'un arg dans la couche arg qui est au sommet de la pile TabArg */
183 void AddBufArg(long *TabLong,int NbLong)
185 int i;
187 for (i=0;i<NbLong;i++)
189 BuffArg[SPileArg][i+NbArg[SPileArg]+1]=TabLong[i];
191 NbArg[SPileArg]=NbArg[SPileArg]+NbLong;
194 /* Recheche d'un nom de var dans TabVar, s'il n'existe pas il le cree */
195 /* Retourne un Id */
196 void AddVar(char *Name) /* ajout de variable a la fin de la derniere commande pointee */
198 int i;
200 /* Comparaison avec les variables deja existante */
201 for (i=0;i<=NbVar;i++)
202 if (strcmp(TabNVar[i],Name)==0)
204 l=(long)i;
205 AddBufArg(&l,1);
206 return ;
209 if (NbVar>MAX_VARS-2)
211 fprintf(stderr,
212 "[%s] Line %d: too many variables (>5120)\n",ScriptName,numligne);
213 exit(1);
216 /* La variable n'a pas ete trouvee: creation */
217 NbVar++;
219 if (NbVar==0)
221 TabNVar=(char**)safecalloc(1,sizeof(long));
222 TabVVar=(char**)safecalloc(1,sizeof(long));
224 else
226 TabNVar=(char**)realloc(TabNVar,sizeof(long)*(NbVar+1));
227 TabVVar=(char**)realloc(TabVVar,sizeof(long)*(NbVar+1));
230 TabNVar[NbVar]=(char*)safestrdup(Name);
231 TabVVar[NbVar]=(char*)safecalloc(1,sizeof(char));
232 TabVVar[NbVar][0]='\0';
235 /* Ajout de la variable dans le buffer Arg */
236 l=(long)NbVar;
237 AddBufArg(&l,1);
238 return ;
241 /* Ajout d'une constante str comme argument */
242 void AddConstStr(char *Name)
244 /* On cree une nouvelle variable et on range la constante dedans */
245 NbVar++;
246 if (NbVar==0)
248 TabVVar=(char**)safecalloc(1,sizeof(long));
249 TabNVar=(char**)safecalloc(1,sizeof(long));
251 else
253 TabVVar=(char**)realloc(TabVVar,sizeof(long)*(NbVar+1));
254 TabNVar=(char**)realloc(TabNVar,sizeof(long)*(NbVar+1));
257 TabNVar[NbVar]=(char*)safecalloc(1,sizeof(char));
258 TabNVar[NbVar][0]='\0';
259 TabVVar[NbVar]=(char*)safestrdup(Name);
261 /* Ajout de l'id de la constante dans la liste courante des arguments */
262 l=(long)NbVar;
263 AddBufArg(&l,1);
266 /* Ajout d'une constante numerique comme argument */
267 void AddConstNum(long num)
270 /* On ne cree pas de nouvelle variable */
271 /* On code la valeur numerique afin de le ranger sous forme d'id */
272 l=num+200000;
273 /* Ajout de la constante dans la liste courante des arguments */
274 AddBufArg(&l,1);
277 /* Ajout d'une fonction comme argument */
278 /* Enleve les args de func de la pile, */
279 /* le concate, et les range dans la pile */
280 void AddFunct(int code,int NbLevelArg)
282 int size;
283 long *l;
284 int i;
286 /* Methode: depiler BuffArg et completer le niveau inferieur de BuffArg */
287 l=Depile(NbLevelArg, &size);
289 size++;
290 if (size==1)
291 l=(long*)safecalloc(1,sizeof(long));
292 else
294 l=(long*)realloc(l,sizeof(long)*(size));
295 for (i=size-2;i>-1;i--) /* Deplacement des args */
297 l[i+1]=l[i];
300 l[0]=(long)code-150000;
302 AddBufArg(l,size);
305 /* Ajout d'une instruction de test pour executer un ou plusieurs blocs */
306 /* enregistre l'instruction et le champs de ces blocs = NULL */
307 void AddComBloc(int TypeCond, int NbLevelArg, int NbBloc)
309 int i;
310 int OldNA;
311 int CurrInstr;
313 /* Ajout de l'instruction de teste comme d'une commande */
314 AddCom(TypeCond, NbLevelArg);
316 /* On initialise ensuite les deux champs reserve à bloc1 et bloc2 */
317 CurrInstr=PileBloc[TopPileB]->NbInstr;
318 /* Attention NbArg peur changer si on utilise en arg une fonction */
319 OldNA=PileBloc[TopPileB]->TabInstr[CurrInstr].NbArg;
321 PileBloc[TopPileB]->TabInstr[CurrInstr].TabArg=(long*)realloc(
322 PileBloc[TopPileB]->TabInstr[CurrInstr].TabArg,sizeof(long)*(OldNA+NbBloc));
323 for (i=0;i<NbBloc;i++)
325 PileBloc[TopPileB]->TabInstr[CurrInstr].TabArg[OldNA+i]=0;
327 PileBloc[TopPileB]->TabInstr[CurrInstr].NbArg=OldNA+NbBloc;
330 /* Creer un nouveau bloc, et l'empile: il devient le bloc courant */
331 void EmpilerBloc(void)
333 Bloc *TmpBloc;
335 TmpBloc=(Bloc*)safecalloc(1,sizeof(Bloc));
336 TmpBloc->NbInstr=-1;
337 TmpBloc->TabInstr=NULL;
338 TopPileB++;
339 PileBloc[TopPileB]=TmpBloc;
343 /* Depile le bloc d'initialisation du script et le range a sa place speciale */
344 void DepilerBloc(int IdBloc)
346 Bloc *Bloc1;
347 Instr *IfInstr;
349 Bloc1=PileBloc[TopPileB];
350 TopPileB--;
351 IfInstr=&PileBloc[TopPileB]->TabInstr[PileBloc[TopPileB]->NbInstr];
352 IfInstr->TabArg[IfInstr->NbArg-IdBloc]=(long)Bloc1;
355 /* Gestion des erreurs de syntaxes */
356 int yyerror(char *errmsg)
358 fprintf(stderr,"[%s] Line %d: %s\n",ScriptName,numligne,errmsg);
359 return 0;
365 /* Declaration des types des tokens, tous les types sont assemblés dans union */
366 /* Le type est celui de yyval, yyval est utilisé dans lex explicitement */
367 /* Dans bison, il est utlise implicitement avec $1, $2... */
368 %union { char *str;
369 int number;
372 /* Declaration des symboles terminaux */
373 %token <str> STR GSTR VAR FONT
374 %token <number> NUMBER /* Nombre pour communiquer les dimensions */
376 %token WINDOWTITLE WINDOWLOCALETITLE WINDOWSIZE WINDOWPOSITION USEGETTEXT
377 %token FORECOLOR BACKCOLOR SHADCOLOR LICOLOR COLORSET
378 %token OBJECT INIT PERIODICTASK QUITFUNC MAIN END PROP
379 %token TYPE SIZE POSITION VALUE VALUEMIN VALUEMAX TITLE SWALLOWEXEC ICON FLAGS WARP WRITETOFILE LOCALETITLE
380 %token HIDDEN NOFOCUS NORELIEFSTRING CENTER LEFT RIGHT
381 %token CASE SINGLECLIC DOUBLECLIC BEG POINT
382 %token EXEC HIDE SHOW CHFONT CHFORECOLOR CHBACKCOLOR CHCOLORSET CHWINDOWTITLE CHWINDOWTITLEFARG KEY
383 %token GETVALUE GETMINVALUE GETMAXVALUE GETFORE GETBACK GETHILIGHT GETSHADOW CHVALUE CHVALUEMAX CHVALUEMIN
384 %token ADD DIV MULT GETTITLE GETOUTPUT STRCOPY NUMTOHEX HEXTONUM QUIT
385 %token LAUNCHSCRIPT GETSCRIPTFATHER SENDTOSCRIPT RECEIVFROMSCRIPT
386 %token GET SET SENDSIGN REMAINDEROFDIV GETTIME GETSCRIPTARG
387 %token GETPID SENDMSGANDGET PARSE LASTSTRING GETTEXT
388 %token IF THEN ELSE FOR TO DO WHILE
389 %token BEGF ENDF
390 %token EQUAL INFEQ SUPEQ INF SUP DIFF
393 script: initvar head initbloc periodictask quitfunc object ;
395 /* Initialisation des variables */
396 initvar: { InitVarGlob(); }
399 /* Entete du scripte decrivant les options par defaut */
400 head:
401 | head USEGETTEXT GSTR
403 FGettextInit("FvwmScript", LOCALEDIR, "FvwmScript");
404 FGettextSetLocalePath($3);
406 | head USEGETTEXT
408 fprintf(stderr,"UseGettext!\n");
409 FGettextInit("FvwmScript", LOCALEDIR, "FvwmScript");
411 /* vide: dans ce cas on utilise les valeurs par défaut */
412 | head WINDOWTITLE GSTR
414 /* Titre de la fenetre */
415 scriptprop->titlewin=$3;
417 | head WINDOWLOCALETITLE GSTR
419 /* Titre de la fenetre */
420 scriptprop->titlewin=(char *)FGettext($3);
422 | head ICON STR
424 scriptprop->icon=$3;
426 | head WINDOWPOSITION NUMBER NUMBER
428 /* Position et taille de la fenetre */
429 scriptprop->x=$3;
430 scriptprop->y=$4;
432 | head WINDOWSIZE NUMBER NUMBER
434 /* Position et taille de la fenetre */
435 scriptprop->width=$3;
436 scriptprop->height=$4;
438 | head BACKCOLOR GSTR
440 /* Couleur de fond */
441 scriptprop->backcolor=$3;
442 scriptprop->colorset = -1;
444 | head FORECOLOR GSTR
446 /* Couleur des lignes */
447 scriptprop->forecolor=$3;
448 scriptprop->colorset = -1;
450 | head SHADCOLOR GSTR
452 /* Couleur des lignes */
453 scriptprop->shadcolor=$3;
454 scriptprop->colorset = -1;
456 | head LICOLOR GSTR
458 /* Couleur des lignes */
459 scriptprop->hilicolor=$3;
460 scriptprop->colorset = -1;
462 | head COLORSET NUMBER
464 scriptprop->colorset = $3;
465 AllocColorset($3);
467 | head FONT
469 scriptprop->font=$2;
472 /* Bloc d'initialisation du script */
473 initbloc: /* cas ou il n'y pas de bloc d'initialisation du script */
474 | INIT creerbloc BEG instr END {
475 scriptprop->initbloc=PileBloc[TopPileB];
476 TopPileB--;
479 periodictask: /* cas ou il n'y a pas de tache periodique */
480 | PERIODICTASK creerbloc BEG instr END {
481 scriptprop->periodictasks=PileBloc[TopPileB];
482 TopPileB--;
485 quitfunc: /* case where there are no QuitFunc */
486 | QUITFUNC creerbloc BEG instr END {
487 scriptprop->quitfunc=PileBloc[TopPileB];
488 TopPileB--;
494 /* Desciption d'un objet */
495 object : /* Vide */
496 | object OBJECT id PROP init verify mainloop
499 id: NUMBER { nbobj++;
500 if (nbobj>1000)
501 { yyerror("Too many items\n");
502 exit(1);}
503 if (($1<1)||($1>1000))
504 { yyerror("Choose item id between 1 and 1000\n");
505 exit(1);}
506 if (TabIdObj[$1]!=-1)
507 { i=$1; fprintf(stderr,"Line %d: item id %d already used:\n",numligne,$1);
508 exit(1);}
509 TabIdObj[$1]=nbobj;
510 (*tabobj)[nbobj].id=$1;
511 (*tabobj)[nbobj].colorset = -1;
515 init: /* vide */
516 | init TYPE STR {
517 (*tabobj)[nbobj].type=$3;
518 HasType=1;
520 | init SIZE NUMBER NUMBER {
521 (*tabobj)[nbobj].width=$3;
522 (*tabobj)[nbobj].height=$4;
524 | init POSITION NUMBER NUMBER {
525 (*tabobj)[nbobj].x=$3;
526 (*tabobj)[nbobj].y=$4;
527 HasPosition=1;
529 | init VALUE NUMBER {
530 (*tabobj)[nbobj].value=$3;
532 | init VALUEMIN NUMBER {
533 (*tabobj)[nbobj].value2=$3;
535 | init VALUEMAX NUMBER {
536 (*tabobj)[nbobj].value3=$3;
538 | init TITLE GSTR {
539 (*tabobj)[nbobj].title= $3;
541 | init LOCALETITLE GSTR {
542 (*tabobj)[nbobj].title= FGettextCopy($3);
544 | init SWALLOWEXEC GSTR {
545 (*tabobj)[nbobj].swallow=$3;
547 | init ICON STR {
548 (*tabobj)[nbobj].icon=$3;
550 | init BACKCOLOR GSTR {
551 (*tabobj)[nbobj].backcolor=$3;
552 (*tabobj)[nbobj].colorset = -1;
554 | init FORECOLOR GSTR {
555 (*tabobj)[nbobj].forecolor=$3;
556 (*tabobj)[nbobj].colorset = -1;
558 | init SHADCOLOR GSTR {
559 (*tabobj)[nbobj].shadcolor=$3;
560 (*tabobj)[nbobj].colorset = -1;
562 | init LICOLOR GSTR {
563 (*tabobj)[nbobj].hilicolor=$3;
564 (*tabobj)[nbobj].colorset = -1;
566 | init COLORSET NUMBER {
567 (*tabobj)[nbobj].colorset = $3;
568 AllocColorset($3);
570 | init FONT {
571 (*tabobj)[nbobj].font=$2;
573 | init FLAGS flags
575 flags:
576 | flags HIDDEN {
577 (*tabobj)[nbobj].flags[0]=True;
579 | flags NORELIEFSTRING {
580 (*tabobj)[nbobj].flags[1]=True;
582 | flags NOFOCUS {
583 (*tabobj)[nbobj].flags[2]=True;
585 | flags CENTER {
586 (*tabobj)[nbobj].flags[3]=TEXT_POS_CENTER;
588 | flags LEFT {
589 (*tabobj)[nbobj].flags[3]=TEXT_POS_LEFT;
591 | flags RIGHT {
592 (*tabobj)[nbobj].flags[3]=TEXT_POS_RIGHT;
597 verify: {
598 if (!HasPosition)
599 { yyerror("No position for object");
600 exit(1);}
601 if (!HasType)
602 { yyerror("No type for object");
603 exit(1);}
604 HasPosition=0;
605 HasType=0;
608 mainloop: END { InitObjTabCase(0); }
609 | MAIN addtabcase CASE case END
612 addtabcase: { InitObjTabCase(1); }
614 case:
615 | case clic POINT bloc
616 | case number POINT bloc
619 clic : SINGLECLIC { InitCase(-1); }
620 | DOUBLECLIC { InitCase(-2); }
623 number : NUMBER { InitCase($1); }
626 bloc: BEG instr END
630 /* ensemble d'instructions */
631 instr:
632 | instr EXEC exec
633 | instr WARP warp
634 | instr WRITETOFILE writetofile
635 | instr HIDE hide
636 | instr SHOW show
637 | instr CHVALUE chvalue
638 | instr CHVALUEMAX chvaluemax
639 | instr CHVALUEMIN chvaluemin
640 | instr CHWINDOWTITLE addlbuff gstrarg {AddCom(27,1);}
641 | instr CHWINDOWTITLEFARG numarg {AddCom(28,1);}
642 | instr POSITION position
643 | instr SIZE size
644 | instr TITLE title
645 | instr LOCALETITLE localetitle
646 | instr ICON icon
647 | instr CHFONT font
648 | instr CHFORECOLOR chforecolor
649 | instr CHBACKCOLOR chbackcolor
650 | instr CHCOLORSET chcolorset
651 | instr SET set
652 | instr SENDSIGN sendsign
653 | instr QUIT quit
654 | instr SENDTOSCRIPT sendtoscript
655 | instr IF ifthenelse
656 | instr FOR loop
657 | instr WHILE while
658 | instr KEY key
661 /* une seule instruction */
662 oneinstr: EXEC exec
663 | WARP warp
664 | WRITETOFILE writetofile
665 | HIDE hide
666 | SHOW show
667 | CHVALUE chvalue
668 | CHVALUEMAX chvaluemax
669 | CHVALUEMIN chvaluemin
670 | CHWINDOWTITLE addlbuff gstrarg {AddCom(27,1);}
671 | CHWINDOWTITLEFARG numarg {AddCom(28,1);}
672 | POSITION position
673 | SIZE size
674 | TITLE title
675 | LOCALETITLE localetitle
676 | ICON icon
677 | CHFONT font
678 | CHFORECOLOR chforecolor
679 | CHBACKCOLOR chbackcolor
680 | CHCOLORSET chcolorset
681 | SET set
682 | SENDSIGN sendsign
683 | QUIT quit
684 | SENDTOSCRIPT sendtoscript
685 | FOR loop
686 | WHILE while
687 | KEY key
690 exec: addlbuff args { AddCom(1,1); }
692 hide: addlbuff numarg { AddCom(2,1);}
694 show: addlbuff numarg { AddCom(3,1);}
696 chvalue: addlbuff numarg addlbuff numarg { AddCom(4,2);}
698 chvaluemax: addlbuff numarg addlbuff numarg { AddCom(21,2);}
700 chvaluemin: addlbuff numarg addlbuff numarg { AddCom(22,2);}
702 position: addlbuff numarg addlbuff numarg addlbuff numarg { AddCom(5,3);}
704 size: addlbuff numarg addlbuff numarg addlbuff numarg { AddCom(6,3);}
706 icon: addlbuff numarg addlbuff strarg { AddCom(7,2);}
708 title: addlbuff numarg addlbuff gstrarg { AddCom(8,2);}
710 font: addlbuff numarg addlbuff args { AddCom(9,2);}
712 chforecolor: addlbuff numarg addlbuff gstrarg { AddCom(10,2);}
714 chbackcolor: addlbuff numarg addlbuff gstrarg { AddCom(19,2);}
716 chcolorset : addlbuff numarg addlbuff numarg { AddCom(24,2);}
718 set: addlbuff vararg GET addlbuff args { AddCom(11,2);}
720 sendsign: addlbuff numarg addlbuff numarg { AddCom(12,2);}
722 quit: { AddCom(13,0);}
724 warp: addlbuff numarg { AddCom(17,1);}
726 sendtoscript: addlbuff numarg addlbuff args { AddCom(23,2);}
728 writetofile: addlbuff strarg addlbuff args { AddCom(18,2);}
730 key: addlbuff strarg addlbuff strarg addlbuff numarg addlbuff numarg addlbuff args { AddCom(25,5);}
732 localetitle: addlbuff numarg addlbuff gstrarg { AddCom(26,2);}
734 ifthenelse: headif creerbloc bloc1 else
736 loop: headloop creerbloc bloc2
738 while: headwhile creerbloc bloc2
741 /* Boucle conditionnelle: compare n'importe quel type d'argument */
742 headif: addlbuff arg addlbuff compare addlbuff arg THEN { AddComBloc(14,3,2); }
744 else: /* Le else est optionnel */
745 | ELSE creerbloc bloc2
747 creerbloc: { EmpilerBloc(); }
749 bloc1: BEG instr END { DepilerBloc(2); }
750 | oneinstr { DepilerBloc(2); }
753 bloc2: BEG instr END { DepilerBloc(1); }
754 | oneinstr { DepilerBloc(1); }
757 /* Boucle sur une variable */
758 headloop: addlbuff vararg GET addlbuff arg TO addlbuff arg DO { AddComBloc(15,3,1); }
761 /* Boucle conditionnelle while */
762 headwhile: addlbuff arg addlbuff compare addlbuff arg DO { AddComBloc(16,3,1); }
765 /* Argument de commandes */
766 /* Argument elementaire */
767 var : VAR { AddVar($1); }
769 str : STR { AddConstStr($1); }
771 gstr : GSTR { AddConstStr($1); }
773 num : NUMBER { AddConstNum($1); }
775 singleclic2: SINGLECLIC { AddConstNum(-1); }
777 doubleclic2: DOUBLECLIC { AddConstNum(-2); }
779 addlbuff: { AddLevelBufArg(); }
781 function: GETVALUE numarg { AddFunct(1,1); }
782 | GETTITLE numarg { AddFunct(2,1); }
783 | GETOUTPUT gstrarg numarg numarg { AddFunct(3,1); }
784 | NUMTOHEX numarg numarg { AddFunct(4,1); }
785 | HEXTONUM gstrarg { AddFunct(5,1); }
786 | ADD numarg numarg { AddFunct(6,1); }
787 | MULT numarg numarg { AddFunct(7,1); }
788 | DIV numarg numarg { AddFunct(8,1); }
789 | STRCOPY gstrarg numarg numarg { AddFunct(9,1); }
790 | LAUNCHSCRIPT gstrarg { AddFunct(10,1); }
791 | GETSCRIPTFATHER { AddFunct(11,1); }
792 | RECEIVFROMSCRIPT numarg { AddFunct(12,1); }
793 | REMAINDEROFDIV numarg numarg { AddFunct(13,1); }
794 | GETTIME { AddFunct(14,1); }
795 | GETSCRIPTARG numarg { AddFunct(15,1); }
796 | GETFORE numarg { AddFunct(16,1); }
797 | GETBACK numarg { AddFunct(17,1); }
798 | GETHILIGHT numarg { AddFunct(18,1); }
799 | GETSHADOW numarg { AddFunct(19,1); }
800 | GETMINVALUE numarg { AddFunct(20,1); }
801 | GETMAXVALUE numarg { AddFunct(21,1); }
802 | GETPID { AddFunct(22,1); }
803 | SENDMSGANDGET gstrarg gstrarg numarg { AddFunct(23,1); }
804 | PARSE gstrarg numarg { AddFunct(24,1); }
805 | LASTSTRING { AddFunct(25,1); }
806 | GETTEXT gstrarg { AddFunct(26,1); }
810 /* Plusieurs arguments de type differents */
811 args : { }
812 | singleclic2 args
813 | doubleclic2 args
814 | var args
815 | gstr args
816 | str args
817 | num args
818 | BEGF addlbuff function ENDF args
821 /* Argument unique de n'importe quel type */
822 arg : var
823 | singleclic2
824 | doubleclic2
825 | gstr
826 | str
827 | num
828 | BEGF addlbuff function ENDF
831 /* Argument unique de type numerique */
832 numarg : singleclic2
833 | doubleclic2
834 | num
835 | var
836 | BEGF addlbuff function ENDF
839 /* Argument unique de type str */
840 strarg : var
841 | str
842 | BEGF addlbuff function ENDF
845 /* Argument unique de type gstr */
846 gstrarg : var
847 | gstr
848 | BEGF addlbuff function ENDF
851 /* Argument unique de type var, pas de fonction */
852 vararg : var
855 /* element de comparaison entre deux variables numerique */
856 compare : INF { l=1-250000; AddBufArg(&l,1); }
857 | INFEQ { l=2-250000; AddBufArg(&l,1); }
858 | EQUAL { l=3-250000; AddBufArg(&l,1); }
859 | SUPEQ { l=4-250000; AddBufArg(&l,1); }
860 | SUP { l=5-250000; AddBufArg(&l,1); }
861 | DIFF { l=6-250000; AddBufArg(&l,1); }