Fix VM bug in BRNE/BREQ, parse lvalue bug, and rename stdlib to cmdsys

This commit is contained in:
dschmenk 2015-01-28 12:56:14 -08:00
parent a71d652f30
commit 508a2c84fb
7 changed files with 466 additions and 349 deletions

View File

@ -33,7 +33,7 @@ predef loadmod, execmod, lookupstrmod
// //
// System variable. // System variable.
// //
word version = $0011 // 00.11 word version = $0080 // 00.80
word systemflags = 0 word systemflags = 0
word heap word heap
word xheap = $0800 word xheap = $0800
@ -43,7 +43,7 @@ byte cmdln = "" // Overlay exported strings table
// //
// Standard Library exported functions. // Standard Library exported functions.
// //
byte stdlibstr = "STDLIB" byte syslibstr = "CMDSYS"
byte machidstr = "MACHID" byte machidstr = "MACHID"
byte sysstr = "SYSCALL" byte sysstr = "SYSCALL"
byte callstr = "CALL" byte callstr = "CALL"
@ -56,7 +56,6 @@ byte hpmarkstr = "HEAPMARK"
byte hpalignstr = "HEAPALLOCALIGN" byte hpalignstr = "HEAPALLOCALIGN"
byte hpallocstr = "HEAPALLOC" byte hpallocstr = "HEAPALLOC"
byte hprelstr = "HEAPRELEASE" byte hprelstr = "HEAPRELEASE"
byte hpavailstr = "HEAPAVAIL"
byte memsetstr = "MEMSET" byte memsetstr = "MEMSET"
byte memcpystr = "MEMCPY" byte memcpystr = "MEMCPY"
byte uisgtstr = "ISUGT" byte uisgtstr = "ISUGT"
@ -92,7 +91,7 @@ word = @modadrstr, @lookupstrmod
word = @machidstr, MACHID word = @machidstr, MACHID
word = @argstr, @cmdln word = @argstr, @cmdln
word = 0 word = 0
word stdlibsym = @exports word syslibsym = @exports
// //
// String pool. // String pool.
// //
@ -193,30 +192,33 @@ asm reboot
end end
// //
// SET MEMORY TO VALUE // SET MEMORY TO VALUE
// MEMSET(ADDR, SIZE, VALUE) // MEMSET(ADDR, VALUE, SIZE)
// With optimizations from Peter Ferrie // With optimizations from Peter Ferrie
// //
asm memset asm memset
LDY #$00
LDA ESTKL+2,X LDA ESTKL+2,X
STA DSTL STA DSTL
LDA ESTKH+2,X LDA ESTKH+2,X
STA DSTH STA DSTH
INC ESTKL+1,X LDY ESTKL,X
INC ESTKH+1,X BEQ +
SETMLPL CLC INC ESTKH,X
LDA ESTKL,X LDY #$00
SETMLPH DEC ESTKL+1,X + LDA ESTKH,X
BNE +
DEC ESTKH+1,X
BEQ SETMEX BEQ SETMEX
+ STA (DST),Y SETMLPL CLC
INY LDA ESTKL+1,X
SETMLPH STA (DST),Y
DEC ESTKL,X
BNE +
DEC ESTKH,X
BEQ SETMEX
+ INY
BNE + BNE +
INC DSTH INC DSTH
+ BCS SETMLPL + BCS SETMLPL
SEC SEC
LDA ESTKH,X LDA ESTKH+1,X
BCS SETMLPH BCS SETMLPH
SETMEX INX SETMEX INX
INX INX
@ -248,6 +250,8 @@ asm memcpy
STA SRCL STA SRCL
LDA ESTKH-1,X LDA ESTKH-1,X
STA SRCH STA SRCH
LDY ESTKL-2,X
BEQ FORCPYLP
INC ESTKH-2,X INC ESTKH-2,X
LDY #$00 LDY #$00
FORCPYLP LDA (SRC),Y FORCPYLP LDA (SRC),Y
@ -1213,7 +1217,7 @@ def resetmemfiles
// //
// Set memory bitmap // Set memory bitmap
// //
memset($BF58, 24, 0) memset($BF58, 0, 24)
^$BF58 = $CF ^$BF58 = $CF
^$BF6F = $01 ^$BF6F = $01
end end
@ -1246,22 +1250,21 @@ def execmod(modfile)
byte moddci[17] byte moddci[17]
word saveheap, savexheap, savesym, saveflags word saveheap, savexheap, savesym, saveflags
perr = 1
if stodci(modfile, @moddci) if stodci(modfile, @moddci)
saveheap = heap saveheap = heap
savexheap = xheap savexheap = xheap
savesym = lastsym savesym = lastsym
saveflags = systemflags saveflags = systemflags
^lastsym = 0 if loadmod(@moddci) < modkeep
perr = loadmod(@moddci)
if perr < modkeep
lastsym = savesym lastsym = savesym
xheap = savexheap xheap = savexheap
heap = saveheap heap = saveheap
else
perr = perr & ~modkeep
fin fin
^lastsym = 0
systemflags = saveflags systemflags = saveflags
fin fin
return perr
end end
// //
// Get heap start. // Get heap start.
@ -1270,19 +1273,19 @@ heap = *freemem
// //
// Init symbol table. // Init symbol table.
// //
stodci(@stdlibstr, heap) stodci(@syslibstr, heap)
addmod(heap, @version) addmod(heap, @version)
while *stdlibsym while *syslibsym
stodci(stdlibsym=>0, heap) stodci(syslibsym=>0, heap)
addsym(heap, stdlibsym=>2) addsym(heap, syslibsym=>2)
stdlibsym = stdlibsym + 4 syslibsym = syslibsym + 4
loop loop
// //
// Try to load autorun. // Try to load autorun.
// //
autorun = open(@autorun, iobuffer) autorun = open(@autorun, iobuffer)
if autorun > 0 if autorun > 0
cmdln = read(autorun, @stdlibstr, 128) cmdln = read(autorun, @syslibstr, 128)
close(autorun) close(autorun)
else else
// //

View File

@ -67,22 +67,103 @@ int tos_op_prec(int tos)
{ {
return opsptr <= tos ? 100 : precstack[opsptr]; return opsptr <= tos ? 100 : precstack[opsptr];
} }
int parse_expr(void); long valstack[16];
int parse_term(void) int typestack[16];
int sizestack[16];
int valptr = -1;
void push_val(long value, int size, int type)
{ {
if (++valptr == 16)
{
parse_error("Stack overflow\n");
return;
}
valstack[valptr] = value;
sizestack[valptr] = size;
typestack[valptr] = type;
}
int pop_val(long *value, int *size, int *type)
{
if (valptr < 0)
{
parse_error("Stack underflow\n");
return (-1);
}
*value = valstack[valptr];
*size = sizestack[valptr];
*type = typestack[valptr];
return valptr--;
}
/*
* Constant expression parsing
*/
int calc_op(t_token op)
{
long val1, val2;
int size1, size2, type1, type2;
if (!pop_val(&val2, &size2, &type2))
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:
val1 *= val2;
break;
case DIV_TOKEN:
val1 /= val2;
break;
case MOD_TOKEN:
val1 %= val2;
break;
case ADD_TOKEN:
val1 += val2;
break;
case SUB_TOKEN:
val1 -= val2;
break;
case SHL_TOKEN:
val1 <<= val2;
break;
case SHR_TOKEN:
val1 >>= val2;
break;
case AND_TOKEN:
val1 &= val2;
break;
case OR_TOKEN:
val1 |= val2;
break;
case EOR_TOKEN:
val1 ^= val2;
break;
default:
return (0);
}
size1 = size1 > size2 ? size1 : size2;
push_val(val1, size1, type1);
return (1);
}
int parse_constexpr(long *value, int *size);
int parse_constterm(long *value, int *size)
{
int type;
/* /*
* Parse terminal tokens. * Parse terminal tokens.
*/ */
switch (scan()) switch (type = scan())
{ {
case CHAR_TOKEN: case CHAR_TOKEN:
case INT_TOKEN: case INT_TOKEN:
case FLOAT_TOKEN:
case ID_TOKEN: case ID_TOKEN:
case STRING_TOKEN: case STRING_TOKEN:
break; break;
case OPEN_PAREN_TOKEN: case OPEN_PAREN_TOKEN:
if (!parse_expr()) if (!(type = parse_constexpr(value, size)))
{ {
parse_error("Bad expression in parenthesis"); parse_error("Bad expression in parenthesis");
return (0); return (0);
@ -99,13 +180,16 @@ int parse_term(void)
*/ */
return (0); return (0);
} }
return (1); return (type);
} }
int parse_constval(long *value, int *size) int parse_constval(void)
{ {
int mod = 0, type = 0; int mod = 0, type, size;
*value = 0; long value;
while (!parse_term())
value = 0;
size = 1;
while (!(type = parse_constterm(&value, &size)))
{ {
switch (scantoken) switch (scantoken)
{ {
@ -133,63 +217,170 @@ int parse_constval(long *value, int *size)
/* /*
* Determine which terminal type. * Determine which terminal type.
*/ */
if (scantoken == STRING_TOKEN) switch (scantoken)
{ {
*value = constval; case CLOSE_PAREN_TOKEN:
*size = tokenlen - 1; break;
case STRING_TOKEN:
size = tokenlen - 1;
value = constval;
type = STRING_TYPE; type = STRING_TYPE;
if (mod) if (mod)
{ {
parse_error("Invalid string modifiers"); parse_error("Invalid string modifiers");
return (0); return (0);
} }
} break;
else if (scantoken == CHAR_TOKEN) case CHAR_TOKEN:
{ size = 1;
*value = constval; value = constval;
*size = 1;
type = CONST_TYPE; type = CONST_TYPE;
} break;
else if (scantoken == INT_TOKEN) case INT_TOKEN:
{ size = 2;
*value = constval; value = constval;
*size = 2;
type = CONST_TYPE; type = CONST_TYPE;
} break;
else if (scantoken == ID_TOKEN) case ID_TOKEN:
{ size = 2;
type = id_type(tokenstr, tokenlen); type = id_type(tokenstr, tokenlen);
if (type & CONST_TYPE) if (type & CONST_TYPE)
*value = id_const(tokenstr, tokenlen); value = id_const(tokenstr, tokenlen);
else if ((type & (FUNC_TYPE | EXTERN_TYPE)) || ((type & ADDR_TYPE) && (mod & 8))) else if ((type & (FUNC_TYPE | EXTERN_TYPE)) || ((type & ADDR_TYPE) && (mod == 8)))
*value = id_tag(tokenstr, tokenlen); value = id_tag(tokenstr, tokenlen);
else else
{
parse_error("Invalid constant");
return (0); return (0);
} break;
} default:
else
{
parse_error("Invalid constant");
return (0); return (0);
} }
if (mod & 1) if (mod & 1)
*value = -*value; value = -value;
if (mod & 2) if (mod & 2)
*value = ~*value; value = ~value;
if (mod & 4) if (mod & 4)
*value = *value ? 0 : -1; value = value ? 0 : -1;
push_val(value, size, type);
return (type); return (type);
} }
int parse_constexpr(long *value, int *size)
{
int prevmatch;
int matchop = 0;
int optos = opsptr;
int i;
int type = CONST_TYPE;
*value = 0;
*size = 1;
do
{
/*
* Parse sequence of double operand operations.
*/
prevmatch = matchop;
matchop = 0;
if (parse_constval())
{
matchop = 1;
scan();
for (i = 0; i < sizeof(binary_ops_table); i++)
if (scantoken == binary_ops_table[i])
{
matchop = 2;
if (binary_ops_precedence[i] >= tos_op_prec(optos))
if (!calc_op(pop_op()))
{
parse_error(": Invalid binary operation");
return (0);
}
push_op(scantoken, binary_ops_precedence[i]);
break;
}
}
} while (matchop == 2);
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);
}
pop_val(value, size, &type);
return (type);
}
int parse_const(long *value)
{
/*
* Get simple constant.
*/
switch (scan())
{
case CHAR_TOKEN:
case INT_TOKEN:
*value = constval;
break;
case ID_TOKEN:
if (id_type(tokenstr, tokenlen) & CONST_TYPE)
{
*value = id_const(tokenstr, tokenlen);
break;
}
default:
*value = 0;
return (0);
}
return (CONST_TYPE);
}
/*
* Normal expression parsing
*/
int parse_expr(void);
int parse_term(void)
{
/*
* Parse terminal tokens.
*/
switch (scan())
{
case CHAR_TOKEN:
case INT_TOKEN:
case ID_TOKEN:
case STRING_TOKEN:
break;
case OPEN_PAREN_TOKEN:
if (!parse_expr())
{
parse_error("Bad expression in parenthesis");
return (0);
}
if (scantoken != CLOSE_PAREN_TOKEN)
{
parse_error("Missing closing parenthesis");
return (0);
}
break;
default:
/*
* Non-terminal token.
*/
return (0);
}
return (1);
}
int parse_value(int rvalue) int parse_value(int rvalue)
{ {
int cparams; int cparams;
int deref = rvalue; int deref = rvalue;
int optos = opsptr; int optos = opsptr;
int type = 0, value = 0, emit_value = 0; int type = 0, value = 0, emit_value = 0;
int elem_size, elem_type; int ref_type, const_size;
long elem_offset = 0; long ref_offset, const_offset;
/* /*
* Parse pre operand operators. * Parse pre operand operators.
*/ */
@ -207,8 +398,8 @@ int parse_value(int rvalue)
push_op(scantoken, 0); push_op(scantoken, 0);
else else
{ {
type |= BPTR_TYPE;
deref++; deref++;
type |= BPTR_TYPE;
} }
break; break;
case WPTR_TOKEN: case WPTR_TOKEN:
@ -216,8 +407,8 @@ int parse_value(int rvalue)
push_op(scantoken, 0); push_op(scantoken, 0);
else else
{ {
type |= WPTR_TYPE;
deref++; deref++;
type |= WPTR_TYPE;
} }
break; break;
case AT_TOKEN: case AT_TOKEN:
@ -286,6 +477,8 @@ int parse_value(int rvalue)
/* /*
* Parse post operand operators. * Parse post operand operators.
*/ */
ref_type = type & ~PTR_TYPE;
ref_offset = 0;
while (scan() == OPEN_PAREN_TOKEN while (scan() == OPEN_PAREN_TOKEN
|| scantoken == OPEN_BRACKET_TOKEN || scantoken == OPEN_BRACKET_TOKEN
|| scantoken == PTRB_TOKEN || scantoken == PTRB_TOKEN
@ -295,165 +488,20 @@ int parse_value(int rvalue)
{ {
switch (scantoken) switch (scantoken)
{ {
case OPEN_BRACKET_TOKEN:
/*
* Array
*/
if (!emit_value)
{
if (type & ADDR_TYPE)
{
if (type & LOCAL_TYPE)
emit_localaddr(value);
else
emit_globaladdr(value, 0, type);
}
else if (type & CONST_TYPE)
{
emit_const(value);
}
emit_value = 1;
}
if (type & PTR_TYPE)
emit_lw();
if (!parse_expr())
{
parse_error("Bad expression");
return (0);
}
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
if (type & WORD_TYPE)
{
//type |= WPTR_TYPE;
type = WPTR_TYPE;
emit_indexword();
}
else
{
//type |= BPTR_TYPE;
type = BPTR_TYPE;
emit_indexbyte();
}
//type &= ~(ADDR_TYPE | CONST_TYPE);
break;
case PTRB_TOKEN:
case PTRW_TOKEN:
if (!emit_value)
{
if (type & FUNC_TYPE)
emit_call(value, type);
else if (type & VAR_TYPE)
{
if (type & LOCAL_TYPE)
(type & BYTE_TYPE) ? emit_llb(value + elem_offset) : emit_llw(value + elem_offset);
else
(type & BYTE_TYPE) ? emit_lab(value, elem_offset, type) : emit_law(value, elem_offset, type);
}
else
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
emit_value = 1;
}
else
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
type &= ~(VAR_TYPE | ADDR_TYPE);
type |= WORD_TYPE;
scantoken = scantoken == PTRB_TOKEN ? DOT_TOKEN : COLON_TOKEN;
case DOT_TOKEN:
case COLON_TOKEN:
/*
* Structure member offset or array of arrays
*/
elem_type = (scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE;
if (parse_constval(&elem_offset, &elem_size))
{
/*
* Constant member offset
*/
if (!emit_value)
{
if (type & VAR_TYPE)
{
elem_type = (type & ~VAR_TYPE) | (elem_type == BPTR_TYPE ? BYTE_TYPE : WORD_TYPE);
}
else if (type & CONST_TYPE)
{
value += elem_offset;
emit_const(value);
elem_offset = 0;
emit_value = 1;
}
else // FUNC_TYPE
{
emit_globaladdr(value, elem_offset, type);
elem_offset = 0;
emit_value = 1;
}
}
else
{
if (elem_offset != 0)
{
emit_const(elem_offset);
emit_op(ADD_TOKEN);
elem_offset = 0;
}
}
}
else if (scantoken == OPEN_BRACKET_TOKEN)
{
/*
* Array of arrays
*/
if (!emit_value)
{
if (type & ADDR_TYPE)
{
if (type & LOCAL_TYPE)
emit_localaddr(value + elem_offset);
else
emit_globaladdr(value, elem_offset, type);
}
else if (type & CONST_TYPE)
{
emit_const(value + elem_offset);
}
elem_offset = 0;
emit_value = 1;
}
while (parse_expr())
{
if (scantoken != COMMA_TOKEN)
break;
emit_indexword();
emit_lw();
}
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
if (elem_type & WPTR_TYPE)
emit_indexword();
else
emit_indexbyte();
}
else
{
parse_error("Invalid member offset");
return (0);
}
type = elem_type;
break;
case OPEN_PAREN_TOKEN: case OPEN_PAREN_TOKEN:
/* /*
* Function call * Function call
*/ */
if (emit_value) if (emit_value)
{ {
if (ref_offset != 0)
{
emit_const(ref_offset);
emit_op(ADD_TOKEN);
ref_offset = 0;
}
if (ref_type & PTR_TYPE)
(ref_type & BPTR_TYPE) ? emit_lb() : emit_lw();
if (scan_lookahead() != CLOSE_PAREN_TOKEN) if (scan_lookahead() != CLOSE_PAREN_TOKEN)
emit_push(); emit_push();
} }
@ -469,21 +517,22 @@ int parse_value(int rvalue)
parse_error("Missing closing parenthesis"); parse_error("Missing closing parenthesis");
return (0); return (0);
} }
if (type & (FUNC_TYPE | CONST_TYPE)) if (ref_type & (FUNC_TYPE | CONST_TYPE))
emit_call(value, type); emit_call(value, ref_type);
else else
{ {
if (!emit_value) if (!emit_value)
{ {
if (type & VAR_TYPE) if (type & CONST_TYPE)
emit_const(value);
else if (type & VAR_TYPE)
{ {
if (type & LOCAL_TYPE) if (type & LOCAL_TYPE)
emit_llw(value + elem_offset); emit_llw(value + ref_offset);
else else
emit_law(value, elem_offset, type); emit_law(value, ref_offset, type);
ref_offset = 0;
} }
else if (type & PTR_TYPE)
emit_lw();
} }
else else
if (cparams) if (cparams)
@ -491,39 +540,170 @@ int parse_value(int rvalue)
emit_ical(); emit_ical();
} }
emit_value = 1; emit_value = 1;
type = WORD_TYPE; //(type & ~(FUNC_TYPE | CONST_TYPE)) | WORD_TYPE; ref_type = 0;
break;
case OPEN_BRACKET_TOKEN:
/*
* Array of arrays
*/
if (!emit_value)
{
if (type & CONST_TYPE)
emit_const(value);
else if (type & ADDR_TYPE)
{
if (type & LOCAL_TYPE)
emit_localaddr(value + ref_offset);
else
emit_globaladdr(value, ref_offset, type);
ref_offset = 0;
}
else
{
parse_error("Bad index reference");
return (0);
}
emit_value = 1;
}
else
{
if (ref_offset != 0)
{
emit_const(ref_offset);
emit_op(ADD_TOKEN);
ref_offset = 0;
}
}
while (parse_expr())
{
if (scantoken != COMMA_TOKEN)
break;
emit_indexword();
emit_lw();
}
if (scantoken != CLOSE_BRACKET_TOKEN)
{
parse_error("Missing closing bracket");
return (0);
}
if (ref_type & (WPTR_TYPE | WORD_TYPE))
{
emit_indexword();
ref_type = WPTR_TYPE;
}
else
{
emit_indexbyte();
ref_type = BPTR_TYPE;
}
break;
case PTRB_TOKEN:
case PTRW_TOKEN:
/*
* Structure member pointer
*/
if (!emit_value)
{
if (type & CONST_TYPE)
emit_const(value);
else if (type & ADDR_TYPE)
{
if (type & LOCAL_TYPE)
(ref_type & BYTE_TYPE) ? emit_llb(value + ref_offset) : emit_llw(value + ref_offset);
else
(ref_type & BYTE_TYPE) ? emit_lab(value, ref_offset, type) : emit_law(value, ref_offset, type);
}
emit_value = 1;
}
else
{
if (ref_offset != 0)
{
emit_const(ref_offset);
emit_op(ADD_TOKEN);
}
if (ref_type & PTR_TYPE)
(ref_type & BPTR_TYPE) ? emit_lb() : emit_lw();
}
ref_offset = 0;
ref_type = (scantoken == PTRB_TOKEN) ? BPTR_TYPE : WPTR_TYPE;
if (!parse_const(&ref_offset))
scan_rewind(tokenstr);
break;
case DOT_TOKEN:
case COLON_TOKEN:
/*
* Structure member offset
*/
ref_type = (ref_type & (VAR_TYPE | CONST_TYPE))
? ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE)
: ((scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE);
if (parse_const(&const_offset))
ref_offset += const_offset;
else
scan_rewind(tokenstr);
if (!emit_value)
{
if (type & CONST_TYPE)
{
value += ref_offset;
ref_offset = 0;
}
else if (type & FUNC_TYPE)
{
emit_globaladdr(value, ref_offset, type);
ref_offset = 0;
emit_value = 1;
}
}
break; break;
} }
} }
if (emit_value) if (emit_value)
{ {
if (rvalue && deref && (type & PTR_TYPE)) if (ref_offset != 0)
(type & BPTR_TYPE) ? emit_lb() : emit_lw(); {
emit_const(ref_offset);
emit_op(ADD_TOKEN);
ref_offset = 0;
}
if (deref)
{
if (ref_type & BPTR_TYPE) emit_lb();
else if (ref_type & WPTR_TYPE) emit_lw();
}
}
else
{
if (deref)
{
if (type & CONST_TYPE)
{
emit_const(value);
if (ref_type & VAR_TYPE)
(ref_type & BYTE_TYPE) ? emit_lb() : emit_lw();
}
else if (type & FUNC_TYPE)
emit_call(value, ref_type);
else if (type & VAR_TYPE)
{
if (type & LOCAL_TYPE)
(ref_type & BYTE_TYPE) ? emit_llb(value + ref_offset) : emit_llw(value + ref_offset);
else
(ref_type & BYTE_TYPE) ? emit_lab(value, ref_offset, ref_type) : emit_law(value, ref_offset, ref_type);
}
} }
else else
{ {
if (type & CONST_TYPE) if (type & CONST_TYPE)
emit_const(value); emit_const(value);
else if (deref) else if (type & ADDR_TYPE)
{
if (type & FUNC_TYPE)
emit_call(value, type);
else if (type & VAR_TYPE)
{ {
if (type & LOCAL_TYPE) if (type & LOCAL_TYPE)
(type & BYTE_TYPE) ? emit_llb(value + elem_offset) : emit_llw(value + elem_offset); emit_localaddr(value + ref_offset);
else else
(type & BYTE_TYPE) ? emit_lab(value, elem_offset, type) : emit_law(value, elem_offset, type); emit_globaladdr(value, ref_offset, ref_type);
} }
else if (type & PTR_TYPE)
(type & BPTR_TYPE) ? emit_lb() : emit_lw();
}
else
{
if (type & LOCAL_TYPE)
emit_localaddr(value + elem_offset);
else
emit_globaladdr(value, elem_offset, type);
} }
} }
while (optos < opsptr) while (optos < opsptr)
@ -534,61 +714,9 @@ int parse_value(int rvalue)
return (0); return (0);
} }
} }
return (type ? type : WORD_TYPE); if (type & PTR_TYPE)
} ref_type = type;
int parse_constexpr(long *value, int *size) return (ref_type ? ref_type : WORD_TYPE);
{
long val1, val2;
int type, size1, size2 = 0;
if (!(type = parse_constval(&val1, &size1)))
return (0);
if (scan() == ADD_TOKEN)
{
if (!parse_constval(&val2, &size2))
return (0);
*value = val1 + val2;
}
else if (scantoken == SUB_TOKEN)
{
if (!parse_constval(&val2, &size2))
return (0);
*value = val1 - val2;
}
else if (scantoken == MUL_TOKEN)
{
if (!parse_constval(&val2, &size2))
return (0);
*value = val1 * val2;
}
else if (scantoken == DIV_TOKEN)
{
if (!parse_constval(&val2, &size2))
return (0);
*value = val1 / val2;
}
else if (scantoken == AND_TOKEN)
{
if (!parse_constval(&val2, &size2))
return (0);
*value = val1 & val2;
}
else if (scantoken == OR_TOKEN)
{
if (!parse_constval(&val2, &size2))
return (0);
*value = val1 | val2;
}
else if (scantoken == EOR_TOKEN)
{
if (!parse_constval(&val2, &size2))
return (0);
*value = val1 ^ val2;
}
else
*value = val1;
*size = size1 > size2 ? size1 : size2;
return (type);
} }
int parse_expr() int parse_expr()
{ {
@ -853,6 +981,10 @@ int parse_stmnt(void)
return (0); return (0);
} }
} }
else if (scantoken == EOL_TOKEN)
{
next_line();
}
else else
{ {
parse_error("Bad CASE clause"); parse_error("Bad CASE clause");
@ -932,7 +1064,7 @@ int parse_stmnt(void)
*/ */
int elem_size; int elem_size;
elem_type = (scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE; elem_type = (scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE;
if (!parse_constval(&elem_offset, &elem_size)) if (!parse_const(&elem_offset))
scantoken = ID_TOKEN; scantoken = ID_TOKEN;
else else
scan(); scan();

View File

@ -874,7 +874,7 @@ void interp(code *ip)
} }
} }
char *stdlib_exp[] = { char *syslib_exp[] = {
"PUTC", "PUTC",
"PUTS", "PUTS",
"PUTSZ", "PUTSZ",
@ -902,12 +902,12 @@ int main(int argc, char **argv)
/* /*
* Add default library. * Add default library.
*/ */
stodci("STDLIB", dci); stodci("CMDSYS", dci);
add_mod(dci, 0xFFFF); add_mod(dci, 0xFFFF);
for (i = 0; stdlib_exp[i]; i++) for (i = 0; syslib_exp[i]; i++)
{ {
mem_data[i] = i + 3; mem_data[i] = i + 3;
stodci(stdlib_exp[i], dci); stodci(syslib_exp[i], dci);
add_sym(dci, i); add_sym(dci, i);
} }
if (argc) if (argc)

View File

@ -1308,16 +1308,16 @@ BREQ INX
LDA ESTKL-1,X LDA ESTKL-1,X
CMP ESTKL,X CMP ESTKL,X
BNE NOBRNCH BNE NOBRNCH
LDA ESTKL-1,X LDA ESTKH-1,X
CMP ESTKL,X CMP ESTKH,X
BEQ BRNCH BEQ BRNCH
BNE NOBRNCH BNE NOBRNCH
BRNE INX BRNE INX
LDA ESTKL-1,X LDA ESTKL-1,X
CMP ESTKL,X CMP ESTKL,X
BNE BRNCH BNE BRNCH
LDA ESTKL-1,X LDA ESTKH-1,X
CMP ESTKL,X CMP ESTKH,X
BEQ NOBRNCH BEQ NOBRNCH
BNE BRNCH BNE BRNCH
BRGT INX BRGT INX

View File

@ -1,18 +0,0 @@
import stdlib
predef putc, putln, puts, getc, gets
predef call, syscall
predef heapmark, heapallocallign, heapalloc, heaprelease, heapavail
predef memset, memcpy
predef isugt, isuge, isult, isule
predef load, exec
word MACHID, sysvars
//
// System flags: memory allocator screen holes.
//
const restxt1 = $0001
const restxt2 = $0002
const reshgr1 = $0004
const reshgr2 = $0008
const resxhgr1 = $0010
const resxhgr2 = $0020
end

View File

@ -1,7 +1,7 @@
// //
// Include all imported modules and their data/functions. // Include all imported modules and their data/functions.
// //
include(stdlib.plh) include(cmdsys.plh)
include(testlib.plh) include(testlib.plh)
// //
// Structure definition. // Structure definition.
@ -13,6 +13,10 @@ struc mystruc
word data word data
end end
// //
// Const expression
//
const constval = 2*(2+3) // a test expression should evaluate to 10
//
// Declare all global variables for this module. // Declare all global variables for this module.
// Note that arrays are declared with prefix []. postfix [], or no []. // Note that arrays are declared with prefix []. postfix [], or no [].
// Only arrays with predclared sizes need [ and ], such as "int[3] a". // Only arrays with predclared sizes need [ and ], such as "int[3] a".
@ -24,6 +28,7 @@ byte[] a2p = "][+"
byte[] a2e = "//e" byte[] a2e = "//e"
byte[] a2c = "//c" byte[] a2c = "//c"
byte[] a3 = "///" byte[] a3 = "///"
byte constr = "Constant expression = "
byte[] offsets = "Structure offsets:" byte[] offsets = "Structure offsets:"
word array[] = 1, 10, 100, 1000, 10000 word array[] = 1, 10, 100, 1000, 10000
word ptr word ptr
@ -87,8 +92,9 @@ export def main(range)
wend wend
putln putln
end end
ptr = @main
ptr(@array:6)
ptr = @array ptr = @array
main(@array:6)
puti((ptr):6) puti((ptr):6)
putln putln
puti(ptr=>6) puti(ptr=>6)
@ -107,4 +113,5 @@ puti(data)
putln putln
puti(mystruc) puti(mystruc)
putln putln
puts(@constr); puti(constval); putln
done done

View File

@ -1,22 +1,17 @@
// //
// Include all imported modules and their data/functions. // Include all imported modules and their data/functions.
// //
include(cmdsys.plh)
include(stdlib.plh)
// //
// Module data. // Module data.
// //
predef puti, puth, putln predef puti, puth, putln
export word print[] = @puti, @puth, @putln, @puts, @putc 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 valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
byte loadstr[] = "testlib loaded!" byte loadstr[] = "testlib loaded!"
// //
// Define functions. // Define functions.
// //
def puth(h) def puth(h)
putc('$') putc('$')
putc(valstr[(h >> 12) & $0F]) putc(valstr[(h >> 12) & $0F])
@ -24,7 +19,6 @@ def puth(h)
putc(valstr[(h >> 4) & $0F]) putc(valstr[(h >> 4) & $0F])
putc(valstr[ h & $0F]) putc(valstr[ h & $0F])
end end
export def puti(i) export def puti(i)
if i < 0; putc('-'); i = -i; fin if i < 0; putc('-'); i = -i; fin
if i < 10 if i < 10
@ -34,7 +28,6 @@ export def puti(i)
putc(i % 10 + '0') putc(i % 10 + '0')
fin fin
end end
puts(@loadstr) puts(@loadstr)
putln putln
done done