mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 06:16:15 +00:00
better error when trying to use a const pointer (which is not supported yet)
This commit is contained in:
@@ -938,7 +938,7 @@ internal class ProgramAndVarsGen(
|
||||
asmgen.out(" ${it.name} = ${it.address.toHex()}")
|
||||
}
|
||||
consts.sortedBy { it.name }.forEach {
|
||||
if(it.dt==BaseDataType.FLOAT)
|
||||
if(it.dt.isFloat)
|
||||
asmgen.out(" ${it.name} = ${it.value}")
|
||||
else
|
||||
asmgen.out(" ${it.name} = ${it.value.toHex()}")
|
||||
|
||||
@@ -122,7 +122,6 @@ private fun convert(variable: StMemVar): IRStMemVar {
|
||||
|
||||
|
||||
private fun convert(constant: StConstant): IRStConstant {
|
||||
val dt = DataType.forDt(constant.dt)
|
||||
val scopedName = if('.' in constant.name) {
|
||||
constant.name
|
||||
} else {
|
||||
@@ -132,7 +131,7 @@ private fun convert(constant: StConstant): IRStConstant {
|
||||
constant.name
|
||||
}
|
||||
}
|
||||
return IRStConstant(scopedName, dt, constant.value)
|
||||
return IRStConstant(scopedName, constant.dt, constant.value)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -876,7 +876,7 @@ internal class AstChecker(private val program: Program,
|
||||
// CONST can only occur on simple types (byte, word, float)
|
||||
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,6 +27,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
||||
if(valueType.isUnknown)
|
||||
return noModifications
|
||||
val valueDt = valueType.getOrUndef()
|
||||
if(!(valueDt.isWord && decl.datatype.isPointer)) {
|
||||
when(decl.type) {
|
||||
VarDeclType.VAR -> {
|
||||
if(decl.isArray) {
|
||||
@@ -65,7 +66,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
||||
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))
|
||||
|
||||
@@ -13,6 +13,7 @@ Future Things and Ideas
|
||||
- struct/ptr: optimize the float copying in assignIndexedPointer() (also word and long?)
|
||||
- struct/ptr: optimize augmented assignments to indexed pointer targets like sprptr[2]^^.y++ (these are now not performend in-place but as a regular assignment)
|
||||
- struct/ptr: implement even more struct instance assignments (via memcopy) in CodeDesugarer (see the TODO) (add to documentation as well, paragraph 'Structs')
|
||||
- struct/ptr: support const pointers (simple and struct types)
|
||||
- struct/ptr: support @nosplit pointer arrays?
|
||||
- struct/ptr: support pointer to pointer?
|
||||
- struct/ptr: support for typed function pointers? (&routine could be typed by default as well then)
|
||||
|
||||
149
examples/test.p8
149
examples/test.p8
@@ -1,135 +1,26 @@
|
||||
;%zeropage basicsafe
|
||||
;%import textio
|
||||
;
|
||||
;main {
|
||||
; sub start() {
|
||||
; ^^uword @shared ptr = 7000
|
||||
; const ^^uword cptr = 8000 ; TODO fix type error; loses pointer
|
||||
; ptr^^ = 12345
|
||||
; cptr^^ = 12345
|
||||
; txt.print_uw(peekw(7000))
|
||||
; txt.spc()
|
||||
; txt.print_uw(peekw(8000))
|
||||
; }
|
||||
;}
|
||||
|
||||
|
||||
; TYPE CAST CRASH:
|
||||
;%zeropage basicsafe
|
||||
;%import strings
|
||||
;%import textio
|
||||
;
|
||||
;main {
|
||||
; struct Line {
|
||||
; ^^Line prev
|
||||
; ^^Line next
|
||||
; ^^ubyte text
|
||||
; }
|
||||
; uword buffer = memory("buffer", 100*sizeof(Line), 1)
|
||||
; ^^Line next = buffer
|
||||
;
|
||||
; sub start() {
|
||||
; ^^Line line = next
|
||||
; next += 1
|
||||
; line.text = next as ^^ubyte ; TODO fix crash here
|
||||
; next = (next as uword) + 81
|
||||
; txt.print_uwhex(buffer, true) txt.nl()
|
||||
; txt.print_uwhex(next, true) txt.nl()
|
||||
; txt.print_uwhex(line, true) txt.nl()
|
||||
; txt.print_uwhex(line.text, true) txt.nl()
|
||||
; }
|
||||
;}
|
||||
|
||||
|
||||
%import floats
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
struct Node1 {
|
||||
ubyte type
|
||||
word ww
|
||||
}
|
||||
struct Node2 {
|
||||
ubyte type
|
||||
^^ubyte text
|
||||
}
|
||||
|
||||
sub start() {
|
||||
bytetest()
|
||||
wordtest()
|
||||
longtest()
|
||||
floattest() ; TODO fix invalid 6502 code gen /crash
|
||||
}
|
||||
^^Node1 @shared next
|
||||
^^Node2 @shared this
|
||||
^^ubyte ubptr
|
||||
|
||||
sub bytetest() {
|
||||
ubyte[] foo = [11, 22, 33]
|
||||
ubyte i
|
||||
txt.print("before:")
|
||||
for i in 0 to 2 {
|
||||
txt.chrout(' ')
|
||||
txt.print_ub(foo[i])
|
||||
}
|
||||
txt.nl()
|
||||
foo[2] = foo[1]
|
||||
foo[1] = foo[0]
|
||||
foo[0] = 0
|
||||
txt.print(" after:")
|
||||
for i in 0 to 2 {
|
||||
txt.chrout(' ')
|
||||
txt.print_ub(foo[i])
|
||||
}
|
||||
txt.nl()
|
||||
}
|
||||
ubptr = next as ^^ubyte
|
||||
ubptr = 12345
|
||||
ubptr = cx16.r0
|
||||
ubptr = next as uword ; TODO fix type error; the cast should succeed
|
||||
|
||||
sub wordtest() {
|
||||
uword[] foo = [1111, 2222, 3333]
|
||||
ubyte i
|
||||
txt.print("before:")
|
||||
for i in 0 to 2 {
|
||||
txt.chrout(' ')
|
||||
txt.print_uw(foo[i])
|
||||
}
|
||||
txt.nl()
|
||||
foo[2] = foo[1]
|
||||
foo[1] = foo[0]
|
||||
foo[0] = 0
|
||||
txt.print(" after:")
|
||||
for i in 0 to 2 {
|
||||
txt.chrout(' ')
|
||||
txt.print_uw(foo[i])
|
||||
}
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub longtest() {
|
||||
long[] foo = [111111, 222222, 333333]
|
||||
ubyte i
|
||||
txt.print("before:")
|
||||
for i in 0 to 2 {
|
||||
txt.chrout(' ')
|
||||
txt.print_l(foo[i])
|
||||
}
|
||||
txt.nl()
|
||||
foo[2] = foo[1]
|
||||
foo[1] = foo[0]
|
||||
foo[0] = 0
|
||||
txt.print(" after:")
|
||||
for i in 0 to 2 {
|
||||
txt.chrout(' ')
|
||||
txt.print_l(foo[i])
|
||||
}
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub floattest() {
|
||||
float[] foo = [1.1, 2.2, 3.3]
|
||||
ubyte i
|
||||
txt.print("before:")
|
||||
for i in 0 to 2 {
|
||||
txt.chrout(' ')
|
||||
txt.print_f(foo[i])
|
||||
}
|
||||
txt.nl()
|
||||
foo[2] = foo[1]
|
||||
foo[1] = foo[0]
|
||||
foo[0] = 0
|
||||
txt.print(" after:")
|
||||
for i in 0 to 2 {
|
||||
txt.chrout(' ')
|
||||
txt.print_f(foo[i])
|
||||
}
|
||||
txt.nl()
|
||||
this.text = next as ^^ubyte
|
||||
this.text = 12345
|
||||
this.text = cx16.r0
|
||||
this.text = next as uword ; TODO fix type error; the cast should succeed
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +270,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
val value: String = when {
|
||||
dt.isBool -> constant.value.toInt().toString()
|
||||
dt.isFloat -> constant.value.toString()
|
||||
dt.isPointer -> TODO("constant pointer $constant")
|
||||
dt.isInteger -> constant.value.toInt().toHex()
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ class StStaticVariable(name: String,
|
||||
}
|
||||
|
||||
|
||||
class StConstant(name: String, val dt: BaseDataType, val value: Double, astNode: PtNode?) :
|
||||
class StConstant(name: String, val dt: DataType, val value: Double, astNode: PtNode?) :
|
||||
StNode(name, StNodeType.CONSTANT, astNode)
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
||||
}
|
||||
is PtConstant -> {
|
||||
require(node.type.isNumericOrBool)
|
||||
StConstant(node.name, node.type.base, node.value, node)
|
||||
StConstant(node.name, node.type, node.value, node)
|
||||
}
|
||||
is PtLabel -> {
|
||||
StNode(node.name, StNodeType.LABEL, node)
|
||||
|
||||
Reference in New Issue
Block a user