1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-08-21 06:29:07 +00:00

More robust stack depth checking and var parsing

This commit is contained in:
David Schmenk 2017-12-24 20:35:39 -08:00
parent 70ba7d0e0e
commit 7843bc41ce
5 changed files with 774 additions and 619 deletions

View File

@ -623,42 +623,15 @@ def emit_pending_seq#0
if not pending_seq; return; fin if not pending_seq; return; fin
lcl_pending = pending_seq lcl_pending = pending_seq
pending_seq = NULL pending_seq = NULL
//if outflags & OPTIMIZE if outflags & OPTIMIZE
// while crunch_seq(@lcl_pending, 0); loop while crunch_seq(@lcl_pending, 0); loop
// while crunch_seq(@lcl_pending, 1); loop if outflags & OPTIMIZE2
//fin while crunch_seq(@lcl_pending, 1); loop
fin
fin
while lcl_pending while lcl_pending
op = lcl_pending op = lcl_pending
when op->code when op->code
is NEG_CODE
is COMP_CODE
is LOGIC_NOT_CODE
is INC_CODE
is DEC_CODE
is BPTR_CODE
is WPTR_CODE
emit_unaryop(op->code)
break
is MUL_CODE
is DIV_CODE
is MOD_CODE
is ADD_CODE
is SUB_CODE
is SHL_CODE
is SHR_CODE
is AND_CODE
is OR_CODE
is EOR_CODE
is EQ_CODE
is NE_CODE
is GE_CODE
is LT_CODE
is GT_CODE
is LE_CODE
is LOGIC_OR_CODE
is LOGIC_AND_CODE
emit_op(op->code)
break
is CONST_CODE is CONST_CODE
emit_const(op=>val) emit_const(op=>val)
break break
@ -755,6 +728,63 @@ def emit_pending_seq#0
is CODETAG_CODE is CODETAG_CODE
printf("_B%03d%c\n", op->tag, LBL); printf("_B%03d%c\n", op->tag, LBL);
break; break;
is NEG_CODE
is COMP_CODE
is LOGIC_NOT_CODE
is INC_CODE
is DEC_CODE
is BPTR_CODE
is WPTR_CODE
emit_unaryop(op->code)
break
is MUL_CODE
is DIV_CODE
is MOD_CODE
is ADD_CODE
is SUB_CODE
is SHL_CODE
is SHR_CODE
is AND_CODE
is OR_CODE
is EOR_CODE
is EQ_CODE
is NE_CODE
is GE_CODE
is LT_CODE
is GT_CODE
is LE_CODE
is LOGIC_OR_CODE
is LOGIC_AND_CODE
emit_op(op->code)
break
is MUL_CODE
is DIV_CODE
is MOD_CODE
is ADD_CODE
is SUB_CODE
is SHL_CODE
is SHR_CODE
is AND_CODE
is OR_CODE
is EOR_CODE
is EQ_CODE
is NE_CODE
is GE_CODE
is LT_CODE
is GT_CODE
is LE_CODE
is LOGIC_OR_CODE
is LOGIC_AND_CODE
emit_op(op->code)
break
is NEG_CODE
is COMP_CODE
is LOGIC_NOT_CODE
is INC_CODE
is DEC_CODE
is BPTR_CODE
is WPTR_CODE
emit_unaryop(op->code)
is NOP_CODE is NOP_CODE
break break
otherwise otherwise
@ -774,10 +804,10 @@ end
def emit_seq(seq)#0 def emit_seq(seq)#0
word op word op
byte string byte string
string = 0 string = FALSE
op = seq op = seq
while op while op
if op->code == STR_CODE; string = 1; fin if op->code == STR_CODE; string = TRUE; break; fin
op = op=>nextop op = op=>nextop
loop loop
pending_seq = cat_seq(pending_seq, seq) pending_seq = cat_seq(pending_seq, seq)
@ -788,6 +818,6 @@ def emit_seq(seq)#0
// //
// We must also force output if the sequence includes a CS opcode, as the // We must also force output if the sequence includes a CS opcode, as the
// associated 'constant' is only temporarily valid. // associated 'constant' is only temporarily valid.
if !(outflags & OPTIMIZE) or (outflags & NO_COMBINE) or string if !(outflags & (OPTIMIZE|OPTIMIZE2)) or (outflags & NO_COMBINE) or string
emit_pending_seq emit_pending_seq
end end

