enable strict parameter/return count checking

This commit is contained in:
David Schmenk 2017-12-13 14:56:15 -08:00
parent f27a1b89c7
commit ed1e7ef9d7
6 changed files with 85 additions and 334 deletions

View File

@ -12,7 +12,7 @@ import cmdsys
const MACHID_III = $C0
const MACHID_IIC = $88
const MACHID_I = $08
word MACHID
byte MACHID
//
// System flags: memory allocator screen holes.
//
@ -36,10 +36,10 @@ import cmdsys
//
// CMD exported functions
//
predef putc, putln, puts, getc, gets
predef call, syscall
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
predef memset, memcpy
predef isugt, isuge, isult, isule
predef modload, modexec, modaddr
predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1, toupper(c)#1
predef call(addr,areg,xreg,yreg,status)#1, syscall(cmd,params)#1
predef heapmark()#1, heapallocalign(size, pow2, freeaddr), heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
predef isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#1
predef modload(mod)#1, modexec(modfile)#1, modaddr(str)#1
end

View File

@ -49,20 +49,20 @@ $(CMD): cmd.pla cmdstub.s $(PLVM) $(PLASM)
acme --setpc 8192 -o $(CMD) cmdstub.s
TESTLIB\#FE1000: testlib.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < testlib.pla > testlib.a
./$(PLASM) -AMW < testlib.pla > testlib.a
acme --setpc 4094 -o TESTLIB\#FE1000 testlib.a
test: test.pla TESTLIB\#FE1000 $(PLVM) $(PLASM)
./$(PLASM) -AM < test.pla > test.a
./$(PLASM) -AMW < test.pla > test.a
acme --setpc 4094 -o TEST\#FE1000 test.a
./$(PLVM) TEST
debug: test.pla TESTLIB $(PLVM) $(PLASM)
./$(PLASM) -AM < test.pla > test.a
./$(PLASM) -AMW < test.pla > test.a
acme --setpc 4094 -o TEST\#FE1000 test.a
./$(PLVM) -s TEST MAIN
hello: hello.pla $(PLVM) $(PLASM)
./$(PLASM) -AM < hello.pla > hello.a
./$(PLASM) -AMW < hello.pla > hello.a
acme --setpc 4094 -o HELLO\#FE1000 hello.a
./$(PLVM) HELLO

View File

