Logo
~Apps~
~Projects~
~Contact~

a.lex

Go to the documentation of this file.
00001 %{
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 #include <unistd.h>
00007 
00008 
00009 #include "a.h"
00010 #include "a.tab.h"
00011 
00012 
00013         LINE *linebase;
00014         LINE *current_line;
00015         LINE *next_line;
00016         VARIABLE *variablebase;
00017         VARIABLE *placeholder;
00018         NEXT *nextbase;
00019         SUB *subbase;
00020         OPEN *openbase;
00021         DATA *database;
00022         FUNC *funcbase;
00023 //      map<int,LINE *> linemap;
00024         char the_str[1024];
00025         int the_ptr;
00026         int prevx;
00027         short running;
00028         char run_program[40];
00029 
00030 #define C the_str[the_ptr]
00031 #define C_INCR the_str[the_ptr++]
00032 
00033 #define YY_INPUT(buf,result,max_size) { \
00034         if (the_str) \
00035                 *buf = C_INCR; \
00036         result = (the_str && *buf) ? 1 : YY_NULL; \
00037 }
00038 
00039 void yyparse(void *);
00040 
00041 
00042 %}
00043 
00044 
00045 DIGIT   [0-9]
00046 ID      [A-Z][A-Z0-9]*
00047 STRING  "\""[^\"]*"\""
00048 
00049 %%
00050 
00051 {DIGIT}+        {
00052                         yylval.d = atof(yytext);
00053                         return NUM;
00054                 }
00055 
00056 {DIGIT}*"."{DIGIT}* {
00057                         yylval.d = atof(yytext);
00058                         return NUM;
00059                 }
00060 
00061 {STRING}        {
00062                         strcpy(yylval.s,yytext + 1);
00063                         yylval.s[strlen(yylval.s) - 1] = 0;
00064                         return STRING;
00065                 }
00066 
00067 END             return End;
00068 FOR             return For;
00069 NEXT            return Next;
00070 DATA            {
00071                         prevx = the_ptr;
00072                         while (C && C != ':')
00073                         {
00074                                 yylval.s[the_ptr - prevx] = C;
00075                                 the_ptr++;
00076                         }
00077                         yylval.s[the_ptr - prevx] = 0;
00078                         return Data;
00079                 }
00080 INPUT           return Input;
00081 DEL             return Del;
00082 DIM             return Dim;
00083 READ            return Read;
00084 
00085 GR              return Gr;
00086 TEXT            return Text;
00087 PR              return Pr;
00088 IN              return In;
00089 CALL            return Call;
00090 PLOT            return Plot;
00091 HLIN            return Hlin;
00092 VLIN            return Vlin;
00093 
00094 HGR2            return Hgr2;
00095 HGR             return Hgr;
00096 HCOLOR          return Hcolor;
00097 HPLOT           return Hplot;
00098 DRAW            return Draw;
00099 XDRAW           return Xdraw;
00100 HTAB            return Htab;
00101 HOME            return Home;
00102 
00103 ROT             return Rot;
00104 SCALE           return Scale;
00105 SHLOAD          return Shload;
00106 TRACE           return Trace;
00107 NOTRACE         return Notrace;
00108 NORMAL          return Normal;
00109 INVERSE         return Inverse;
00110 FLASH           return Flash;
00111 
00112 COLOR           return Color;
00113 POP             return Pop;
00114 VTAB            return Vtab;
00115 HIMEM           return Himem;
00116 LOMEM           return Lomem;
00117 ONERR           return Onerr;
00118 RESUME          return Resume;
00119 RECALL          return Recall;
00120 
00121 STORE           return Store;
00122 SPEED"="        return Speed;
00123 LET             return Let;
00124 GOTO            return Goto;
00125 RUN             return Run;
00126 IF              return If;
00127 RESTORE         return Restore;
00128 
00129 GOSUB           return Gosub;
00130 RETURN          return Return;
00131 REM             {
00132                         strcpy(yylval.s,the_str + the_ptr);
00133                         C = 0;
00134                         return Rem;
00135                 }
00136 STOP            return Stop;
00137 ON              return On;
00138 WAIT            return Wait;
00139 LOAD            return Load;
00140 SAVE            return Save;
00141 
00142 DEF             return Def;
00143 POKE            return Poke;
00144 PRINT           return Print;
00145 CONT            return Cont;
00146 LIST            return List;
00147 CLEAR           return Clear;
00148 GET             return Get;
00149 NEW             return New;
00150 
00151 TAB             return Tab;
00152 TO              return To;
00153 FN              return Fn;
00154 SPC             return Spc;
00155 THEN            return Then;
00156 AT              return At;
00157 NOT             return Not;
00158 STEP            return Step;
00159 
00160 AND             return And;
00161 OR              return Or;
00162 
00163 SGN             return Sgn;
00164 INT             return Int;
00165 ABS             return Abs;
00166 USR             return Usr;
00167 FRE             return Fre;
00168 SCRN            return Scrn;
00169 
00170 PDL             return Pdl;
00171 POS             return Pos;
00172 SQR             return Sqr;
00173 RND             return Rnd;
00174 LOG             return Log;
00175 EXP             return Exp;
00176 COS             return Cos;
00177 SIN             return Sin;
00178 
00179 TAN             return Tan;
00180 ATN             return Atn;
00181 PEEK            return Peek;
00182 LEN             return Len;
00183 STR"$"          return Str;
00184 VAL             return Val;
00185 ASC             return Asc;
00186 CHR"$"          return Chr;
00187 
00188 LEFT"$"         return Left;
00189 RIGHT"$"        return Right;
00190 MID"$"          return Mid;
00191 
00192 
00193 "<"[ ]*"="              return LTEQ;
00194 "<"[ ]*">"              return NEQ;
00195 ">"[ ]*"="              return GTEQ;
00196 
00197 ","|":"|";"     return *yytext;
00198 
00199 "="|"<"|">"|"("|")" {
00200                         return *yytext;
00201                 }
00202 "*"|"/"|"+"|"-" return *yytext;
00203 
00204 {ID}"$"         {
00205                         strcpy(yylval.s,yytext);
00206                         return STRINGVAR;
00207                 }
00208 
00209 {ID}"%"         {
00210                         strcpy(yylval.s,yytext);
00211                         return NUMVAR;
00212                 }
00213 
00214 {ID}            {
00215                         strcpy(yylval.s,yytext);
00216                         return IDENTIFIER;
00217                 }
00218 
00219 [ \t\n]
00220 
00221 "\""[^\"]*
00222 
00223 .               {
00224                         printf("Unrecognized char '%c'\n",*yytext);
00225                         exit(-1);
00226                 }
00227 
00228 %%
00229 
00230 char applesoft_tokens[][8]=
00231 {
00232         "END", "FOR", "NEXT", "DATA", "INPUT", "DEL", "DIM", "READ",
00233         "GR", "TEXT", "PR#", "IN#", "CALL", "PLOT", "HLIN", "VLIN",
00234 
00235         "HGR2", "HGR", "HCOLOR=", "HPLOT", "DRAW", "XDRAW", "HTAB", "HOME",
00236         "ROT=", "SCALE=", "SHLOAD", "TRACE", "NOTRACE", "NORMAL", "INVERSE", "FLASH",
00237 
00238         "COLOR=", "POP", "VTAB", "HIMEM:", "LOMEM:", "ONERR", "RESUME", "RECALL",
00239         "STORE", "SPEED=", "LET", "GOTO", "RUN", "IF", "RESTORE", "&",
00240 
00241         "GOSUB", "RETURN", "REM", "STOP", "ON", "WAIT", "LOAD", "SAVE",
00242         "DEF", "POKE", "PRINT", "CONT", "LIST", "CLEAR", "GET", "NEW",
00243 
00244         "TAB(", "TO", "FN", "SPC(", "THEN", "AT", "NOT", "STEP",
00245         "+", "-", "*", "/", "^", "AND", "OR", ">",
00246         "=", "<", "SGN", "INT", "ABS", "USR", "FRE", "SCRN(",
00247         "PDL", "POS", "SQR", "RND", "LOG", "EXP", "COS", "SIN",
00248         "TAN", "ATN", "PEEK", "LEN", "STR$", "VAL", "ASC", "CHR$",
00249         "LEFT$", "RIGHT$", "MID$", "", "", "", "", "",
00250         "", "", "", "", "", "", "", "",
00251         "", "", "", "", "", "(", "(", "("
00252 };
00253 
00254 int yywrap()
00255 {
00256         return 1;               // end of file
00257 }
00258 
00259 void yyerror(char *s)
00260 {
00261         int i;
00262 
00263         printf("\n***\n");
00264         printf("%s\n",the_str);
00265         for (i = 0; i < the_ptr; i++)
00266                 printf(" ");
00267         printf("^ %s\n",s);
00268         exit(-1);
00269 }
00270 
00271 void addlist(void *_base,void *_item)
00272 {
00273         LINE **base = (LINE **)_base;
00274         LINE *item = (LINE *)_item;
00275         LINE *q;
00276 
00277         item -> next = NULL;
00278         q = *base;
00279         if (!q)
00280                 *base = item;
00281         else
00282         {
00283                 while (q -> next)
00284                         q = q -> next;
00285                 q -> next = item;
00286         }
00287 }
00288 
00289 void removelist(void *_base,void *_item)
00290 {
00291         LINE **base = (LINE **)_base;
00292         LINE *item = (LINE *)_item;
00293         LINE *q,*prev = NULL;
00294 
00295         if (item == *base)
00296                 *base = item -> next;
00297         else
00298         {
00299                 for (q = *base; q; q = q -> next)
00300                         if (item == q)
00301                         {
00302                                 prev -> next = item -> next;
00303                                 break;
00304                         }
00305                         else
00306                                 prev = q;
00307         }
00308 }
00309 
00310 void read_file(char *filename)
00311 {
00312         FILE *fil;
00313         LINE *ln;
00314         int parent;
00315         int child;
00316         short size;
00317         short q;        // quote
00318         short ifc;
00319         short data;
00320         unsigned char c_length;
00321         unsigned char c_eight;
00322         unsigned char c_line1;
00323         unsigned char c_line2;
00324         unsigned char c;
00325         char slask[1024];
00326 
00327         if ((fil = fopen(filename,"rb")) != NULL)
00328         {
00329                 // 2 bytes size
00330                 fread(&size,1,2,fil);
00331                 while (!feof(fil))
00332                 {
00333                         // 1 byte length, 1 byte == 8
00334                         fread(&c_length,1,1,fil);
00335                         fread(&c_eight,1,1,fil);
00336                         if (!c_eight)
00337                         {
00338                                 break;
00339                         }
00340                         // 2 bytes line number
00341                         fread(&c_line1,1,1,fil);
00342                         fread(&c_line2,1,1,fil);
00343                         ln = (LINE *)malloc(sizeof(LINE));
00344                         ln -> line = (((int)c_line2) << 8) + c_line1;
00345                         ln -> parent = ln -> line;
00346                         ln -> child = 0;
00347                         // line data
00348                         fread(&c,1,1,fil);
00349                         *slask = 0;
00350                         q = 0;
00351                         ifc = 0;
00352                         data = 0;
00353                         parent = ln -> line;
00354                         child = 1;
00355                         while (c && !feof(fil))
00356                         {
00357                                 if (c >= 0x80)
00358                                 {
00359                                         if (c == 0x83) // Data
00360                                                 data = 1;
00361                                         if (c == 0xad) // If
00362                                                 ifc = 1;
00363                                         if (ifc && *slask && (c == 0xc4 || c == 0xab)) // Then / Goto
00364                                         {
00365                                                 ln -> the_str = (char *)malloc(strlen(slask) + 1);
00366                                                 strcpy(ln -> the_str,slask);
00367                                                 if (*slask)
00368                                                         addlist(&linebase,ln);
00369                                                 else
00370                                                         free(ln);
00371                                                 if (data && *slask)
00372                                                 {
00373                                                         strcpy(the_str,slask);
00374                                                         the_ptr = 0;
00375                                                         current_line = ln;
00376                                                         yyparse(NULL);
00377                                                 }
00378 
00379                                                 ln = (LINE *)malloc(sizeof(LINE));
00380                                                 ln -> line = -1;
00381                                                 ln -> parent = parent;
00382                                                 ln -> child = child++;
00383                                                 *slask = 0;
00384                                                 q = 0;
00385                                                 ifc = 0;
00386                                                 data = 0;
00387                                         }
00388                                         sprintf(slask + strlen(slask)," %s ",applesoft_tokens[c - 0x80]);
00389                                 }
00390                                 else
00391                                 if (c == ':' && !q)
00392                                 {
00393                                         ln -> the_str = (char *)malloc(strlen(slask) + 1);
00394                                         strcpy(ln -> the_str,slask);
00395                                         if (*slask)
00396                                                 addlist(&linebase,ln);
00397                                         else
00398                                                 free(ln);
00399                                         if (data && *slask)
00400                                         {
00401                                                 strcpy(the_str,slask);
00402                                                 the_ptr = 0;
00403                                                 current_line = ln;
00404                                                 yyparse(NULL);
00405                                         }
00406 
00407                                         ln = (LINE *)malloc(sizeof(LINE));
00408                                         ln -> line = -1;
00409                                         ln -> parent = parent;
00410                                         ln -> child = child++;
00411                                         *slask = 0;
00412                                         q = 0;
00413                                         ifc = 0;
00414                                         data = 0;
00415                                 }
00416                                 else
00417                                 {
00418                                         sprintf(slask + strlen(slask),"%c",c);
00419                                         if (c == 34)
00420                                                 q = !q;
00421                                 }
00422                                 fread(&c,1,1,fil);
00423                         }
00424                         ln -> the_str = (char *)malloc(strlen(slask) + 1);
00425                         strcpy(ln -> the_str,slask);
00426                         if (*slask)
00427                                 addlist(&linebase,ln);
00428                         else
00429                                 free(ln);
00430                         if (data && *slask)
00431                         {
00432                                 strcpy(the_str,slask);
00433                                 the_ptr = 0;
00434                                 current_line = ln;
00435                                 yyparse(NULL);
00436                         }
00437                 }
00438                 fclose(fil);
00439         }
00440         else
00441         {
00442                 printf("Couldn't open '%s'...\n",filename);
00443                 exit(-1);
00444         }
00445 }
00446 
00447 void execute()
00448 {
00449         current_line = linebase;
00450         while (current_line)
00451         {
00452                 next_line = current_line -> next;
00453                 strcpy(the_str,current_line -> the_str);
00454                 the_ptr = 0;
00455 #ifdef DEBUGEXPR
00456 printf(" %4d %s\n",current_line -> line,current_line -> the_str);
00457 #endif
00458                 placeholder = NULL;
00459                 yyparse(NULL);
00460                 if (placeholder)
00461                         placeholder -> value = placeholder -> fnvalue;
00462                 current_line = next_line;
00463         }
00464 }
00465 
00466 void finish()
00467 {
00468         LINE *ln;
00469         LINE *tmpln;
00470         VARIABLE *v;
00471         VARIABLE *tmpv;
00472         NEXT *nx;
00473         NEXT *tmpnx;
00474         SUB *sub;
00475         SUB *tmpsub;
00476         OPEN *o;
00477         OPEN *tmpo;
00478         DATA *d;
00479         DATA *tmpd;
00480         FUNC *f;
00481         FUNC *tmpf;
00482 
00483         for (ln = linebase; ln; ln = tmpln)
00484         {
00485                 tmpln = ln -> next;
00486                 free(ln -> the_str);
00487                 free(ln);
00488         }
00489         for (v = variablebase; v; v = tmpv)
00490         {
00491                 tmpv = v -> next;
00492                 free(v);
00493         }
00494         for (nx = nextbase; nx; nx = tmpnx)
00495         {
00496                 tmpnx = nx -> next;
00497                 free(nx);
00498         }
00499         for (sub = subbase; sub; sub = tmpsub)
00500         {
00501                 tmpsub = sub -> next;
00502                 free(sub);
00503         }
00504         for (o = openbase; o; o = tmpo)
00505         {
00506                 tmpo = o -> next;
00507                 fclose(o -> fil);
00508                 free(o);
00509         }
00510         for (d = database; d; d = tmpd)
00511         {
00512                 tmpd = d -> next;
00513                 free(d -> data);
00514                 free(d);
00515         }
00516         for (f = funcbase; f; f = tmpf)
00517         {
00518                 tmpf = f -> next;
00519                 free(f);
00520         }
00521 }
00522 
00523 int main(int argc,char *argv[])
00524 {
00525         LINE *ln;
00526         int loop;
00527         short source = 0;
00528 
00529         for (loop = 1; loop < argc; loop++)
00530                 if (!strcmp(argv[loop],"-source"))
00531                         source++;
00532 
00533         if (argc > 1)
00534         {
00535                 strcpy(run_program,argv[1]);
00536                 if (source)
00537                 {
00538                         linebase = NULL;
00539                         variablebase = NULL;
00540                         nextbase = NULL;
00541                         subbase = NULL;
00542                         openbase = NULL;
00543                         database = NULL;
00544                         funcbase = NULL;
00545 
00546                         running = 0;
00547                         read_file(argv[1]);
00548                         for (ln = linebase; ln; ln = ln -> next)
00549                         {
00550                                 if (ln -> line > -1)
00551                                         printf(" %5d",ln -> line);
00552                                 else
00553                                         printf("      ");
00554                                 printf(" %s\n",ln -> the_str);
00555                                 strcpy(the_str,ln -> the_str);
00556                                 the_ptr = 0;
00557                                 yyparse(NULL);
00558                         }
00559                         finish();
00560                         return 0;
00561                 }
00562                 do
00563                 {
00564                         linebase = NULL;
00565                         variablebase = NULL;
00566                         nextbase = NULL;
00567                         subbase = NULL;
00568                         openbase = NULL;
00569                         database = NULL;
00570                         funcbase = NULL;
00571 
00572                         running = 0;
00573                         read_file(run_program);
00574                         file_init();
00575 
00576                         *run_program = 0;
00577                         running = 1;
00578                         execute();
00579 
00580                         finish();
00581                 } while (*run_program);
00582         } else
00583         {
00584                 printf("Usage: %s <A file> [-source]\n",*argv);
00585         }
00586         return 0;
00587 }
00588 
Page, code, and content Copyright (C) 2005 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4