allow to re-assign string variables

This commit is contained in:
Irmen de Jong 2018-10-08 01:20:53 +02:00
parent 3ac2385d4b
commit c2a1cb956a
3 changed files with 16 additions and 12 deletions

View File

@ -6,13 +6,14 @@
sub start() { sub start() {
repeat { str s1 = "hello"
_vm_write_str("333\n") str s2 = "bye"
} until(1)
repeat { _vm_write_str(s1)
_vm_write_str("444\n") s1 = s2
} until (0) _vm_write_str(s1)
s1 = "ciao"
_vm_write_str(s1)
return return

View File

@ -259,12 +259,9 @@ class AstChecker(private val namespace: INameScope,
} }
// it is not possible to assign a new array to something. // it is not possible to assign a new array to something.
// currently, it's also not possible to assign a new string to a string variable.
when(assignment.value.resultingDatatype(namespace, heap)) { when(assignment.value.resultingDatatype(namespace, heap)) {
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS ->
checkResult.add(SyntaxError("it's not possible to reassign a string", assignment.position)) // todo allow reassigning strings
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX ->
checkResult.add(SyntaxError("it's not possible to reassign an array", assignment.position)) checkResult.add(SyntaxError("it's not possible to assign an array literal value to something, use it as a variable decl initializer instead", assignment.position))
else -> {} else -> {}
} }
@ -708,6 +705,8 @@ class AstChecker(private val namespace: INameScope,
return err("value '$number' out of range for unsigned word") return err("value '$number' out of range for unsigned word")
} }
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> { DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> {
if(!value.isString)
return err("string value expected")
val str = value.strvalue ?: heap.get(value.heapId!!).str!! val str = value.strvalue ?: heap.get(value.heapId!!).str!!
if (str.isEmpty() || str.length > 255) if (str.isEmpty() || str.length > 255)
return err("string length must be 1 to 255") return err("string length must be 1 to 255")
@ -818,6 +817,10 @@ class AstChecker(private val namespace: INameScope,
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
DataType.STR_S -> sourceDatatype==DataType.STR_S
DataType.STR_P -> sourceDatatype==DataType.STR_P
DataType.STR_PS -> sourceDatatype==DataType.STR_PS
else -> checkResult.add(SyntaxError("cannot assign new value to variable of type $targetDatatype", position)) else -> checkResult.add(SyntaxError("cannot assign new value to variable of type $targetDatatype", position))
} }

View File

@ -901,9 +901,9 @@ class StackVm(private var traceOutputFile: String?) {
} }
Opcode.POP_VAR_W -> { Opcode.POP_VAR_W -> {
val value = evalstack.pop() val value = evalstack.pop()
checkDt(value, setOf(DataType.WORD, DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS, DataType.MATRIX)) checkDt(value, setOf(DataType.WORD, DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS))
val variable = variables[ins.callLabel] ?: throw VmExecutionException("unknown variable: ${ins.callLabel}") val variable = variables[ins.callLabel] ?: throw VmExecutionException("unknown variable: ${ins.callLabel}")
checkDt(variable, DataType.WORD) checkDt(variable, setOf(DataType.WORD, DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS))
variables[ins.callLabel!!] = value variables[ins.callLabel!!] = value
} }
Opcode.POP_VAR_F -> { Opcode.POP_VAR_F -> {