@ -58,20 +58,14 @@ int opsptr = -1;
void push_op(t_token op, int prec)
{
if (++opsptr == 16)
{
parse_error("Stack overflow\n");
return;
}
parse_error("Stack overflow");
opstack[opsptr] = op;
precstack[opsptr] = prec;
}
t_token pop_op(void)
{
if (opsptr < 0)
{
parse_error("Stack underflow\n");
return (0);
}
parse_error("Stack underflow");
return opstack[opsptr--];
}
t_token tos_op(void)
@ -89,10 +83,7 @@ int valptr = -1;
void push_val(long value, int size, int type)
{
if (++valptr == 16)
{
parse_error("Stack overflow\n");
return;
}
parse_error("Stack overflow");
valstack[valptr] = value;
sizestack[valptr] = size;
typestack[valptr] = type;
@ -100,10 +91,7 @@ void push_val(long value, int size, int type)
int pop_val(long *value, int *size, int *type)
{
if (valptr < 0)
{
parse_error("Stack underflow\n");
return (-1);
}
parse_error("Stack underflow");
*value = valstack[valptr];
*size = sizestack[valptr];
*type = typestack[valptr];
@ -120,10 +108,7 @@ int calc_op(t_token op)
return 0;
pop_val(&val1, &size1, &type1);
if (type1 != CONST_TYPE || type2 != CONST_TYPE)
{
parse_error("Bad constant operand");
return (0);
}
switch (op)
{
case MUL_TOKEN:
@ -179,15 +164,9 @@ int parse_constterm(long *value, int *size)
break;
case OPEN_PAREN_TOKEN:
if (!(type = parse_constexpr(value, size)))
{
parse_error("Bad expression in parenthesis");
return (0);
}
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Missing closing parenthesis");
return (0);
}
break;
default:
/*
@ -241,10 +220,7 @@ int parse_constval(void)
value = constval;
type = STRING_TYPE;
if (mod)
{
parse_error("Invalid string modifiers");
return (0);
}
break;
case CHAR_TOKEN:
size = 1;
@ -304,10 +280,7 @@ int parse_constexpr(long *value, int *size)
matchop = 2;
if (binary_ops_precedence[i] >= tos_op_prec(optos))
if (!calc_op(pop_op()))
{
parse_error(": Invalid binary operation");
return (0);
}
parse_error("Invalid binary operation");
push_op(scantoken, binary_ops_precedence[i]);
break;
}
@ -316,16 +289,10 @@ int parse_constexpr(long *value, int *size)
if (matchop == 0 && prevmatch == 0)
return (0);
if (matchop == 0 && prevmatch == 2)
{
parse_error("Missing operand");
return (0);
}
while (optos < opsptr)
if (!calc_op(pop_op()))
{
parse_error(": Invalid binary operation");
return (0);
}
parse_error("Invalid binary operation");
pop_val(value, size, &type);
return (type);
}
@ -400,10 +367,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
else if (scantoken == AT_TOKEN)
{
if (deref-- == 0)
{
parse_error("Invalid ADDRESS-OF op");
return (NULL);
}
}
else if (scantoken == BPTR_TOKEN || scantoken == WPTR_TOKEN)
{
@ -416,10 +380,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
else if (scantoken == NEG_TOKEN || scantoken == COMP_TOKEN || scantoken == LOGIC_NOT_TOKEN)
{
if (!rvalue)
{
parse_error("Invalid op for LVALUE");
return (NULL);
}
uopseq = gen_uop(uopseq, scantoken);
}
else
@ -473,15 +434,9 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
else if (scantoken == OPEN_PAREN_TOKEN)
{
if (!(valseq = parse_expr(NULL, stackdepth)))
{
parse_error("Bad expression in parenthesis");
return (NULL);
}
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Missing closing parenthesis");
return (NULL);
}
}
else
return (NULL);
@ -497,25 +452,21 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
*/
valseq = cat_seq(parse_list(NULL, &value), valseq);
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Missing function call closing parenthesis");
return (NULL);
}
if (scan() == POUND_TOKEN)
{
/*
* Override return vals count
* Set function pointer return vals count - can't do this to regular function call
*/
if (type & FUNC_TYPE)
parse_error("Overriding function return count");
if (!parse_const(&cfnvals))
{
parse_error("Invalid def return value count");
return (0);
}
}
else
scan_rewind(tokenstr);
if ((type & FUNC_TYPE) && (cfnparms != value))
parse_warn("Parameter count mismatch");
parse_error("Parameter count mismatch");
if (stackdepth)
*stackdepth = cfnvals + cfnparms - value;
if (type & (VAR_TYPE | PTR_TYPE)) //!(type & (FUNC_TYPE | CONST_TYPE)))
@ -553,10 +504,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
valseq = gen_lw(valseq);
}
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (NULL);
}
if (type & (WPTR_TYPE | WORD_TYPE))
{
valseq = gen_idxw(valseq);
@ -594,10 +542,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
if (!parse_const(&const_offset))
{
if (scantoken == EOL_TOKEN || scantoken == CLOSE_PAREN_TOKEN)
{
parse_error("Syntax");
return (NULL);
}
/*
* Setting type override for following operations
*/
@ -633,10 +578,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
if (!parse_const(&const_offset))
{
if (scantoken == EOL_TOKEN || scantoken == CLOSE_PAREN_TOKEN)
{
parse_error("Syntax");
return (NULL);
}
/*
* Setting type override for following operations
*/
@ -745,10 +687,7 @@ t_opseq *parse_expr(t_opseq *codeseq, int *stackdepth)
}
} while (matchop == 2);
if (matchop == 0 && prevmatch == 2)
{
parse_error("Missing operand");
return (NULL);
}
while (optos < opsptr)
{
codeseq = gen_op(codeseq, pop_op());
@ -770,10 +709,7 @@ t_opseq *parse_expr(t_opseq *codeseq, int *stackdepth)
codeseq = gen_brfls(codeseq, tag_else);
codeseq = parse_expr(codeseq, &stackdepth1);
if (scantoken != TRIELSE_TOKEN)
{
parse_error("Missing '::' in ternary op");
return (NULL);
}
codeseq = gen_brnch(codeseq, tag_endtri);
codeseq = gen_codetag(codeseq, tag_else);
codeseq = parse_expr(codeseq, stackdepth);
@ -813,10 +749,7 @@ t_opseq *parse_set(t_opseq *codeseq)
}
rseq = parse_list(NULL, &rparms);
if (lparms > rparms)
{
parse_error("Set value list underflow");
return (NULL);
}
if ((lparms != rparms) && (rparms - lparms != 1))
codeseq = gen_pushexp(codeseq);
codeseq = cat_seq(codeseq, rseq);
@ -847,10 +780,7 @@ int parse_stmnt(void)
{
case IF_TOKEN:
if (!(seq = parse_expr(NULL, NULL)))
{
parse_error("Bad expression");
return (0);
}
tag_else = tag_new(BRANCH_TYPE);
tag_endif = tag_new(BRANCH_TYPE);
seq = gen_brfls(seq, tag_else);
@ -864,10 +794,7 @@ int parse_stmnt(void)
emit_brnch(tag_endif);
emit_codetag(tag_else);
if (!(seq = parse_expr(NULL, NULL)))
{
parse_error("Bad expression");
return (0);
}
tag_else = tag_new(BRANCH_TYPE);
seq = gen_brfls(seq, tag_else);
emit_seq(seq);
@ -886,10 +813,7 @@ int parse_stmnt(void)
emit_codetag(tag_endif);
}
if (scantoken != FIN_TOKEN)
{
parse_error("Missing IF/FIN");
return (0);
}
break;
case WHILE_TOKEN:
tag_while = tag_new(BRANCH_TYPE);
@ -900,18 +824,12 @@ int parse_stmnt(void)
break_tag = tag_wend;
emit_codetag(tag_while);
if (!(seq = parse_expr(NULL, NULL)))
{
parse_error("Bad expression");
return (0);
}
seq = gen_brfls(seq, tag_wend);
emit_seq(seq);
while (parse_stmnt()) next_line();
if (scantoken != LOOP_TOKEN)
{
parse_error("Missing WHILE/END");
return (0);
}
emit_brnch(tag_while);
emit_codetag(tag_wend);
break_tag = tag_prevbrk;
@ -927,17 +845,11 @@ int parse_stmnt(void)
scan();
while (parse_stmnt()) next_line();
if (scantoken != UNTIL_TOKEN)
{
parse_error("Missing REPEAT/UNTIL");
return (0);
}
emit_codetag(cont_tag);
cont_tag = tag_prevcnt;
if (!(seq = parse_expr(NULL, NULL)))
{
parse_error("Bad expression");
return (0);
}
seq = gen_brfls(seq, tag_repeat);
emit_seq(seq);
emit_codetag(break_tag);
@ -951,22 +863,13 @@ int parse_stmnt(void)
tag_prevcnt = cont_tag;
cont_tag = tag_for;
if (scan() != ID_TOKEN)
{
parse_error("Missing FOR variable");
return (0);
}
type = id_type(tokenstr, tokenlen);
addr = id_tag(tokenstr, tokenlen);
if (scan() != SET_TOKEN)
{
parse_error("Missing FOR =");
return (0);
}
if (!emit_seq(parse_expr(NULL, NULL)))
{
parse_error("Bad FOR expression");
return (0);
}
emit_codetag(tag_for);
if (type & LOCAL_TYPE)
type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr);
@ -977,33 +880,21 @@ int parse_stmnt(void)
else if (scantoken == DOWNTO_TOKEN)
step = -1;
else
{
parse_error("Missing FOR TO");
return (0);
}
if (!emit_seq(parse_expr(NULL, NULL)))
{
parse_error("Bad FOR TO expression");
return (0);
}
step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag);
if (scantoken == STEP_TOKEN)
{
if (!emit_seq(parse_expr(NULL, NULL)))
{
parse_error("Bad FOR STEP expression");
return (0);
}
emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN);
}
else
emit_unaryop(step > 0 ? INC_TOKEN : DEC_TOKEN);
while (parse_stmnt()) next_line();
if (scantoken != NEXT_TOKEN)
{
parse_error("Missing FOR/NEXT ");
return (0);
}
parse_error("Missing FOR/NEXT");
emit_brnch(tag_for);
cont_tag = tag_prevcnt;
emit_codetag(break_tag);
@ -1018,20 +909,14 @@ int parse_stmnt(void)
tag_choice = tag_new(BRANCH_TYPE);
tag_of = tag_new(BRANCH_TYPE);
if (!emit_seq(parse_expr(NULL, NULL)))
{
parse_error("Bad CASE expression");
return (0);
}
next_line();
while (scantoken != ENDCASE_TOKEN)
{
if (scantoken == OF_TOKEN)
{
if (!emit_seq(parse_expr(NULL, NULL)))
{
parse_error("Bad CASE OF expression");
return (0);
}
emit_brne(tag_choice);
emit_codetag(tag_of);
while (parse_stmnt()) next_line();
@ -1048,20 +933,12 @@ int parse_stmnt(void)
scan();
while (parse_stmnt()) next_line();
if (scantoken != ENDCASE_TOKEN)
{
parse_error("Bad CASE DEFAULT clause");
return (0);
}
}
else if (scantoken == EOL_TOKEN)
{
next_line();
}
else
{
parse_error("Bad CASE clause");
return (0);
}
}
if (tag_of)
emit_codetag(tag_of);
@ -1074,19 +951,13 @@ int parse_stmnt(void)
if (cont_tag)
emit_brnch(cont_tag);
else
{
parse_error("CONTINUE without loop");
return (0);
}
break;
case BREAK_TOKEN:
if (break_tag)
emit_brnch(break_tag);
else
{
parse_error("BREAK without loop");
return (0);
}
break;
case RETURN_TOKEN:
if (infunc)
@ -1096,10 +967,14 @@ int parse_stmnt(void)
emit_drop();
cfnvals = 0;
emit_seq(parse_list(NULL, &cfnvals));
if (cfnvals != infuncvals)
parse_warn("Inconsistent return value count");
while (cfnvals++ < infuncvals)
emit_const(0);
if (cfnvals > infuncvals)
parse_error("Too many return values");
if (cfnvals < infuncvals)
{
parse_warn("Too few return values");
while (cfnvals++ < infuncvals)
emit_const(0);
}
emit_leave();
}
else
@ -1154,24 +1029,13 @@ int parse_stmnt(void)
emit_seq(rseq);
}
else
{
parse_error("Invalid LVALUE");
return (0);
}
}
else
{
parse_error("Syntax error");
return (0);
}
}
}
if (scan() != EOL_TOKEN /*&& scantoken != COMMENT_TOKEN*/)
{
parse_error("Extraneous characters");
return (0);
}
return (1);
return (scan() == EOL_TOKEN);
}
int parse_var(int type)
{
@ -1185,10 +1049,7 @@ int parse_var(int type)
size = 0;
parse_constexpr(&size, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
scan();
}
if (scantoken == ID_TOKEN)
@ -1200,10 +1061,7 @@ int parse_var(int type)
size = 0;
parse_constexpr(&size, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
scan();
}
}
@ -1212,10 +1070,7 @@ int parse_var(int type)
if (scantoken == SET_TOKEN)
{
if (type & (EXTERN_TYPE | LOCAL_TYPE))
{
parse_error("Cannot initiallize local/external variables");
return (0);
}
if (idlen)
idglobal_add(idstr, idlen, type, 0);
if ((consttype = parse_constexpr(&constval, &constsize)))
@ -1229,19 +1084,13 @@ int parse_var(int type)
if ((consttype = parse_constexpr(&constval, &constsize)))
arraysize += emit_data(type, consttype, constval, constsize);
else
{
parse_error("Bad array declaration");
return (0);
}
}
if (size > arraysize)
idglobal_size(PTR_TYPE, size, arraysize);
}
else
{
parse_error("Bad variable initializer");
return (0);
}
}
else if (idlen)
id_add(idstr, idlen, type, size);
@ -1272,10 +1121,7 @@ int parse_struc(void)
size = 0;
parse_constexpr(&size, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
scan();
}
do {
@ -1289,10 +1135,7 @@ int parse_struc(void)
size = 0;
parse_constexpr(&size, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
scan();
}
}
@ -1302,12 +1145,9 @@ int parse_struc(void)
idconst_add(idstr, idlen, offset);
offset += size;
} while (scantoken == COMMA_TOKEN);
if (scantoken != EOL_TOKEN /*&& scantoken != COMMENT_TOKEN*/)
return (0);
}
if (struclen)
idconst_add(strucid, struclen, offset);
//return (scantoken == END_TOKEN);
if (scantoken != END_TOKEN)
return (0);
scan();
@ -1324,50 +1164,29 @@ int parse_vars(int type)
{
case SYSFLAGS_TOKEN:
if (type & (EXTERN_TYPE | LOCAL_TYPE))
{
parse_error("sysflags must be global");
return (0);
}
if (!parse_constexpr(&value, &size))
{
parse_error("Bad constant");
return (0);
}
emit_sysflags(value);
break;
case CONST_TOKEN:
if (scan() != ID_TOKEN)
{
parse_error("Missing variable");
return (0);
}
idstr = tokenstr;
idlen = tokenlen;
if (scan() != SET_TOKEN)
{
parse_error("Bad LValue");
return (0);
}
if (!parse_constexpr(&value, &size))
{
parse_error("Bad constant");
return (0);
}
idconst_add(idstr, idlen, value);
break;
case STRUC_TOKEN:
if (!parse_struc())
{
parse_error("Bad structure definition");
return (0);
}
break;
case EXPORT_TOKEN:
if (type & (EXTERN_TYPE | LOCAL_TYPE))
{
parse_error("Cannot export local/imported variables");
return (0);
}
type = EXPORT_TYPE;
idstr = tokenstr;
if (scan() != BYTE_TOKEN && scantoken != WORD_TOKEN)
@ -1415,19 +1234,13 @@ int parse_vars(int type)
}
} while (scantoken == COMMA_TOKEN);
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Bad function parameter list");
return (0);
}
scan();
}
if (scantoken == POUND_TOKEN)
{
if (!parse_const(&cfnvals))
{
parse_error("Invalid def return value count");
return (0);
}
scan();
}
type |= funcparms_type(cfnparms) | funcvals_type(cfnvals);
@ -1452,40 +1265,26 @@ int parse_vars(int type)
}
} while (scantoken == COMMA_TOKEN);
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Bad function parameter list");
return (0);
}
scan();
}
if (scantoken == POUND_TOKEN)
{
if (!parse_const(&cfnvals))
{
parse_error("Invalid def return value count");
return (0);
}
scan();
}
type |= funcparms_type(cfnparms) | funcvals_type(cfnvals);
idfunc_add(idstr, idlen, type, tag_new(type));
}
else
{
parse_error("Bad function pre-declaration");
return (0);
}
//scan();
}
}
else
{
parse_error("Bad function pre-declaration");
return (0);
}
case EOL_TOKEN:
//case COMMENT_TOKEN:
return (1);
break;
default:
return (0);
}
@ -1496,25 +1295,15 @@ int parse_mods(void)
if (scantoken == IMPORT_TOKEN)
{
if (scan() != ID_TOKEN)
{
parse_error("Bad import definition");
return (0);
}
emit_moddep(tokenstr, tokenlen);
scan();
while (parse_vars(EXTERN_TYPE)) next_line();
if (scantoken != END_TOKEN)
{
parse_error("Syntax error");
return (0);
}
if (scan() != EOL_TOKEN /*&& scantoken != COMMENT_TOKEN*/)
{
parse_error("Extraneous characters");
return (0);
}
parse_error("Missing END");
return (scan() == EOL_TOKEN);
}
if (scantoken == EOL_TOKEN /*|| scantoken == COMMENT_TOKEN*/)
if (scantoken == EOL_TOKEN)
return (1);
emit_moddep(0, 0);
return (0);
@ -1526,10 +1315,7 @@ int parse_lambda(void)
char *expr;
if (!infunc)
{
parse_error("Lambda functions only allowed inside definitions");
return (0);
}
idlocal_save();
/*
* Parse parameters and return value count
@ -1547,16 +1333,10 @@ int parse_lambda(void)
}
} while (scantoken == COMMA_TOKEN);
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Bad function parameter list");
return (0);
}
}
else
{
parse_error("Missing parameter list in lambda function");
return (0);
}
expr = scanpos;
if (scan_lookahead() == OPEN_PAREN_TOKEN)
{
@ -1566,10 +1346,7 @@ int parse_lambda(void)
scan();
lambda_seq[lambda_cnt] = parse_list(NULL, NULL);
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Missing closing lambda function parenthesis");
return (0);
}
}
else
{
@ -1601,19 +1378,13 @@ int parse_defs(void)
if (scantoken == EXPORT_TOKEN)
{
if (scan() != DEF_TOKEN && scantoken != ASM_TOKEN)
{
parse_error("Bad export definition");
return 0;
}
type = EXPORT_TYPE;
}
if (scantoken == DEF_TOKEN)
{
if (scan() != ID_TOKEN)
{
parse_error("Missing function name");
return (0);
}
emit_bytecode_seg();
lambda_cnt = 0;
bytecode = 1;
@ -1639,19 +1410,13 @@ int parse_defs(void)
}
} while (scantoken == COMMA_TOKEN);
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Bad function parameter list");
return (0);
}
scan();
}
if (scantoken == POUND_TOKEN)
{
if (!parse_const(&infuncvals))
{
parse_error("Invalid def return value count");
return (0);
}
scan();
}
type |= funcparms_type(cfnparms) | funcvals_type(infuncvals);
@ -1659,12 +1424,9 @@ int parse_defs(void)
{
pretype = id_type(idstr, idlen);
if (!(pretype & PREDEF_TYPE))
{
parse_error("Mismatch function type");
return (0);
}
if ((pretype & FUNC_PARMVALS) != (type & FUNC_PARMVALS))
parse_warn("Mismatch function params/return values");
parse_error("Mismatch function params/return values");
emit_idfunc(id_tag(idstr, idlen), PREDEF_TYPE, idstr, 0);
func_tag = tag_new(type);
idfunc_set(idstr, idlen, type, func_tag); // Override any predef type & tag
@ -1687,19 +1449,12 @@ int parse_defs(void)
while (parse_stmnt()) next_line();
infunc = 0;
if (scantoken != END_TOKEN)
{
parse_error("Syntax error");
return (0);
}
if (scan() != EOL_TOKEN /*&& scantoken != COMMENT_TOKEN*/)
{
parse_error("Extraneous characters");
return (0);
}
parse_error("Missing END");
scan();
if (prevstmnt != RETURN_TOKEN)
{
if (infuncvals)
parse_warn("Inconsistent return value count");
parse_warn("No return values");
for (cfnvals = 0; cfnvals < infuncvals; cfnvals++)
emit_const(0);
emit_leave();
@ -1711,15 +1466,9 @@ int parse_defs(void)
else if (scantoken == ASM_TOKEN)
{
if (scan() != ID_TOKEN)
{
parse_error("Missing function name");
return (0);
}
if (bytecode)
{
parse_error("ASM code only allowed before DEF code");
return (0);
}
cfnparms = 0;
infuncvals = 1; // Defaut to one return value for compatibility
infunc = 1;
@ -1739,19 +1488,13 @@ int parse_defs(void)
}
while (scantoken == COMMA_TOKEN);
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Bad function parameter list");
return (0);
}
scan();
}
if (scantoken == POUND_TOKEN)
{
if (!parse_const(&infuncvals))
{
parse_error("Invalid def return value count");
return (0);
}
scan();
}
type |= funcparms_type(cfnparms) | funcvals_type(infuncvals);
@ -1759,12 +1502,9 @@ int parse_defs(void)
{
pretype = id_type(idstr, idlen);
if (!(pretype & PREDEF_TYPE))
{
parse_error("Mismatch function type");
return (0);
}
if ((pretype & FUNC_PARMVALS) != (type & FUNC_PARMVALS))
parse_warn("Mismatch function params/return values");
parse_error("Mismatch function params/return values");
emit_idfunc(id_tag(idstr, idlen), PREDEF_TYPE, idstr, 0);
func_tag = tag_new(type);
idfunc_set(idstr, idlen, type, func_tag); // Override any predef type & tag
@ -1780,8 +1520,6 @@ int parse_defs(void)
idstr[idlen] = c;
do
{
///if (scantoken == EOL_TOKEN /*|| scantoken == COMMENT_TOKEN*/)
//next_line();
if (scantoken != END_TOKEN && scantoken != EOL_TOKEN)
{
scantoken = EOL_TOKEN;
@ -1792,9 +1530,7 @@ int parse_defs(void)
scan();
return (1);
}
if (scantoken == EOL_TOKEN /*|| scantoken == COMMENT_TOKEN*/)
return (1);
return (0);
return (scantoken == EOL_TOKEN);
}
int parse_module(void)
{
@ -1813,7 +1549,7 @@ int parse_module(void)
prevstmnt = 0;
while (parse_stmnt()) next_line();
if (scantoken != DONE_TOKEN)
parse_error("Missing DONE statement");
parse_error("Missing DONE");
if (prevstmnt != RETURN_TOKEN)
{
emit_const(0);

View File

@ -457,12 +457,10 @@ void call(uword pc)
if (c == 0x0D)
c = '\n';
putchar(c);
PUSH(0);
break;
case 4: // LIBRARY STDLIB::PUTS
s = POP;
i = mem_data[s++];
PUSH(i);
while (i--)
{
c = mem_data[s++];
@ -479,7 +477,6 @@ void call(uword pc)
c = '\n';
putchar(c);
}
PUSH(0);
break;
case 6: // LIBRARY STDLIB::GETC
PUSH(getchar());
@ -495,7 +492,13 @@ void call(uword pc)
case 8: // LIBRARY STDLIB::PUTNL
putchar('\n');
fflush(stdout);
PUSH(0);
break;
case 9: // LIBRARY STDLIB::MACHID
PUSH(0x0000);
break;
case 10: // LIBRARY STDLIB::PUTI
i = POP;
printf("%d", i);
break;
default:
printf("\nBad call code:$%02X\n", mem_data[pc - 1]);
@ -511,7 +514,7 @@ OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E
DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E
DW DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E
DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E
DW BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,??? ; 50 52 54 56 58 5A 5C 5E
DW BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E
DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E
DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E
*/
@ -882,6 +885,7 @@ char *syslib_exp[] = {
"GETS",
"PUTLN",
"MACHID",
"PUTI",
0
};
@ -923,6 +927,10 @@ int main(int argc, char **argv)
stodci(*argv, dci);
call(lookup_sym(dci));
}
if (esp != &eval_stack[EVAL_STACKSZ])
{
printf("Eval stack pointer mismatch at end of execution = %d.\n", EVAL_STACKSZ - (esp - eval_stack));
}
}
return 0;
}

