mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
fixed memory vars in compiler, added invalid assignment check
This commit is contained in:
parent
7f28f8be11
commit
91f9229b07
@ -1,13 +1,16 @@
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
memory byte jiffyclockHi = $a0
|
||||
memory byte jiffyclockMid = $a1
|
||||
memory byte jiffyclockLo = $a2
|
||||
|
||||
|
||||
sub start() -> () {
|
||||
|
||||
byte jiffyclockHi = $a0
|
||||
byte jiffyclockMid = $a1
|
||||
byte jiffyclockLo = $a2
|
||||
|
||||
_vm_gfx_pixel(2,2,jiffyclockHi)
|
||||
_vm_gfx_pixel(4,2,jiffyclockMid)
|
||||
_vm_gfx_pixel(6,2,jiffyclockLo)
|
||||
_vm_gfx_pixel(jiffyclockLo,190,jiffyclockHi)
|
||||
_vm_gfx_pixel(jiffyclockLo,191,jiffyclockMid)
|
||||
_vm_gfx_pixel(jiffyclockLo,192,jiffyclockLo)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -712,19 +712,13 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
||||
position: Position) : Boolean {
|
||||
|
||||
if(sourceValue is RangeExpr)
|
||||
return checkValueTypeAndRange(targetDatatype, null, sourceValue)
|
||||
checkResult.add(SyntaxError("can't assign a range value", position))
|
||||
|
||||
val result = when(targetDatatype) {
|
||||
DataType.BYTE -> sourceDatatype==DataType.BYTE
|
||||
DataType.WORD -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD
|
||||
DataType.FLOAT -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD || sourceDatatype==DataType.FLOAT
|
||||
DataType.STR -> sourceDatatype==DataType.STR
|
||||
DataType.STR_P -> sourceDatatype==DataType.STR_P
|
||||
DataType.STR_S -> sourceDatatype==DataType.STR_S
|
||||
DataType.STR_PS -> sourceDatatype==DataType.STR_PS
|
||||
DataType.ARRAY -> sourceDatatype==DataType.ARRAY
|
||||
DataType.ARRAY_W -> sourceDatatype==DataType.ARRAY_W
|
||||
DataType.MATRIX -> sourceDatatype==DataType.MATRIX
|
||||
else -> checkResult.add(SyntaxError("cannot assign new value to variable of type $targetDatatype", position))
|
||||
}
|
||||
|
||||
if(result)
|
||||
|
@ -118,12 +118,10 @@ class Compiler(private val options: CompilationOptions) {
|
||||
// collect all the VarDecls to make them into one global list
|
||||
// @todo maybe keep the block structure intact and allocate them per block? this is needed eventually for the actual 6502 code generation so...
|
||||
override fun process(decl: VarDecl): IStatement {
|
||||
if(decl.type == VarDeclType.MEMORY)
|
||||
TODO("stackVm doesn't support memory vars for now")
|
||||
|
||||
if (decl.type == VarDeclType.VAR) {
|
||||
stackvmProg.blockvar(decl.scopedname, decl)
|
||||
}
|
||||
// MEMORY variables are memory mapped and thus need no storage at all
|
||||
return super.process(decl)
|
||||
}
|
||||
}
|
||||
@ -333,7 +331,21 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram, priva
|
||||
val target = expr.targetStatement(namespace)
|
||||
when(target) {
|
||||
is VarDecl -> {
|
||||
stackvmProg.instr(Opcode.PUSH_VAR, Value(DataType.STR, null, target.scopedname))
|
||||
when(target.type) {
|
||||
VarDeclType.VAR ->
|
||||
stackvmProg.instr(Opcode.PUSH_VAR, Value(DataType.STR, null, target.scopedname))
|
||||
VarDeclType.CONST ->
|
||||
throw CompilerException("const ref should have been const-folded away")
|
||||
VarDeclType.MEMORY -> {
|
||||
when(target.datatype){
|
||||
DataType.BYTE -> stackvmProg.instr(Opcode.PUSH_MEM, Value(DataType.WORD, (target.value as LiteralValue).asNumericValue))
|
||||
DataType.WORD -> stackvmProg.instr(Opcode.PUSH_MEM_W, Value(DataType.WORD, (target.value as LiteralValue).asNumericValue))
|
||||
DataType.FLOAT -> stackvmProg.instr(Opcode.PUSH_MEM_F, Value(DataType.WORD, (target.value as LiteralValue).asNumericValue))
|
||||
else -> TODO("invalid datatype for memory variable expression: $target")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else -> throw CompilerException("expression identifierref should be a vardef, not $target")
|
||||
}
|
||||
|
@ -364,6 +364,10 @@ Assignment statements assign a single value to a target variable or memory locat
|
||||
Augmented assignments (such as ``A += X``) are also available, but these are just shorthands
|
||||
for normal assignments (``A = A + X``).
|
||||
|
||||
Only register variables and variables of type byte, word and float can be assigned a new value.
|
||||
It's not possible to set a new value to string or array variables etc, because they get allocated
|
||||
a fixed amount of memory which will not change.
|
||||
|
||||
.. attention::
|
||||
**Data type conversion (in assignments):**
|
||||
When assigning a value with a 'smaller' datatype to a register or variable with a 'larger' datatype,
|
||||
|
@ -335,7 +335,8 @@ bitwise arithmetic: ``&`` ``|`` ``^`` ``~``
|
||||
``&`` is bitwise and, ``|`` is bitwise or, ``^`` is bitwise xor, ``~`` is bitwise invert (this one is an unary operator)
|
||||
|
||||
assignment: ``=``
|
||||
Sets the target on the LHS (left hand side) of the operator to the value of the expression on the RHS (right hand side).
|
||||
Sets the target on the LHS (left hand side) of the operator to the value of the expression on the RHS (right hand side).
|
||||
Note that an assignment sometimes is not possible or supported.
|
||||
|
||||
augmented assignment: ``+=`` ``-=`` ``*=`` ``/=`` ``**=`` ``&=`` ``|=`` ``^=``
|
||||
Syntactic sugar; ``A += X`` is equivalent to ``A = A + X``
|
||||
|
Loading…
Reference in New Issue
Block a user