Logo
~Apps~
~Projects~
~Contact~

a.y

Go to the documentation of this file.
00001 %{
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <ctype.h>
00005 #include <string.h>
00006 #include <math.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <unistd.h>
00010 
00011 #include "a.h"
00012 
00013 #define YYPARSE_PARAM pars
00014 #define YYLEX_PARAM pars
00015 
00016 
00017         static LINE *ln;
00018         static NEXT *nx;
00019         static FILE *fil = NULL;
00020         static LINE *onerror;
00021         static SUB *sub;
00022         static OPEN *o;
00023         static DATA *d;
00024         static DATA *current_data;
00025         static FUNC *fn;
00026         static int i;
00027         static int tab_pos = 0;
00028         static int option_s;
00029         static int option_d;
00030         static int option_l;
00031         static int option_r;
00032         static int dataptr;
00033         static short file_read = 0;
00034         static short file_write = 0;
00035         static char slask[1024];
00036         static char temp[1024];
00037 
00038 %}
00039 
00040 
00041 %union {
00042   double d;
00043   char s[1024];
00044   VARIABLE *v;
00045   VARLIST vl;
00046   EXPRLIST el;
00047   INTLIST il;
00048 }
00049 
00050 %token <d> NUM
00051 %token <s> STRING
00052 %token <s> NUMVAR
00053 %token <s> STRINGVAR
00054 %token <s> IDENTIFIER
00055 
00056 %token LTEQ GTEQ NEQ
00057 
00058 %token End For Next
00059 %token <s> Data
00060 %token Input Del Dim Read
00061 
00062 %token Gr Text Pr In Call Plot Hlin Vlin
00063 %token Hgr2 Hgr Hcolor Hplot Draw Xdraw Htab Home
00064 %token Rot Scale Shload Trace Notrace Normal Inverse Flash
00065 %token Color Pop Vtab Himem Lomem Onerr Resume Recall
00066 %token Store Speed Let Goto Run If Restore Amper
00067 
00068 %token Gosub Return
00069 %token <s> Rem
00070 %token Stop On Wait Load Save
00071 
00072 %token Def Poke Print Cont List Clear Get New
00073 
00074 %token <s> Tab
00075 %token To Fn Spc Then At Not Step
00076 
00077 %token And Or
00078 %token Sgn Int Abs Usr Fre Scrn
00079 %token Pdl Pos Sqr Rnd Log Exp Cos Sin
00080 %token Tan Atn Peek Len Str Val Asc Chr
00081 %token Left Right Mid
00082 
00083 %left Or And 
00084 %right Not
00085 %left '<' '>' LTEQ GTEQ NEQ '='
00086 %left '+' '-'
00087 %left '*' '/' '^'
00088 %left UNARYMINUS
00089 
00090 %type <d> expr
00091 %type <s> string_expr
00092 %type <s> print_exprs
00093 %type <v> variable
00094 %type <v> string_variable
00095 %type <vl> var_list
00096 %type <el> expr_list
00097 %type <il> int_list
00098 
00099 %%
00100 
00101 line:
00102         statement
00103 
00104 statement:
00105         End
00106         {
00107                 next_line = NULL;
00108         }
00109 |
00110         For variable '=' expr To expr
00111         {
00112                 for (nx = nextbase; nx; nx = nx -> next)
00113                         if (nx -> ln == current_line)
00114                         {
00115                                 removelist(&nextbase,nx);
00116                                 break;
00117                         }
00118                 if (!nx)
00119                         nx = (NEXT *)malloc(sizeof(NEXT));
00120                 nx -> ln = current_line;
00121                 nx -> var = $2;
00122                 $2 -> value = $4;
00123                 nx -> tolimit = $6;
00124                 nx -> step = 1;
00125                 nx -> reline = next_line;
00126                 nx -> next = nextbase;
00127                 nextbase = nx;
00128 #ifdef DEBUG
00129 printf("%s\n",current_line -> the_str);
00130 printf(" for %d:%d (%s = %d) .. %d\n",
00131  nx -> ln -> parent,
00132  nx -> ln -> child,
00133  nx -> var -> name,
00134  (int)nx -> var -> value,
00135  (int)nx -> tolimit);
00136 #endif
00137         }
00138 |
00139         For variable '=' expr To expr Step expr
00140         {
00141                 for (nx = nextbase; nx; nx = nx -> next)
00142                         if (nx -> ln == current_line)
00143                         {
00144                                 removelist(&nextbase,nx);
00145                                 break;
00146                         }
00147                 if (!nx)
00148                         nx = (NEXT *)malloc(sizeof(NEXT));
00149                 nx -> ln = current_line;
00150                 nx -> var = $2;
00151                 $2 -> value = $4;
00152                 nx -> tolimit = $6;
00153                 nx -> step = $8;
00154                 nx -> reline = next_line;
00155                 nx -> next = nextbase;
00156                 nextbase = nx;
00157         }
00158 |
00159         Next
00160         {
00161                 nx = nextbase;
00162                 if (nx)
00163                 {
00164 #ifdef DEBUG
00165 printf(" next %d:%d\n",nx -> ln -> parent,nx -> ln -> child);
00166 #endif
00167                 nx -> var -> value += nx -> step;
00168                 if (nx -> step > 0)
00169                 {
00170                         if (nx -> var -> value > nx -> tolimit + nx -> step / 2)
00171                         {
00172                                 nextbase = nx -> next;
00173                                 free(nx);
00174                         }
00175                         else
00176                         {
00177                                 next_line = nx -> reline;
00178                         }
00179                 }
00180                 else
00181                 {
00182                         if (nx -> var -> value < nx -> tolimit - nx -> step / 2)
00183                         {
00184                                 nextbase = nx -> next;
00185                                 free(nx);
00186                         }
00187                         else
00188                         {
00189                                 next_line = nx -> reline;
00190                         }
00191                 }
00192                 } // if (nx)
00193         }
00194 |
00195         Next var_list
00196         {
00197                 nx = nextbase;
00198                 i = 0; /* index in var_list */
00199                 while (nx && i < $2.qty)
00200                 {
00201 #ifdef DEBUG
00202 printf(" next %d:%d\n",nx -> ln -> parent,nx -> ln -> child);
00203 #endif
00204                         nx -> var -> value += nx -> step;
00205                         if (nx -> step > 0)
00206                         {
00207                                 if (nx -> var -> value > nx -> tolimit)
00208                                 {
00209                                         nextbase = nx -> next;
00210                                         free(nx);
00211                                         nx = nextbase;
00212                                 }
00213                                 else
00214                                 {
00215                                         next_line = nx -> reline;
00216                                         nx = NULL;
00217                                 }
00218                         }
00219                         else
00220                         {
00221                                 if (nx -> var -> value < nx -> tolimit)
00222                                 {
00223                                         nextbase = nx -> next;
00224                                         free(nx);
00225                                         nx = nextbase;
00226                                 }
00227                                 else
00228                                 {
00229                                         next_line = nx -> reline;
00230                                         nx = NULL;
00231                                 }
00232                         }
00233                         i++; /* index in var_list */
00234                 }
00235         }
00236 |
00237         Data 
00238         {
00239 #ifdef DEBUG
00240 printf("Data '%s'\n",$1);
00241 #endif
00242                 if (!running)
00243                 {
00244                         d = (DATA *)malloc(sizeof(DATA));
00245                         d -> line = current_line -> line;
00246                         d -> data = (char *)malloc(strlen($1) + 1);
00247                         strcpy(d -> data,$1);
00248                         addlist(&database,d);
00249                 }
00250         }
00251 |
00252         Input var_list
00253         {
00254 /* check for file ops */
00255                 if (running)
00256                 for (i = 0; i < $2.qty; i++)
00257                 {
00258 #ifdef DEBUG
00259 printf(" * Input %d\n",i);
00260 #endif
00261                         if (fil && file_read)
00262                         {
00263                                 file_input($2.var[i] -> svalue,1024);
00264                         }
00265                         else
00266                         {
00267                                 *$2.var[i] -> svalue = '.';
00268                                 while ($2.var[i] -> svalue[0] == '.')
00269                                 {
00270                                         gets($2.var[i] -> svalue);
00271                                         if ($2.var[i] -> svalue[0] == '.')
00272                                         {
00273                                                 chdir($2.var[i] -> svalue);
00274                                         }
00275                                 }
00276                         }
00277                         $2.var[i] -> value = atof($2.var[i] -> svalue);
00278                 }
00279         }
00280 |
00281         Input STRING ';' var_list
00282         {
00283 /* check for file ops */
00284                 if (running)
00285                 {
00286                         text_output($2);
00287                         for (i = 0; i < $4.qty; i++)
00288                         {
00289 #ifdef DEBUG
00290 printf(" * Input %d\n",i);
00291 #endif
00292                                 if (fil && file_read)
00293                                         file_input($4.var[i] -> svalue,1024);
00294                                 else
00295                                         gets($4.var[i] -> svalue);
00296                                 $4.var[i] -> value = atof($4.var[i] -> svalue);
00297                         }
00298                 }
00299         }
00300 |
00301         Del
00302 |
00303         Dim var_list
00304         {
00305         }
00306 |
00307         Read var_list
00308         {
00309                 read_data(&$2);
00310         }
00311 |
00312         Gr
00313 |
00314         Text
00315 |
00316         Htab expr
00317 |
00318         Home
00319 |
00320         Normal
00321 |
00322         Inverse
00323 |
00324         Flash
00325 |
00326         Pop
00327         {
00328                 if (!subbase)
00329                 {
00330 //                      printf(" *** pop without gosub\n");
00331                         next_line = onerror;
00332                 }
00333                 else
00334                 {
00335                         sub = subbase;
00336                         subbase = sub -> next;
00337                         free(sub);
00338                 }
00339         }
00340 |
00341         Vtab expr
00342 |
00343         Onerr Goto NUM
00344         {
00345                 onerror = NULL;
00346                 for (ln = linebase; ln && !onerror; ln = ln -> next)
00347                         if (ln -> line == $3)
00348                                 onerror = ln;
00349         }
00350 |
00351         Speed expr
00352 |
00353         Let variable '=' expr
00354         {
00355                 $2 -> value = $4;
00356         }
00357 |
00358         Let string_variable '=' string_expr
00359         {
00360                 strcpy($2 -> svalue,$4);
00361         }
00362 |
00363         variable '=' expr
00364         {
00365                 $1 -> value = $3;
00366         }
00367 |
00368         string_variable '=' string_expr
00369         {
00370                 strcpy($1 -> svalue,$3);
00371         }
00372 |
00373         Goto NUM
00374         {
00375                 for (ln = linebase; ln; ln = ln -> next)
00376                         if (ln -> line == (int)($2 + .01))
00377                                 break;
00378                 if (!ln)
00379                         printf("GOTO undefined line number: %d\n",(int)($2 + .01));
00380                 next_line = ln;
00381         }
00382 |
00383         If expr
00384         {
00385                 if (!$2 && running)
00386                 {
00387                         while (next_line -> line == -1 && next_line -> next)
00388                                 next_line = next_line -> next;
00389                 }
00390         }
00391 |
00392         Then statement
00393 |
00394         Then NUM
00395         {
00396                 for (ln = linebase; ln; ln = ln -> next)
00397                         if (ln -> line == (int)($2 + .01))
00398                                 break;
00399                 if (!ln)
00400                         printf("GOTO undefined line number: %d\n",(int)$2);
00401                 next_line = ln;
00402         }
00403 |
00404         Gosub NUM
00405         {
00406                 for (ln = linebase; ln; ln = ln -> next)
00407                         if (ln -> line == (int)$2)
00408                                 break;
00409                 if (!ln)
00410                         printf("GOSUB undefined line number: %d\n",(int)$2);
00411                 sub = (SUB *)malloc(sizeof(SUB));
00412                 sub -> returnline = next_line;
00413                 sub -> next = subbase;
00414                 subbase = sub;
00415                 next_line = ln;
00416         }
00417 |
00418         Return
00419         {
00420                 if (!subbase)
00421                 {
00422 //                      printf(" *** return without gosub\n");
00423                         next_line = onerror;
00424                 }
00425                 else
00426                 {
00427                         sub = subbase;
00428                         subbase = sub -> next;
00429                         next_line = sub -> returnline;
00430                         free(sub);
00431                 }
00432         }
00433 |
00434         Rem
00435         {
00436 //              printf("Remark '%s'\n",$1);
00437         }
00438 |
00439         Stop
00440 |
00441         On expr Goto int_list
00442         {
00443 #ifdef DEBUG
00444 printf(" ON %d GOTO ...\n",(int)$2);
00445 #endif
00446                 if ( (int)$2 > 0 && (int)$2 <= $4.qty)
00447                 {
00448                         for (ln = linebase; ln; ln = ln -> next)
00449                                 if (ln -> line == $4.values[(int)$2 - 1])
00450                                         break;
00451                         if (!ln && running)
00452                                 printf("ON ... GOTO undefined line number: %d\n",(int)$2);
00453                         next_line = ln;
00454                 }
00455                 else
00456                 {
00457                         if (running)
00458                                 printf("ON ... GOTO outside bounds\n");
00459                         next_line = NULL;
00460                 }
00461         }
00462 |
00463         Def Fn IDENTIFIER '(' IDENTIFIER ')' '=' expr
00464         {
00465                 for (fn = funcbase; fn; fn = fn -> next)
00466                         if (!strcmp(fn -> name,$3))
00467                                 break;
00468                 if (!fn)
00469                 {
00470                         fn = (FUNC *)malloc(sizeof(FUNC));
00471                         strcpy(fn -> name,$3);
00472                         addlist(&funcbase,fn);
00473                 }
00474                 sprintf(temp,"%s",$5);
00475                 fn -> placeholder = reg_variable(temp,NULL);
00476                 fn -> fnline = current_line;
00477         }
00478 |
00479         Poke expr ',' expr
00480 |
00481         Print
00482         {
00483                 strcpy(temp,"\n");
00484                 text_output(temp);
00485                 tab_pos = 0;
00486         }
00487 |
00488         Print print_exprs
00489         {
00490                 sprintf(temp,"%s\n",$2);
00491                 text_output(temp);
00492                 tab_pos = 0;
00493         }
00494 |
00495         Print print_exprs ';'
00496         {
00497                 text_output($2);
00498                 tab_pos = strlen($2);
00499         }
00500 |
00501         Get string_variable
00502         {
00503                 if (running)
00504                 {
00505                         if (fil && file_read)
00506                         {
00507                                 fread($2 -> svalue,1,1,fil);
00508                         }
00509                         else
00510                         {
00511                                 *$2 -> svalue = '.';
00512                                 while ($2 -> svalue[0] == '.')
00513                                 {
00514                                         gets($2 -> svalue);
00515                                         if ($2 -> svalue[0] == '.')
00516                                         {
00517                                                 chdir($2 -> svalue);
00518                                         }
00519                                 }
00520                         }
00521                         $2 -> svalue[1] = 0;
00522                 }
00523         }
00524 
00525 
00526 expr_list:
00527         expr
00528         {
00529                 $$.qty = 0;
00530                 $$.values[$$.qty++] = $1;
00531         }
00532 |
00533         expr_list ',' expr
00534         {
00535                 $$ = $1;
00536                 $$.values[$$.qty++] = $3;
00537         }
00538 
00539 print_exprs:
00540         expr
00541         {
00542                 sprintf(slask,"%f",$1);
00543                 while (slask[strlen(slask) - 1] == '0')
00544                         slask[strlen(slask) - 1] = 0;
00545                 if (slask[strlen(slask) - 1] == '.')
00546                         slask[strlen(slask) - 1] = 0;
00547                 strcpy($$,slask);
00548                 tab_pos = strlen($$);
00549         }
00550 |
00551         string_expr
00552         {
00553                 strcpy($$,$1);
00554                 tab_pos = strlen($$);
00555         }
00556 |
00557         print_exprs STRING
00558         {
00559                 sprintf($$,"%s%s",$1,$2);
00560                 tab_pos = strlen($$);
00561         }
00562 |
00563         print_exprs ';' expr
00564         {
00565                 sprintf(slask,"%f",$3);
00566                 while (slask[strlen(slask) - 1] == '0')
00567                         slask[strlen(slask) - 1] = 0;
00568                 if (slask[strlen(slask) - 1] == '.')
00569                         slask[strlen(slask) - 1] = 0;
00570                 sprintf($$,"%s%s",$1,slask);
00571                 tab_pos = strlen($$);
00572         }
00573 |
00574         print_exprs ';' string_expr
00575         {
00576                 sprintf($$,"%s%s",$1,$3);
00577                 tab_pos = strlen($$);
00578         }
00579 |
00580         print_exprs ',' expr
00581         {
00582                 sprintf(slask,"%f",$3);
00583                 while (slask[strlen(slask) - 1] == '0')
00584                         slask[strlen(slask) - 1] = 0;
00585                 if (slask[strlen(slask) - 1] == '.')
00586                         slask[strlen(slask) - 1] = 0;
00587                 sprintf($$,"%s%s",$1,slask);
00588                 tab_pos = strlen($$);
00589         }
00590 |
00591         print_exprs ',' string_expr
00592         {
00593                 sprintf($$,"%s%s",$1,$3);
00594                 tab_pos = strlen($$);
00595         }
00596 
00597 
00598 expr:
00599         NUM
00600         {
00601 #ifdef DEBUGEXPR
00602 printf(" *-* expr: NUM(%.1f)\n",$1);
00603 #endif
00604                 $$ = $1;
00605         }
00606 |
00607         variable
00608         {
00609 #ifdef DEBUGEXPR
00610 printf(" *-* expr: variable(%s)\n",$1 -> name);
00611 #endif
00612                 $$ = $1 -> value;
00613         }
00614 |
00615         '-' expr %prec UNARYMINUS
00616         {
00617 #ifdef DEBUGEXPR
00618 printf(" *-* expr: - expr\n");
00619 #endif
00620                 $$ = -$2;
00621         }
00622 |
00623         expr '+' expr
00624         {
00625 #ifdef DEBUGEXPR
00626 printf(" *-* expr: expr + expr\n");
00627 #endif
00628                 $$ = $1 + $3;
00629         }
00630 |
00631         expr '-' expr
00632         {
00633 #ifdef DEBUGEXPR
00634 printf(" *-* expr: expr - expr\n");
00635 #endif
00636                 $$ = $1 - $3;
00637         }
00638 |
00639         expr '*' expr
00640         {
00641 #ifdef DEBUGEXPR
00642 printf(" *-* expr: expr * expr\n");
00643 #endif
00644                 $$ = $1 * $3;
00645         }
00646 |
00647         expr '/' expr
00648         {
00649 #ifdef DEBUGEXPR
00650 printf(" *-* expr: expr / expr\n");
00651 #endif
00652                 $$ = $1 / $3;
00653         }
00654 |
00655         expr '<' expr
00656         {
00657 #ifdef DEBUGEXPR
00658 printf(" *-* expr: expr < expr\n");
00659 #endif
00660                 $$ = $1 < $3;
00661         }
00662 |
00663         expr '>' expr
00664         {
00665 #ifdef DEBUGEXPR
00666 printf(" *-* expr: expr > expr\n");
00667 #endif
00668                 $$ = $1 > $3;
00669         }
00670 |
00671         expr LTEQ expr
00672         {
00673 #ifdef DEBUGEXPR
00674 printf(" *-* expr: expr <= expr\n");
00675 #endif
00676                 $$ = $1 <= $3;
00677         }
00678 |
00679         expr GTEQ expr
00680         {
00681 #ifdef DEBUGEXPR
00682 printf(" *-* expr: expr >= expr\n");
00683 #endif
00684                 $$ = $1 >= $3;
00685         }
00686 |
00687         expr NEQ expr
00688         {
00689 #ifdef DEBUGEXPR
00690 printf(" *-* expr: expr != expr\n");
00691 #endif
00692                 $$ = $1 != $3;
00693         }
00694 |
00695         expr '=' expr
00696         {
00697 #ifdef DEBUGEXPR
00698 printf(" *-* expr: expr == expr\n");
00699 #endif
00700                 $$ = $1 == $3;
00701         }
00702 |
00703         string_expr '<' string_expr
00704         {
00705 #ifdef DEBUGEXPR
00706 printf(" *-* expr: string_expr < string_expr\n");
00707 #endif
00708                 $$ = (strcmp($1,$3) < 0) ? 1 : 0;
00709         }
00710 |
00711         string_expr '>' string_expr
00712         {
00713 #ifdef DEBUGEXPR
00714 printf(" *-* expr: string_expr > string_expr\n");
00715 #endif
00716                 $$ = (strcmp($1,$3) > 0) ? 1 : 0;
00717         }
00718 |
00719         string_expr LTEQ string_expr
00720         {
00721 #ifdef DEBUGEXPR
00722 printf(" *-* expr: string_expr <= string_expr\n");
00723 #endif
00724                 $$ = (strcmp($1,$3) <= 0) ? 1 : 0;
00725         }
00726 |
00727         string_expr GTEQ string_expr
00728         {
00729 #ifdef DEBUGEXPR
00730 printf(" *-* expr: string_expr >= string_expr\n");
00731 #endif
00732                 $$ = (strcmp($1,$3) >= 0) ? 1 : 0;
00733         }
00734 |
00735         string_expr NEQ string_expr
00736         {
00737 #ifdef DEBUGEXPR
00738 printf(" *-* expr: string_expr != string_expr\n");
00739 #endif
00740                 $$ = strcmp($1,$3) ? 1 : 0;
00741         }
00742 |
00743         string_expr '=' string_expr
00744         {
00745 #ifdef DEBUGEXPR
00746 printf(" *-* expr: string_expr == string_expr\n");
00747 #endif
00748                 $$ = !strcmp($1,$3);
00749         }
00750 |
00751         expr Or expr
00752         {
00753 #ifdef DEBUGEXPR
00754 printf(" *-* expr: expr || expr\n");
00755 #endif
00756                 $$ = $1 || $3;
00757         }
00758 |
00759         expr And expr
00760         {
00761 #ifdef DEBUGEXPR
00762 printf(" *-* expr: expr && expr\n");
00763 #endif
00764                 $$ = $1 && $3;
00765         }
00766 |
00767         Abs '(' expr ')'
00768         {
00769 #ifdef DEBUGEXPR
00770 printf(" *-* expr: ABS(expr)\n");
00771 #endif
00772                 if ($3 < 0)
00773                         $$ = -$3;
00774                 else
00775                         $$ = $3;
00776         }
00777 |
00778         Asc '(' string_expr ')'
00779         {
00780 #ifdef DEBUGEXPR
00781 printf(" *-* expr: ASC(string_expr)\n");
00782 #endif
00783                 $$ = *$3;
00784         }
00785 |
00786         Atn '(' expr ')'
00787         {
00788 #ifdef DEBUGEXPR
00789 printf(" *-* expr: ATN(expr)\n");
00790 #endif
00791                 $$ = atan($3);
00792         }
00793 |
00794         Int '(' expr ')'
00795         {
00796 #ifdef DEBUGEXPR
00797 printf(" *-* expr: INT(expr)\n");
00798 #endif
00799                 $$ = (long)$3;
00800         }
00801 |
00802         Val '(' string_expr ')'
00803         {
00804 #ifdef DEBUGEXPR
00805 printf(" *-* expr: VAL(string_expr)\n");
00806 #endif
00807                 $$ = atof($3);
00808         }
00809 |
00810         Rnd '(' expr ')'
00811         {
00812 #ifdef DEBUGEXPR
00813 printf(" *-* expr: RND(expr)\n");
00814 #endif
00815                 $$ = (double)rand();
00816                 $$ /= RAND_MAX;
00817         }
00818 |
00819         '(' expr ')'
00820         {
00821 #ifdef DEBUGEXPR
00822 printf(" *-* expr: (expr)\n");
00823 #endif
00824                 $$ = $2;
00825         }
00826 |
00827         Not expr
00828         {
00829 #ifdef DEBUGEXPR
00830 printf(" *-* expr: NOT expr\n");
00831 #endif
00832                 $$ = !$2;
00833         }
00834 |
00835         Fn IDENTIFIER '(' expr ')'
00836         {
00837 #ifdef DEBUGEXPR
00838 printf(" *-* expr: FN ... ( expr )\n");
00839 #endif
00840 //printf("LINE: '%s'\n",the_str);
00841 //printf("REST: '%s'\n",the_str + the_ptr);
00842                 for (fn = funcbase; fn; fn = fn -> next)
00843                         if (!strcmp(fn -> name,$2))
00844                                 break;
00845                 if (fn)
00846                 {
00847                         fn -> placeholder -> fnvalue = fn -> placeholder -> value;
00848                         fn -> placeholder -> value = $4;
00849                         placeholder = fn -> placeholder;
00850                         i = 0;
00851 #define FC fn -> fnline -> the_str[i]
00852                         while (FC && FC != '=')
00853                                 i++;
00854                         if (FC == '=')
00855                         {
00856 //printf("BEFORE: '%s'\n",the_str);
00857                                 sprintf(temp,"*%s%s",fn -> fnline -> the_str + i + 1,the_str + the_ptr);
00858                                 strcpy(the_str + the_ptr,temp);
00859 //printf(" AFTER: '%s'\n",the_str);
00860                         }
00861                 }
00862                 else
00863                 {
00864                         printf("Using Undefined Function '%s'\n",$2);
00865                         next_line = onerror;
00866                 }
00867 //printf("REPL: '%s'\n",fn -> fnline -> the_str);
00868                 $$ = 1;
00869         }
00870 |
00871         Len '(' string_expr ')'
00872         {
00873 #ifdef DEBUGEXPR
00874 printf(" *-* expr: LEN(string_expr)\n");
00875 #endif
00876                 $$ = strlen($3);
00877         }
00878 |
00879         Peek '(' expr ')'
00880         {
00881 #ifdef DEBUGEXPR
00882 printf(" *-* expr: PEEK(expr)\n");
00883 #endif
00884                 $$ = 0;
00885         }
00886 
00887 string_expr:
00888         STRING
00889 |
00890         string_variable
00891         {
00892                 strcpy($$,$1 -> svalue);
00893         }
00894 |
00895         Mid '(' string_expr ',' expr ')'
00896         {
00897                 if ($5 <= strlen($3))
00898                 {
00899                         strcpy($$,$3 + (int)$5 - 1);
00900                 }
00901                 else
00902                         *$$ = 0;
00903         }
00904 |
00905         Mid '(' string_expr ',' expr ',' expr ')'
00906         {
00907                 if ($5 <= strlen($3))
00908                 {
00909                         strcpy($$,$3 + (int)$5 - 1);
00910                         $$[ (int)$7] = 0;
00911                 }
00912                 else
00913                         *$$ = 0;
00914         }
00915 |
00916         Left '(' string_expr ',' expr ')'
00917         {
00918                 if ($5 > 0)
00919                 {
00920                         strncpy($$,$3, (int)$5);
00921                         $$[(int)$5] = 0;
00922                 }
00923         }
00924 |
00925         Right '(' string_expr ',' expr ')'
00926         {
00927                 if (strlen($3) > $5)
00928                         strcpy($$,$3 + strlen($3) - (int)($5 + 0.01));
00929                 else
00930                         strcpy($$,$3);
00931         }
00932 |
00933         Chr '(' expr ')'
00934         {
00935                 *$$ = (char)$3;
00936                 $$[1] = 0;
00937         }
00938 |
00939         string_expr '+' string_expr
00940         {
00941                 sprintf($$,"%s%s",$1,$3);
00942         }
00943 |
00944         Str '(' expr ')'
00945         {
00946                 sprintf($$,"%f",$3);
00947                 while ($$[strlen($$) - 1] == '0')
00948                         $$[strlen($$) - 1] = 0;
00949                 if ($$[strlen($$) - 1] == '.')
00950                         $$[strlen($$) - 1] = 0;
00951         }
00952 |
00953         Tab '(' expr ')'
00954         {
00955                 *$$ = 0;
00956                 while (tab_pos < $3)
00957                 {
00958                         strcat($$," ");
00959                         tab_pos++;
00960                 }
00961         }
00962 |
00963         Spc '(' expr ')'
00964         {
00965                 *$$ = 0;
00966                 for (i = 0; i < $3; i++)
00967                         strcat($$," ");
00968         }
00969 
00970 int_list:
00971         NUM
00972         {
00973                 $$.qty = 0;
00974                 $$.values[$$.qty++] = (long)$1;
00975         }
00976 |
00977         int_list ',' NUM
00978         {
00979                 $$ = $1;
00980                 $$.values[$$.qty++] = (long)$3;
00981         }
00982 
00983 var_list:
00984         variable
00985         {
00986                 $$.qty = 0;
00987                 $$.var[$$.qty++] = $1;
00988         }
00989 |
00990         string_variable
00991         {
00992                 $$.qty = 0;
00993                 $$.var[$$.qty++] = $1;
00994         }
00995 |
00996         var_list ',' variable
00997         {
00998                 $$ = $1;
00999                 $$.var[$$.qty++] = $3;
01000         }
01001 |
01002         var_list ',' string_variable
01003         {
01004                 $$ = $1;
01005                 $$.var[$$.qty++] = $3;
01006         }
01007 
01008 variable:
01009         NUMVAR
01010         {
01011                 $$ = reg_variable($1,NULL);
01012         }
01013 |
01014         IDENTIFIER
01015         {
01016                 $$ = reg_variable($1,NULL);
01017         }
01018 |
01019         NUMVAR '(' expr_list ')'
01020         {
01021                 $$ = reg_variable($1,&$3);
01022         }
01023 |
01024         IDENTIFIER '(' expr_list ')'
01025         {
01026                 $$ = reg_variable($1,&$3);
01027         }
01028 
01029 string_variable:
01030         STRINGVAR
01031         {
01032                 $$ = reg_variable($1,NULL);
01033 #ifdef DEBUG
01034 printf("%s = '%s'\n",$$ -> name,$$ -> svalue);
01035 #endif
01036         }
01037 |
01038         STRINGVAR '(' expr_list ')'
01039         {
01040                 $$ = reg_variable($1,&$3);
01041 #ifdef DEBUG
01042 printf("%s(",$$ -> name);
01043 for (i = 0; i < $$ -> qindex; i++)
01044         printf("%s%d",i ? "," : "",$$ -> index[i]);
01045 printf(") = '%s'\n",$$ -> svalue);
01046 #endif
01047         }
01048 
01049 %%
01050 
01051 
01052 VARIABLE *reg_variable(char *name,EXPRLIST *p)
01053 {
01054         VARIABLE *v;
01055         int i;
01056         char type[2];
01057 
01058 //printf(" ### variablebase %lx\n",(long)variablebase);
01059 
01060         if (*name != '$') // not a function (def fn)
01061         {
01062                 switch (name[strlen(name) - 1])
01063                 {
01064                 case '$':
01065                         strcpy(type,"$");
01066                         name[strlen(name) - 1] = 0;
01067                         break;
01068                 case '%':
01069                         strcpy(type,"%");
01070                         name[strlen(name) - 1] = 0;
01071                         break;
01072                 default:
01073                         *type = 0;
01074                 }
01075                 name[2] = 0;
01076                 strcat(name,type);
01077         }
01078 
01079         if (p)
01080         {
01081                 strcat(name,"(");
01082                 for (i = 0; i < p -> qty; i++)
01083                 {
01084                         if (i)
01085                                 strcat(name,",");
01086                         sprintf(name + strlen(name),"%d",(int)(p -> values[i] + 0.01));
01087                 }
01088                 strcat(name,")");
01089         }
01090 
01091         for (v = variablebase; v; v = v -> next)
01092         {
01093                 if (!strcmp(v -> name,name))
01094                         break;
01095         }
01096         if (!v)
01097         {
01098                 v = (VARIABLE *)malloc(sizeof(VARIABLE));
01099                 if (!v)
01100                 {
01101                         printf("malloc failed\n");
01102                         exit(-1);
01103                 }
01104                 strcpy(v -> name,name);
01105                 v -> ivalue = 0;
01106                 v -> value = v -> fnvalue = 0;
01107                 *v -> svalue = 0;
01108                 v -> next = variablebase;
01109                 variablebase = v;
01110         }
01111         return v;
01112 }
01113 
01114 void text_output(char *s)
01115 {
01116         char *cmd;
01117         char *arg;
01118         char *option;
01119         long offset;
01120         int i;
01121         short cmnum;
01122 
01123         if (*s == 4)    // CHR$(4) - dos command
01124         {
01125                 if (s[strlen(s) - 1] == '\n');
01126                         s[strlen(s) - 1] = 0;
01127                 file_read = 0;
01128                 file_write = 0;
01129                 fil = NULL;
01130                 cmd = strtok(s + 1," ");
01131                 if (!cmd)
01132                 {
01133 #ifdef DEBUG
01134                         printf(" * Empty CHR$(4)\n");
01135 #endif
01136                         return;
01137                 }
01138                 arg = strtok(NULL,",");
01139 #ifdef DEBUG
01140 printf(" * file command '%s' argument '%s'\n",cmd,arg);
01141 #endif
01142                 if (!strcmp(cmd,"RUN"))
01143                         cmnum = 1;
01144                 else
01145                 if (!strcmp(cmd,"OPEN"))
01146                         cmnum = 2;
01147                 else
01148                 if (!strcmp(cmd,"CLOSE"))
01149                         cmnum = 3;
01150                 else
01151                 if (!strcmp(cmd,"READ"))
01152                         cmnum = 4;
01153                 else
01154                 if (!strcmp(cmd,"WRITE"))
01155                         cmnum = 5;
01156                 else
01157                 if (!strcmp(cmd,"DELETE"))
01158                         cmnum = 6;
01159                 else
01160                 {
01161                         printf("##############################################\n");
01162                         printf("#### implement dos command\n");
01163                         printf("####  cmd '%s' arg '%s'\n",cmd,arg);
01164                         printf("##############################################\n");
01165                         cmnum = 0;
01166                 }
01167 
01168                 option = strtok(NULL,",");
01169                 option_s = -1;
01170                 option_d = -1;
01171                 option_l = -1;
01172                 option_r = -1;
01173                 while (option)
01174                 {
01175 #ifdef DEBUG
01176 printf("   option '%s'\n",option);
01177 #endif
01178                         switch (*option)
01179                         {
01180                         case 'S':
01181                                 option_s = atoi(option + 1);
01182                                 break;
01183                         case 'D':
01184                                 option_d = atoi(option + 1);
01185                                 break;
01186                         case 'L':
01187                                 option_l = atoi(option + 1);
01188                                 break;
01189                         case 'R':
01190                                 option_r = atoi(option + 1);
01191                                 break;
01192                         default:
01193                                 printf("####  cmd '%s' arg '%s' option '%s'\n",cmd,arg,option);
01194                                 printf("##############################################\n");
01195                         }
01196                         option = strtok(NULL,",");
01197                 }
01198 
01199                 if (!running)
01200                         return;
01201 
01202                 switch (cmnum)
01203                 {
01204                 case 1: // run
01205                         printf(" * RUN '%s'\n",arg);
01206                         strcpy(run_program,arg);
01207                         next_line = NULL;
01208                         break;
01209                 case 2: // open ,S ,D ,L
01210                         for (o = openbase; o; o = o -> next)
01211                                 if (!strcmp(o -> name,arg))
01212                                         break;
01213                         if (o)
01214                         {
01215 //                              printf(" *** FILE already OPEN\n");
01216                         }
01217                         else
01218                         {
01219                                 o = (OPEN *)malloc(sizeof(OPEN));
01220                                 o -> fil = fopen(arg,"r+b");
01221                                 if (!o -> fil)
01222                                         o -> fil = fopen(arg,"w+b");
01223                                 if (!o -> fil)
01224                                 {
01225                                         printf(" *** OPEN '%s' failed\n",arg);
01226                                         next_line = onerror;
01227                                         free(o);
01228                                 }
01229                                 else
01230                                 {
01231                                         strcpy(o -> name,arg);
01232                                         stat(arg,&o -> file_stat);
01233                                         o -> option_s = option_s;
01234                                         o -> option_d = option_d;
01235                                         o -> option_l = option_l;
01236                                         o -> option_r = 0;
01237                                         addlist(&openbase,o);
01238                                 }
01239                         }
01240                         break;
01241                 case 3: // close
01242                         if (arg)
01243                         {
01244                                 for (o = openbase; o; o = o -> next)
01245                                         if (!strcmp(o -> name,arg))
01246                                                 break;
01247                                 if (!o)
01248                                         printf(" *** FILE not OPEN (CLOSE)\n");
01249                                 else
01250                                 {
01251                                         fclose(o -> fil);
01252                                         removelist(&openbase,o);
01253                                         free(o);
01254                                 }
01255                         }
01256                         else
01257                         {
01258                                 while (openbase)
01259                                 {
01260                                         o = openbase;
01261                                         fclose(o -> fil);
01262                                         removelist(&openbase,o);
01263                                         free(o);
01264                                 }
01265                         }
01266                         break;
01267                 case 4: // read ,R
01268                         for (o = openbase; o; o = o -> next)
01269                                 if (!strcmp(o -> name,arg))
01270                                         break;
01271                         if (!o)
01272                                 printf(" *** FILE not OPEN (READ)\n");
01273                         else
01274                         {
01275                                 if (option_r > -1)
01276                                 {
01277                                         o -> option_r = option_r;
01278                                         offset = (long)o -> option_l * (long)o -> option_r;
01279                                         if (offset > o -> file_stat.st_size)
01280                                                 next_line = onerror;
01281 //                                      printf(" * READ '%s' ,L%d ,R%d  Offset 0x%04lx\n",arg,o -> option_l,o -> option_r,offset);
01282                                         if (fseek(o -> fil,offset,SEEK_SET))
01283                                                 next_line = onerror;
01284                                 }
01285                                 file_read = 1;
01286                                 fil = o -> fil;
01287                         }
01288                         break;
01289                 case 5: // write ,R
01290                         for (o = openbase; o; o = o -> next)
01291                                 if (!strcmp(o -> name,arg))
01292                                         break;
01293                         if (!o)
01294                                 printf(" *** FILE not OPEN (WRITE)\n");
01295                         else
01296                         {
01297 #ifdef DEBUG
01298 printf(" * Write to file '%s'\n",o -> name);
01299 #endif
01300                                 if (option_r > -1)
01301                                 {
01302                                         o -> option_r = option_r;
01303                                         offset = (long)o -> option_l * (long)o -> option_r;
01304 #ifdef DEBUG
01305                                         printf(" * WRITE '%s' ,L%d ,R%d  Offset 0x%04lx\n",arg,o -> option_l,o -> option_r,offset);
01306 #endif
01307                                         if (fseek(o -> fil,offset,SEEK_SET))
01308                                                 next_line = onerror;
01309                                 }
01310                                 file_write = 1;
01311                                 fil = o -> fil;
01312 #ifdef DEBUG
01313 printf(" * ...\n");
01314 #endif
01315                         }
01316                         break;
01317                 case 6: // delete
01318                         unlink(arg);
01319                         break;
01320 
01321                 default:
01322                         break;
01323                 } // switch (cmnum)
01324 
01325         }
01326         else
01327         {
01328                 if (!running)
01329                         return;
01330 
01331                 if (fil && file_write)
01332                 {
01333                         if (s[strlen(s) - 1] == 0x0a)
01334                                 s[strlen(s) - 1] = 0x8d;
01335                         fwrite(s,strlen(s),1,fil);
01336                 }
01337                 else
01338                 {
01339                         i = 0;
01340                         while (s[i])
01341                         {
01342                                 if (strlen(s + i) > 40)
01343                                 {
01344                                         strncpy(slask,s + i,40);
01345                                         slask[40] = 0;
01346                                         printf("%s\n",slask);
01347                                         i += 40;
01348                                 }
01349                                 else
01350                                 {
01351                                         printf("%s",s + i);
01352                                         i += strlen(s + i);
01353                                 }
01354                                 fflush(stdout);
01355                         }
01356                 }
01357         }
01358 }
01359 
01360 void file_input(char *s,int l)
01361 {
01362         int i = 0;
01363         short q = 0;
01364         unsigned char c;
01365 
01366         if (fil)
01367                 fread(&c,1,1,fil);
01368         while (fil && !feof(fil) && c != 0x8d && (q || (c & 0x7f) != ',') && c)
01369         {
01370                 if (i >= l - 1)
01371                 {
01372                         printf(" ********* BUFFER OVERFLOW ********\n");
01373                         s[l - 1] = 0;
01374                         printf("%s\n",s);
01375                         exit(-1);
01376                 }
01377                 s[i++] = c & 0x7f;
01378                 if ( (c & 0x7f) == 34)
01379                         q = !q;
01380 #ifdef DEBUG
01381 printf("%c",c & 0x7f);
01382 #endif
01383                 fread(&c,1,1,fil);
01384         }
01385         s[i] = 0;
01386         if (*s == 34 && s[strlen(s) - 1] == 34)
01387         {
01388                 memmove(s,s + 1,strlen(s) + 1);
01389                 s[strlen(s) - 1] = 0;
01390         }
01391 #ifdef DEBUG
01392 printf("\n");
01393 #endif
01394 }
01395 
01396 void file_init(void)
01397 {
01398         fil = NULL;
01399         onerror = NULL;
01400         current_data = database;
01401         dataptr = 0;
01402 }
01403 
01404 #define DC (current_data?current_data->data[dataptr]:0)
01405 
01406 void get_data(char *s)
01407 {
01408         int x = 0;
01409 
01410         while (DC == ' ' || DC == 9)
01411                 dataptr++;
01412         if (!DC)
01413         {
01414                 current_data = current_data ? current_data -> next : NULL;
01415                 dataptr = 0;
01416                 while (DC == ' ' || DC == 9)
01417                         dataptr++;
01418         }
01419         if (DC)
01420         {
01421                 while (DC && DC != ',')
01422                 {
01423                         s[x++] = DC;
01424                         dataptr++;
01425                 }
01426                 if (DC == ',')
01427                         dataptr++;
01428         }
01429         s[x] = 0;
01430 }
01431 
01432 void read_data(VARLIST *vl)
01433 {
01434         int i;
01435 
01436         for (i = 0; i < vl -> qty; i++)
01437         {
01438                 get_data(vl -> var[i] -> svalue);
01439                 vl -> var[i] -> value = atof(vl -> var[i] -> svalue);
01440         }
01441 }
01442 
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