Scripting Dynamics
/* * Copyright (c) 2013 Miguel Pando * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include
#include
#include
#include
#include
#include
#include
//--------- LIMITS ---------------- #define SB_NUM_LAB 100 //127 maximum #define SB_NUM_IF 100 //127 maximum #define SB_FOR_NEST 5 #define SB_SUB_NEST 25 #define SB_TABSTOP 8 #define SB_NUM_LIBS 10 #define SB_NUM_INCS 10 #define SB_NUM_VAR 40 #define SB_UNKNCOM 0 #define SB_RESERVED 1 #define SB_INPUT 2 #define SB_IF 3 #define SB_THEN 4 #define SB_FOR 5 #define SB_NEXT 6 #define SB_TO 7 #define SB_GOTO 8 #define SB_GOSUB 9 #define SB_RETURN 10 #define SB_EOL 11 #define SB_FORMAT 12 #define SB_ELSE 13 #define SB_ENDIF 14 #define SB_VAL 15 #define SB_CALL 16 #define SB_IMPORT 17 #define SB_PARSE 18 #define SB_PARSECOUNT 19 #define SB_XCALL 20 #define SB_OR 21 #define SB_AND 22 #define SB_CHR 23 #define SB_INSTR 24 #define SB_MID 25 #define SB_LEN 26 #define SB_REP 27 #define SB_TRIM 28 #define SB_LTRIM 29 #define SB_RTRIM 30 #define SB_ASC 31 #define SB_RE 32 #define SB_DATE 33 #define SB_TIME 34 #define SB_LCASE 35 #define SB_UCASE 36 #define SB_INCLUDE 37 #define SB_RAISE 38 #define SB_STEP 39 #define SB_GETFILE 40 #define SB_RUN 41 #define SB_XOR 42 #define SB_FINISHED 43 #define SB_END 44 #define SB_ANY 45 #define SB_PLUS 46 #define SB_MINUS 47 #define SB_ASTER 48 #define SB_DIV 49 #define SB_IDIV 50 #define SB_OPAREN 51 #define SB_GE 52 #define SB_NE 53 #define SB_LE 54 #define SB_G 55 #define SB_L 56 #define SB_EQ 57 #define SB_AMPER 58 #define SB_ASSIGN 59 #define SB_MOD 60 #define SB_EXP 61 #define SB_xGOTO 62 #define SB_INSTR1 63 #define SB_PARSECOUNT1 64 #define SB_PARSECOUNT2 65 #define SB_RE1 66 #define SB_PARSE1 67 #define SB_PARSE2 68 #define SB_REP1 69 #define SB_CPAREN 70 #define SB_COMMA 71 #define SB_SEMI 72 #define SB_MID1 73 #define SB_OSQR 74 #define SB_CSQR 75 #define SB_DIM 76 #define SB_ARRAY2 90 #define SB_ARRAY0 77 #define SB_ARRAY1 78 #define SB_ASSIGNARRAY 79 #define SB_ARG 80 #define SB_PRINT 81 #define SB_REREP 82 #define SB_STRNG 83 #define SB_STRNG1 84 #define SB_CONST1 85 #define SB_CONST2 86 #define SB_ERR 87 #define SB_ERRORMSG 88 #define SB_SLEEP 89 char *getfile(char *, int *); int parsecount(char *, char *, int); void Exec_StrExp(); int Exec_Exp(double *); int Exec_Exp1(double *); int Exec_Exp1a(double *); int Exec_Exp2(double *); int Exec_Exp3(double *); int Exec_Exp4(double *); int Exec_Exp5(double *); int Exec_Exp6(double *); int Atom(double *); //char relops = {SB_GE, SB_NE, SB_LE, SB_G, SB_L, SB_EQ}; char *relops="456789"; int nrelops=6; char *months="JanFebMarAprMayJunJulAugSepOctNovDec"; int fflag, Eflag, Rflag, ProgPtr, ftos, gtos; int Label_Table[SB_NUM_LAB], IF_TABLE[SB_NUM_IF][2]; char ErrorMsg[128], Tok; unsigned char *pcode; char *gSB_Format, bFormat[10]; int fStack[SB_FOR_NEST][4]; int gStack[SB_SUB_NEST]; int VarInteger[40]; double VarFloat[40]; char *VarStr[40]; char *VS=NULL; int ubI[10], ubN[10], ubS[10]; int *IX[10]; double *NX[10]; char **SX[10]; char **Consts; //char linebuffer[1024]; char *linebuffer; char *ixx, *sixx; int bsize; char xrun[30]; int builtins; int argn; char **argz; int do_loop(int); //***************************************************************** unsigned char Get_Token() { //***************************************************************** unsigned char ch; ch=pcode[ProgPtr++]; Tok=ch; return ch; } //***************************************************************** void Put_Back() { //***************************************************************** ProgPtr--; } //***************************************************************** int Exec_Iarray(int x) { //***************************************************************** int n; double r; n=Exec_Exp(&r); if (n > ubI[x] || n<0) { strcpy(ErrorMsg,"Subscript Out Of Bounds"); Eflag=1; return 0; } return IX[x][n]; } //***************************************************************** double Exec_Narray(int x) { //***************************************************************** int n; double r; n=Exec_Exp(&r); if (n>ubN[x] || n<0) { strcpy(ErrorMsg,"Subscript Out Of Bounds"); Eflag=1; return 0.0; } return NX[x][n]; } //***************************************************************** char *Exec_Sarray(int x) { //***************************************************************** int n; double r; n=Exec_Exp(&r); if (n>ubS[x] || n<0) { strcpy(ErrorMsg, "Subscript Out Of Bounds"); Eflag=1; return NULL; } return SX[x][n]; } //***************************************************************** char Exec_CHR() { //***************************************************************** int n; char c; double r; n=Exec_Exp(&r); c=n; return c; } //***************************************************************** int Exec_ASC() { //***************************************************************** char c, *s; s=ixx; Exec_StrExp(); ixx=s; c=ixx[0]; return (int) c; } //***************************************************************** int Exec_LEN() { //***************************************************************** char *s; int n; s=ixx; Exec_StrExp(); ixx=s; n=strlen(s); *ixx='\0'; return n; } //***************************************************************** int Exec_VAL(double *dbl) { //***************************************************************** char *s; s=ixx; Exec_StrExp(); ixx=s; *dbl = atof(ixx); return atoi(ixx); } //***************************************************************** int instr(char *s1, char *s2, int n, int x) { //***************************************************************** int ln, ln2, i, i2; ln=strlen(s1); ln2=strlen(s2); if (ln2==0) return -1; if ((ln - ln2) < 0) return -1; for (i=n; i <= (ln-ln2); i++) { i2=0; while (i2 < ln2) { if (x) { if (s1[i] == s2[i2]) return i; } else { if (s1[i + i2] != s2[i2]) break; } i2++; } if (x==0 && i2==ln2) return i; } return -1; } //***************************************************************** int Exec_PARSECOUNT(int x) { //***************************************************************** char *s1, *s2; int r; s1=ixx; Exec_StrExp(); s2=++ixx; Exec_StrExp(); r=parsecount(s1, s2, x); ixx=s1; return r; } //***************************************************************** int Exec_INSTR(int x) { //***************************************************************** char *s1, *s2; int n; double r; //n=INSTR(5, z$, "?\") 'SB_INSTR //n=INSTR(5, z$, ANY "?\") 'SB_INSTR1 n=Exec_Exp(&r); //The compiler should default to zero, Not 1 s1=ixx; Exec_StrExp(); s2=++ixx; Exec_StrExp(); n = instr(s1, s2, n, x); ixx=s1; return ++n; } //***************************************************************** void Exec_REPLACE() { //***************************************************************** char *s, *z, *c, *bufx; int r, n, sln, zln; z=ixx; Exec_StrExp(); zln=strlen(z); s=++ixx; Exec_StrExp(); sln=strlen(s); c=++ixx; Exec_StrExp(); bufx=++ixx; bufx[0]='\0'; n=0; while (1) { r = instr(z, s, n, 0); if (r==-1) { strcat(bufx, z+n); break;} strncat(bufx, z+n, r-n); strcat(bufx, c); n=r + sln; if (n > zln) break; } ixx=z; strcpy(ixx, bufx); } //***************************************************************** char *Get_String(ch1) { //***************************************************************** int n; n=(int) Get_Token(); switch (ch1) { case SB_CONST2: return Consts[n - 1]; break; default: strcpy(ErrorMsg, "get_string Error"); Eflag=1; return NULL; } } char modules[50]; HINSTANCE libs[10]; char *(__cdecl *vt[10])(char *proc, int *status, int argn, char **argz); //***************************************************************** int parse(char *s1, char *sep, char *s2) { //***************************************************************** int i; char *p, *z; z=malloc(strlen(s1)+1); z[0]='\0'; strcpy(z, s1); i=1; p=strtok(z, sep); while (p != NULL) { if (strcmp(s2, p)==0) break; i++; p=strtok(NULL, sep); } if (p==NULL) i=0; free(z); return i; } //***************************************************************** void Exec_PARSE1() { //***************************************************************** char *s, *sep; int i, n, ln, sln, r, x; double dbl; //x$=PARSE(z$, "?!", n) %SB_PARSE1 s=ixx; Exec_StrExp(); sln=strlen(s); sep=++ixx; Exec_StrExp(); ln=strlen(sep); n=Exec_Exp(&dbl); x=1; i=0; ixx=s; while (1) { r = instr(s, sep, i, 0); if (r==-1) break; if (n==1) { ixx[r]='\0'; return; } if (x==n) { ixx[r]='\0'; memmove(ixx, ixx + i, (r-i+1)); return; } x++; i=r + ln; if (i > sln) { r=-1; break; } } if (r==-1 && i>0) { memmove(ixx, ixx + i, (sln-i+1)); return; } ixx[0]='\0'; } //***************************************************************** void Exec_PARSE2() { //***************************************************************** char *s, *sep, *p; int i, n; double dbl; //x$=PARSE(z$, ANY "?!", n) %SB_PARSE2 s=ixx; Exec_StrExp(); sep=++ixx; Exec_StrExp(); n=Exec_Exp(&dbl); i=1; p=strtok(s, sep); while (p != NULL) { if (i==n) break; i++; p=strtok(NULL, sep); } ixx=s; if (p!=NULL) { strcpy(s, p); } else { ixx[0]='\0'; } } //***************************************************************** void Exec_IMPORT() { //***************************************************************** char *lib, ch; int i, n; HINSTANCE hndl; FARPROC proc; char *s; ch=Get_Token(); if (ch==SB_CONST2) { lib=Get_String(ch); } else { s=ixx; Put_Back(); Exec_StrExp(); ixx=s; lib=s; } for (i=builtins; i<10; i++) { if (vt[i]==0) break; } if (i>=10) { strcpy(ErrorMsg, "Limit of 10 Modules Exceeded"); Eflag=1; return; } n=parse(modules, ";", lib); if (n) return; hndl=LoadLibrary(lib); proc=GetProcAddress(hndl, "_run"); if (proc==0) { Rflag=1; strcpy(ErrorMsg, "Unable To Load "); strcat(ErrorMsg, lib); //strcpy(ErrorMsg, "Unable To Load Module"); //Eflag=1; return; } if ( (strlen(modules) + strlen(lib)) > 50 ) { strcpy(ErrorMsg, "Modules Buffer Full"); Eflag=1; return; } strcat(modules, lib); strcat(modules, ";"); libs[i]=hndl; vt[i]=proc; } //***************************************************************** void cback(int argc, char *argv[]) { //***************************************************************** int i, n; n = Label_Table[0]; if (n <= 0) { Eflag=1; strcpy(ErrorMsg, "No CBACK Pointer"); return; } argn0=argn; argz0=argz; argn=argc; argz=argv; gStack[gtos++] = ProgPtr; ProgPtr = n; i=do_loop(1); argn=argn0; argz=argz0; ProgPtr=gStack[--gtos]; return; } //***************************************************************** void Exec_CALL() { //***************************************************************** int n, i, e; char *s, *z, *lib, *p, ch, *a[10]; char *proc; z=ixx; ch=Get_Token(); if (ch==SB_CONST2) { lib=Get_String(ch); } else { s=ixx; Exec_StrExp(); ixx=s; lib=s; } i=parse(modules, ";", lib); if (i==0) { Rflag=1; strcpy(ErrorMsg, "Lib Not Found "); strcat(ErrorMsg, lib); //Eflag=1; while(1) { if (Tok==SB_XCALL) break; ch=Get_Token(); } return; } ch=Get_Token(); proc=Get_String(ch); n=0; while (1) { if (n>=9) { Eflag=1; strcpy(ErrorMsg, "Too many parameters"); return; } ch=Get_Token(); if (Tok==SB_EOL) continue; if (Tok==SB_XCALL) break; Put_Back(); a[n]=ixx; Exec_StrExp(); ixx++; n++; } char xb[12]; sprintf(xb, "%d", &cback); a[n]=xb; e=0; s=vt[i-1](proc, &e, n, a); if (e==1) { Rflag=1; strcpy(ErrorMsg, s); return; } int n1, n2; ixx=z; n=strlen(ixx) + strlen(s); if (n > bsize) { i=((n/1024) + 1); if (i>64) { Eflag=1; strcpy(ErrorMsg, "Call Return Exceeds Buffer MaxSize Of 64 Kb"); return; } else { bsize=i*1024; n1=ixx-linebuffer; n2=sixx-linebuffer; linebuffer=realloc(linebuffer, bsize); ixx=linebuffer+n1; sixx=linebuffer+n2; } } strcpy(ixx, s); if (e==-1) free(s); //Indicates memory was allocated } //***************************************************************** void Exec_STRNG(int x) { //***************************************************************** char *s, c, *z; int n, n1, i, ii, ln; double r; s=ixx; n=Exec_Exp(&r); if (x==1) { Exec_StrExp(); ln=strlen(s); z=ixx; for (i=0; i<(n*ln); i+=ln) { for (ii=0; ii
argn || argz[n]==NULL) { ixx[0]='\0'; //Error Rflag=1; strcpy(ErrorMsg, "Error Null Arg"); } else { strcpy(ixx, argz[n]); } break; default: x = (ch1 & 0x80); if (x) { x=(ch1 & 0x7f); if (x > 80) { x-=80; if (VarStr[x] != NULL) strcpy(ixx, VarStr[x]); else nflag=1; } else { Put_Back(); n=Exec_Exp(&dbl); if (fflag) { if (strlen(gSB_Format)==0) { sprintf(ixx, "%1.2f", dbl); } else { sprintf(ixx, gSB_Format, dbl); } } else { sprintf(ixx, "%d", n); } } } else { n = (int) Get_Token(); if (ch1==SB_ARRAY2) { s=Exec_Sarray(n-48); if (s!=NULL) strcpy(ixx, s); } else { Put_Back(); Put_Back(); n=Exec_Exp(&dbl); if (fflag) { if (strlen(gSB_Format)==0) { sprintf(ixx, "%1.2f", dbl); } else { sprintf(ixx, gSB_Format, dbl); } } else { //sprintf(ixx, gSB_Format, n); ??? sprintf(ixx, "%d", n); } } } break; } if (Eflag==1 || ch1==SB_EOL) break; if (nflag==0) ixx+=strlen(ixx); } if (Eflag==1) { if (strlen(ErrorMsg)==0) strcpy(ErrorMsg," Error In StrExp"); } } //***************************************************************** int Exec_StrExp1() { //***************************************************************** char *s1, *s2, op; int r, ret; s1=ixx; Exec_StrExp(); op = Get_Token(); s2=++ixx; Exec_StrExp(); r=strcmp(s1, s2); ret=0; switch (op) { case SB_L: if (r < 0) ret=1; break; case SB_G: if (r > 0) ret=1; break; case SB_EQ: if (r==0) ret=1; break; case SB_NE: if (r != 0 ) ret=1; break; case SB_GE: if (r >= 0) ret=1; break; case SB_LE: if (r <=0 ) ret=1; break; default: Eflag=1; strcpy(ErrorMsg,"Error in StrExp1"); break; } ixx=s1; return ret; } //***************************************************************** int Exec_Exp(double *dbl) { //***************************************************************** char op; int r; fflag=0; r=0; *dbl=0.0; op = Get_Token(); r = Exec_Exp1(dbl); if (Eflag==1) return 0; if (Tok==SB_EOL) return r; strcpy(ErrorMsg, "Missing EOL"); Eflag=1; return 0; } //***************************************************************** int Exec_Exp1(double *dbl) { //***************************************************************** int r, i1, i2; char op, ch; r = Exec_Exp1a(dbl); op = Tok; if (op==SB_AND || op==SB_OR || op==SB_XOR) { ch = Get_Token(); i1 = r; i2 = Exec_Exp1(dbl); switch (op) { case SB_AND: i1=(i1 & i2); break; case SB_OR: i1=(i1 | i2); break; case SB_XOR: i1=(i1 ^ i2); break; } r = i1; } return r; } //***************************************************************** int Exec_Exp1a(double *dbl) { //***************************************************************** int r, i, i2; double temp; char ch, op; r = Exec_Exp2(dbl); op = Tok; ch = op; //which=strchr(relops, ch); for (i=0; i
temp); else r = (r > i2); break; case SB_GE: if (fflag) r = (*dbl >= temp); else r = (r >= i2); break; case SB_EQ: if (fflag) r = (*dbl == temp); else r = (r == i2); break; case SB_NE: if (fflag) r = (*dbl != temp); else r = (r != i2); break; } } return r; } //***************************************************************** int Exec_Exp2(double *dbl) { //***************************************************************** int r, i1; double temp; char op, ch; r = Exec_Exp3(dbl); op = Tok; while(1) { if (op==SB_PLUS || op==SB_MINUS) { ch = Get_Token(); i1 = Exec_Exp3(&temp); switch (op) { case SB_PLUS: if (fflag) *dbl = *dbl + temp; else r = r + i1; break; case SB_MINUS: if (fflag) *dbl = *dbl - temp; else r = r - i1; break; } op = Tok; } else { break; } if (fflag) { r=(int) *dbl; } else { *dbl=r; } } return r; } //***************************************************************** int Exec_Exp3(double *dbl) { //***************************************************************** int r, i1; double temp, d; char op, ch; r = Exec_Exp4(dbl); op = Tok; while(1) { if (op==SB_ASTER || op==SB_DIV || op==SB_IDIV || op==SB_MOD) { ch = Get_Token(); i1 = Exec_Exp4(&temp); switch (op) { case SB_ASTER: if (fflag) { d = *dbl * temp; *dbl=d; r=(int) d; } else { r = r * i1; *dbl=r; } break; case SB_DIV: if ((fflag==1 && temp==0.0) || (fflag==0 && i1==0)) { strcpy(ErrorMsg, "Division By Zero"); Eflag=1; return 0; } if (fflag) { d = *dbl / temp; } else { d = (double) r / i1; fflag=1; } *dbl=d; r=d; break; case SB_IDIV: if ((fflag==1 && temp==0.0) || (fflag==0 && i1==0)) { strcpy(ErrorMsg, "Division By Zero"); Eflag=1; return 0; } if (fflag) { r = *dbl / temp; } else { r = r / i1; } *dbl=r; break; case SB_MOD: if (fflag) { //r = *dbl % temp; r=0; //Like VBScript } else { r = r % i1; } break; } op = Tok; } else { break; } } return r; } //***************************************************************** int Exec_Exp4(double *dbl) { //***************************************************************** int r, i1; double temp, x; char op, ch; r = Exec_Exp5(dbl); op = Tok; if (op==SB_EXP) { if (fflag) x=*dbl; else x=(double) r; ch = Get_Token(); i1 = Exec_Exp4(&temp); if (fflag) { if (temp==0) { *dbl=1.0; return 1; } } else { if (i1==0) { *dbl=1.0; return 1; } } if (fflag) { *dbl = pow(x, temp); r=0; } else { r = pow(x, i1); } } return r; } //***************************************************************** int Exec_Exp5(double *dbl) { //***************************************************************** char op, x; int r; op = Tok; if (op==SB_MINUS || op==SB_PLUS) x = Get_Token(); r = Exec_Exp6(dbl); if (op==SB_MINUS) { if (fflag) { *dbl *= -1; } else { r = -r; } } return r; } //***************************************************************** int Exec_Exp6(double *dbl) { //***************************************************************** char op, x; int r; op = Tok; if (op==SB_OSQR) { x = Get_Token(); r = Exec_Exp2(dbl); x = Get_Token(); // Throw SB_CSQR } else { r = Atom(dbl); } return r; } //***************************************************************** int Atom(double *dbl) { //***************************************************************** int n, r; char *s, x; unsigned char op; double d; r=0; d=0.0; op=Tok; switch (op) { case SB_ARRAY0: n = (int) Get_Token(); r=Exec_Iarray(n-48); break; case SB_ARRAY1: n = (int) Get_Token(); d=Exec_Narray(n-48); break; case SB_ARRAY2: n = (int) Get_Token(); s=Exec_Sarray(n-48); if (Eflag==1) break; if (s!=NULL) { d=atof(s); r=atoi(s); } break; case SB_ASC: r = Exec_ASC(); break; case SB_LEN: r = Exec_LEN(); break; case SB_INSTR: r = Exec_INSTR(0); break; case SB_INSTR1: r = Exec_INSTR(1); break; case SB_PARSECOUNT1: r = Exec_PARSECOUNT(0); break; case SB_PARSECOUNT2: r = Exec_PARSECOUNT(1); break; case SB_VAL: r = Exec_VAL(&d); break; case SB_CALL: Exec_CALL(); if (Rflag) { while (x!=SB_EOL) x = Get_Token(); Put_Back(); break; } d = atof(ixx); r = atoi(ixx); break; case SB_CONST1: n=(int) Get_Token(); r = --n; break; case SB_CONST2: n=(int) Get_Token(); d = atof(Consts[n - 1]); break; case SB_ERR: r = Rflag; Rflag=0; break; default: x = (op & 0x80); if (x) { x=(op & 0x7f); if (x > 80) { x-=80; strcpy(ixx, VarStr[x]); } else { if (x>40) { x-=40; d=VarFloat[x]; } else { r=VarInteger[x]; } } } else { Eflag=1; } break; } if (Eflag==1) { if (strlen(ErrorMsg)==0) strcpy(ErrorMsg, "Error In Atom"); } if (d) { r=d; if (d!=r) fflag=1; } else { d=r; } x = Get_Token(); *dbl=d; return r; } //***************************************************************** void Exec_ASSIGN() { //***************************************************************** double r; int n, x; unsigned char ch; char *s; ch = Get_Token(); x=(ch & 0x7f); if (x>80) { x-=80; sixx=ixx; Exec_StrExp(); free(VarStr[x]); VarStr[x] = (char *) malloc(strlen(sixx) + 1); strcpy(VarStr[x], sixx); } else { if (x>40) { x-=40; n = Exec_Exp(&r); VarFloat[x]=r; } else { n = Exec_Exp(&r); VarInteger[x]=n; } } if (Eflag==1) return; } //***************************************************************** void Exec_PRINT() { //***************************************************************** char *s, ch; ch=Get_Token(); if (ch==SB_EOL) { printf("\n"); return; } Put_Back(); s=ixx; Exec_StrExp(); printf("%s", s); ixx=s; } //***************************************************************** void Exec_GOTO() { //***************************************************************** int n; char ch; ch = Get_Token(); n = ch; if (n > SB_NUM_LAB) { Eflag=1; return; } n = Label_Table[n]; if (n <= 0) { Eflag=1; strcpy(ErrorMsg, "Invalid GOTO pointer"); return; } ProgPtr = n; } //***************************************************************** void Exec_xGOTO() { //***************************************************************** unsigned char ch; ch = Get_Token(); if (ch > 64) { ch-=64; ProgPtr = IF_TABLE[ch][1] - 1; } else { if (IF_TABLE[ch][0] > 1) { ProgPtr = IF_TABLE[ch][0] - 1; } else { ProgPtr = IF_TABLE[ch][1] - 1; } } if (ProgPtr <= 0) { Eflag=1; strcpy(ErrorMsg, "Invalid XGOTO pointer"); } } //***************************************************************** void gPush() { //***************************************************************** if (gtos >= SB_SUB_NEST) { strcpy(ErrorMsg, "Too Many Nested GoSub"); Eflag=1; return; } gStack[gtos++] = ProgPtr; } //***************************************************************** int gPop() { //***************************************************************** if (gtos == 0) { strcpy(ErrorMsg, "Return Without GOSUB"); Eflag=1; return 1; } return gStack[--gtos]; } //***************************************************************** void Exec_GOSUB() { //***************************************************************** int n; char ch; ch = Get_Token(); n = ch; if (n > SB_NUM_LAB) { Eflag=1; return; } n = Label_Table[n]; if (n <= 0) { Eflag=1; strcpy(ErrorMsg, "Invalid GOSUB pointer"); return; } gPush(); ProgPtr = n; } //***************************************************************** void Exec_RETURN() { //***************************************************************** ProgPtr = gPop(); } //***************************************************************** void fPush(int f[]) { //***************************************************************** int i; ftos++; if (ftos >= SB_FOR_NEST) { strcpy(ErrorMsg, "Too Many FOR"); Eflag=1; return; } for (i=0; i<4; i++) fStack[ftos][i]=f[i]; } //***************************************************************** void Exec_FOR() { //***************************************************************** int r, x, xTO, n; unsigned char ch1, ch2; int f[4]; double dbl; ch1=Get_Token(); n = (int) (ch1 & 0x7f); f[0] = n; r = Exec_Exp(&dbl); VarInteger[n] = r; xTO = Exec_Exp(&dbl); f[1] = xTO; x=Exec_Exp(&dbl); f[3] = x; if (x > 0 && xTO >= r) { f[2] = ProgPtr; fPush(f); return; } if (x < 0 && xTO <= r) { f[2] = ProgPtr; fPush(f); return; } ch1 = SB_NEXT; while (Tok != ch1) { ch2 = Get_Token(); } } //***************************************************************** void Exec_NEXT() { //***************************************************************** int f[4], ix, i; //fPop(); if (ftos==0) { strcpy(ErrorMsg, "NEXT Without FOR"); Eflag=1; return; } for (i=0; i<4; i++) f[i]=fStack[ftos][i]; ftos--; ix = f[0]; VarInteger[ix] += f[3]; if (f[3] > 0 && VarInteger[f[0]] > f[1]) return; if (f[3] < 0 && VarInteger[f[0]] < f[1]) return; fPush(f); ProgPtr=f[2]; } //***************************************************************** void Exec_FORMAT() { //***************************************************************** char *s; s=ixx; Exec_StrExp(); ixx=s; strncpy(bFormat, ixx, 10); } //***************************************************************** void Exec_SLEEP() { //***************************************************************** char ch; int n; double r; n = Exec_Exp(&r); if (n<1) return; sleep(n); } //***************************************************************** int Exec_END() { //***************************************************************** char ch; int n; double r; ch = Get_Token(); if (ch==SB_EOL) return 0; Put_Back(); n = Exec_Exp(&r); if (r) { return (int) r; } else { return n; } } //***************************************************************** void Exec_RAISE() { //***************************************************************** char *s; s=ixx; Exec_StrExp(); ixx=s; Eflag=1; strcpy(ErrorMsg, ixx); } //***************************************************************** void Exec_RUN() { //***************************************************************** char *s; unsigned char ch; int n; for (n=0; n<=9; n++) { if (argz[n]) free(argz[n]); argz[n]=NULL; } s=ixx; Exec_StrExp(); ixx=s; strcpy(xrun, ixx); n=0; while (1) { if (n>9) { Eflag=1; strcpy(ErrorMsg, "Too many parameters"); return; } ch=Get_Token(); if (Tok==SB_XCALL) break; Put_Back(); s=ixx; Exec_StrExp(); argz[n]=malloc(strlen(s) + 1); strcpy(argz[n], s); ixx++; n++; } argn=n; } //***************************************************************** void Exec_IF() { //***************************************************************** int r; r = Exec_Test(); if (r !=0) ProgPtr+=2; } //***************************************************************** int parsecount(char *s1, char *s2, int x) { //***************************************************************** int i, i2, count, ln1, ln2; ln1=strlen(s1); ln2=strlen(s2); count=1; for (i=0; i <= (ln1-ln2); i++) { i2=0; while (i2 < ln2) { if (x) { if (s1[i] == s2[i2]) break; } else { if ((int) s1[i + i2] != (int) s2[i2]) break; } i2++; } if (x==0) { if (i2==ln2) count++; } else { if (i2!=ln2) count++; } } return count; } int do_loop(int cbflag) { int ret, i, n, n1, Result; unsigned char ch; char *z, x; double dbl; Rflag=0; ret=0; while (1) { ixx=linebuffer; if (Rflag==2) {Eflag=1; strcpy(ErrorMsg, "Uncaught Error");} if (Rflag) Rflag=2; if (Eflag==1) {xrun[0]='\0'; break;} ch=Get_Token(); if (ch >= 128) { strcpy(ErrorMsg, "Token Error"); Eflag=1; break; } switch (ch) { case SB_EOL: // do nothing break; case SB_ASSIGN: Exec_ASSIGN(); break; case SB_ASSIGNARRAY: x = Get_Token(); n1 = (int) Get_Token(); n1-=48; n = Exec_Exp(&dbl); switch (x) { case 48: if (n > ubI[n1]) { Eflag=1; break;} Result = Exec_Exp(&dbl); IX[n1][n] = Result; break; case 49: if (n > ubN[n1]) { Eflag=1; break;} Result = Exec_Exp(&dbl); NX[n1][n] = dbl; break; case 50: if (n > ubS[n1]) { Eflag=1; break;} z=ixx; Exec_StrExp(); if (SX[n1][n]) free(SX[n1][n]); SX[n1][n] = (char *) malloc(strlen(z) + 1); strcpy(SX[n1][n], z); break; } if (Eflag) strcpy(ErrorMsg, "Bounds Error"); break; case SB_DIM: x = Get_Token(); n1 = (int) Get_Token(); n = Exec_Exp(&dbl); if (n<1) break; n1-=48; //if (n > somelimit) {Eflag=1; break;} switch (x) { case 48: if (ubI[n1] > 0) free(IX[n1]); IX[n1] = (int *) malloc((n+1) * sizeof(int)); ubI[n1] = n; for (i=0; i<=n; i++) IX[n1][i]=0; break; case 49: if (ubN[n1] > 0) free(NX[n1]); NX[n1] = (double *) malloc((n+1) * sizeof(double)); ubN[n1] = n; for (i=0; i<=n; i++) NX[n1][i]=0; break; case 50: if (ubS[n1] > 0) { for (i=0; i<=ubS[n1]; i++) { free(SX[n1][i]); SX[n1][i]=NULL;} } SX[n1] = (char **) malloc((n+1) * sizeof(char *)); ubS[n1] = n; for (i=0; i<=n; i++) SX[n1][i]=NULL; break; } //if (Eflag) strcpy(ErrorMsg, "Exceeds bounds limit"); break; case SB_PRINT: Exec_PRINT(); break; case SB_GOTO: Exec_GOTO(); break; case SB_xGOTO: Exec_xGOTO(); break; case SB_GOSUB: Exec_GOSUB(); break; case SB_RETURN: if (cbflag) return 0; Exec_RETURN(); break; case SB_FOR: Exec_FOR(); break; case SB_NEXT: Exec_NEXT(); break; case SB_IF: Exec_IF(); break; case SB_IMPORT: Exec_IMPORT(); break; case SB_FORMAT: Exec_FORMAT(); break; case SB_SLEEP: Exec_SLEEP(); break; case SB_RAISE: Exec_RAISE(); break; case SB_RUN: Exec_RUN(); return 0; break; case SB_END: if (cbflag==0) xrun[0]='\0'; return Exec_END(); break; case SB_FINISHED: if (cbflag==0) xrun[0]='\0'; return 0; break; default: strcpy(ErrorMsg, "Unknown Token"); Eflag=1; break; } } } /* char * __cdecl _tstrun(char *proc, int *status, int argn, char **argz); char * __cdecl _librun(char *proc, int *status, int argn, char **argz); */ char * __cdecl librun(char *proc, int *status, int argn, char **argz); char * __cdecl tstrun(char *proc, int *status, int argn, char **argz); int xsize; //***************************************************************** int Exec_xRun(char *s) { //***************************************************************** int c, n, count, ln, Result; int b; unsigned char b1, b2, ch; int sections[3], i, i1, sep; char *p, *z, x; double dbl; for (i=0; i
SB_NUM_LAB) return -2; c=0; for (count=0; count
SB_NUM_IF) return -3; b=sections[0]+2; c=1; for (count=0; count
t1) x=1; } } e=0; if (x>0) { //Compile strcpy(fname, arg1); strcat(fname, ".sd"); s=getfile(fname, &e); if (e) {printf("Unable To Open File %s\n", fname); exit(EXIT_FAILURE);} z=Exec_Compile(s, &xsize, &e); //e=Exec_Compile(s, z); } if (e==0) { strcpy(fname, arg1); strcat(fname, ".sdx"); if (x > 0) { e=write_pcode(fname, z); if (e) printf("Error Write pCode\n"); } else { z=getfile(fname, &e); } e=Exec_xRun(z); if (x > 0) free(s); free(z); } if (e==0) { if (strlen(xrun)) { arg1=xrun; goto run_again; } } exit(e); }