mirror of
https://github.com/irmen/prog8.git
synced 2025-11-26 04:17:47 +00:00
revert & to untyped pointer, added && for typed pointer address-of
This commit is contained in:
@@ -39,14 +39,14 @@ internal class BeforeAsmTypecastCleaner(val program: Program,
|
|||||||
listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent))
|
listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent))
|
||||||
} else {
|
} else {
|
||||||
listOf(IAstModification.ReplaceNode(typecast,
|
listOf(IAstModification.ReplaceNode(typecast,
|
||||||
AddressOf(identifier, null, null, false, typecast.position), parent))
|
AddressOf(identifier, null, null, false, false,typecast.position), parent))
|
||||||
}
|
}
|
||||||
} else if (typecast.expression is IFunctionCall) {
|
} else if (typecast.expression is IFunctionCall) {
|
||||||
return listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent))
|
return listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent))
|
||||||
}
|
}
|
||||||
} else if(sourceDt.isString && typecast.type.isPointer && typecast.type.sub==BaseDataType.UBYTE) {
|
} else if(sourceDt.isString && typecast.type.isPointer && typecast.type.sub==BaseDataType.UBYTE) {
|
||||||
// casting a string to a ^^ubyte is just taking the address of the string.
|
// casting a string to a ^^ubyte is just taking the address of the string.
|
||||||
val addr = AddressOf(typecast.expression as IdentifierReference, null, null, false, typecast.position)
|
val addr = AddressOf(typecast.expression as IdentifierReference, null, null, false, true, typecast.position)
|
||||||
return listOf(IAstModification.ReplaceNode(typecast, addr, parent))
|
return listOf(IAstModification.ReplaceNode(typecast, addr, parent))
|
||||||
} else {
|
} else {
|
||||||
errors.err("cannot cast pass-by-reference value to type ${typecast.type} (only to UWORD)", typecast.position)
|
errors.err("cannot cast pass-by-reference value to type ${typecast.type} (only to UWORD)", typecast.position)
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
if(!argDt.isString || it.second is IdentifierReference) {
|
if(!argDt.isString || it.second is IdentifierReference) {
|
||||||
modifications += IAstModification.ReplaceNode(
|
modifications += IAstModification.ReplaceNode(
|
||||||
identifier,
|
identifier,
|
||||||
AddressOf(identifier, null, null, false, it.second.position),
|
AddressOf(identifier, null, null, false, true, it.second.position),
|
||||||
call as Node
|
call as Node
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -337,7 +337,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
// take the address of the identifier
|
// take the address of the identifier
|
||||||
modifications += IAstModification.ReplaceNode(
|
modifications += IAstModification.ReplaceNode(
|
||||||
identifier,
|
identifier,
|
||||||
AddressOf(identifier, null, null, false, it.second.position),
|
AddressOf(identifier, null, null, false, false,it.second.position),
|
||||||
call as Node
|
call as Node
|
||||||
)
|
)
|
||||||
} else if(dt.isUnknown) {
|
} else if(dt.isUnknown) {
|
||||||
@@ -346,7 +346,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
// take the address of the subroutine or label
|
// take the address of the subroutine or label
|
||||||
modifications += IAstModification.ReplaceNode(
|
modifications += IAstModification.ReplaceNode(
|
||||||
identifier,
|
identifier,
|
||||||
AddressOf(identifier, null, null, false, it.second.position),
|
AddressOf(identifier, null, null, false, false, it.second.position),
|
||||||
call as Node
|
call as Node
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -481,7 +481,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
val eltType = elt.inferType(program)
|
val eltType = elt.inferType(program)
|
||||||
val tgt = elt.targetStatement()
|
val tgt = elt.targetStatement()
|
||||||
if(eltType.isIterable || tgt is Subroutine || tgt is Label || tgt is Block) {
|
if(eltType.isIterable || tgt is Subroutine || tgt is Label || tgt is Block) {
|
||||||
val addressof = AddressOf(elt, null, null, false, elt.position)
|
val addressof = AddressOf(elt, null, null, false, false, elt.position)
|
||||||
addressof.linkParents(array)
|
addressof.linkParents(array)
|
||||||
array.value[index] = addressof
|
array.value[index] = addressof
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ import prog8.ast.expressions.ArrayIndexedExpression
|
|||||||
import prog8.ast.expressions.DirectMemoryRead
|
import prog8.ast.expressions.DirectMemoryRead
|
||||||
import prog8.ast.expressions.PtrDereference
|
import prog8.ast.expressions.PtrDereference
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.code.ast.PtAssignment
|
import prog8.code.ast.*
|
||||||
import prog8.code.ast.PtReturn
|
|
||||||
import prog8.code.ast.PtSubSignature
|
|
||||||
import prog8.code.core.BaseDataType
|
import prog8.code.core.BaseDataType
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.code.core.IMemSizer
|
import prog8.code.core.IMemSizer
|
||||||
@@ -585,7 +583,7 @@ main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("type of & operator (address-of)") {
|
test("internal type for address-of") {
|
||||||
DataType.BYTE.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.BYTE)
|
DataType.BYTE.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.BYTE)
|
||||||
DataType.WORD.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.WORD)
|
DataType.WORD.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.WORD)
|
||||||
DataType.FLOAT.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.FLOAT)
|
DataType.FLOAT.typeForAddressOf(false) shouldBe DataType.pointer(BaseDataType.FLOAT)
|
||||||
@@ -605,6 +603,31 @@ main {
|
|||||||
DataType.pointer(BaseDataType.BOOL).typeForAddressOf(false) shouldBe DataType.UWORD
|
DataType.pointer(BaseDataType.BOOL).typeForAddressOf(false) shouldBe DataType.UWORD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("untyped and typed address-of operators") {
|
||||||
|
val src="""
|
||||||
|
%option enable_floats
|
||||||
|
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
float f
|
||||||
|
cx16.r0 = &f+1
|
||||||
|
cx16.r1 = &&f+1
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
val result = compileText(VMTarget(), false, src, outputDir, writeAssembly = true)!!
|
||||||
|
val st = result.codegenAst!!.entrypoint()!!.children
|
||||||
|
st.size shouldBe 6
|
||||||
|
val r0v = (st[3] as PtAssignment).value as PtBinaryExpression
|
||||||
|
val r1v = (st[4] as PtAssignment).value as PtBinaryExpression
|
||||||
|
r0v.left shouldBe instanceOf<PtAddressOf>()
|
||||||
|
r0v.right shouldBe instanceOf<PtNumber>()
|
||||||
|
(r0v.right as PtNumber).number shouldBe 1.0
|
||||||
|
r1v.left shouldBe instanceOf<PtAddressOf>()
|
||||||
|
r1v.right shouldBe instanceOf<PtNumber>()
|
||||||
|
(r1v.right as PtNumber).number shouldBe VMTarget.FLOAT_MEM_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
test("address-of struct fields") {
|
test("address-of struct fields") {
|
||||||
val src="""
|
val src="""
|
||||||
%option enable_floats
|
%option enable_floats
|
||||||
@@ -1375,7 +1398,7 @@ main {
|
|||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests()
|
||||||
compileText(VMTarget(), false, src, outputDir, errors = errors) shouldBe null
|
compileText(VMTarget(), false, src, outputDir, errors = errors) shouldBe null
|
||||||
errors.errors.size shouldBe 999
|
errors.errors.size shouldBe 999
|
||||||
// TODO
|
// TODO implement this test
|
||||||
}
|
}
|
||||||
|
|
||||||
xtest("array of pointers as subroutine param") {
|
xtest("array of pointers as subroutine param") {
|
||||||
|
|||||||
@@ -65,13 +65,13 @@ class TestAsmGenSymbols: StringSpec({
|
|||||||
position = Position.DUMMY
|
position = Position.DUMMY
|
||||||
)
|
)
|
||||||
val assign1 = Assignment(tgt, IdentifierReference(listOf("localvar"), Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
val assign1 = Assignment(tgt, IdentifierReference(listOf("localvar"), Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||||
val assign2 = Assignment(tgt, AddressOf(IdentifierReference(listOf("locallabel"), Position.DUMMY), null, null, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
val assign2 = Assignment(tgt, AddressOf(IdentifierReference(listOf("locallabel"), Position.DUMMY), null, null, false, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||||
val assign3 = Assignment(tgt, AddressOf(IdentifierReference(listOf("var_outside"), Position.DUMMY), null, null, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
val assign3 = Assignment(tgt, AddressOf(IdentifierReference(listOf("var_outside"), Position.DUMMY), null, null, false, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||||
val assign4 = Assignment(tgt, AddressOf(IdentifierReference(listOf("label_outside"), Position.DUMMY), null, null, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
val assign4 = Assignment(tgt, AddressOf(IdentifierReference(listOf("label_outside"), Position.DUMMY), null, null, false, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||||
val assign5 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","start","localvar"), Position.DUMMY), null, null, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
val assign5 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","start","localvar"), Position.DUMMY), null, null, false, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||||
val assign6 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","start","locallabel"), Position.DUMMY), null, null, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
val assign6 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","start","locallabel"), Position.DUMMY), null, null, false, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||||
val assign7 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","var_outside"), Position.DUMMY), null, null, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
val assign7 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","var_outside"), Position.DUMMY), null, null, false, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||||
val assign8 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","label_outside"), Position.DUMMY), null, null, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
val assign8 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","label_outside"), Position.DUMMY), null, null, false, false, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||||
|
|
||||||
val statements = mutableListOf(varInSub, var2InSub, labelInSub, assign1, assign2, assign3, assign4, assign5, assign6, assign7, assign8)
|
val statements = mutableListOf(varInSub, var2InSub, labelInSub, assign1, assign2, assign3, assign4, assign5, assign6, assign7, assign8)
|
||||||
val subroutine = Subroutine("start", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, statements, Position.DUMMY)
|
val subroutine = Subroutine("start", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, statements, Position.DUMMY)
|
||||||
|
|||||||
@@ -280,10 +280,17 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor<Node
|
|||||||
val msb = ctx.ADDRESS_OF_MSB()!=null
|
val msb = ctx.ADDRESS_OF_MSB()!=null
|
||||||
// note: &< (ADDRESS_OF_LSB) is equivalent to a regular &.
|
// note: &< (ADDRESS_OF_LSB) is equivalent to a regular &.
|
||||||
val index = ctx.arrayindex()?.accept(this) as? ArrayIndex
|
val index = ctx.arrayindex()?.accept(this) as? ArrayIndex
|
||||||
|
var typed = false
|
||||||
|
if(ctx.TYPED_ADDRESS_OF()!=null) {
|
||||||
|
// new typed AddressOf
|
||||||
|
if(msb)
|
||||||
|
throw SyntaxError("typed address of not allowed with msb", ctx.toPosition())
|
||||||
|
typed = true
|
||||||
|
}
|
||||||
return if (index != null) {
|
return if (index != null) {
|
||||||
AddressOf(identifier, index, null, msb, ctx.toPosition())
|
AddressOf(identifier, index, null, msb, typed, ctx.toPosition())
|
||||||
} else {
|
} else {
|
||||||
AddressOf(identifier,null, null, msb, ctx.toPosition())
|
AddressOf(identifier, null, null, msb, typed, ctx.toPosition())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -502,7 +502,8 @@ class TypecastExpression(var expression: Expression, var type: DataType, val imp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: ArrayIndex?, var dereference: PtrDereference?, val msb: Boolean, override val position: Position) : Expression() {
|
data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: ArrayIndex?, var dereference: PtrDereference?,
|
||||||
|
val msb: Boolean, val typed: Boolean, override val position: Position) : Expression() {
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
|
|
||||||
override fun linkParents(parent: Node) {
|
override fun linkParents(parent: Node) {
|
||||||
@@ -538,7 +539,7 @@ data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: Array
|
|||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun copy() = AddressOf(identifier?.copy(), arrayIndex?.copy(), dereference?.copy(), msb, position)
|
override fun copy() = AddressOf(identifier?.copy(), arrayIndex?.copy(), dereference?.copy(), msb, typed, position)
|
||||||
override fun constValue(program: Program): NumericLiteral? {
|
override fun constValue(program: Program): NumericLiteral? {
|
||||||
if(msb)
|
if(msb)
|
||||||
return null
|
return null
|
||||||
@@ -574,8 +575,9 @@ data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: Array
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
override fun referencesIdentifier(nameInSource: List<String>) = identifier?.nameInSource==nameInSource || arrayIndex?.referencesIdentifier(nameInSource)==true || dereference?.referencesIdentifier(nameInSource)==true
|
override fun referencesIdentifier(nameInSource: List<String>) = identifier?.nameInSource==nameInSource || arrayIndex?.referencesIdentifier(nameInSource)==true || dereference?.referencesIdentifier(nameInSource)==true
|
||||||
// override fun inferType(program: Program): InferredTypes.InferredType = InferredTypes.knownFor(BaseDataType.UWORD) // TODO orignal behavior
|
|
||||||
override fun inferType(program: Program): InferredTypes.InferredType {
|
override fun inferType(program: Program): InferredTypes.InferredType {
|
||||||
|
if(!typed)
|
||||||
|
return InferredTypes.knownFor(BaseDataType.UWORD) // orignal pre-v12 untyped AddressOf
|
||||||
if(identifier!=null) {
|
if(identifier!=null) {
|
||||||
val type = identifier!!.inferType(program).getOrUndef()
|
val type = identifier!!.inferType(program).getOrUndef()
|
||||||
val addrofDt = type.typeForAddressOf(msb)
|
val addrofDt = type.typeForAddressOf(msb)
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ class VarDecl(
|
|||||||
// parameter variable memory mapped to a R0-R15 virtual register
|
// parameter variable memory mapped to a R0-R15 virtual register
|
||||||
val regname = param.registerOrPair.asScopedNameVirtualReg(param.type)
|
val regname = param.registerOrPair.asScopedNameVirtualReg(param.type)
|
||||||
decltype = VarDeclType.MEMORY
|
decltype = VarDeclType.MEMORY
|
||||||
value = AddressOf(IdentifierReference(regname, param.position), null, null, false, param.position)
|
value = AddressOf(IdentifierReference(regname, param.position), null, null, false, false,param.position)
|
||||||
}
|
}
|
||||||
val dt = if(param.type.isArray) DataType.UWORD else param.type
|
val dt = if(param.type.isArray) DataType.UWORD else param.type
|
||||||
return VarDecl(decltype, VarDeclOrigin.SUBROUTINEPARAM, dt, param.zp, SplitWish.DONTCARE, null, param.name, emptyList(), value,
|
return VarDecl(decltype, VarDeclOrigin.SUBROUTINEPARAM, dt, param.zp, SplitWish.DONTCARE, null, param.name, emptyList(), value,
|
||||||
|
|||||||
@@ -999,7 +999,7 @@ containment check: ``in``
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
address of: ``&``, ``&<``, ``&>``
|
address of: ``&``, ``&<``, ``&>``, ``&&``
|
||||||
This is a prefix operator that can be applied to a string or array variable or literal value.
|
This is a prefix operator that can be applied to a string or array variable or literal value.
|
||||||
It results in the memory address (UWORD) of that string or array in memory: ``uword a = &stringvar``
|
It results in the memory address (UWORD) of that string or array in memory: ``uword a = &stringvar``
|
||||||
Sometimes the compiler silently inserts this operator to make it easier for instance
|
Sometimes the compiler silently inserts this operator to make it easier for instance
|
||||||
@@ -1012,6 +1012,11 @@ address of: ``&``, ``&<``, ``&>``
|
|||||||
and MSB byte array separately, respectively. Note that ``&<`` is just the same as ``&`` in this case.
|
and MSB byte array separately, respectively. Note that ``&<`` is just the same as ``&`` in this case.
|
||||||
For more details on split word arrays, see :ref:`arrayvars`.
|
For more details on split word arrays, see :ref:`arrayvars`.
|
||||||
|
|
||||||
|
**Typed pointer version:** the single ``&`` operator still returns an untyped uword address for
|
||||||
|
backward compatibility reasons, so existing programs keep working. The *double ampersand* ``&&`` operator
|
||||||
|
however returns a *typed* pointer to the value. The semantics are slightly different because adding or subtracting
|
||||||
|
a number from a typed pointer uses *pointer arithmetic* that takes the size of the value that it points to into account.
|
||||||
|
|
||||||
|
|
||||||
ternary:
|
ternary:
|
||||||
Prog8 doesn't have a ternary operator to choose one of two values (``x? y : z`` in many other languages)
|
Prog8 doesn't have a ternary operator to choose one of two values (``x? y : z`` in many other languages)
|
||||||
|
|||||||
@@ -81,3 +81,11 @@ Typed pointer to Struct type
|
|||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
Work in progress.
|
Work in progress.
|
||||||
|
|
||||||
|
|
||||||
|
Address-Of: untyped vs typed
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
``&`` still returns untyped (uword) pointer, as it did in older Prog8 versions. This is for backward compatibility reasons so existing programs don't break.
|
||||||
|
The *double ampersand* operator ``&&`` returns a *typed* pointer to the value. The semantics are slightly different from the old untyped address-of operator, because adding or subtracting
|
||||||
|
a number from a typed pointer uses *pointer arithmetic* that takes the size of the value that it points to into account.
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
What to do with the changed adress-of behavior? &x now returns a typed pointer to &x + 10 will now be calculated differently (C pointer arithmetic semantics rather than simply byte addition)
|
|
||||||
compiler flag to select old behavior? new operator that has the new behavior? Don't want to break existing code that used &....
|
|
||||||
Old behavior can be put back by always returning UWORD as the inferred type for AddressOf nodes
|
|
||||||
|
|
||||||
|
|
||||||
STRUCTS and TYPED POINTERS
|
STRUCTS and TYPED POINTERS
|
||||||
--------------------------
|
--------------------------
|
||||||
@@ -58,6 +54,7 @@ STRUCTS and TYPED POINTERS
|
|||||||
- DONE: fix _msb/_lsb storage of the split-words pointer-arrays
|
- DONE: fix _msb/_lsb storage of the split-words pointer-arrays
|
||||||
- DONE: what about static initialization of an array of struct pointers? -> impossible right now because the pointer values are not constants.
|
- DONE: what about static initialization of an array of struct pointers? -> impossible right now because the pointer values are not constants.
|
||||||
- DONE: make typeForAddressOf() be even more specific about the typed pointers it returns for the address-of operator.
|
- DONE: make typeForAddressOf() be even more specific about the typed pointers it returns for the address-of operator.
|
||||||
|
- DONE: existing '&' address-of still returns untyped uword (for backward compatibility). New '&&' operator returns typed pointer.
|
||||||
- DONE: allow list1^^ = list2^^ (value wise assignment of List structures) by replacing it with a sys.memcopy(list2, list1, sizeof(List)) call.
|
- DONE: allow list1^^ = list2^^ (value wise assignment of List structures) by replacing it with a sys.memcopy(list2, list1, sizeof(List)) call.
|
||||||
- DONE: allow a.b.ptr[i].value (equiv to a.b.ptr[i]^^.value) expressions (assignment target doesn't parse yet, see below)
|
- DONE: allow a.b.ptr[i].value (equiv to a.b.ptr[i]^^.value) expressions (assignment target doesn't parse yet, see below)
|
||||||
- DONE: check passing arrays to typed ptr sub-parameters. NOTE: word array can only be a @nosplit array if the parameter type is ^^word, because the words need to be sequential in memory there
|
- DONE: check passing arrays to typed ptr sub-parameters. NOTE: word array can only be a @nosplit array if the parameter type is ^^word, because the words need to be sequential in memory there
|
||||||
|
|||||||
@@ -5,48 +5,23 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
ubyte @shared thingIndex = 10
|
|
||||||
uword[20] @shared dummy
|
|
||||||
uword[10] @split curframesplit
|
|
||||||
uword[10] @nosplit curframe
|
|
||||||
uword p1, p2
|
|
||||||
float f
|
float f
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
classic()
|
txt.print("classic float pointer+1: ")
|
||||||
; new()
|
|
||||||
}
|
|
||||||
|
|
||||||
sub classic() {
|
|
||||||
txt.print("float pointer+1: ")
|
|
||||||
txt.print_uwhex(&f, true)
|
txt.print_uwhex(&f, true)
|
||||||
txt.spc()
|
txt.spc()
|
||||||
txt.print_uwhex(&f + 1, true)
|
txt.print_uwhex(&f + 1, true)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_uw(&f + 1 - &f)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
p1 = &curframesplit[thingIndex]
|
txt.print("typed float pointer+1: ")
|
||||||
p2 = &curframe[thingIndex]
|
txt.print_uwhex(&&f, true)
|
||||||
|
|
||||||
txt.print("&array (split): ")
|
|
||||||
txt.print_uwhex(&curframesplit, true)
|
|
||||||
txt.spc()
|
txt.spc()
|
||||||
txt.print_uwhex(p1, true)
|
txt.print_uwhex(&&f + 1, true)
|
||||||
txt.spc()
|
txt.spc()
|
||||||
txt.print_uw(p1 - &curframesplit)
|
txt.print_uw(&&f + 1 - &&f)
|
||||||
txt.spc()
|
|
||||||
txt.print_uwhex(p1 + &curframesplit, true)
|
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
txt.print("&array (normal): ")
|
|
||||||
txt.print_uwhex(&curframe, true)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_uwhex(p2, true)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_uw(p2 - &curframe)
|
|
||||||
txt.spc()
|
|
||||||
txt.print_uwhex(p2 + &curframe, true)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
}
|
}
|
||||||
|
|
||||||
; 6502 data size: $0251
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ DEC_INTEGER : DEC_DIGIT (DEC_DIGIT | '_')* ;
|
|||||||
HEX_INTEGER : '$' HEX_DIGIT (HEX_DIGIT | '_')* ;
|
HEX_INTEGER : '$' HEX_DIGIT (HEX_DIGIT | '_')* ;
|
||||||
BIN_INTEGER : '%' BIN_DIGIT (BIN_DIGIT | '_')* ;
|
BIN_INTEGER : '%' BIN_DIGIT (BIN_DIGIT | '_')* ;
|
||||||
ADDRESS_OF: '&' ;
|
ADDRESS_OF: '&' ;
|
||||||
|
TYPED_ADDRESS_OF: '&&' ;
|
||||||
ADDRESS_OF_MSB: '&>' ;
|
ADDRESS_OF_MSB: '&>' ;
|
||||||
ADDRESS_OF_LSB: '&<' ;
|
ADDRESS_OF_LSB: '&<' ;
|
||||||
INVALID_AND_COMPOSITE: '&&' ;
|
|
||||||
POINTER: '^^';
|
POINTER: '^^';
|
||||||
|
|
||||||
fragment HEX_DIGIT: ('a'..'f') | ('A'..'F') | ('0'..'9') ;
|
fragment HEX_DIGIT: ('a'..'f') | ('A'..'F') | ('0'..'9') ;
|
||||||
@@ -241,7 +241,7 @@ typecast : 'as' datatype;
|
|||||||
|
|
||||||
directmemory : '@' '(' expression ')';
|
directmemory : '@' '(' expression ')';
|
||||||
|
|
||||||
addressof : <assoc=right> (ADDRESS_OF | ADDRESS_OF_LSB | ADDRESS_OF_MSB) scoped_identifier arrayindex? ;
|
addressof : <assoc=right> (ADDRESS_OF | TYPED_ADDRESS_OF | | ADDRESS_OF_LSB | ADDRESS_OF_MSB) scoped_identifier arrayindex? ;
|
||||||
|
|
||||||
functioncall : scoped_identifier '(' expression_list? ')' ;
|
functioncall : scoped_identifier '(' expression_list? ')' ;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user