mirror of
https://github.com/irmen/prog8.git
synced 2025-11-24 06:17:39 +00:00
better error when trying to use a const pointer (which is not supported yet)
This commit is contained in:
@@ -874,9 +874,9 @@ internal class AstChecker(private val program: Program,
|
||||
err("recursive var declaration")
|
||||
|
||||
// CONST can only occur on simple types (byte, word, float)
|
||||
if(decl.type== VarDeclType.CONST) {
|
||||
if(decl.type==VarDeclType.CONST) {
|
||||
if (!decl.datatype.isNumericOrBool)
|
||||
err("const can only be used on numeric types or booleans")
|
||||
err("const can only be used on numbers and booleans")
|
||||
}
|
||||
|
||||
// FLOATS enabled?
|
||||
|
||||
@@ -27,45 +27,46 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
||||
if(valueType.isUnknown)
|
||||
return noModifications
|
||||
val valueDt = valueType.getOrUndef()
|
||||
when(decl.type) {
|
||||
VarDeclType.VAR -> {
|
||||
if(decl.isArray) {
|
||||
// using a array of words as initializer to a pointer array is fine
|
||||
if (!valueDt.isSplitWordArray || !decl.datatype.isPointerArray)
|
||||
errors.err("value has incompatible type ($valueType) for the variable (${decl.datatype})", decl.value!!.position)
|
||||
} else if(!decl.datatype.isString) {
|
||||
if (valueDt.largerSizeThan(decl.datatype)) {
|
||||
val constValue = decl.value?.constValue(program)
|
||||
if (constValue != null)
|
||||
errors.err("value '$constValue' out of range for ${decl.datatype}", constValue.position)
|
||||
else
|
||||
errors.err("value out of range for ${decl.datatype}", decl.value!!.position)
|
||||
if(!(valueDt.isWord && decl.datatype.isPointer)) {
|
||||
when(decl.type) {
|
||||
VarDeclType.VAR -> {
|
||||
if(decl.isArray) {
|
||||
// using a array of words as initializer to a pointer array is fine
|
||||
if (!valueDt.isSplitWordArray || !decl.datatype.isPointerArray)
|
||||
errors.err("value has incompatible type ($valueType) for the variable (${decl.datatype})", decl.value!!.position)
|
||||
} else if(!decl.datatype.isString) {
|
||||
if (valueDt.largerSizeThan(decl.datatype)) {
|
||||
val constValue = decl.value?.constValue(program)
|
||||
if (constValue != null)
|
||||
errors.err("value '$constValue' out of range for ${decl.datatype}", constValue.position)
|
||||
else
|
||||
errors.err("value out of range for ${decl.datatype}", decl.value!!.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
VarDeclType.CONST -> {
|
||||
// change the vardecl type itself as well, but only if new type is smaller
|
||||
if(valueDt.largerSizeThan(decl.datatype)) {
|
||||
val constValue = decl.value!!.constValue(program)!!
|
||||
errors.err("value '${constValue.number}' out of range for ${decl.datatype}", constValue.position)
|
||||
} else {
|
||||
// don't make it signed if it was unsigned and vice versa, except when it is a long const declaration
|
||||
if(!decl.datatype.isLong &&
|
||||
(valueDt.isSigned && decl.datatype.isUnsigned ||
|
||||
valueDt.isUnsigned && decl.datatype.isSigned))
|
||||
{
|
||||
VarDeclType.CONST -> {
|
||||
// change the vardecl type itself as well, but only if new type is smaller
|
||||
if(valueDt.largerSizeThan(decl.datatype)) {
|
||||
val constValue = decl.value!!.constValue(program)!!
|
||||
errors.err("value '${constValue.number}' out of range for ${decl.datatype}", constValue.position)
|
||||
} else {
|
||||
val changed = decl.copy(valueDt)
|
||||
return listOf(IAstModification.ReplaceNode(decl, changed, parent))
|
||||
// don't make it signed if it was unsigned and vice versa, except when it is a long const declaration
|
||||
if(!decl.datatype.isLong &&
|
||||
(valueDt.isSigned && decl.datatype.isUnsigned ||
|
||||
valueDt.isUnsigned && decl.datatype.isSigned))
|
||||
{
|
||||
val constValue = decl.value!!.constValue(program)!!
|
||||
errors.err("value '${constValue.number}' out of range for ${decl.datatype}", constValue.position)
|
||||
} else {
|
||||
val changed = decl.copy(valueDt)
|
||||
return listOf(IAstModification.ReplaceNode(decl, changed, parent))
|
||||
}
|
||||
}
|
||||
}
|
||||
VarDeclType.MEMORY -> if(!valueType.isWords && !valueType.isBytes)
|
||||
throw FatalAstException("value type for a memory var should be word or byte (address)")
|
||||
}
|
||||
VarDeclType.MEMORY -> if(!valueType.isWords && !valueType.isBytes)
|
||||
throw FatalAstException("value type for a memory var should be word or byte (address)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check splitting of word arrays
|
||||
|
||||
@@ -690,20 +690,28 @@ main {
|
||||
this.text = next as uword ; TODO fix type error; the cast should succeed
|
||||
}
|
||||
}"""
|
||||
compileText(VMTarget(), false, src, outputDir, writeAssembly = false) shouldNotBe null
|
||||
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
|
||||
compileText(C64Target(), false, src, outputDir) shouldNotBe null
|
||||
}
|
||||
|
||||
xtest("const pointer") {
|
||||
test("const pointer gives proper error") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
^^uword @shared ptr = 7000
|
||||
const ^^uword cptr = 8000 ; TODO fix type error; loses pointer
|
||||
ptr^^ = 12345
|
||||
cptr^^ = 12345
|
||||
const ^^uword cptr = 8000
|
||||
|
||||
;ptr^^ = 12345
|
||||
;cptr^^ = 12345
|
||||
|
||||
cx16.r0 = cptr
|
||||
cx16.r1 = ptr
|
||||
}
|
||||
}"""
|
||||
compileText(VMTarget(), false, src, outputDir, writeAssembly = false) shouldNotBe null
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(VMTarget(), false, src, outputDir, errors=errors, writeAssembly = true) shouldBe null
|
||||
errors.errors.size shouldBe 1
|
||||
errors.errors[0] shouldContain("const can only be used on numbers and booleans")
|
||||
}
|
||||
|
||||
test("unknown field") {
|
||||
|
||||
@@ -208,8 +208,8 @@ private fun makeSt(): SymbolTable {
|
||||
val sub12 = StNode("sub2", StNodeType.SUBROUTINE, astSub2)
|
||||
block1.add(sub11)
|
||||
block1.add(sub12)
|
||||
block1.add(StConstant("c1", BaseDataType.UWORD, 12345.0, astConstant1))
|
||||
block1.add(StConstant("blockc", BaseDataType.UWORD, 999.0, astConstant2))
|
||||
block1.add(StConstant("c1", DataType.UWORD, 12345.0, astConstant1))
|
||||
block1.add(StConstant("blockc", DataType.UWORD, 999.0, astConstant2))
|
||||
sub11.add(StStaticVariable("v1", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0u, false, astSub1v1))
|
||||
sub11.add(StStaticVariable("v2", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0u, false, astSub1v2))
|
||||
sub11.add(StMemVar("v3", DataType.FLOAT, 12345u, null, astSub1v3))
|
||||
|
||||
Reference in New Issue
Block a user