![]() |
Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members
a.yGo 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 |