mirror of
https://github.com/irmen/prog8.git
synced 2024-12-27 20:33:39 +00:00
created direct-on-memory ++/-- and augmented assignemnts.
This commit is contained in:
parent
aeb963673a
commit
c07bd8a4a8
@ -4,11 +4,22 @@
|
||||
|
||||
sub start() {
|
||||
|
||||
ubyte[63] balloonsprite = [ 0,127,0,1,255,192,3,255,224,3,231,224,
|
||||
7,217,240,7,223,240,7,217,240,3,231,224,
|
||||
3,255,224,3,255,224,2,255,160,1,127,64,
|
||||
1,62,64,0,156,128,0,156,128,0,73,0,0,73,0,
|
||||
0,62,0,0,62,0,0,62,0,0,28,0 ]
|
||||
A+=5
|
||||
|
||||
; @todo if-else if should compile ?:
|
||||
; if A>100
|
||||
; Y=2
|
||||
; else if A>20
|
||||
; Y=3
|
||||
|
||||
|
||||
; @($d020) = 5
|
||||
@($d020)++
|
||||
@($d021)--
|
||||
; @($d020)=(@$d020)+5
|
||||
@($d020)+=5
|
||||
; @($d021)=(@$d021)-5
|
||||
@($d021)-=5
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +391,6 @@ class AstChecker(private val namespace: INameScope,
|
||||
if(memAddr!=null) {
|
||||
if(memAddr<0 || memAddr>=65536)
|
||||
checkResult.add(ExpressionError("address out of range", target.position))
|
||||
return assignment
|
||||
}
|
||||
|
||||
if(target.identifier!=null) {
|
||||
@ -436,6 +435,16 @@ class AstChecker(private val namespace: INameScope,
|
||||
target.register != null -> RegisterExpr(target.register, target.position)
|
||||
target.identifier != null -> target.identifier
|
||||
target.arrayindexed != null -> target.arrayindexed
|
||||
target.memAddressExpression != null -> {
|
||||
// @addr += 4 --> @addr = @addr +4
|
||||
// TODO: make it so that it follows the others
|
||||
val memRead = DirectMemoryExpression(target.memAddressExpression!!, target.position)
|
||||
val expression = BinaryExpression(memRead, assignment.aug_op.substringBeforeLast('='), assignment.value, assignment.position)
|
||||
expression.linkParents(assignment.parent)
|
||||
val assignment2 = Assignment(listOf(target), null, expression, assignment.position)
|
||||
assignment2.linkParents(assignment.parent)
|
||||
return assignment2
|
||||
}
|
||||
else -> throw FatalAstException("strange assignment")
|
||||
}
|
||||
|
||||
@ -818,6 +827,8 @@ class AstChecker(private val namespace: INameScope,
|
||||
if(dt !in NumericDatatypes && dt !in ArrayDatatypes)
|
||||
checkResult.add(SyntaxError("can only increment or decrement a byte/float/word", postIncrDecr.position))
|
||||
}
|
||||
} else if(postIncrDecr.target.memAddressExpression != null) {
|
||||
// a memory location can always be ++/--
|
||||
}
|
||||
return super.process(postIncrDecr)
|
||||
}
|
||||
|
@ -1273,7 +1273,18 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
"--" -> prog.instr(opcodeDecArrayindexedVar(variable.datatype), callLabel = variable.scopedname)
|
||||
}
|
||||
}
|
||||
else -> throw CompilerException("very strange postincrdecr")
|
||||
stmt.target.memAddressExpression != null -> {
|
||||
val address = stmt.target.memAddressExpression!!.constValue(namespace, heap)?.asIntegerValue
|
||||
if(address!=null) {
|
||||
when(stmt.operator) {
|
||||
"++" -> prog.instr(Opcode.INC_MEMORY, Value(DataType.UWORD, address))
|
||||
"--" -> prog.instr(Opcode.DEC_MEMORY, Value(DataType.UWORD, address))
|
||||
}
|
||||
} else {
|
||||
TODO("memory ++/-- ${stmt.target.memAddressExpression}")
|
||||
}
|
||||
}
|
||||
else -> throw CompilerException("very strange postincrdecr ${stmt.target}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1357,6 +1368,9 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
assignTarget.register != null -> prog.instr(Opcode.PUSH_VAR_BYTE, callLabel = assignTarget.register.toString())
|
||||
assignTarget.arrayindexed != null -> translate(assignTarget.arrayindexed, false)
|
||||
assignTarget.memAddressExpression != null -> {
|
||||
TODO("translate aug assign on memory address $stmt")
|
||||
}
|
||||
}
|
||||
|
||||
translateAugAssignOperator(stmt.aug_op, stmt.value.resultingDatatype(namespace, heap))
|
||||
@ -1496,7 +1510,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateAugAssignOperator(aug_op: String, valueDt: DataType?) {
|
||||
private fun translateAugAssignOperator(aug_op: String, valueDt: DataType?) { // @todo: not used in practice? (all augassigns are converted to normal assigns)
|
||||
if(valueDt==null)
|
||||
throw CompilerException("value datatype not known")
|
||||
val validDt = setOf(DataType.UBYTE, DataType.UWORD, DataType.FLOAT)
|
||||
|
@ -164,6 +164,8 @@ enum class Opcode {
|
||||
DEC_VAR_W,
|
||||
DEC_VAR_UW,
|
||||
DEC_VAR_F,
|
||||
INC_MEMORY,
|
||||
DEC_MEMORY,
|
||||
|
||||
// comparisons
|
||||
// @todo the comparisons push the result back on the stack. Optimize this to work with just processor flags? This does mean you can no longer use a logical boolean result as a byte 0/1 value ?
|
||||
|
@ -655,6 +655,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
jsr prog8_lib.dec_var_f
|
||||
"""
|
||||
}
|
||||
Opcode.INC_MEMORY -> " inc ${hexVal(ins)}"
|
||||
Opcode.DEC_MEMORY -> " dec ${hexVal(ins)}"
|
||||
Opcode.NEG_B -> " jsr prog8_lib.neg_b"
|
||||
Opcode.NEG_W -> " jsr prog8_lib.neg_w"
|
||||
Opcode.NEG_F -> " jsr prog8_lib.neg_f"
|
||||
|
@ -968,6 +968,16 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
val array = heap.get(variable.heapId)
|
||||
array.array!![index].dec()
|
||||
}
|
||||
Opcode.INC_MEMORY -> {
|
||||
val address = evalstack.pop()
|
||||
checkDt(address, DataType.UWORD)
|
||||
TODO("inc_memory $address")
|
||||
}
|
||||
Opcode.DEC_MEMORY -> {
|
||||
val address = evalstack.pop()
|
||||
checkDt(address, DataType.UWORD)
|
||||
TODO("dec_memory $address")
|
||||
}
|
||||
Opcode.MSB -> {
|
||||
val v = evalstack.pop()
|
||||
checkDt(v, DataType.UWORD, DataType.WORD)
|
||||
|
Loading…
Reference in New Issue
Block a user