View File

@ -505,12 +505,8 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
cfnparms = 0; cfnvals = 1; cfnparms = 0; cfnvals = 1;
type &= ~FUNC_TYPE; type &= ~FUNC_TYPE;
} }
//while ((idxseq = parse_expr(NULL, stackdepth)))
while ((valseq = parse_expr(valseq, stackdepth)) && scantoken == COMMA_TOKEN) while ((valseq = parse_expr(valseq, stackdepth)) && scantoken == COMMA_TOKEN)
{ {
// valseq = cat_seq(valseq, idxseq);
// if (scantoken != COMMA_TOKEN)
// break;
valseq = gen_idxw(valseq); valseq = gen_idxw(valseq);
valseq = gen_lw(valseq); valseq = gen_lw(valseq);
} }
@ -794,8 +790,13 @@ int parse_stmnt(void)
switch (scantoken) switch (scantoken)
{ {
case IF_TOKEN: case IF_TOKEN:
if (!(seq = parse_expr(NULL, NULL))) if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad expression"); parse_error("Bad expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
tag_else = tag_new(BRANCH_TYPE); tag_else = tag_new(BRANCH_TYPE);
tag_endif = tag_new(BRANCH_TYPE); tag_endif = tag_new(BRANCH_TYPE);
seq = gen_brfls(seq, tag_else); seq = gen_brfls(seq, tag_else);
@ -807,8 +808,13 @@ int parse_stmnt(void)
break; break;
emit_brnch(tag_endif); emit_brnch(tag_endif);
emit_codetag(tag_else); emit_codetag(tag_else);
if (!(seq = parse_expr(NULL, NULL))) if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad expression"); parse_error("Bad expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
tag_else = tag_new(BRANCH_TYPE); tag_else = tag_new(BRANCH_TYPE);
seq = gen_brfls(seq, tag_else); seq = gen_brfls(seq, tag_else);
emit_seq(seq); emit_seq(seq);
@ -837,11 +843,16 @@ int parse_stmnt(void)
tag_prevbrk = break_tag; tag_prevbrk = break_tag;
break_tag = tag_wend; break_tag = tag_wend;
emit_codetag(tag_while); emit_codetag(tag_while);
if (!(seq = parse_expr(NULL, NULL))) if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad expression"); parse_error("Bad expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
seq = gen_brfls(seq, tag_wend); seq = gen_brfls(seq, tag_wend);
emit_seq(seq); emit_seq(seq);
while (parse_stmnt()) next_line(); while (parse_stmnt()) next_line();
if (scantoken != LOOP_TOKEN) if (scantoken != LOOP_TOKEN)
parse_error("Missing WHILE/END"); parse_error("Missing WHILE/END");
emit_brnch(tag_while); emit_brnch(tag_while);
@ -862,8 +873,13 @@ int parse_stmnt(void)
parse_error("Missing REPEAT/UNTIL"); parse_error("Missing REPEAT/UNTIL");
emit_codetag(cont_tag); emit_codetag(cont_tag);
cont_tag = tag_prevcnt; cont_tag = tag_prevcnt;
if (!(seq = parse_expr(NULL, NULL))) if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad expression"); parse_error("Bad expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
seq = gen_brfls(seq, tag_repeat); seq = gen_brfls(seq, tag_repeat);
emit_seq(seq); emit_seq(seq);
emit_codetag(break_tag); emit_codetag(break_tag);
@ -882,8 +898,13 @@ int parse_stmnt(void)
addr = id_tag(tokenstr, tokenlen); addr = id_tag(tokenstr, tokenlen);
if (scan() != SET_TOKEN) if (scan() != SET_TOKEN)
parse_error("Missing FOR ="); parse_error("Missing FOR =");
if (!emit_seq(parse_expr(NULL, NULL))) if (!emit_seq(parse_expr(NULL, &cfnvals)))
parse_error("Bad FOR expression"); parse_error("Bad FOR expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_codetag(tag_for); emit_codetag(tag_for);
if (type & LOCAL_TYPE) if (type & LOCAL_TYPE)
type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr); type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr);
@ -895,13 +916,23 @@ int parse_stmnt(void)
step = -1; step = -1;
else else
parse_error("Missing FOR TO"); parse_error("Missing FOR TO");
if (!emit_seq(parse_expr(NULL, NULL))) if (!emit_seq(parse_expr(NULL, &cfnvals)))
parse_error("Bad FOR TO expression"); parse_error("Bad FOR TO expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag); step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag);
if (scantoken == STEP_TOKEN) if (scantoken == STEP_TOKEN)
{ {
if (!emit_seq(parse_expr(NULL, NULL))) if (!emit_seq(parse_expr(NULL, &cfnvals)))
parse_error("Bad FOR STEP expression"); parse_error("Bad FOR STEP expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN); emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN);
} }
else else
@ -922,15 +953,25 @@ int parse_stmnt(void)
break_tag = tag_new(BRANCH_TYPE); break_tag = tag_new(BRANCH_TYPE);
tag_choice = tag_new(BRANCH_TYPE); tag_choice = tag_new(BRANCH_TYPE);
tag_of = tag_new(BRANCH_TYPE); tag_of = tag_new(BRANCH_TYPE);
if (!emit_seq(parse_expr(NULL, NULL))) if (!emit_seq(parse_expr(NULL, &cfnvals)))
parse_error("Bad CASE expression"); parse_error("Bad CASE expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
next_line(); next_line();
while (scantoken != ENDCASE_TOKEN) while (scantoken != ENDCASE_TOKEN)
{ {
if (scantoken == OF_TOKEN) if (scantoken == OF_TOKEN)
{ {
if (!emit_seq(parse_expr(NULL, NULL))) if (!emit_seq(parse_expr(NULL, &cfnvals)))
parse_error("Bad CASE OF expression"); parse_error("Bad CASE OF expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_brne(tag_choice); emit_brne(tag_choice);
emit_codetag(tag_of); emit_codetag(tag_of);
while (parse_stmnt()) next_line(); while (parse_stmnt()) next_line();
@ -961,18 +1002,18 @@ int parse_stmnt(void)
break_tag = tag_prevbrk; break_tag = tag_prevbrk;
stack_loop--; stack_loop--;
break; break;
case CONTINUE_TOKEN:
if (cont_tag)
emit_brnch(cont_tag);
else
parse_error("CONTINUE without loop");
break;
case BREAK_TOKEN: case BREAK_TOKEN:
if (break_tag) if (break_tag)
emit_brnch(break_tag); emit_brnch(break_tag);
else else
parse_error("BREAK without loop"); parse_error("BREAK without loop");
break; break;
case CONTINUE_TOKEN:
if (cont_tag)
emit_brnch(cont_tag);
else
parse_error("CONTINUE without loop");
break;
case RETURN_TOKEN: case RETURN_TOKEN:
if (infunc) if (infunc)
{ {
@ -993,13 +1034,17 @@ int parse_stmnt(void)
} }
else else
{ {
if (!emit_seq(parse_expr(NULL, NULL))) if (!emit_seq(parse_expr(NULL, &cfnvals)))
emit_const(0); emit_const(0);
else if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_ret(); emit_ret();
} }
break; break;
case EOL_TOKEN: case EOL_TOKEN:
//case COMMENT_TOKEN:
return (1); return (1);
case ELSE_TOKEN: case ELSE_TOKEN:
case ELSEIF_TOKEN: case ELSEIF_TOKEN:
@ -1027,8 +1072,7 @@ int parse_stmnt(void)
{ {
emit_seq(rseq); emit_seq(rseq);
emit_unaryop(scantoken); emit_unaryop(scantoken);
tokenstr = idptr; scan_rewind(idptr);
scan_rewind(tokenstr);
emit_seq(parse_value(NULL, LVALUE, NULL)); emit_seq(parse_value(NULL, LVALUE, NULL));
} }
else if (scantoken != SET_TOKEN) else if (scantoken != SET_TOKEN)
@ -1051,22 +1095,14 @@ int parse_stmnt(void)
} }
return (scan() == EOL_TOKEN); return (scan() == EOL_TOKEN);
} }
int parse_var(int type) int parse_var(int type, long basesize)
{ {
char *idstr; char *idstr;
long constval; long constval;
int consttype, constsize, arraysize, idlen = 0;
long size = 1; long size = 1;
int consttype, constsize, arraysize, idlen = 0;
if (scan() == OPEN_BRACKET_TOKEN) if (scan() == ID_TOKEN)
{
size = 0;
parse_constexpr(&size, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN)
parse_error("Missing closing bracket");
scan();
}
if (scantoken == ID_TOKEN)
{ {
idstr = tokenstr; idstr = tokenstr;
idlen = tokenlen; idlen = tokenlen;
@ -1079,8 +1115,7 @@ int parse_var(int type)
scan(); scan();
} }
} }
if (type & WORD_TYPE) size *= basesize;
size *= 2;
if (scantoken == SET_TOKEN) if (scantoken == SET_TOKEN)
{ {
if (type & (EXTERN_TYPE | LOCAL_TYPE)) if (type & (EXTERN_TYPE | LOCAL_TYPE))
@ -1138,7 +1173,8 @@ int parse_struc(void)
parse_error("Missing closing bracket"); parse_error("Missing closing bracket");
scan(); scan();
} }
do { do
{
idlen = 0; idlen = 0;
if (scantoken == ID_TOKEN) if (scantoken == ID_TOKEN)
{ {
@ -1163,9 +1199,8 @@ int parse_struc(void)
if (struclen) if (struclen)
idconst_add(strucid, struclen, offset); idconst_add(strucid, struclen, offset);
if (scantoken != END_TOKEN) if (scantoken != END_TOKEN)
return (0); parse_error("Missing STRUC/END");
scan(); scan();
return (1);
} }
int parse_vars(int type) int parse_vars(int type)
{ {
@ -1178,7 +1213,7 @@ int parse_vars(int type)
{ {
case SYSFLAGS_TOKEN: case SYSFLAGS_TOKEN:
if (type & (EXTERN_TYPE | LOCAL_TYPE)) if (type & (EXTERN_TYPE | LOCAL_TYPE))
parse_error("sysflags must be global"); parse_error("SYSFLAGS must be global");
if (!parse_constexpr(&value, &size)) if (!parse_constexpr(&value, &size))
parse_error("Bad constant"); parse_error("Bad constant");
emit_sysflags(value); emit_sysflags(value);
@ -1195,8 +1230,7 @@ int parse_vars(int type)
idconst_add(idstr, idlen, value); idconst_add(idstr, idlen, value);
break; break;
case STRUC_TOKEN: case STRUC_TOKEN:
if (!parse_struc()) parse_struc();
parse_error("Bad structure definition");
break; break;
case EXPORT_TOKEN: case EXPORT_TOKEN:
if (type & (EXTERN_TYPE | LOCAL_TYPE)) if (type & (EXTERN_TYPE | LOCAL_TYPE))
@ -1217,86 +1251,63 @@ int parse_vars(int type)
*/ */
case BYTE_TOKEN: case BYTE_TOKEN:
case WORD_TOKEN: case WORD_TOKEN:
type |= (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE; type |= (scantoken == BYTE_TOKEN) ? BYTE_TYPE : WORD_TYPE;
if (!parse_var(type)) cfnvals = 1; // Just co-opt a long variable for this case
return (0); if (scan() == OPEN_BRACKET_TOKEN)
while (scantoken == COMMA_TOKEN)
{ {
if (!parse_var(type)) //
return (0); // Get base size for variables
//
cfnvals = 0;
parse_constexpr(&cfnvals, &size);
if (scantoken != CLOSE_BRACKET_TOKEN)
parse_error("Missing closing bracket");
} }
else
scan_rewind(tokenstr);
if (type & WORD_TYPE)
cfnvals *= 2;
do parse_var(type, cfnvals); while (scantoken == COMMA_TOKEN);
break; break;
case PREDEF_TOKEN: case PREDEF_TOKEN:
/* /*
* Pre definition. * Pre definition.
*/ */
if (scan() == ID_TOKEN) do
{ {
type |= PREDEF_TYPE; if (scan() == ID_TOKEN)
idstr = tokenstr;
idlen = tokenlen;
cfnparms = 0;
cfnvals = 1; // Default to one return value for compatibility
if (scan() == OPEN_PAREN_TOKEN)
{ {
do type = (type & ~FUNC_PARMVALS) | PREDEF_TYPE;
idstr = tokenstr;
idlen = tokenlen;
cfnparms = 0;
cfnvals = 1; // Default to one return value for compatibility
if (scan() == OPEN_PAREN_TOKEN)
{ {
if (scan() == ID_TOKEN) do
{ {
cfnparms++; if (scan() == ID_TOKEN)
scan();
}
} while (scantoken == COMMA_TOKEN);
if (scantoken != CLOSE_PAREN_TOKEN)
parse_error("Bad function parameter list");
scan();
}
if (scantoken == POUND_TOKEN)
{
if (!parse_const(&cfnvals))
parse_error("Invalid def return value count");
scan();
}
type |= funcparms_type(cfnparms) | funcvals_type(cfnvals);
idfunc_add(idstr, idlen, type, tag_new(type));
while (scantoken == COMMA_TOKEN)
{
if (scan() == ID_TOKEN)
{
idstr = tokenstr;
idlen = tokenlen;
type &= ~FUNC_PARMVALS;
cfnparms = 0;
cfnvals = 1; // Default to one return value for compatibility
if (scan() == OPEN_PAREN_TOKEN)
{
do
{ {
if (scan() == ID_TOKEN) cfnparms++;
{ scan();
cfnparms++; }
scan(); } while (scantoken == COMMA_TOKEN);
} if (scantoken != CLOSE_PAREN_TOKEN)
} while (scantoken == COMMA_TOKEN); parse_error("Bad function parameter list");
if (scantoken != CLOSE_PAREN_TOKEN) scan();
parse_error("Bad function parameter list");
scan();
}
if (scantoken == POUND_TOKEN)
{
if (!parse_const(&cfnvals))
parse_error("Invalid def return value count");
scan();
}
type |= funcparms_type(cfnparms) | funcvals_type(cfnvals);
idfunc_add(idstr, idlen, type, tag_new(type));
} }
else if (scantoken == POUND_TOKEN)
parse_error("Bad function pre-declaration"); {
if (!parse_const(&cfnvals))
parse_error("Invalid def return value count");
scan();
}
type |= funcparms_type(cfnparms) | funcvals_type(cfnvals);
idfunc_add(idstr, idlen, type, tag_new(type));
} }
} else
else parse_error("Bad function pre-declaration");
parse_error("Bad function pre-declaration"); } while (scantoken == COMMA_TOKEN);
case EOL_TOKEN: case EOL_TOKEN:
break; break;
default: default:
@ -1315,7 +1326,7 @@ int parse_mods(void)
while (parse_vars(EXTERN_TYPE)) next_line(); while (parse_vars(EXTERN_TYPE)) next_line();
if (scantoken != END_TOKEN) if (scantoken != END_TOKEN)
parse_error("Missing END"); parse_error("Missing END");
return (scan() == EOL_TOKEN); scan();
} }
if (scantoken == EOL_TOKEN) if (scantoken == EOL_TOKEN)
return (1); return (1);
@ -1326,7 +1337,6 @@ int parse_lambda(void)
{ {
int func_tag; int func_tag;
int cfnparms; int cfnparms;
char *expr;
if (!infunc) if (!infunc)
parse_error("Lambda functions only allowed inside definitions"); parse_error("Lambda functions only allowed inside definitions");
@ -1351,7 +1361,6 @@ int parse_lambda(void)
} }
else else
parse_error("Missing parameter list in lambda function"); parse_error("Missing parameter list in lambda function");
expr = scanpos;
if (scan_lookahead() == OPEN_PAREN_TOKEN) if (scan_lookahead() == OPEN_PAREN_TOKEN)
{ {
/* /*

File diff suppressed because it is too large Load Diff

View File

@ -272,17 +272,24 @@ byte no_ctag_offst[] = "CODE OFFSET NOT SUPPORTED"
byte no_close_paren[] = "MISSING CLOSING PAREN" byte no_close_paren[] = "MISSING CLOSING PAREN"
byte no_close_bracket[] = "MISSING CLOSING BRACKET" byte no_close_bracket[] = "MISSING CLOSING BRACKET"
byte missing_op[] = "MISSING OPERAND" byte missing_op[] = "MISSING OPERAND"
byte no_fin[] = "MISSING FIN"
byte no_loop[] = "MISSING LOOP" byte no_loop[] = "MISSING LOOP"
byte no_until[] = "MISSING UNTIL" byte no_until[] = "MISSING UNTIL"
byte no_done[] = "MISSING DONE" byte no_done[] = "MISSING DONE"
byte no_local_init[] = "NO INITIALIZED LOCALS" byte no_local_init[] = "NO INITIALIZED LOCALS"
// //
// Compiler optimizer flags
//
const OPTIMIZE = 1
const OPTIMIZE2 = 2
const NO_COMBINE = 4
byte outflags
//
// ProDOS/SOS file references // ProDOS/SOS file references
// //
byte refnum, srcref, incref byte refnum, srcref, incref
byte[32] srcfile byte[32] srcfile
byte[32] incfile byte[32] incfile
byte[32] relfile
word parsefile // Pointer to current file word parsefile // Pointer to current file
word sysincbuf // System I/O buffer for include files word sysincbuf // System I/O buffer for include files
word srcline // Saved source line number word srcline // Saved source line number
@ -293,6 +300,7 @@ byte[128] strconst
byte infunc = 0 byte infunc = 0
byte stack_loop = 0 byte stack_loop = 0
byte prevstmnt = 0 byte prevstmnt = 0
word infunvals = 0
word retfunc_tag = 0 word retfunc_tag = 0
word break_tag = 0 word break_tag = 0
word cont_tag = 0 word cont_tag = 0
@ -308,6 +316,17 @@ word exit
// //
//===================================== //=====================================
//
// Handy functions
//
def strcpy(dst, src)
if ^src
memcpy(dst, src, ^src + 1)
else
^dst = 0
fin
return ^dst
end
// //
// Error handler // Error handler
// //
@ -333,14 +352,45 @@ include "toolsrc/parse.pla"
// Look at command line arguments and compile module // Look at command line arguments and compile module
// //
arg = argNext(argFirst) arg = argNext(argFirst)
if ^arg and ^(arg + 1) == '-'
arg = arg + 2
while TRUE
if toupper(^arg) == 'O'
outflags = outflags | OPTIMIZE
arg++
if ^arg == '2'
outflags = outflags | OPTIMIZE
arg++
fin
elsif toupper(^arg) == 'N'
outflags = outflags | NO_COMBINE
else
break
fin
loop
arg = argNext(arg)
fin
if arg if arg
strcpy(@srcfile, arg) strcpy(@srcfile, arg)
arg = argNext(arg)
if arg
strcpy(@relfile, arg)
fin
fin
if srcfile and relfile
exit = heapalloc(t_longjmp) exit = heapalloc(t_longjmp)
if not setjmp(exit) if not setjmp(exit)
//
// Parse source code module
//
parsemodule parsemodule
puts("Bytes compiled: "); puti(codeptr - codebuff); putln puts("Bytes compiled: "); puti(codeptr - codebuff); putln
//
// Write REL file
//
writerel
fin fin
else else
puts("Usage: +PLASM [srcfile]\n") puts("Usage: +PLASM [-O[2]] <srcfile> <relfile>\n")
fin fin
done done

View File

@ -873,6 +873,7 @@ void interp(code *ip)
*/ */
default: default:
fprintf(stderr, "Illegal opcode 0x%02X @ 0x%04X\n", ip[-1], ip - mem_data); fprintf(stderr, "Illegal opcode 0x%02X @ 0x%04X\n", ip[-1], ip - mem_data);
exit(-1);
} }
} }
} }