mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +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 {
|
~ main {
|
||||||
|
|
||||||
|
memory byte jiffyclockHi = $a0
|
||||||
|
memory byte jiffyclockMid = $a1
|
||||||
|
memory byte jiffyclockLo = $a2
|
||||||
|
|
||||||
|
|
||||||
sub start() -> () {
|
sub start() -> () {
|
||||||
|
_vm_gfx_pixel(jiffyclockLo,190,jiffyclockHi)
|
||||||
byte jiffyclockHi = $a0
|
_vm_gfx_pixel(jiffyclockLo,191,jiffyclockMid)
|
||||||
byte jiffyclockMid = $a1
|
_vm_gfx_pixel(jiffyclockLo,192,jiffyclockLo)
|
||||||
byte jiffyclockLo = $a2
|
return
|
||||||
|
|
||||||
_vm_gfx_pixel(2,2,jiffyclockHi)
|
|
||||||
_vm_gfx_pixel(4,2,jiffyclockMid)
|
|
||||||
_vm_gfx_pixel(6,2,jiffyclockLo)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -712,19 +712,13 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
|||||||
position: Position) : Boolean {
|
position: Position) : Boolean {
|
||||||
|
|
||||||
if(sourceValue is RangeExpr)
|
if(sourceValue is RangeExpr)
|
||||||
return checkValueTypeAndRange(targetDatatype, null, sourceValue)
|
checkResult.add(SyntaxError("can't assign a range value", position))
|
||||||
|
|
||||||
val result = when(targetDatatype) {
|
val result = when(targetDatatype) {
|
||||||
DataType.BYTE -> sourceDatatype==DataType.BYTE
|
DataType.BYTE -> sourceDatatype==DataType.BYTE
|
||||||
DataType.WORD -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD
|
DataType.WORD -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD
|
||||||
DataType.FLOAT -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD || sourceDatatype==DataType.FLOAT
|
DataType.FLOAT -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD || sourceDatatype==DataType.FLOAT
|
||||||
DataType.STR -> sourceDatatype==DataType.STR
|
else -> checkResult.add(SyntaxError("cannot assign new value to variable of type $targetDatatype", position))
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
|
@ -118,12 +118,10 @@ class Compiler(private val options: CompilationOptions) {
|
|||||||
// collect all the VarDecls to make them into one global list
|
// 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...
|
// @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 {
|
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) {
|
if (decl.type == VarDeclType.VAR) {
|
||||||
stackvmProg.blockvar(decl.scopedname, decl)
|
stackvmProg.blockvar(decl.scopedname, decl)
|
||||||
}
|
}
|
||||||
|
// MEMORY variables are memory mapped and thus need no storage at all
|
||||||
return super.process(decl)
|
return super.process(decl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,7 +331,21 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram, priva
|
|||||||
val target = expr.targetStatement(namespace)
|
val target = expr.targetStatement(namespace)
|
||||||
when(target) {
|
when(target) {
|
||||||
is VarDecl -> {
|
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")
|
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
|
Augmented assignments (such as ``A += X``) are also available, but these are just shorthands
|
||||||
for normal assignments (``A = A + X``).
|
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::
|
.. attention::
|
||||||
**Data type conversion (in assignments):**
|
**Data type conversion (in assignments):**
|
||||||
When assigning a value with a 'smaller' datatype to a register or variable with a 'larger' datatype,
|
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)
|
``&`` is bitwise and, ``|`` is bitwise or, ``^`` is bitwise xor, ``~`` is bitwise invert (this one is an unary operator)
|
||||||
|
|
||||||
assignment: ``=``
|
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: ``+=`` ``-=`` ``*=`` ``/=`` ``**=`` ``&=`` ``|=`` ``^=``
|
augmented assignment: ``+=`` ``-=`` ``*=`` ``/=`` ``**=`` ``&=`` ``|=`` ``^=``
|
||||||
Syntactic sugar; ``A += X`` is equivalent to ``A = A + X``
|
Syntactic sugar; ``A += X`` is equivalent to ``A = A + X``
|
||||||
|
Loading…
Reference in New Issue
Block a user