diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index 6d8c6a80e..a36e1ccaa 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -6,13 +6,14 @@ sub start() { - repeat { - _vm_write_str("333\n") - } until(1) + str s1 = "hello" + str s2 = "bye" - repeat { - _vm_write_str("444\n") - } until (0) + _vm_write_str(s1) + s1 = s2 + _vm_write_str(s1) + s1 = "ciao" + _vm_write_str(s1) return diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index bb468fdf6..b20e42f2c 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -259,12 +259,9 @@ class AstChecker(private val namespace: INameScope, } // 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)) { - 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 -> - 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 -> {} } @@ -708,6 +705,8 @@ class AstChecker(private val namespace: INameScope, return err("value '$number' out of range for unsigned word") } 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!! if (str.isEmpty() || str.length > 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.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_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)) } diff --git a/compiler/src/prog8/stackvm/StackVm.kt b/compiler/src/prog8/stackvm/StackVm.kt index df8d5944e..8787932ad 100644 --- a/compiler/src/prog8/stackvm/StackVm.kt +++ b/compiler/src/prog8/stackvm/StackVm.kt @@ -901,9 +901,9 @@ class StackVm(private var traceOutputFile: String?) { } Opcode.POP_VAR_W -> { 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}") - checkDt(variable, DataType.WORD) + checkDt(variable, setOf(DataType.WORD, DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS)) variables[ins.callLabel!!] = value } Opcode.POP_VAR_F -> {