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:
parent
70ba7d0e0e
commit
7843bc41ce
@ -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
|
||||||
|
@ -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
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user