"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "bas.c" between
bas-2.5.tar.gz and bas-2.6.tar.gz

About: bas is an interpreter for the programming language BASIC.

bas.c  (bas-2.5):bas.c  (bas-2.6)
skipping to change at line 78 skipping to change at line 78
}; };
/*}}}*/ /*}}}*/
/* variables */ /*{{{*/ /* variables */ /*{{{*/
static unsigned int labelStackPointer,labelStackCapacity; static unsigned int labelStackPointer,labelStackCapacity;
static struct LabelStack *labelStack; static struct LabelStack *labelStack;
static struct Pc *lastdata; static struct Pc *lastdata;
static struct Pc curdata; static struct Pc curdata;
static struct Pc nextdata; static struct Pc nextdata;
static enum { DECLARE, COMPILE, INTERPRET } pass; static enum { DECLARE, COMPILE, INTERPRET } pass;
static int stopped; static int stopped;
static int optionbase; static long int optionbase;
static struct Pc pc; static struct Pc pc;
static struct Auto stack; static struct Auto stack;
static struct Program program; static struct Program program;
static struct Global globals; static struct Global globals;
static int run_restricted; static int run_restricted;
int bas_argc; int bas_argc;
char *bas_argv0; char *bas_argv0;
char **bas_argv; char **bas_argv;
int bas_end; int bas_end;
skipping to change at line 431 skipping to change at line 431
if (!r) Value_new_VOID(value); if (!r) Value_new_VOID(value);
} }
else Value_new_null(value,sym->u.sub.retType); else Value_new_null(value,sym->u.sub.retType);
} }
Auto_funcReturn(&stack,pass==INTERPRET && value->type!=V_ERROR ? &pc : (stru ct Pc*)0); Auto_funcReturn(&stack,pass==INTERPRET && value->type!=V_ERROR ? &pc : (stru ct Pc*)0);
} }
return value; return value;
} }
/*}}}*/ /*}}}*/
#ifdef USE_LR0
/* Grammar with LR(0) sets */ /*{{{*/
/*
Grammar:
1 EV -> E
2 E -> E op E
3 E -> op E
4 E -> ( E )
5 E -> value
i0:
EV -> . E goto(0,E)=5
E -> . E op E goto(0,E)=5
E -> . op E +,- shift 2
E -> . ( E ) ( shift 3
E -> . value value shift 4
i5:
EV -> E . else accept
E -> E . op E op shift 1
i2:
E -> op . E goto(2,E)=6
E -> . E op E goto(2,E)=6
E -> . op E +,- shift 2
E -> . ( E ) ( shift 3
E -> . value value shift 4
i3:
E -> ( . E ) goto(3,E)=7
E -> . E op E goto(3,E)=7
E -> . op E +,- shift 2
E -> . ( E ) ( shift 3
E -> . value value shift 4
i4:
E -> value . reduce 5
i1:
E -> E op . E goto(1,E)=8
E -> . E op E goto(1,E)=8
E -> . op E +,- shift 2
E -> . ( E ) ( shift 3
E -> . value value shift 4
i6:
E -> op E . reduce 3
E -> E . op E op* shift 1 *=if stack[-2] contains op of unary lower prior
ity
i7:
E -> ( E . ) ) shift 9
E -> E . op E op shift 1
i8:
E -> E op E . reduce 2
E -> E . op E op* shift 1 *=if stack[-2] contains op of lower priority or
if
if it is of equal priority and right associat
ive
i9:
E -> ( E ) . reduce 4
*/
/*}}}*/
static struct Value *eval(struct Value *value, const char *desc) /*{{{*/
{
/* variables */ /*{{{*/
static const int gotoState[10]={ 5,8,6,7,-1,-1,-1,-1,-1,-1 };
int capacity=10;
struct Pdastack
{
union
{
enum TokenType token;
struct Value value;
} u;
char state;
};
struct Pdastack *pdastack=malloc(capacity*sizeof(struct Pdastack));
struct Pdastack *sp=pdastack;
struct Pdastack *stackEnd=pdastack+capacity-1;
enum TokenType ip;
/*}}}*/
sp->state=0;
while (1)
{
if (sp==stackEnd)
{
pdastack=realloc(pdastack,(capacity+10)*sizeof(struct Pdastack));
sp=pdastack+capacity-1;
capacity+=10;
stackEnd=pdastack+capacity-1;
}
ip=pc.token->type;
switch (sp->state)
{
case 0:
case 1:
case 2:
case 3: /*{{{*/ /* including 4 */
{
if (ip==T_IDENTIFIER) /*{{{*/
{
/* printf("state %d: shift 4\n",sp->state); */
/* printf("state 4: reduce E -> value\n"); */
++sp;
sp->state=gotoState[(sp-1)->state];
if (pass==COMPILE)
{
if
(
((pc.token+1)->type==T_OP || Auto_find(&stack,pc.token->u.identifi
er)==0)
&& Global_find(&globals,pc.token->u.identifier,(pc.token+1)->type=
=T_OP)==0
)
{
Value_new_ERROR(value,UNDECLARED);
goto error;
}
}
if (pass!=DECLARE && (pc.token->u.identifier->sym->type==GLOBALVAR ||
pc.token->u.identifier->sym->type==GLOBALARRAY || pc.token->u.identifier->sym->t
ype==LOCALVAR))
{
struct Value *l;
if ((l=lvalue(value))->type==V_ERROR) goto error;
Value_clone(&sp->u.value,l);
}
else
{
struct Pc var=pc;
func(&sp->u.value);
if (sp->u.value.type==V_VOID)
{
pc=var;
Value_new_ERROR(value,VOIDVALUE);
goto error;
}
}
}
/*}}}*/
else if (ip==T_INTEGER) /*{{{*/
{
/* printf("state %d: shift 4\n",sp->state); */
/* printf("state 4: reduce E -> value\n"); */
++sp;
sp->state=gotoState[(sp-1)->state];
VALUE_NEW_INTEGER(&sp->u.value,pc.token->u.integer);
++pc.token;
}
/*}}}*/
else if (ip==T_REAL) /*{{{*/
{
/* printf("state %d: shift 4\n",sp->state); */
/* printf("state 4: reduce E -> value\n"); */
++sp;
sp->state=gotoState[(sp-1)->state];
VALUE_NEW_REAL(&sp->u.value,pc.token->u.real);
++pc.token;
}
/*}}}*/
else if (TOKEN_ISUNARYOPERATOR(ip)) /*{{{*/
{
/* printf("state %d: shift 2\n",sp->state); */
++sp;
sp->state=2;
sp->u.token=ip;
++pc.token;
}
/*}}}*/
else if (ip==T_HEXINTEGER) /*{{{*/
{
/* printf("state %d: shift 4\n",sp->state); */
/* printf("state 4: reduce E -> value\n"); */
++sp;
sp->state=gotoState[(sp-1)->state];
VALUE_NEW_INTEGER(&sp->u.value,pc.token->u.hexinteger);
++pc.token;
}
/*}}}*/
else if (ip==T_OCTINTEGER) /*{{{*/
{
/* printf("state %d: shift 4\n",sp->state); */
/* printf("state 4: reduce E -> value\n"); */
++sp;
sp->state=gotoState[(sp-1)->state];
VALUE_NEW_INTEGER(&sp->u.value,pc.token->u.octinteger);
++pc.token;
}
/*}}}*/
else if (ip==T_OP) /*{{{*/
{
/* printf("state %d: shift 3\n",sp->state); */
++sp;
sp->state=3;
sp->u.token=T_OP;
++pc.token;
}
/*}}}*/
else if (ip==T_STRING) /*{{{*/
{
/* printf("state %d: shift 4\n",sp->state); */
/* printf("state 4: reduce E -> value\n"); */
++sp;
sp->state=gotoState[(sp-1)->state];
Value_new_STRING(&sp->u.value);
String_destroy(&sp->u.value.u.string);
String_clone(&sp->u.value.u.string,pc.token->u.string);
++pc.token;
}
/*}}}*/
else /*{{{*/
{
char state=sp->state;
if (state==0)
{
if (desc) Value_new_ERROR(value,MISSINGEXPR,desc);
else value=(struct Value*)0;
}
else Value_new_ERROR(value,MISSINGEXPR,_("operand"));
goto error;
}
/*}}}*/
break;
}
/*}}}*/
case 5: /*{{{*/
{
if (TOKEN_ISBINARYOPERATOR(ip))
{
/* printf("state %d: shift 1\n",sp->state); */
++sp;
sp->state=1;
sp->u.token=ip;
++pc.token;
break;
}
else
{
assert(sp==pdastack+1);
*value=sp->u.value;
free(pdastack);
return value;
}
break;
}
/*}}}*/
case 6: /*{{{*/
{
if (TOKEN_ISBINARYOPERATOR(ip) && TOKEN_UNARYPRIORITY((sp-1)->u.token)<T
OKEN_BINARYPRIORITY(ip))
{
assert(TOKEN_ISUNARYOPERATOR((sp-1)->u.token));
/* printf("state %d: shift 1 (not reducing E -> op E)\n",sp->state); *
/
++sp;
sp->state=1;
sp->u.token=ip;
++pc.token;
}
else
{
enum TokenType op;
/* printf("reduce E -> op E\n"); */
--sp;
op=sp->u.token;
sp->u.value=(sp+1)->u.value;
switch (op)
{
case T_PLUS: break;
case T_MINUS: Value_uneg(&sp->u.value,pass==INTERPRET); break;
case T_NOT: Value_unot(&sp->u.value,pass==INTERPRET); break;
default: assert(0);
}
sp->state=gotoState[(sp-1)->state];
if (sp->u.value.type==V_ERROR)
{
*value=sp->u.value;
--sp;
goto error;
}
}
break;
}
/*}}}*/
case 7: /*{{{*/ /* including 9 */
{
if (TOKEN_ISBINARYOPERATOR(ip))
{
/* printf("state %d: shift 1\n"sp->state); */
++sp;
sp->state=1;
sp->u.token=ip;
++pc.token;
}
else if (ip==T_CP)
{
/* printf("state %d: shift 9\n",sp->state); */
/* printf("state 9: reduce E -> ( E )\n"); */
--sp;
sp->state=gotoState[(sp-1)->state];
sp->u.value=(sp+1)->u.value;
++pc.token;
}
else
{
Value_new_ERROR(value,MISSINGCP);
goto error;
}
break;
}
/*}}}*/
case 8: /*{{{*/
{
int p1,p2;
if
(
TOKEN_ISBINARYOPERATOR(ip)
&&
(
((p1=TOKEN_BINARYPRIORITY((sp-1)->u.token))<(p2=TOKEN_BINARYPRIORITY
(ip)))
|| (p1==p2 && TOKEN_ISRIGHTASSOCIATIVE((sp-1)->u.token))
)
)
{
/* printf("state %d: shift 1\n",sp->state); */
++sp;
sp->state=1;
sp->u.token=ip;
++pc.token;
}
else
{
/* printf("state %d: reduce E -> E op E\n",sp->state); */
if (Value_commonType[(sp-2)->u.value.type][sp->u.value.type]==V_ERROR)
{
Value_destroy(&sp->u.value);
sp-=2;
Value_destroy(&sp->u.value);
Value_new_ERROR(value,INVALIDOPERAND);
--sp;
goto error;
}
else switch ((sp-1)->u.token)
{
case T_LT: Value_lt(&(sp-2)->u.value,&sp->u.value,pass==INTERPRET
); break;
case T_LE: Value_le(&(sp-2)->u.value,&sp->u.value,pass==INTERPRET
); break;
case T_EQ: Value_eq(&(sp-2)->u.value,&sp->u.value,pass==INTERPRET
); break;
case T_GE: Value_ge(&(sp-2)->u.value,&sp->u.value,pass==INTERPRET
); break;
case T_GT: Value_gt(&(sp-2)->u.value,&sp->u.value,pass==INTERPRET
); break;
case T_NE: Value_ne(&(sp-2)->u.value,&sp->u.value,pass==INTERPRET
); break;
case T_PLUS: Value_add(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
case T_MINUS: Value_sub(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
case T_MULT: Value_mult(&(sp-2)->u.value,&sp->u.value,pass==INTERPR
ET); break;
case T_DIV: Value_div(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
case T_IDIV: Value_idiv(&(sp-2)->u.value,&sp->u.value,pass==INTERPR
ET); break;
case T_MOD: Value_mod(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
case T_POW: Value_pow(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
case T_AND: Value_and(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
case T_OR: Value_or(&(sp-2)->u.value,&sp->u.value,pass==INTERPRET
); break;
case T_XOR: Value_xor(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
case T_EQV: Value_eqv(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
case T_IMP: Value_imp(&(sp-2)->u.value,&sp->u.value,pass==INTERPRE
T); break;
default: assert(0);
}
Value_destroy(&sp->u.value);
sp-=2;
sp->state=gotoState[(sp-1)->state];
if (sp->u.value.type==V_ERROR)
{
*value=sp->u.value;
--sp;
goto error;
}
}
break;
}
/*}}}*/
}
}
error:
while (sp>pdastack)
{
switch (sp->state)
{
case 5:
case 6:
case 7:
case 8: Value_destroy(&sp->u.value);
}
--sp;
}
free(pdastack);
return value;
}
/*}}}*/
#else
static inline struct Value *binarydown(struct Value *value, struct Value *(level )(struct Value *value), const int prio) /*{{{*/ static inline struct Value *binarydown(struct Value *value, struct Value *(level )(struct Value *value), const int prio) /*{{{*/
{ {
enum TokenType op; enum TokenType op;
struct Pc oppc; struct Pc oppc;
if (level(value)==(struct Value*)0) return (struct Value*)0; if (level(value)==(struct Value*)0) return (struct Value*)0;
if (value->type==V_ERROR) return value; if (value->type==V_ERROR) return value;
do do
{ {
struct Value x; struct Value x;
skipping to change at line 1000 skipping to change at line 602
{ {
Value_destroy(value); Value_destroy(value);
return Value_new_ERROR(value,MISSINGCP); return Value_new_ERROR(value,MISSINGCP);
} }
++pc.token; ++pc.token;
break; break;
} }
/*}}}*/ /*}}}*/
default: /*{{{*/ default: /*{{{*/
{ {
return (struct Value *)0; if (TOKEN_ISUNARYOPERATOR(pc.token->type)) return unarydown(value,eval8,6)
;
else return (struct Value *)0;
} }
/*}}}*/ /*}}}*/
} }
return value; return value;
} }
/*}}}*/ /*}}}*/
static struct Value *eval7(struct Value *value) /*{{{*/ static struct Value *eval7(struct Value *value) /*{{{*/
{ {
return binarydown(value,eval8,7); return binarydown(value,eval8,7);
} }
skipping to change at line 1063 skipping to change at line 666
default: break; default: break;
} }
if (binarydown(value,eval1,0)==(struct Value*)0) if (binarydown(value,eval1,0)==(struct Value*)0)
{ {
if (desc) return Value_new_ERROR(value,MISSINGEXPR,desc); if (desc) return Value_new_ERROR(value,MISSINGEXPR,desc);
else return (struct Value*)0; else return (struct Value*)0;
} }
else return value; else return value;
} }
/*}}}*/ /*}}}*/
#endif
static void new(void) /*{{{*/ static void new(void) /*{{{*/
{ {
Global_destroy(&globals); Global_destroy(&globals);
Global_new(&globals); Global_new(&globals);
Auto_destroy(&stack); Auto_destroy(&stack);
Auto_new(&stack); Auto_new(&stack);
Program_destroy(&program); Program_destroy(&program);
Program_new(&program); Program_new(&program);
FS_closefiles(); FS_closefiles();
optionbase=0; optionbase=0;
} }
/*}}}*/ /*}}}*/
static void pushLabel(enum LabelType type, struct Pc *patch) /*{{{*/ static void pushLabel(enum LabelType type, struct Pc *patch) /*{{{*/
{ {
if (labelStackPointer==labelStackCapacity) if (labelStackPointer==labelStackCapacity)
{ {
struct LabelStack *more; struct LabelStack *more;
more=realloc(labelStack,sizeof(struct LabelStack)*(labelStackCapacity?(label StackCapacity*=2):(32))); more=realloc(labelStack,sizeof(struct LabelStack)*(labelStackCapacity?(label StackCapacity*=2):(labelStackCapacity=32)));
labelStack=more; labelStack=more;
} }
assert(labelStackPointer<labelStackCapacity);
labelStack[labelStackPointer].type=type; labelStack[labelStackPointer].type=type;
labelStack[labelStackPointer].patch=*patch; labelStack[labelStackPointer].patch=*patch;
++labelStackPointer; ++labelStackPointer;
} }
/*}}}*/ /*}}}*/
static struct Pc *popLabel(enum LabelType type) /*{{{*/ static struct Pc *popLabel(enum LabelType type) /*{{{*/
{ {
if (labelStackPointer==0 || labelStack[labelStackPointer-1].type!=type) return (struct Pc*)0; if (labelStackPointer==0 || labelStack[labelStackPointer-1].type!=type) return (struct Pc*)0;
else return &labelStack[--labelStackPointer].patch; else return &labelStack[--labelStackPointer].patch;
} }
skipping to change at line 1156 skipping to change at line 759
default: assert(0); default: assert(0);
} }
/* NOTREACHED */ /* NOTREACHED */
return (const char*)0; return (const char*)0;
} }
/*}}}*/ /*}}}*/
static struct Value *assign(struct Value *value) /*{{{*/ static struct Value *assign(struct Value *value) /*{{{*/
{ {
struct Pc expr; struct Pc expr;
assert(pc.token->type==T_IDENTIFIER);
if (strcasecmp(pc.token->u.identifier->name,"mid$")==0) /* mid$(a$,n,m)=b$ */ /*{{{*/ if (strcasecmp(pc.token->u.identifier->name,"mid$")==0) /* mid$(a$,n,m)=b$ */ /*{{{*/
{ {
long int n,m; long int n,m;
struct Value *l; struct Value *l;
++pc.token; ++pc.token;
if (pc.token->type!=T_OP) return Value_new_ERROR(value,MISSINGOP); if (pc.token->type!=T_OP) return Value_new_ERROR(value,MISSINGOP);
++pc.token; ++pc.token;
if (pc.token->type!=T_IDENTIFIER) return Value_new_ERROR(value,MISSINGSTRIDE NT); if (pc.token->type!=T_IDENTIFIER) return Value_new_ERROR(value,MISSINGSTRIDE NT);
if (pass==DECLARE) if (pass==DECLARE)
skipping to change at line 1213 skipping to change at line 817
} }
/*}}}*/ /*}}}*/
else /*{{{*/ else /*{{{*/
{ {
struct Value **l=(struct Value**)0; struct Value **l=(struct Value**)0;
int i, used=0, capacity=0; int i, used=0, capacity=0;
struct Value retyped_value; struct Value retyped_value;
for (;;) for (;;)
{ {
if (pc.token->type!=T_IDENTIFIER) return Value_new_ERROR(value,MISSINGVARI
DENT);
if (used==capacity) if (used==capacity)
{ {
struct Value **more; struct Value **more;
capacity=capacity?2*capacity:2; capacity=capacity?2*capacity:2;
more=realloc(l,capacity*sizeof(*l)); more=realloc(l,capacity*sizeof(*l));
l=more; l=more;
} }
if (pass==DECLARE) if (pass==DECLARE)
skipping to change at line 1693 skipping to change at line 1299
if (line->type!=T_EOL) if (line->type!=T_EOL)
{ {
if (line->type==T_INTEGER && line->u.integer>0) if (line->type==T_INTEGER && line->u.integer>0)
{ {
if (program.numbered) if (program.numbered)
{ {
if ((line+1)->type==T_EOL) if ((line+1)->type==T_EOL)
{ {
struct Pc where; struct Pc where;
if (Program_goLine(&program,line->u.integer,&where)==(struct Pc*)0) FS_putChars(STDCHANNEL,(NOSUCHLINE)); if (Program_goLine(&program,line->u.integer,&where)==(struct Pc*)0) FS_putChars(STDCHANNEL,NOSUCHLINE_MSG);
else Program_delete(&program,&where,&where); else Program_delete(&program,&where,&where);
Token_destroy(line); Token_destroy(line);
} }
else Program_store(&program,line,line->u.integer); else Program_store(&program,line,line->u.integer);
} }
else else
{ {
FS_putChars(STDCHANNEL,_("Use `renum' to number program first")); FS_putChars(STDCHANNEL,_("Use `renum' to number program first"));
Token_destroy(line); Token_destroy(line);
} }
 End of changes. 9 change blocks. 
431 lines changed or deleted 11 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)