View File

@ -35,20 +35,20 @@ word ptr
//
// Define functions.
//
def tens(start)
def tens(start)#0
word i, pptr
i = start
pptr = @print
repeat
print:hex(i)
print:str(" ")
pptr=>dec(i)
print:newln()
print:hex(i)#0
print:str(" ")#0
pptr=>dec(i)#0
print:newln()#0
i = i / 10
until i == 0
end
def ascii
def ascii#0
byte i
i = 32
while i < 128
@ -56,7 +56,7 @@ def ascii
i = i + 1
loop
end
def nums(range)
def nums(range)#0
word i
byte j
for i = range downto -range step range/10
@ -81,7 +81,7 @@ def printfunc(a, b, lambda)#0
puti(lambda(a,b))
putln
end
export def main(range)
export def main(range)#0
byte a
word lambda
@ -122,8 +122,13 @@ export def main(range)
puti(lambda(2,3));putln
end
def dummy(zz)#0
def dummy(zz)#2
puts("dummy func"); putln
return 0
end
def value1
return 1
end
puti(array[0]);putc(' ')
@ -137,7 +142,7 @@ puti((@array)=>4);putc(' ')
puti((@array)=>6);putc(' ')
puti((@array)=>8);putln
ptr = @main
ptr(@array:6)
ptr(@array:6)#0
ptr = @array
puti((ptr):6)
putln
@ -160,6 +165,17 @@ putln
puts(@constr); puti(constval); putln
puts("Signed byte constant:"); puti(-3); putln
puts("Hello from in-line string!\$7F\n")
puts(1 ?? "This is TRUE\n" :: "This is FALSE\n")
puts(0 ?? "This is TRUE\n" :: "This is FALSE\n")
puti(array:0); puts(" == "); puti(array:1); puts (" is "); puts(array:0 == array:1 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" <> "); puti(array:1); puts (" is "); puts(array:0 <> array:1 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" >= "); puti(array:1); puts (" is "); puts(array:0 >= array:1 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" <= "); puti(array:1); puts (" is "); puts(array:0 <= array:1 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" > "); puti(array:1); puts (" is "); puts(array:0 > array:1 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" < "); puti(array:1); puts (" is "); puts(array:0 < array:1 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" == "); puti(array:0); puts (" is "); puts(array:0 == array:0 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" <> "); puti(array:0); puts (" is "); puts(array:0 <> array:0 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" >= "); puti(array:0); puts (" is "); puts(array:0 >= array:0 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" <= "); puti(array:0); puts (" is "); puts(array:0 <= array:0 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" > "); puti(array:0); puts (" is "); puts(array:0 > array:0 ?? "TRUE\n" :: "FALSE\n")
puti(array:0); puts(" < "); puti(array:0); puts (" is "); puts(array:0 < array:0 ?? "TRUE\n" :: "FALSE\n")
ptr = 0
done

View File

@ -5,29 +5,20 @@ include "cmdsys.plh"
//
// Module data.
//
predef puti, puth
predef puth(h)#0
export word print[] = @puti, @puth, @putln, @puts, @putc
byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
byte loadstr[] = "testlib loaded!"
//
// Define functions.
//
def puth(h)
def puth(h)#0
putc('$')
putc(valstr[(h >> 12) & $0F])
putc(valstr[(h >> 8) & $0F])
putc(valstr[(h >> 4) & $0F])
putc(valstr[ h & $0F])
end
export def puti(i)
if i < 0; putc('-'); i = -i; fin
if i < 10
putc(i + '0')
else
puti(i / 10)
putc(i % 10 + '0')
fin
end
puts(@loadstr)
putln
done