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.
6 *
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.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, see: <http://www.gnu.org/licenses/>
14 */
15 #include "config.h"
16 #include "types.h"
17 #include "libs/FGettext.h"
18
19 #define MAX_VARS 5120
20 extern int numligne;
21 ScriptProp *scriptprop;
22 int nbobj=-1; /* Number of objects */
23 int HasPosition,HasType=0;
24 TabObj *tabobj; /* Array of objects, limit=1000 */
25 int TabIdObj[1001]; /* Array of object IDs */
26 Bloc **TabIObj; /* TabIObj[Obj][Case] -> block linked to case */
27 Bloc *PileBloc[10]; /* 10 imbrications max of conditional loops */
28 int TopPileB=0; /* Top of block stack */
29 CaseObj *TabCObj; /* Structure to store cases values and their ID */
30 int CurrCase;
31 int i;
32 char **TabNVar; /* Array of variable names */
33 char **TabVVar; /* Array of variable values */
34 int NbVar;
35 long BuffArg[6][20]; /* Arguments are added by layers for each function */
36 int NbArg[6]; /* Array: number of arguments for each layer */
37 int SPileArg; /* Size of argument stack */
38 long l;
39 extern char* ScriptName;
40
41 /* Global Initialization */
InitVarGlob(void)42 void InitVarGlob(void)
43 {
44 scriptprop=fxcalloc(1, sizeof(ScriptProp));
45 scriptprop->x=-1;
46 scriptprop->y=-1;
47 scriptprop->colorset = -1;
48 scriptprop->initbloc=NULL;
49
50 tabobj=fxcalloc(1, sizeof(TabObj));
51 for (i=0;i<1001;i++)
52 TabIdObj[i]=-1;
53 TabNVar=NULL;
54 TabVVar=NULL;
55 NbVar=-1;
56
57 SPileArg=-1;
58 scriptprop->usegettext = False;
59 scriptprop->periodictasks=NULL;
60 scriptprop->quitfunc=NULL;
61 }
62
63 /* Object Initialization */
InitObjTabCase(int HasMainLoop)64 void InitObjTabCase(int HasMainLoop)
65 {
66 if (nbobj==0)
67 {
68 TabIObj=fxcalloc(1, sizeof(long));
69 TabCObj=fxcalloc(1, sizeof(CaseObj));
70 }
71 else
72 {
73 TabIObj=(Bloc**)realloc(TabIObj,sizeof(long)*(nbobj+1));
74 TabCObj=(CaseObj*)realloc(TabCObj,sizeof(CaseObj)*(nbobj+1));
75 }
76
77 if (!HasMainLoop)
78 TabIObj[nbobj]=NULL;
79 CurrCase=-1;
80 TabCObj[nbobj].NbCase=-1;
81 }
82
83 /* Add a case into TabCase array */
84 /* Initialization of a case: increase array size */
InitCase(int cond)85 void InitCase(int cond)
86 {
87 CurrCase++;
88
89 /* We store the case condition */
90 TabCObj[nbobj].NbCase++;
91 if (TabCObj[nbobj].NbCase==0)
92 TabCObj[nbobj].LstCase=fxcalloc(1, sizeof(int));
93 else
94 TabCObj[nbobj].LstCase=(int*)realloc(TabCObj[nbobj].LstCase,sizeof(int)*(CurrCase+1));
95 TabCObj[nbobj].LstCase[CurrCase]=cond;
96
97 if (CurrCase==0)
98 TabIObj[nbobj]=fxcalloc(1, sizeof(Bloc));
99 else
100 TabIObj[nbobj]=(Bloc*)realloc(TabIObj[nbobj],sizeof(Bloc)*(CurrCase+1));
101
102 TabIObj[nbobj][CurrCase].NbInstr=-1;
103 TabIObj[nbobj][CurrCase].TabInstr=NULL;
104
105 /* This case is for the current instruction block: we stack it */
106 PileBloc[0]=&TabIObj[nbobj][CurrCase];
107 TopPileB=0;
108 }
109
110 /* Remove a level of args in BuffArg stack */
RmLevelBufArg(void)111 void RmLevelBufArg(void)
112 {
113 SPileArg--;
114 }
115
116 /* Function to concatenate the n latest levels of stack */
117 /* Returns the sorted and unstacked elements and size */
Depile(int NbLevelArg,int * s)118 long *Depile(int NbLevelArg, int *s)
119 {
120 long *Temp;
121 int j;
122 int i;
123 int size;
124
125 if (NbLevelArg>0)
126 {
127 Temp=fxcalloc(1, sizeof(long));
128 size=0;
129 for (i=SPileArg-NbLevelArg+1;i<=SPileArg;i++)
130 {
131 size=NbArg[i]+size+1;
132 Temp=(long*)realloc (Temp,sizeof(long)*size);
133 for (j=0;j<=NbArg[i];j++)
134 {
135 Temp[j+size-NbArg[i]-1]=BuffArg[i][j];
136 }
137 }
138 *s=size;
139 for (i=0;i<NbLevelArg;i++) /* Unstack the argument layers */
140 RmLevelBufArg();
141 return Temp;
142 }
143 else
144 {
145 *s=0;
146 return NULL;
147 }
148 }
149
150 /* Add a command */
AddCom(int Type,int NbLevelArg)151 void AddCom(int Type, int NbLevelArg)
152 {
153 int CurrInstr;
154
155
156 PileBloc[TopPileB]->NbInstr++;
157 CurrInstr=PileBloc[TopPileB]->NbInstr;
158
159 if (CurrInstr==0)
160 PileBloc[TopPileB]->TabInstr=fxcalloc(1, sizeof(Instr) * (CurrInstr + 1));
161 else
162 PileBloc[TopPileB]->TabInstr=(Instr*)realloc(PileBloc[TopPileB]->TabInstr,
163 sizeof(Instr)*(CurrInstr+1));
164 /* Put instructions into block */
165 PileBloc[TopPileB]->TabInstr[CurrInstr].Type=Type;
166 /* We remove the last arguments layer and put it in command */
167
168 PileBloc[TopPileB]->TabInstr[CurrInstr].TabArg=Depile(NbLevelArg,
169 &PileBloc[TopPileB]->TabInstr[CurrInstr].NbArg);
170 }
171
172 /* Initialization of the buffer containing the current command arguments */
173 /* Add a layer of arguments into stack */
AddLevelBufArg(void)174 void AddLevelBufArg(void)
175 {
176 /* Increase stack size */
177 SPileArg++;
178 NbArg[SPileArg]=-1;
179 }
180
181 /* Add an argument into the argument layer on top of TabArg stack */
AddBufArg(long * TabLong,int NbLong)182 void AddBufArg(long *TabLong,int NbLong)
183 {
184 int i;
185
186 for (i=0;i<NbLong;i++)
187 {
188 BuffArg[SPileArg][i+NbArg[SPileArg]+1]=TabLong[i];
189 }
190 NbArg[SPileArg]=NbArg[SPileArg]+NbLong;
191 }
192
193 /* Search for a variable name in TabVar, create it if nonexistant */
194 /* Returns an ID */
AddVar(char * Name)195 void AddVar(char *Name) /* add a variable at the end of last pointed command */
196 {
197 int i;
198
199 /* Comparison with already existing variables */
200 for (i=0;i<=NbVar;i++)
201 if (strcmp(TabNVar[i],Name)==0)
202 {
203 l=(long)i;
204 AddBufArg(&l,1);
205 return ;
206 }
207
208 if (NbVar>MAX_VARS-2)
209 {
210 fprintf(stderr,
211 "[%s] Line %d: too many variables (>5120)\n",ScriptName,numligne);
212 exit(1);
213 }
214
215 /* Variable not found: create it */
216 NbVar++;
217
218 if (NbVar==0)
219 {
220 TabNVar=fxcalloc(1, sizeof(long));
221 TabVVar=fxcalloc(1, sizeof(long));
222 }
223 else
224 {
225 TabNVar=(char**)realloc(TabNVar,sizeof(long)*(NbVar+1));
226 TabVVar=(char**)realloc(TabVVar,sizeof(long)*(NbVar+1));
227 }
228
229 TabNVar[NbVar]=fxstrdup(Name);
230 TabVVar[NbVar]=fxcalloc(1, sizeof(char));
231 TabVVar[NbVar][0]='\0';
232
233
234 /* Add variable into argument buffer */
235 l=(long)NbVar;
236 AddBufArg(&l,1);
237 return ;
238 }
239
240 /* Add a string constant as argument */
AddConstStr(char * Name)241 void AddConstStr(char *Name)
242 {
243 /* We create a new variable and put constant in it */
244 NbVar++;
245 if (NbVar==0)
246 {
247 TabVVar=fxcalloc(1, sizeof(long));
248 TabNVar=fxcalloc(1, sizeof(long));
249 }
250 else
251 {
252 TabVVar=(char**)realloc(TabVVar,sizeof(long)*(NbVar+1));
253 TabNVar=(char**)realloc(TabNVar,sizeof(long)*(NbVar+1));
254 }
255
256 TabNVar[NbVar]=fxcalloc(1, sizeof(char));
257 TabNVar[NbVar][0]='\0';
258 TabVVar[NbVar]=fxstrdup(Name);
259
260 /* Add the constant ID into the current arguments list */
261 l=(long)NbVar;
262 AddBufArg(&l,1);
263 }
264
265 /* Add a number constant as argument */
AddConstNum(long num)266 void AddConstNum(long num)
267 {
268
269 /* We don't create a new variable */
270 /* We code the number value to form an ID */
271 l=num+200000;
272 /* Add the constant into the current arguments list */
273 AddBufArg(&l,1);
274 }
275
276 /* Add a functon as argument */
277 /* Remove function arguments from stack, */
278 /* concatene them, and put them into stack */
AddFunct(int code,int NbLevelArg)279 void AddFunct(int code,int NbLevelArg)
280 {
281 int size;
282 long *l;
283 int i;
284
285 /* Method: unstack BuffArg and complete the bottom level of BuffArg */
286 l=Depile(NbLevelArg, &size);
287
288 size++;
289 if (size==1)
290 l=fxcalloc(1, sizeof(long));
291 else
292 {
293 l=(long*)realloc(l,sizeof(long)*(size));
294 for (i=size-2;i>-1;i--) /* Move arguments */
295 {
296 l[i+1]=l[i];
297 }
298 }
299 l[0]=(long)code-150000;
300
301 AddBufArg(l,size);
302 }
303
304 /* Add a test instruction to execute one block or more */
305 /* store the instruction, and these blocks field becomes NULL */
AddComBloc(int TypeCond,int NbLevelArg,int NbBloc)306 void AddComBloc(int TypeCond, int NbLevelArg, int NbBloc)
307 {
308 int i;
309 int OldNA;
310 int CurrInstr;
311
312 /* Add the test instruction as a command */
313 AddCom(TypeCond, NbLevelArg);
314
315 /* We then initialize both reserved fields bloc1 and bloc2 */
316 CurrInstr=PileBloc[TopPileB]->NbInstr;
317 /* Caution: NbArg can change if we use a function as argument */
318 OldNA=PileBloc[TopPileB]->TabInstr[CurrInstr].NbArg;
319
320 PileBloc[TopPileB]->TabInstr[CurrInstr].TabArg=(long*)realloc(
321 PileBloc[TopPileB]->TabInstr[CurrInstr].TabArg,sizeof(long)*(OldNA+NbBloc));
322 for (i=0;i<NbBloc;i++)
323 {
324 PileBloc[TopPileB]->TabInstr[CurrInstr].TabArg[OldNA+i]=0;
325 }
326 PileBloc[TopPileB]->TabInstr[CurrInstr].NbArg=OldNA+NbBloc;
327 }
328
329 /* Create a new block, and stack it: it's becoming the current block */
EmpilerBloc(void)330 void EmpilerBloc(void)
331 {
332 Bloc *TmpBloc;
333
334 TmpBloc=fxcalloc(1, sizeof(Bloc));
335 TmpBloc->NbInstr=-1;
336 TmpBloc->TabInstr=NULL;
337 TopPileB++;
338 PileBloc[TopPileB]=TmpBloc;
339
340 }
341
342 /* Unstack the script initialization block and put it into its special location */
DepilerBloc(int IdBloc)343 void DepilerBloc(int IdBloc)
344 {
345 Bloc *Bloc1;
346 Instr *IfInstr;
347
348 Bloc1=PileBloc[TopPileB];
349 TopPileB--;
350 IfInstr=&PileBloc[TopPileB]->TabInstr[PileBloc[TopPileB]->NbInstr];
351 IfInstr->TabArg[IfInstr->NbArg-IdBloc]=(long)Bloc1;
352 }
353
354 /* Syntax error management */
yyerror(char * errmsg)355 int yyerror(char *errmsg)
356 {
357 fprintf(stderr,"[%s] Line %d: %s\n",ScriptName,numligne,errmsg);
358 return 0;
359 }
360
361
362 %}
363
364 /* Declaration of token types, all types are in union */
365 /* Type is the one of yyval, yyval being used in lex */
366 /* In bison, it's implicitly used with $1, $2... */
367 %union { char *str;
368 int number;
369 }
370
371 /* Declaration of terminal symbols */
372 %token <str> STR GSTR VAR FONT
373 %token <number> NUMBER /* Number to give dimensions */
374
375 %token WINDOWTITLE WINDOWLOCALETITLE WINDOWSIZE WINDOWPOSITION USEGETTEXT
376 %token FORECOLOR BACKCOLOR SHADCOLOR LICOLOR COLORSET
377 %token OBJECT INIT PERIODICTASK QUITFUNC MAIN END PROP
378 %token TYPE SIZE POSITION VALUE VALUEMIN VALUEMAX TITLE SWALLOWEXEC ICON FLAGS WARP WRITETOFILE LOCALETITLE
379 %token HIDDEN NOFOCUS NORELIEFSTRING CENTER LEFT RIGHT
380 %token CASE SINGLECLIC DOUBLECLIC BEG POINT
381 %token EXEC HIDE SHOW CHFONT CHFORECOLOR CHBACKCOLOR CHCOLORSET CHWINDOWTITLE CHWINDOWTITLEFARG KEY
382 %token GETVALUE GETMINVALUE GETMAXVALUE GETFORE GETBACK GETHILIGHT GETSHADOW CHVALUE CHVALUEMAX CHVALUEMIN
383 %token ADD DIV MULT GETTITLE GETOUTPUT STRCOPY NUMTOHEX HEXTONUM QUIT
384 %token LAUNCHSCRIPT GETSCRIPTFATHER SENDTOSCRIPT RECEIVFROMSCRIPT
385 %token GET SET SENDSIGN REMAINDEROFDIV GETTIME GETSCRIPTARG
386 %token GETPID SENDMSGANDGET PARSE LASTSTRING GETTEXT
387 %token IF THEN ELSE FOR TO DO WHILE
388 %token BEGF ENDF
389 %token EQUAL INFEQ SUPEQ INF SUP DIFF
390
391 %%
392 script: initvar head initbloc periodictask quitfunc object ;
393
394 /* Variables Initialization */
395 initvar: { InitVarGlob(); }
396 ;
397
398 /* Script header for default options */
399 head:
400 | head USEGETTEXT GSTR
401 {
402 FGettextInit("FvwmScript", LOCALEDIR, "FvwmScript");
403 FGettextSetLocalePath($3);
404 }
405 | head USEGETTEXT
406 {
407 fprintf(stderr,"UseGettext!\n");
408 FGettextInit("FvwmScript", LOCALEDIR, "FvwmScript");
409 }
410 /* empty: we use default values */
411 | head WINDOWTITLE GSTR
412 {
413 /* Window Title */
414 scriptprop->titlewin=$3;
415 }
416 | head WINDOWLOCALETITLE GSTR
417 {
418 /* Window Title */
419 scriptprop->titlewin=(char *)FGettext($3);
420 }
421 | head ICON STR
422 {
423 scriptprop->icon=$3;
424 }
425 | head WINDOWPOSITION NUMBER NUMBER
426 {
427 /* Window Position and Size */
428 scriptprop->x=$3;
429 scriptprop->y=$4;
430 }
431 | head WINDOWSIZE NUMBER NUMBER
432 {
433 /* Window Width and Height */
434 scriptprop->width=$3;
435 scriptprop->height=$4;
436 }
437 | head BACKCOLOR GSTR
438 {
439 /* Background Color */
440 scriptprop->backcolor=$3;
441 scriptprop->colorset = -1;
442 }
443 | head FORECOLOR GSTR
444 {
445 /* Foreground Color */
446 scriptprop->forecolor=$3;
447 scriptprop->colorset = -1;
448 }
449 | head SHADCOLOR GSTR
450 {
451 /* Shaded Color */
452 scriptprop->shadcolor=$3;
453 scriptprop->colorset = -1;
454 }
455 | head LICOLOR GSTR
456 {
457 /* Highlighted Color */
458 scriptprop->hilicolor=$3;
459 scriptprop->colorset = -1;
460 }
461 | head COLORSET NUMBER
462 {
463 scriptprop->colorset = $3;
464 AllocColorset($3);
465 }
466 | head FONT
467 {
468 scriptprop->font=$2;
469 }
470
471 /* Script initialization block */
472 initbloc: /* case where there's no script initialization block */
473 | INIT creerbloc BEG instr END {
474 scriptprop->initbloc=PileBloc[TopPileB];
475 TopPileB--;
476 }
477
478 periodictask: /* case where there's no periodic task */
479 | PERIODICTASK creerbloc BEG instr END {
480 scriptprop->periodictasks=PileBloc[TopPileB];
481 TopPileB--;
482 }
483
484 quitfunc: /* case where there are no QuitFunc */
485 | QUITFUNC creerbloc BEG instr END {
486 scriptprop->quitfunc=PileBloc[TopPileB];
487 TopPileB--;
488 }
489
490 ;
491
492
493 /* Object Desciption */
494 object : /* Empty */
495 | object OBJECT id PROP init verify mainloop
496 ;
497
498 id: NUMBER { nbobj++;
499 if (nbobj>1000)
500 { yyerror("Too many items\n");
501 exit(1);}
502 if (($1<1)||($1>1000))
503 { yyerror("Choose item id between 1 and 1000\n");
504 exit(1);}
505 if (TabIdObj[$1]!=-1)
506 { i=$1; fprintf(stderr,"Line %d: item id %d already used:\n",numligne,$1);
507 exit(1);}
508 TabIdObj[$1]=nbobj;
509 (*tabobj)[nbobj].id=$1;
510 (*tabobj)[nbobj].colorset = -1;
511 }
512 ;
513
514 init: /* vide */
515 | init TYPE STR {
516 (*tabobj)[nbobj].type=$3;
517 HasType=1;
518 }
519 | init SIZE NUMBER NUMBER {
520 (*tabobj)[nbobj].width=$3;
521 (*tabobj)[nbobj].height=$4;
522 }
523 | init POSITION NUMBER NUMBER {
524 (*tabobj)[nbobj].x=$3;
525 (*tabobj)[nbobj].y=$4;
526 HasPosition=1;
527 }
528 | init VALUE NUMBER {
529 (*tabobj)[nbobj].value=$3;
530 }
531 | init VALUEMIN NUMBER {
532 (*tabobj)[nbobj].value2=$3;
533 }
534 | init VALUEMAX NUMBER {
535 (*tabobj)[nbobj].value3=$3;
536 }
537 | init TITLE GSTR {
538 (*tabobj)[nbobj].title= $3;
539 }
540 | init LOCALETITLE GSTR {
541 (*tabobj)[nbobj].title= FGettextCopy($3);
542 }
543 | init SWALLOWEXEC GSTR {
544 (*tabobj)[nbobj].swallow=$3;
545 }
546 | init ICON STR {
547 (*tabobj)[nbobj].icon=$3;
548 }
549 | init BACKCOLOR GSTR {
550 (*tabobj)[nbobj].backcolor=$3;
551 (*tabobj)[nbobj].colorset = -1;
552 }
553 | init FORECOLOR GSTR {
554 (*tabobj)[nbobj].forecolor=$3;
555 (*tabobj)[nbobj].colorset = -1;
556 }
557 | init SHADCOLOR GSTR {
558 (*tabobj)[nbobj].shadcolor=$3;
559 (*tabobj)[nbobj].colorset = -1;
560 }
561 | init LICOLOR GSTR {
562 (*tabobj)[nbobj].hilicolor=$3;
563 (*tabobj)[nbobj].colorset = -1;
564 }
565 | init COLORSET NUMBER {
566 (*tabobj)[nbobj].colorset = $3;
567 AllocColorset($3);
568 }
569 | init FONT {
570 (*tabobj)[nbobj].font=$2;
571 }
572 | init FLAGS flags
573 ;
574 flags:
575 | flags HIDDEN {
576 (*tabobj)[nbobj].flags[0]=True;
577 }
578 | flags NORELIEFSTRING {
579 (*tabobj)[nbobj].flags[1]=True;
580 }
581 | flags NOFOCUS {
582 (*tabobj)[nbobj].flags[2]=True;
583 }
584 | flags CENTER {
585 (*tabobj)[nbobj].flags[3]=TEXT_POS_CENTER;
586 }
587 | flags LEFT {
588 (*tabobj)[nbobj].flags[3]=TEXT_POS_LEFT;
589 }
590 | flags RIGHT {
591 (*tabobj)[nbobj].flags[3]=TEXT_POS_RIGHT;
592 }
593 ;
594
595
596 verify: {
597 if (!HasPosition)
598 { yyerror("No position for object");
599 exit(1);}
600 if (!HasType)
601 { yyerror("No type for object");
602 exit(1);}
603 HasPosition=0;
604 HasType=0;
605 }
606
607 mainloop: END { InitObjTabCase(0); }
608 | MAIN addtabcase CASE case END
609 ;
610
611 addtabcase: { InitObjTabCase(1); }
612
613 case:
614 | case clic POINT bloc
615 | case number POINT bloc
616 ;
617
618 clic : SINGLECLIC { InitCase(-1); }
619 | DOUBLECLIC { InitCase(-2); }
620 ;
621
622 number : NUMBER { InitCase($1); }
623 ;
624
625 bloc: BEG instr END
626 ;
627
628
629 /* instructions */
630 instr:
631 | instr EXEC exec
632 | instr WARP warp
633 | instr WRITETOFILE writetofile
634 | instr HIDE hide
635 | instr SHOW show
636 | instr CHVALUE chvalue
637 | instr CHVALUEMAX chvaluemax
638 | instr CHVALUEMIN chvaluemin
639 | instr CHWINDOWTITLE addlbuff gstrarg {AddCom(27,1);}
640 | instr CHWINDOWTITLEFARG numarg {AddCom(28,1);}
641 | instr POSITION position
642 | instr SIZE size
643 | instr TITLE title
644 | instr LOCALETITLE localetitle
645 | instr ICON icon
646 | instr CHFONT font
647 | instr CHFORECOLOR chforecolor
648 | instr CHBACKCOLOR chbackcolor
649 | instr CHCOLORSET chcolorset
650 | instr SET set
651 | instr SENDSIGN sendsign
652 | instr QUIT quit
653 | instr SENDTOSCRIPT sendtoscript
654 | instr IF ifthenelse
655 | instr FOR loop
656 | instr WHILE while
657 | instr KEY key
658 ;
659
660 /* One single instruction */
661 oneinstr: EXEC exec
662 | WARP warp
663 | WRITETOFILE writetofile
664 | HIDE hide
665 | SHOW show
666 | CHVALUE chvalue
667 | CHVALUEMAX chvaluemax
668 | CHVALUEMIN chvaluemin
669 | CHWINDOWTITLE addlbuff gstrarg {AddCom(27,1);}
670 | CHWINDOWTITLEFARG numarg {AddCom(28,1);}
671 | POSITION position
672 | SIZE size
673 | TITLE title
674 | LOCALETITLE localetitle
675 | ICON icon
676 | CHFONT font
677 | CHFORECOLOR chforecolor
678 | CHBACKCOLOR chbackcolor
679 | CHCOLORSET chcolorset
680 | SET set
681 | SENDSIGN sendsign
682 | QUIT quit
683 | SENDTOSCRIPT sendtoscript
684 | FOR loop
685 | WHILE while
686 | KEY key
687 ;
688
689 exec: addlbuff args { AddCom(1,1); }
690 ;
691 hide: addlbuff numarg { AddCom(2,1);}
692 ;
693 show: addlbuff numarg { AddCom(3,1);}
694 ;
695 chvalue: addlbuff numarg addlbuff numarg { AddCom(4,2);}
696 ;
697 chvaluemax: addlbuff numarg addlbuff numarg { AddCom(21,2);}
698 ;
699 chvaluemin: addlbuff numarg addlbuff numarg { AddCom(22,2);}
700 ;
701 position: addlbuff numarg addlbuff numarg addlbuff numarg { AddCom(5,3);}
702 ;
703 size: addlbuff numarg addlbuff numarg addlbuff numarg { AddCom(6,3);}
704 ;
705 icon: addlbuff numarg addlbuff strarg { AddCom(7,2);}
706 ;
707 title: addlbuff numarg addlbuff gstrarg { AddCom(8,2);}
708 ;
709 font: addlbuff numarg addlbuff args { AddCom(9,2);}
710 ;
711 chforecolor: addlbuff numarg addlbuff gstrarg { AddCom(10,2);}
712 ;
713 chbackcolor: addlbuff numarg addlbuff gstrarg { AddCom(19,2);}
714 ;
715 chcolorset : addlbuff numarg addlbuff numarg { AddCom(24,2);}
716 ;
717 set: addlbuff vararg GET addlbuff args { AddCom(11,2);}
718 ;
719 sendsign: addlbuff numarg addlbuff numarg { AddCom(12,2);}
720 ;
721 quit: { AddCom(13,0);}
722 ;
723 warp: addlbuff numarg { AddCom(17,1);}
724 ;
725 sendtoscript: addlbuff numarg addlbuff args { AddCom(23,2);}
726 ;
727 writetofile: addlbuff strarg addlbuff args { AddCom(18,2);}
728 ;
729 key: addlbuff strarg addlbuff strarg addlbuff numarg addlbuff numarg addlbuff args { AddCom(25,5);}
730 ;
731 localetitle: addlbuff numarg addlbuff gstrarg { AddCom(26,2);}
732 ;
733 ifthenelse: headif creerbloc bloc1 else
734 ;
735 loop: headloop creerbloc bloc2
736 ;
737 while: headwhile creerbloc bloc2
738 ;
739
740 /* Conditional loop: compare whatever argument type */
741 headif: addlbuff arg addlbuff compare addlbuff arg THEN { AddComBloc(14,3,2); }
742 ;
743 else: /* else is optional */
744 | ELSE creerbloc bloc2
745 ;
746 creerbloc: { EmpilerBloc(); }
747 ;
748 bloc1: BEG instr END { DepilerBloc(2); }
749 | oneinstr { DepilerBloc(2); }
750 ;
751
752 bloc2: BEG instr END { DepilerBloc(1); }
753 | oneinstr { DepilerBloc(1); }
754 ;
755
756 /* Loop on a variable */
757 headloop: addlbuff vararg GET addlbuff arg TO addlbuff arg DO { AddComBloc(15,3,1); }
758 ;
759
760 /* While conditional loop */
761 headwhile: addlbuff arg addlbuff compare addlbuff arg DO { AddComBloc(16,3,1); }
762 ;
763
764 /* Command Argument */
765 /* Elementary Argument */
766 var : VAR { AddVar($1); }
767 ;
768 str : STR { AddConstStr($1); }
769 ;
770 gstr : GSTR { AddConstStr($1); }
771 ;
772 num : NUMBER { AddConstNum($1); }
773 ;
774 singleclic2: SINGLECLIC { AddConstNum(-1); }
775 ;
776 doubleclic2: DOUBLECLIC { AddConstNum(-2); }
777 ;
778 addlbuff: { AddLevelBufArg(); }
779 ;
780 function: GETVALUE numarg { AddFunct(1,1); }
781 | GETTITLE numarg { AddFunct(2,1); }
782 | GETOUTPUT gstrarg numarg numarg { AddFunct(3,1); }
783 | NUMTOHEX numarg numarg { AddFunct(4,1); }
784 | HEXTONUM gstrarg { AddFunct(5,1); }
785 | ADD numarg numarg { AddFunct(6,1); }
786 | MULT numarg numarg { AddFunct(7,1); }
787 | DIV numarg numarg { AddFunct(8,1); }
788 | STRCOPY gstrarg numarg numarg { AddFunct(9,1); }
789 | LAUNCHSCRIPT gstrarg { AddFunct(10,1); }
790 | GETSCRIPTFATHER { AddFunct(11,1); }
791 | RECEIVFROMSCRIPT numarg { AddFunct(12,1); }
792 | REMAINDEROFDIV numarg numarg { AddFunct(13,1); }
793 | GETTIME { AddFunct(14,1); }
794 | GETSCRIPTARG numarg { AddFunct(15,1); }
795 | GETFORE numarg { AddFunct(16,1); }
796 | GETBACK numarg { AddFunct(17,1); }
797 | GETHILIGHT numarg { AddFunct(18,1); }
798 | GETSHADOW numarg { AddFunct(19,1); }
799 | GETMINVALUE numarg { AddFunct(20,1); }
800 | GETMAXVALUE numarg { AddFunct(21,1); }
801 | GETPID { AddFunct(22,1); }
802 | SENDMSGANDGET gstrarg gstrarg numarg { AddFunct(23,1); }
803 | PARSE gstrarg numarg { AddFunct(24,1); }
804 | LASTSTRING { AddFunct(25,1); }
805 | GETTEXT gstrarg { AddFunct(26,1); }
806 ;
807
808
809 /* Unique argument of several types */
810 args : { }
811 | singleclic2 args
812 | doubleclic2 args
813 | var args
814 | gstr args
815 | str args
816 | num args
817 | BEGF addlbuff function ENDF args
818 ;
819
820 /* Unique argument of whatever type */
821 arg : var
822 | singleclic2
823 | doubleclic2
824 | gstr
825 | str
826 | num
827 | BEGF addlbuff function ENDF
828 ;
829
830 /* Unique argument of number type */
831 numarg : singleclic2
832 | doubleclic2
833 | num
834 | var
835 | BEGF addlbuff function ENDF
836 ;
837
838 /* Unique argument of str type */
839 strarg : var
840 | str
841 | BEGF addlbuff function ENDF
842 ;
843
844 /* Unique argument of gstr type */
845 gstrarg : var
846 | gstr
847 | BEGF addlbuff function ENDF
848 ;
849
850 /* Unique argument of variable type, no function */
851 vararg : var
852 ;
853
854 /* comparison element between 2 numbers */
855 compare : INF { l=1-250000; AddBufArg(&l,1); }
856 | INFEQ { l=2-250000; AddBufArg(&l,1); }
857 | EQUAL { l=3-250000; AddBufArg(&l,1); }
858 | SUPEQ { l=4-250000; AddBufArg(&l,1); }
859 | SUP { l=5-250000; AddBufArg(&l,1); }
860 | DIFF { l=6-250000; AddBufArg(&l,1); }
861 ;
862
863 %%
864