mirror of
https://github.com/irmen/prog8.git
synced 2026-03-11 05:41:42 +00:00
alias test program, replace alias chains
This commit is contained in:
@@ -44,9 +44,6 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter,
|
||||
override fun visit(alias: Alias) {
|
||||
if(alias.target.targetStatement(program.builtinFunctions)==null)
|
||||
errors.err("undefined symbol: ${alias.target.nameInSource.joinToString(".") }", alias.target.position)
|
||||
|
||||
if(alias.alias == alias.target.nameInSource.first())
|
||||
errors.err("alias references itself", alias.position)
|
||||
}
|
||||
|
||||
override fun visit(block: Block) {
|
||||
|
||||
@@ -341,11 +341,48 @@ class AstPreprocessor(val program: Program,
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(alias: Alias, parent: Node): Iterable<IAstModification> {
|
||||
override fun before(alias: Alias, parent: Node): Iterable<IAstModification> {
|
||||
// shortcut aliases that point to aliases (remove alias chains)
|
||||
val tgt = alias.target.targetStatement(program.builtinFunctions)
|
||||
if(tgt is Block) {
|
||||
errors.err("cannot alias blocks", alias.target.position)
|
||||
|
||||
if(tgt!=null) {
|
||||
if(alias.alias == alias.target.nameInSource.first()) {
|
||||
errors.err("alias loop", alias.position)
|
||||
} else if(tgt is Block) {
|
||||
errors.err("cannot alias blocks", alias.target.position) // TODO remove this check? move it to AstChecker?
|
||||
} else if(tgt is Alias) {
|
||||
var chainedAlias = alias
|
||||
var chainedTargetName = alias.target
|
||||
var maxhops = 100
|
||||
while(true) {
|
||||
val tgt2 = chainedAlias.target.targetStatement(program.builtinFunctions)
|
||||
if (tgt2 is Alias) {
|
||||
chainedAlias = tgt2
|
||||
chainedTargetName = tgt2.target
|
||||
}
|
||||
else {
|
||||
val tgt2 = chainedTargetName.targetStatement(program.builtinFunctions) as? INamedStatement
|
||||
val replacement = if(tgt2!=null) {
|
||||
if(tgt2.scopedName != chainedTargetName.nameInSource) {
|
||||
val scopedTarget = IdentifierReference(tgt2.scopedName, alias.position)
|
||||
Alias(alias.alias, scopedTarget, alias.position)
|
||||
} else {
|
||||
Alias(alias.alias, chainedTargetName, alias.position)
|
||||
}
|
||||
} else {
|
||||
Alias(alias.alias, chainedTargetName, alias.position)
|
||||
}
|
||||
return listOf(IAstModification.ReplaceNode(alias, replacement, parent))
|
||||
}
|
||||
maxhops--
|
||||
if(maxhops==0) {
|
||||
errors.err("alias loop", alias.position)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
|
||||
@@ -126,16 +126,6 @@ internal class LiteralsToAutoVarsAndRecombineIdentifiers(private val program: Pr
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(alias: Alias, parent: Node): Iterable<IAstModification> {
|
||||
val target = alias.target.targetStatement()
|
||||
if(target is Alias) {
|
||||
// shortcut the alias that refers to another alias
|
||||
val newAlias = Alias(alias.alias, target.target, alias.position)
|
||||
return listOf(IAstModification.ReplaceNode(alias, newAlias, parent))
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> {
|
||||
val target = identifier.targetStatement()
|
||||
|
||||
|
||||
@@ -2432,7 +2432,7 @@ main {
|
||||
|
||||
sub alias1() {
|
||||
alias TheNode = structdefs.Node
|
||||
^^TheNode node = 20000
|
||||
^^TheNode @shared node = 20000
|
||||
node.value = 100
|
||||
}
|
||||
|
||||
@@ -2444,7 +2444,7 @@ main {
|
||||
|
||||
sub alias3() {
|
||||
alias TheNode = structdefs.Node
|
||||
^^TheNode node = 20000
|
||||
^^TheNode @shared node = 20000
|
||||
node++
|
||||
}
|
||||
|
||||
|
||||
227
examples/test.p8
227
examples/test.p8
@@ -1,44 +1,203 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
alias print = mytxt.print
|
||||
alias width = mytxt.DEFAULT_WIDTH
|
||||
alias textOverlay_top = mytxt.overlayTop
|
||||
alias textOverlay_bot = mytxt.overlayBot
|
||||
|
||||
sub start() {
|
||||
uword @shared derp=2000
|
||||
derp[1000] = %00111100
|
||||
derp[1001] = %01111110
|
||||
address_of_alias()
|
||||
alias1()
|
||||
alias2()
|
||||
alias3()
|
||||
alias4()
|
||||
alias5()
|
||||
alias6()
|
||||
player.test()
|
||||
alias_scopes()
|
||||
alias_loop_error()
|
||||
alias_error()
|
||||
aliased_func_error()
|
||||
}
|
||||
|
||||
ror(@(3000))
|
||||
txt.print_ubbin(derp[1000], true)
|
||||
txt.spc()
|
||||
sys.clear_carry()
|
||||
rol(@(3000))
|
||||
txt.print_ubbin(derp[1000], true)
|
||||
txt.nl()
|
||||
sub address_of_alias() {
|
||||
ubyte @shared index = 3
|
||||
ubyte[10] array
|
||||
alias curframe = array
|
||||
|
||||
ror(derp[1000])
|
||||
txt.print_ubbin(derp[1000], true)
|
||||
txt.spc()
|
||||
sys.clear_carry()
|
||||
rol(derp[1000])
|
||||
txt.print_ubbin(derp[1000], true)
|
||||
txt.nl()
|
||||
cx16.r0 = &curframe
|
||||
cx16.r1 = &curframe[3]
|
||||
cx16.r2 = &curframe + 3
|
||||
cx16.r3 = &curframe[index]
|
||||
cx16.r4 = &curframe + index
|
||||
}
|
||||
|
||||
ror(@(derp +1000))
|
||||
txt.print_ubbin(derp[1000], true)
|
||||
txt.spc()
|
||||
sys.clear_carry()
|
||||
rol(@(derp +1000))
|
||||
txt.print_ubbin(derp[1000], true)
|
||||
txt.nl()
|
||||
sub alias1() {
|
||||
alias TheNode = structdefs.Node
|
||||
^^TheNode @shared node = 20000
|
||||
node.value = 100
|
||||
}
|
||||
|
||||
^^uword a = derp+1000
|
||||
ror(a^^)
|
||||
txt.print_uwbin(a^^, true)
|
||||
txt.nl()
|
||||
sys.clear_carry()
|
||||
rol(a^^)
|
||||
txt.print_uwbin(a^^, true)
|
||||
txt.nl()
|
||||
sub alias2() {
|
||||
^^structdefs.Node node = 20000
|
||||
alias thing = node
|
||||
thing.value=200
|
||||
}
|
||||
|
||||
sub alias3() {
|
||||
alias TheNode = structdefs.Node
|
||||
^^TheNode @shared node = 20000
|
||||
node++
|
||||
}
|
||||
|
||||
sub alias4() {
|
||||
alias currentElement = structdefs.element
|
||||
currentElement = 20000
|
||||
|
||||
; all 3 should be the same:
|
||||
structdefs.element.value = 42
|
||||
currentElement.value = 42
|
||||
currentElement^^.value = 42
|
||||
|
||||
; all 3 should be the same:
|
||||
structdefs.element.value2 = 4242
|
||||
currentElement.value2 = 4242
|
||||
currentElement^^.value2 = 4242
|
||||
|
||||
cx16.r0 = currentElement^^.value2
|
||||
cx16.r1 = currentElement.value2
|
||||
}
|
||||
|
||||
sub alias5() {
|
||||
alias nid = structdefs.element.value
|
||||
nid++
|
||||
}
|
||||
|
||||
sub alias6() {
|
||||
alias print2 = mytxt.print
|
||||
alias width2 = mytxt.DEFAULT_WIDTH
|
||||
print("one")
|
||||
print2("two")
|
||||
mytxt.print_ub(width)
|
||||
mytxt.print_ub(width2)
|
||||
|
||||
; chained aliases
|
||||
alias chained = print2
|
||||
chained("chained")
|
||||
|
||||
; multi vardecls
|
||||
textOverlay_bot++
|
||||
textOverlay_top++
|
||||
}
|
||||
|
||||
sub alias_scopes() {
|
||||
alias mything = other.thing
|
||||
alias myvariable = other.variable
|
||||
|
||||
mything()
|
||||
myvariable ++
|
||||
|
||||
other.thing2()
|
||||
other.variable2 ++
|
||||
|
||||
alias nid = structdefs.element.value
|
||||
nid++
|
||||
}
|
||||
|
||||
sub alias_loop_error() {
|
||||
alias vv = vv
|
||||
alias xx = xx.yy
|
||||
alias zz = mm
|
||||
alias mm = zz
|
||||
}
|
||||
|
||||
alias print = mytxt.print2222
|
||||
alias width = mytxt.DEFAULT_WIDTH
|
||||
|
||||
sub alias_error() {
|
||||
alias print2 = mytxt.print
|
||||
alias width2 = mytxt.DEFAULT_WIDTH_XXX
|
||||
print("one")
|
||||
print2("two")
|
||||
mytxt.print_ub(width)
|
||||
mytxt.print_ub(width2)
|
||||
}
|
||||
|
||||
sub aliased_func_error() {
|
||||
alias func1 = actualfunc
|
||||
alias func2 = mkword
|
||||
alias func3 = func1
|
||||
alias func4 = func2
|
||||
|
||||
; all wrong:
|
||||
func1(1,2)
|
||||
func1()
|
||||
func2(1,2,3,4)
|
||||
func2()
|
||||
func3()
|
||||
func4()
|
||||
|
||||
; all ok:
|
||||
func1(1)
|
||||
cx16.r0 = func2(1,2)
|
||||
func3(1)
|
||||
cx16.r0 = func4(1,2)
|
||||
|
||||
sub actualfunc(ubyte a) {
|
||||
a++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
cx16 {
|
||||
%option merge
|
||||
&^^word pword4 = &cx16.r4
|
||||
}
|
||||
|
||||
player {
|
||||
alias sxPtr = cx16.pword4
|
||||
&^^word zxPtr = &cx16.r6
|
||||
|
||||
sub test() {
|
||||
sxPtr^^ = -99 ; aliased assignment
|
||||
if (zxPtr^^ - sxPtr^^) in -13 to 13 { ; aliased expression
|
||||
cx16.r0++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mytxt {
|
||||
uword overlayTop, overlayBot
|
||||
|
||||
const ubyte DEFAULT_WIDTH = 80
|
||||
sub print_ub(ubyte value) {
|
||||
; nothing
|
||||
}
|
||||
sub print(str msg) {
|
||||
; nothing
|
||||
}
|
||||
}
|
||||
|
||||
structdefs {
|
||||
struct Node {
|
||||
ubyte value
|
||||
uword value2
|
||||
}
|
||||
|
||||
^^Node @shared element
|
||||
}
|
||||
|
||||
other {
|
||||
sub thing() {
|
||||
cx16.r0++
|
||||
}
|
||||
|
||||
ubyte @shared variable
|
||||
|
||||
alias thing2 = thing
|
||||
alias variable2 = variable
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user