2 Copyright (C) 1998 BJ Eirich (aka vecna)
\r
3 This program is free software; you can redistribute it and/or
\r
4 modify it under the terms of the GNU General Public License
\r
5 as published by the Free Software Foundation; either version 2
\r
6 of the License, or (at your option) any later version.
\r
7 This program is distributed in the hope that it will be useful,
\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\r
10 See the GNU General Public Lic
\r
11 See the GNU General Public License for more details.
\r
12 You should have received a copy of the GNU General Public License
\r
13 along with this program; if not, write to the Free Software
\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
17 // ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
\r
18 // ³ The VergeC Compiler version 2.01 ³
\r
19 // ³ Copyright (C)1998 BJ Eirich (aka vecna) ³
\r
20 // ³ Lexical Parser ³
\r
21 // ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
\r
23 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
\r
26 // + ConvHexToDec() was severely screwed (would not return correct values at
\r
27 // *all*; own fault)--fixed
\r
29 // + fixed some problems with tick mark parsing. didn't like certain chars.
\r
31 // + fixed floating point exception crash in ConvHexToDec(), which occured
\r
32 // when using very large hex numbers (i think; like $ffffffff). was due to
\r
34 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
\r
40 #include "compile.h"
\r
44 // ================================= Data ====================================
\r
54 char token[2000]; // Token buffer
\r
55 int token_nvalue; // int value of token if it's type DIGIT
\r
56 char token_type; // type of current token.
\r
57 char token_subtype; // This is just crap.
\r
58 unsigned char chr_table[256]; // Character type table.
\r
60 int lines, tlines; // current line number being processed in
\r
61 char *source_file; // the current source file
\r
68 "exit", "message", "malloc",
\r
69 "free", "pow", "loadimage",
\r
70 "copysprite", "tcopysprite", "render",
\r
71 "showpage", "entityspawn", "setplayer",
\r
72 "map", "loadfont", "playfli",
\r
75 "gotoxy", "printstring", "loadraw",
\r
76 "settile", "allowconsole", "scalesprite",
\r
77 "processentities", "updatecontrols", "unpress",
\r
78 "entitymove", "hline", "vline",
\r
79 "line", "circle", "circlefill", // 30
\r
82 "rect", "rectfill", "strlen",
\r
83 "strcmp", "cd_stop", "cd_play",
\r
84 "fontwidth", "fontheight", "setpixel",
\r
85 "getpixel", "entityonscreen", "random",
\r
86 "gettile", "hookretrace", "hooktimer",
\r
89 "setresolution", "setrstring", "setcliprect",
\r
90 "setrenderdest", "restorerendersettings","partymove",
\r
91 "sin", "cos", "tan",
\r
92 "readmouse", "setclip", "setlucent",
\r
93 "wrapblit", "twrapblit", "setmousepos", // 60
\r
96 "hookkey", "playmusic", "stopmusic",
\r
97 "palettemorph", "fopen", "fclose",
\r
98 "quickread", "addfollower", "killfollower",
\r
99 "killallfollowers", "resetfollowers", "flatpoly",
\r
100 "tmappoly", "cachesound", "freeallsounds",
\r
103 "playsound", "rotscale", "mapline",
\r
104 "tmapline", "val", "tscalesprite",
\r
105 "grabregion", "log", "fseekline",
\r
106 "fseekpos", "fread", "fgetbyte",
\r
107 "fgetword", "fgetquad", "fgetline", // 90
\r
110 "fgettoken", "fwritestring", "fwrite",
\r
111 "frename", "fdelete", "fwopen",
\r
112 "fwclose", "memcpy", "memset",
\r
113 "silhouette", "initmosaictable", "mosaic",
\r
114 "writevars", "readvars", "callevent", // 105
\r
117 "asc", "callscript", "numforscript",
\r
118 "filesize", "ftell", "checkcorrupt"
\r
121 char returntypes[]=
\r
179 "xwin", "ywin", "cameratracking",
\r
180 "timer", "up", "down",
\r
181 "left", "right", "b1",
\r
183 "screenx", "screeny", "player", // 15
\r
185 "numentsonscreen", "tracker", "mx",
\r
186 "my", "mb", "vctrace",
\r
187 "image_width", "image_height", "music_volume", // 24
\r
188 "vsp", "lastent", "last_pressed"
\r
193 "screen", "entity.x", "entity.y",
\r
194 "entity.tx", "entity.ty", "entity.facing",
\r
195 "entity.moving", "entity.specframe", "entity.speed",
\r
196 "entity.movecode", "entsonscreen", "key",
\r
197 "layer.hline", "byte", "word", // 15
\r
199 "quad", "pal", "sbyte",
\r
204 int varcategory = 0;
\r
206 int numhardfuncs = 111;
\r
207 int numhardvar0 = 27;
\r
208 int numhardvar1 = 20;
\r
210 // ================================= Code ====================================
\r
212 int streq(char *a, char *b)
\r
222 char TokenIs(char *str)
\r
223 { return streq(str,token); }
\r
225 void ParseWhitespace(void)
\r
229 while (*src<=' ' && *src>2)
\r
233 if (src[0]=='/' && src[1]=='/')
\r
235 while (*src && (*src != '\n'))
\r
240 if (src[0]=='/' && src[1]=='*')
\r
242 while (!(src[0]=='*' && src[1]=='/'))
\r
258 lines = (int) *(int *)src;
\r
277 lines = (int) *(int *)src;
\r
286 int GetStringIdx(char i)
\r
290 for (j=0; j<i; j++)
\r
292 if (funcs[c].argtype[j]==STRING) k++;
\r
297 void CheckLibFunc()
\r
303 if (TokenIs("if") || TokenIs("else") || TokenIs("for") ||
\r
304 TokenIs("while") || TokenIs("switch") || TokenIs("case") ||
\r
307 token_type=RESERVED;
\r
310 if (TokenIs("and"))
\r
312 token_type=CONTROL;
\r
313 token[0]='&'; token[1]='&'; token[2]=0;
\r
318 token_type=CONTROL;
\r
319 token[0]='|'; token[1]='|'; token[2]=0;
\r
323 while (i<numhardfuncs)
\r
325 if (!strcmp(hardfuncs[i], token)) break;
\r
328 if (i<numhardfuncs)
\r
330 token_type=FUNCTION;
\r
331 token_subtype=op_BFUNC;
\r
335 while (i<numhardvar0)
\r
337 if (!strcmp(hardvar0[i], token)) break;
\r
342 token_type=IDENTIFIER;
\r
343 varcategory=op_HVAR0;
\r
347 while (i<numhardvar1)
\r
349 if (!strcmp(hardvar1[i], token)) break;
\r
354 token_type=IDENTIFIER;
\r
355 varcategory=op_HVAR1;
\r
362 if (!strcmp(funcs[i].fname, token)) break;
\r
367 token_type=FUNCTION;
\r
368 token_subtype=op_UFUNC;
\r
375 if (!strcmp(vars[i].vname, token)) break;
\r
380 token_type=IDENTIFIER;
\r
382 varcategory=op_UVAR;
\r
383 if (vars[varidx].arraylen>1) varcategory=op_UVARRAY;
\r
386 while (i<funcs[c].numlocals)
\r
388 if (!strcmp(larg[i], token)) break;
\r
391 if (i<funcs[c].numlocals)
\r
393 token_type=IDENTIFIER;
\r
395 switch (funcs[c].argtype[varidx])
\r
397 case INT: varcategory=op_LVAR; break;
\r
398 case STRING: varcategory=op_SLOCAL;
\r
399 varidx=GetStringIdx(varidx);
\r
401 default: vcerr("um.");
\r
407 if (!strcmp(str[i].vname, token)) break;
\r
412 token_type=IDENTIFIER;
\r
414 varcategory=op_STRING;
\r
415 if (str[i].arraylen>1) varcategory=op_SARRAY;
\r
419 void GetIdentifier(void)
\r
424 while ((chr_table[*src] == LETTER) || (chr_table[*src] == DIGIT))
\r
425 token[i++] = *src++;
\r
431 void ConvHexToDec()
\r
433 static const char *const hextbl="0123456789abcdef\0";
\r
434 static int pow_lut[]={1,16,256,4096,65536,1048576,16777216,268435456};
\r
435 int i=0, pos=0, z=0;
\r
438 if (strlen(token)>9)
\r
439 vcerr("Hex number exceeds 8 digit maximum.");
\r
444 for (pos=0; i>0; pos++,i--)
\r
447 for (j=0; j<16; j++)
\r
448 if (hextbl[j]==z) break;
\r
450 vcerr("Invalid hex number.");
\r
451 token_nvalue += (j * pow_lut[pos]);
\r
457 token_nvalue=token[1];
\r
474 while (chr_table[*src] != SPECIAL)
\r
478 if (token[0]=='$') ConvHexToDec();
\r
479 else if (token[0]=='\'') DoTickMarks();
\r
480 else token_nvalue=atoi(token);
\r
483 void GetPunctuation()
\r
489 case '(': token[0]='('; token[1]=0; src++; break;
\r
490 case ')': token[0]=')'; token[1]=0; src++; break;
\r
491 case '{': token[0]='{'; token[1]=0; src++; break;
\r
492 case '}': token[0]='}'; token[1]=0; src++; break;
\r
493 case '[': token[0]='['; token[1]=0; src++; break;
\r
494 case ']': token[0]=']'; token[1]=0; src++; break;
\r
495 case ',': token[0]=','; token[1]=0; src++; break;
\r
496 case ':': token[0]=':'; token[1]=0; src++; break;
\r
497 case ';': token[0]=';'; token[1]=0; src++; break;
\r
498 case '/': token[0]='/'; token[1]=0; src++; break;
\r
499 case '*': token[0]='*'; token[1]=0; src++; break;
\r
500 case '^': token[0]='^'; token[1]=0; src++; break;
\r
501 case '%': token[0]='%'; token[1]=0; src++; break;
\r
502 case '\"': token[0]='\"'; token[1]=0; src++; break;
\r
503 case '+' : token[0]='+';
\r
508 else if (*src=='=')
\r
514 case '-' : token[0]='-';
\r
519 else if (*src=='=')
\r
525 case '>' : token[0]='>';
\r
537 case '<': token[0]='<';
\r
549 case '!': token[0]='!';
\r
557 case '=': token[0]='=';
\r
564 case '&': token[0]='&';
\r
572 case '|': token[0]='|';
\r
580 default: src++; // This should be an error.
\r
584 void GetString(void)
\r
588 // Expects a "quoted" string. Places the contents of the string in
\r
589 // token[] but does not include the quotes.
\r
597 vcerr("String exceeds 250 character maximum.");
\r
603 void GetToken(void)
\r
607 // Simply reads in the next statement and places it in the
\r
613 switch (chr_table[*src])
\r
615 case LETTER: { token_type = IDENTIFIER; GetIdentifier(); break; }
\r
616 case DIGIT: { token_type = DIGIT; GetNumber(); break; }
\r
617 case SPECIAL: { token_type = CONTROL; GetPunctuation(); break; }
\r
620 if (!*src && inevent)
\r
621 err("Unexpected end of file");
\r
624 void Expect(char *str)
\r
627 if (TokenIs(str)) return;
\r
628 vcerr("error: %s expected, %s got", str, token);
\r
634 if (token_type!=DIGIT) err("error: Numerical value expected");
\r
635 return token_nvalue;
\r
638 void InitCompileSystem()
\r
641 vprint("Building chr_table[].");
\r
642 for (i=0; i<256; i++) chr_table[i]=SPECIAL;
\r
643 for (i='0'; i<='9'; i++) chr_table[i]=DIGIT;
\r
644 for (i='A'; i<='Z'; i++) chr_table[i]=LETTER;
\r
645 for (i='a'; i<='z'; i++) chr_table[i]=LETTER;
\r
650 chr_table['_']=LETTER;
\r
651 chr_table['.']=LETTER;
\r
652 chr_table['$']=DIGIT;
\r
653 chr_table[39]=DIGIT;
\r
656 char lasttoken[2048];
\r
658 int NextIs(char *str)
\r
659 { char *ptr,tt,tst;
\r
666 memcpy(lasttoken, token, 2048);
\r
672 //if (!strcmp(str,token)) i=1; else i=0;
\r
673 i=streq(str,token);
\r
674 memcpy(token, lasttoken, 2048);
\r