Commit 3bce7d21 by kollo

fixed Johns issue (2016-12-05) with EXIT

parent 0f2732ae
......@@ -179,6 +179,9 @@ DESCRIPTION:
select statement. This is the preferred way of leaving such a
statement (rather than goto).
COMMENT:
BREAK cannot be used in direct mode. Use EXIT instead.
EXAMPLE:
DO
INC i
......@@ -189,7 +192,6 @@ EXAMPLE:
LOOP
SEE ALSO: EXIT IF
##############################################################################
Command: BSAVE
......
......@@ -577,14 +577,13 @@ Syntax: EXIT
DESCRIPTION:
The command EXIT will either exit a loop, return from a procedure or
subroutine, or quit the interpreter.
WHILE, REPEAT, DO and FOR loops can be
aborted prematurely with the EXIT command. Here it has the same
fuinction as BREAK. EXIT leaves the current
EXIT will either exit a loop, return from a procedure or
subroutine, quit a SELECT/ENDSELECT structure, or quit the interpreter.
WHILE, REPEAT, DO and FOR loops can be aborted prematurely with the EXIT
command. Here it has the same function as BREAK. EXIT leaves the current
(innermost) loop immediately. Outside a loop, but insidde a procedure
or function, that procedure or function is left, like with RETURN.
Outside any procedure or function, or invoked from the direct mode
Outside any procedure or function or loop, or invoked from the direct mode
EXIT has the same effect like QUIT.
SEE ALSO: EXIT IF, BREAK, RETURN, QUIT
......@@ -594,14 +593,15 @@ Syntax: EXIT IF <expression>
DESCRIPTION:
The innermost loop will be exited if the expression is true.
WHILE, REPEAT, DO and FOR loops can be
aborted prematurely with the EXIT command. EXIT leaves the current
(innermost) loop immediately. EXIT IF leaves the current loop only if
the expression after EXIT IF is not FALSE (not null).
SEE ALSO: DO, WHILE, FOR, REPEAT, BREAK, IF
The innermost loop will be left if the expression is true.
WHILE, REPEAT, DO and FOR loops can be aborted prematurely with the
EXIT IF statement. EXIT IF leaves the current (innermost) loop immediately,
if the expression after EXIT IF is not FALSE (not null).
COMMENT:
EXIT IF cannot be used in direct mode.
SEE ALSO: DO, WHILE, FOR, REPEAT, BREAK, IF, EXIT
##############################################################################
Function: EXP()
......
......@@ -2210,48 +2210,28 @@ static int do_break() {
if(pc<=0) return(0);
int i=pcode[pc-1].integer;
if(i==-1) {
int f=0,o;
for(i=pc; (i<prglen && i>=0);i++) {
o=pcode[i].opcode&PM_SPECIAL;
if((o==P_LOOP || o==P_NEXT || o==P_WEND || o==P_UNTIL) && f<=0) break;
if(o & P_LEVELIN) f++;
if(o & P_LEVELOUT) f--;
}
if(i==prglen) return(0);
i=sucheloopend(pc);
if(i<0) return(0);
pc=i+1;
} else pc=i;
return(1);
}
static void c_break() {
if(pc<=0) {xberror(38,"BREAK"); /* Befehl im Direktmodus nicht moeglich */ return;}
int i=pcode[pc-1].integer;
if(i==-1) {
int f=0,o;
for(i=pc; (i<prglen && i>=0);i++) {
o=pcode[i].opcode&PM_SPECIAL;
if((o==P_LOOP || o==P_NEXT || o==P_WEND || o==P_UNTIL) && f<=0) break;
if(o & P_LEVELIN) f++;
if(o & P_LEVELOUT) f--;
}
if(i==prglen) { xberror(36,"BREAK/EXIT IF"); /*Programmstruktur fehlerhaft */return;}
pc=i+1;
} else pc=i;
}
/* EXIT --- same as return or quit
EXIT IF <expression> */
static void c_exit(PARAMETER *plist,int e) {
// printf("c_exit: %d\n",e);
// dump_parameterlist(plist,e);
if(pc<=0) {c_quit(NULL,0);} /* Im Direktmodus f"uhrt das zum Beenden des Interpreters.*/
if(e==0) {
if(do_break()) return;
if(do_return()) return;
c_quit(NULL,0);
c_quit(NULL,0); /* Im Direktmodus und ausserhalb von Schleifen und proceduren
f"uhrt das zum Beenden des Interpreters.*/
}
/* EXIT IF ... */
if(plist->integer) {
if(do_break()==0) xberror(36,"EXIT IF"); /*Programmstruktur fehlerhaft */
}
if(plist->integer) c_break();
}
......
......@@ -810,14 +810,8 @@ int init_program(int prglen) {
case P_BREAK:
case P_EXIT:
case P_EXITIF: { /* Suche ende Schleife*/
int j,f=0,o=0;
for(j=i+1; (j<prglen && j>=0);j++) {
o=pcode[j].opcode&PM_SPECIAL;
if((o==P_LOOP || o==P_NEXT || o==P_WEND || o==P_UNTIL|| o==P_ENDSELECT) && f<=0) break;
if(o & P_LEVELIN) f++;
if(o & P_LEVELOUT) f--;
}
if(j==prglen) {
int j=sucheloopend(i+1);
if(j<0) {
if((pcode[i].opcode&PM_SPECIAL)==P_EXIT) {
/*EXIT ohne Parameter dann als normales Kommando aufrufen.*/
pcode[i].opcode=P_PLISTE|(pcode[i].opcode&PM_COMMS);
......@@ -829,8 +823,8 @@ int init_program(int prglen) {
}
} else {
/* Ansonsten EXIT ohne Parameter wie BREAK behandeln */
if((pcode[i].opcode&PM_SPECIAL)==P_EXIT) pcode[i].opcode=P_BREAK|(pcode[i].opcode&PM_COMMS);
if(o==P_ENDSELECT) pcode[i].integer=j; /* wichtig fuer compiler !*/
if((pcode[i].opcode&PM_SPECIAL)==P_EXIT) pcode[i].opcode=P_BREAK|(pcode[i].opcode&PM_COMMS);
if((pcode[j].opcode&PM_SPECIAL)==P_ENDSELECT) pcode[i].integer=j; /* wichtig fuer compiler !*/
else pcode[i].integer=j+1;
}
} break;
......
......@@ -342,12 +342,26 @@ inline static int suchep(int begin, int richtung, int such, int w1, int w2) {
for(i=begin; (i<prglen && i>=0);i+=richtung) {
o=pcode[i].opcode&PM_SPECIAL;
if(o==such && f==0) return(i);
else if(o==w1) f++;
if(o==w1) f++;
else if(o==w2) f--;
}
return(-1);
}
inline static int sucheloopend(int begin) {
int i,f=0,o;
for(i=begin; i<prglen;i++) {
o=pcode[i].opcode&PM_SPECIAL;
if((o==P_LOOP || o==P_NEXT || o==P_WEND || o==P_UNTIL|| o==P_ENDSELECT) && f==0) return(i);
if(o==P_DO || o==P_FOR || o==P_WHILE || o==P_REPEAT|| o==P_SELECT) f++;
else if(o==P_LOOP || o==P_NEXT || o==P_WEND || o==P_UNTIL|| o==P_ENDSELECT) f--;
}
return(-1);
}
inline static int procnr(const char *n,int typ) {
register int i=anzprocs;
while(--i>=0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment