mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-10-11 18:23:48 +00:00
Fix VM bug in BRNE/BREQ, parse lvalue bug, and rename stdlib to cmdsys
This commit is contained in:
parent
a71d652f30
commit
508a2c84fb
@ -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
|
||||||
//
|
//
|
||||||
|
@ -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();
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user