diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index af8a35b20..7f5cc8694 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -4,4 +4,4 @@
-
\ No newline at end of file
+
diff --git a/build.gradle b/build.gradle
index c122ddb22..b048f783a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,3 +1,3 @@
plugins {
- id "org.jetbrains.kotlin.jvm" version "1.5.20" apply false
+ id "org.jetbrains.kotlin.jvm" version "1.5.30" apply false
}
diff --git a/compiler/res/prog8lib/c64/floats.p8 b/compiler/res/prog8lib/c64/floats.p8
index 7d8ee5d29..417e9faf5 100644
--- a/compiler/res/prog8lib/c64/floats.p8
+++ b/compiler/res/prog8lib/c64/floats.p8
@@ -4,7 +4,6 @@
;
; indent format: TABS, size=8
-%target c64
%option enable_floats
floats {
diff --git a/compiler/res/prog8lib/c64/graphics.p8 b/compiler/res/prog8lib/c64/graphics.p8
index 4593cf563..c41e3d6f4 100644
--- a/compiler/res/prog8lib/c64/graphics.p8
+++ b/compiler/res/prog8lib/c64/graphics.p8
@@ -1,4 +1,3 @@
-%target c64
%import textio
; bitmap pixel graphics module for the C64
diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8
index 56cce7440..ba58ef10d 100644
--- a/compiler/res/prog8lib/c64/syslib.p8
+++ b/compiler/res/prog8lib/c64/syslib.p8
@@ -5,8 +5,6 @@
;
; indent format: TABS, size=8
-%target c64
-
c64 {
&ubyte TIME_HI = $a0 ; software jiffy clock, hi byte
&ubyte TIME_MID = $a1 ; .. mid byte
@@ -502,11 +500,9 @@ sys {
; --- busy wait till the next vsync has occurred (approximately), without depending on custom irq handling.
; note: a more accurate way to wait for vsync is to set up a vsync irq handler instead.
%asm {{
-- lda c64.RASTER
- beq -
-- lda c64.RASTER
- bne -
- bit c64.SCROLY
+- bit c64.SCROLY
+ bpl -
+- bit c64.SCROLY
bmi -
rts
}}
diff --git a/compiler/res/prog8lib/c64/textio.p8 b/compiler/res/prog8lib/c64/textio.p8
index 661403f8e..118d3fa71 100644
--- a/compiler/res/prog8lib/c64/textio.p8
+++ b/compiler/res/prog8lib/c64/textio.p8
@@ -4,7 +4,6 @@
;
; indent format: TABS, size=8
-%target c64
%import syslib
%import conv
diff --git a/compiler/res/prog8lib/cx16/floats.p8 b/compiler/res/prog8lib/cx16/floats.p8
index 9400a2af2..a9a0df938 100644
--- a/compiler/res/prog8lib/cx16/floats.p8
+++ b/compiler/res/prog8lib/cx16/floats.p8
@@ -4,7 +4,6 @@
;
; indent format: TABS, size=8
-%target cx16
%option enable_floats
floats {
diff --git a/compiler/res/prog8lib/cx16/gfx2.p8 b/compiler/res/prog8lib/cx16/gfx2.p8
index 4842a2f02..37fdf6eba 100644
--- a/compiler/res/prog8lib/cx16/gfx2.p8
+++ b/compiler/res/prog8lib/cx16/gfx2.p8
@@ -1,5 +1,3 @@
-%target cx16
-
; Bitmap pixel graphics routines for the CommanderX16
; Custom routines to use the full-screen 640x480 and 320x240 screen modes.
; (These modes are not supported by the documented GRAPH_xxxx kernal routines)
diff --git a/compiler/res/prog8lib/cx16/graphics.p8 b/compiler/res/prog8lib/cx16/graphics.p8
index 09679bff0..f8cb55b1f 100644
--- a/compiler/res/prog8lib/cx16/graphics.p8
+++ b/compiler/res/prog8lib/cx16/graphics.p8
@@ -1,4 +1,3 @@
-%target cx16
%import syslib
%import textio
diff --git a/compiler/res/prog8lib/cx16/palette.p8 b/compiler/res/prog8lib/cx16/palette.p8
index 4a4e184e0..b2a1a5dd9 100644
--- a/compiler/res/prog8lib/cx16/palette.p8
+++ b/compiler/res/prog8lib/cx16/palette.p8
@@ -1,5 +1,3 @@
-%target cx16
-
; Manipulate the Commander X16's display color palette.
; Should you want to restore the default palette, you have to reinitialize the Vera yourself.
@@ -9,7 +7,7 @@ palette {
ubyte c
sub set_color(ubyte index, uword color) {
- vera_palette_ptr = $fa00+index*2
+ vera_palette_ptr = $fa00+(index as uword * 2)
cx16.vpoke(1, vera_palette_ptr, lsb(color))
vera_palette_ptr++
cx16.vpoke(1, vera_palette_ptr, msb(color))
@@ -70,11 +68,11 @@ palette {
}
}
- inline sub set_all_black() {
+ sub set_all_black() {
set_monochrome($000, $000)
}
- inline sub set_all_white() {
+ sub set_all_white() {
set_monochrome($fff, $fff)
}
diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8
index e125f9a99..8fa4ea50b 100644
--- a/compiler/res/prog8lib/cx16/syslib.p8
+++ b/compiler/res/prog8lib/cx16/syslib.p8
@@ -5,9 +5,6 @@
;
; indent format: TABS, size=8
-%target cx16
-
-
c64 {
; ---- kernal routines, these are the same as on the Commodore-64 (hence the same block name) ----
diff --git a/compiler/res/prog8lib/cx16/textio.p8 b/compiler/res/prog8lib/cx16/textio.p8
index 79c071ba8..9b2915264 100644
--- a/compiler/res/prog8lib/cx16/textio.p8
+++ b/compiler/res/prog8lib/cx16/textio.p8
@@ -4,7 +4,6 @@
;
; indent format: TABS, size=8
-%target cx16
%import syslib
%import conv
diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt
index e3166773e..894774ad5 100644
--- a/compiler/src/prog8/compiler/Compiler.kt
+++ b/compiler/src/prog8/compiler/Compiler.kt
@@ -301,17 +301,6 @@ private fun optimizeAst(programAst: Program, errors: IErrorReporter, functions:
break
}
- val inliner = SubroutineInliner(programAst, errors, options)
- inliner.visit(programAst)
- errors.report()
- if(errors.noErrors()) {
- inliner.applyModifications()
- inliner.fixCallsToInlinedSubroutines()
- val remover2 = UnusedCodeRemover(programAst, errors, compTarget)
- remover2.visit(programAst)
- remover2.applyModifications()
- }
-
errors.report()
}
diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt
index 296a4ca01..d5189df59 100644
--- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt
+++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt
@@ -270,10 +270,11 @@ internal class AstChecker(private val program: Program,
}
}
- // scope check
- if(subroutine.parent !is Block && subroutine.parent !is Subroutine) {
+ if(subroutine.inline && !subroutine.isAsmSubroutine)
+ err("subroutine inlining is currently only supported on asmsub routines")
+
+ if(subroutine.parent !is Block && subroutine.parent !is Subroutine)
err("subroutines can only be defined in the scope of a block or within another subroutine")
- }
if(subroutine.isAsmSubroutine) {
if(subroutine.asmParameterRegisters.size != subroutine.parameters.size)
@@ -715,14 +716,6 @@ internal class AstChecker(private val program: Program,
else if(directive.args.map{it.name in setOf("enable_floats", "force_output", "no_sysinit", "align_word", "align_page")}.any { !it })
err("invalid option directive argument(s)")
}
- "%target" -> {
- if(directive.parent !is Block && directive.parent !is Module)
- err("this directive may only occur in a block or at module level")
- if(directive.args.size != 1)
- err("directive requires one argument")
- if(directive.args.single().name !in setOf(C64Target.name, Cx16Target.name))
- err("invalid compilation target")
- }
else -> throw SyntaxError("invalid directive ${directive.directive}", directive.position)
}
super.visit(directive)
diff --git a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt
index f9f173ce2..00ba76541 100644
--- a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt
+++ b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt
@@ -33,16 +33,6 @@ internal class AstIdentifiersChecker(private val program: Program, private val e
super.visit(block)
}
- override fun visit(directive: Directive) {
- if(directive.directive=="%target") {
- val compatibleTarget = directive.args.single().name
- if (compatibleTarget != compTarget.name)
- errors.err("module's compilation target ($compatibleTarget) differs from active target (${compTarget.name})", directive.position)
- }
-
- super.visit(directive)
- }
-
override fun visit(decl: VarDecl) {
decl.datatypeErrors.forEach { errors.err(it.message, it.position) }
diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt
index 0fe3ad9fa..98ba68caa 100644
--- a/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt
+++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt
@@ -864,7 +864,7 @@ internal class AsmGen(private val program: Program,
if(sub.inline) {
if(options.optimize) {
- if(sub.isAsmSubroutine ||callGraph.unused(sub))
+ if(sub.isAsmSubroutine || callGraph.unused(sub))
return
// from an inlined subroutine only the local variables are generated,
@@ -873,7 +873,7 @@ internal class AsmGen(private val program: Program,
onlyVariables = true
}
else if(sub.amountOfRtsInAsm()==0) {
- // make sure the NOT INLINED subroutine actually does an rts at the end
+ // make sure the NOT INLINED subroutine actually does a rts at the end
sub.statements.add(Return(null, Position.DUMMY))
}
}
diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt
index 7ba1b61fa..7ae882f5a 100644
--- a/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt
+++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt
@@ -750,7 +750,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
// optimized simple case: swap two memory locations
if(first is DirectMemoryRead && second is DirectMemoryRead) {
- // TODO optimize swap of two memread values with index, using the same pointer expression/variable, like swap(@(ptr+i1), @(ptr+i2))
val addr1 = (first.addressExpression as? NumericLiteralValue)?.number?.toHex()
val addr2 = (second.addressExpression as? NumericLiteralValue)?.number?.toHex()
val name1 = if(first.addressExpression is IdentifierReference) asmgen.asmVariableName(first.addressExpression as IdentifierReference) else null
@@ -773,6 +772,50 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
asmgen.out(" ldy $name1 | lda $name2 | sta $name1 | sty $name2")
return
}
+ addr1==null && addr2==null && name1==null && name2==null -> {
+ val firstExpr = first.addressExpression as? BinaryExpression
+ val secondExpr = second.addressExpression as? BinaryExpression
+ if(firstExpr!=null && secondExpr!=null) {
+ val pointerVariable = firstExpr.left as? IdentifierReference
+ val firstOffset = firstExpr.right
+ val secondOffset = secondExpr.right
+ if(pointerVariable != null
+ && pointerVariable isSameAs secondExpr.left
+ && firstExpr.operator == "+" && secondExpr.operator == "+"
+ && (firstOffset is NumericLiteralValue || firstOffset is IdentifierReference || firstOffset is TypecastExpression)
+ && (secondOffset is NumericLiteralValue || secondOffset is IdentifierReference || secondOffset is TypecastExpression)
+ ) {
+ val pointerVar = firstExpr.left as IdentifierReference
+ if(firstOffset is NumericLiteralValue && secondOffset is NumericLiteralValue) {
+ if(firstOffset!=secondOffset) {
+ swapArrayValues(
+ DataType.UBYTE,
+ asmgen.asmVariableName(pointerVariable), firstOffset,
+ asmgen.asmVariableName(pointerVariable), secondOffset
+ )
+ return
+ }
+ } else if(firstOffset is TypecastExpression && secondOffset is TypecastExpression) {
+ if(firstOffset.type in WordDatatypes && secondOffset.type in WordDatatypes) {
+ val firstOffsetVar = firstOffset.expression as? IdentifierReference
+ val secondOffsetVar = secondOffset.expression as? IdentifierReference
+ if(firstOffsetVar!=null && secondOffsetVar!=null) {
+ if(firstOffsetVar!=secondOffsetVar) {
+ swapArrayValues(
+ DataType.UBYTE,
+ asmgen.asmVariableName(pointerVariable), firstOffsetVar,
+ asmgen.asmVariableName(pointerVariable), secondOffsetVar
+ )
+ return
+ }
+ }
+ }
+ } else if(firstOffset is IdentifierReference || secondOffset is IdentifierReference) {
+ throw AssemblyError("expected a typecast-to-word for index variable at ${firstOffset.position} and/or ${secondOffset.position}")
+ }
+ }
+ }
+ }
}
}
@@ -888,7 +931,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
sta P8ZP_SCRATCH_W2
lda #>(${arrayVarName2}+$index2)
sta P8ZP_SCRATCH_W2+1
- jsr floats.swap_floats
+ jsr floats.func_swap_f
""")
}
else -> throw AssemblyError("invalid aray elt type")
@@ -961,7 +1004,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
sta P8ZP_SCRATCH_W2
bcc +
inc P8ZP_SCRATCH_W2+1
-+ jsr floats.swap_floats
++ jsr floats.func_swap_f
""")
}
else -> throw AssemblyError("invalid aray elt type")
@@ -1019,7 +1062,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
sta P8ZP_SCRATCH_W1
bcc +
inc P8ZP_SCRATCH_W1+1
-+ jsr floats.swap_floats
++ jsr floats.func_swap_f
""")
}
else -> throw AssemblyError("invalid aray elt type")
@@ -1077,7 +1120,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
sta P8ZP_SCRATCH_W2
lda #>(${arrayVarName2}+$index2)
sta P8ZP_SCRATCH_W2+1
- jsr floats.swap_floats
+ jsr floats.func_swap_f
""")
}
else -> throw AssemblyError("invalid aray elt type")
diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt
index f44866ef1..05fe27299 100644
--- a/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt
+++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt
@@ -118,16 +118,14 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
// we do this by copying the subroutine's statements at the call site.
// NOTE: *if* there is a return statement, it will be the only one, and the very last statement of the subroutine
// (this condition has been enforced by an ast check earlier)
+
+ // note: for now, this is only reliably supported for asmsubs.
+ if(!sub.isAsmSubroutine)
+ throw AssemblyError("can only reliably inline asmsub routines at this time")
+
asmgen.out(" \t; inlined routine follows: ${sub.name}")
- val statements = sub.statements.filter { it !is ParameterVarDecl && it !is Directive }
- statements.forEach {
- if(it is Return) {
- asmgen.translate(it, false) // don't use RTS for the inlined return statement
- } else {
- if(!sub.inline || it !is VarDecl)
- asmgen.translate(it)
- }
- }
+ val assembly = sub.statements.single() as InlineAssembly
+ asmgen.translate(assembly)
asmgen.out(" \t; inlined routine end: ${sub.name}")
}
diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt
index 5b80f89c5..a0f14d766 100644
--- a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt
+++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt
@@ -1359,8 +1359,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister) {
- // we make an exception in the type check for assigning something to a cx16 virtual register
- if(target.register !in Cx16VirtualRegisters) {
+ // we make an exception in the type check for assigning something to a cx16 virtual register, or a register pair
+ // these will be correctly typecasted from a byte to a word value
+ if(target.register !in Cx16VirtualRegisters &&
+ target.register!=RegisterOrPair.AX && target.register!=RegisterOrPair.AY && target.register!=RegisterOrPair.XY) {
if(target.kind==TargetStorageKind.VARIABLE) {
val parts = target.asmVarname.split('.')
if (parts.size != 2 || parts[0] != "cx16")
diff --git a/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt b/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt
index 4efb5a6d5..21d474181 100644
--- a/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt
+++ b/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt
@@ -14,6 +14,7 @@ import prog8.compiler.astprocessing.toConstantIntegerRange
import prog8.compiler.target.ICompilationTarget
// Fix up the literal value's type to match that of the vardecl
+// (also check range literal operands types before they get expanded to arrays for instance)
internal class VarConstantValueTypeAdjuster(private val program: Program, private val errors: IErrorReporter) : AstWalker() {
override fun after(decl: VarDecl, parent: Node): Iterable {
@@ -54,6 +55,35 @@ internal class VarConstantValueTypeAdjuster(private val program: Program, privat
}
return noModifications
}
+
+ override fun after(range: RangeExpr, parent: Node): Iterable {
+ val from = range.from.constValue(program)?.number?.toDouble()
+ val to = range.to.constValue(program)?.number?.toDouble()
+ val step = range.step.constValue(program)?.number?.toDouble()
+
+ if(from==null) {
+ if(!range.from.inferType(program).isInteger())
+ errors.err("range expression from value must be integer", range.from.position)
+ } else if(from-from.toInt()>0) {
+ errors.err("range expression from value must be integer", range.from.position)
+ }
+
+ if(to==null) {
+ if(!range.to.inferType(program).isInteger())
+ errors.err("range expression to value must be integer", range.to.position)
+ } else if(to-to.toInt()>0) {
+ errors.err("range expression to value must be integer", range.to.position)
+ }
+
+ if(step==null) {
+ if(!range.step.inferType(program).isInteger())
+ errors.err("range expression step value must be integer", range.step.position)
+ } else if(step-step.toInt()>0) {
+ errors.err("range expression step value must be integer", range.step.position)
+ }
+
+ return noModifications
+ }
}
diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt
index 5688cb8cf..1db2c0b3f 100644
--- a/compiler/src/prog8/optimizer/StatementOptimizer.kt
+++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt
@@ -40,6 +40,41 @@ internal class StatementOptimizer(private val program: Program,
return noModifications
}
+ override fun before(functionCall: FunctionCall, parent: Node): Iterable {
+ // if the first instruction in the called subroutine is a return statement with a simple value,
+ // remove the jump altogeter and inline the returnvalue directly.
+ val subroutine = functionCall.target.targetSubroutine(program)
+ if(subroutine!=null) {
+ val first = subroutine.statements.asSequence().filterNot { it is VarDecl || it is Directive }.firstOrNull()
+ if(first is Return && first.value?.isSimple==true) {
+ val orig = first.value!!
+ val copy = when(orig) {
+ is AddressOf -> {
+ val scoped = scopePrefix(orig.identifier, subroutine)
+ AddressOf(scoped, orig.position)
+ }
+ is DirectMemoryRead -> {
+ when(val expr = orig.addressExpression) {
+ is NumericLiteralValue -> DirectMemoryRead(expr.copy(), orig.position)
+ else -> return noModifications
+ }
+ }
+ is IdentifierReference -> scopePrefix(orig, subroutine)
+ is NumericLiteralValue -> orig.copy()
+ is StringLiteralValue -> orig.copy()
+ else -> return noModifications
+ }
+ return listOf(IAstModification.ReplaceNode(functionCall, copy, parent))
+ }
+ }
+ return noModifications
+ }
+
+ private fun scopePrefix(variable: IdentifierReference, subroutine: Subroutine): IdentifierReference {
+ val scoped = subroutine.makeScopedName(variable.nameInSource.last())
+ return IdentifierReference(scoped.split('.'), variable.position)
+ }
+
override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable {
if(functionCallStatement.target.nameInSource.size==1 && functionCallStatement.target.nameInSource[0] in functions.names) {
val functionName = functionCallStatement.target.nameInSource[0]
@@ -102,19 +137,19 @@ internal class StatementOptimizer(private val program: Program,
return noModifications
}
- override fun before(functionCall: FunctionCall, parent: Node): Iterable {
- // if the first instruction in the called subroutine is a return statement with constant value, replace with the constant value
- val subroutine = functionCall.target.targetSubroutine(program)
- if(subroutine!=null) {
- val first = subroutine.statements.asSequence().filterNot { it is VarDecl || it is Directive }.firstOrNull()
- if(first is Return && first.value!=null) {
- val constval = first.value?.constValue(program)
- if(constval!=null)
- return listOf(IAstModification.ReplaceNode(functionCall, constval, parent))
- }
- }
- return noModifications
- }
+// override fun before(functionCall: FunctionCall, parent: Node): Iterable {
+// // if the first instruction in the called subroutine is a return statement with constant value, replace with the constant value
+// val subroutine = functionCall.target.targetSubroutine(program)
+// if(subroutine!=null) {
+// val first = subroutine.statements.asSequence().filterNot { it is VarDecl || it is Directive }.firstOrNull()
+// if(first is Return && first.value!=null) {
+// val constval = first.value?.constValue(program)
+// if(constval!=null)
+// return listOf(IAstModification.ReplaceNode(functionCall, constval, parent))
+// }
+// }
+// return noModifications
+// }
override fun after(ifStatement: IfStatement, parent: Node): Iterable {
// remove empty if statements
diff --git a/compiler/src/prog8/optimizer/SubroutineInliner.kt b/compiler/src/prog8/optimizer/SubroutineInliner.kt
deleted file mode 100644
index 8f45ead9a..000000000
--- a/compiler/src/prog8/optimizer/SubroutineInliner.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-package prog8.optimizer
-
-import prog8.ast.IFunctionCall
-import prog8.ast.Node
-import prog8.ast.Program
-import prog8.ast.base.Position
-import prog8.ast.expressions.FunctionCall
-import prog8.ast.expressions.IdentifierReference
-import prog8.ast.statements.*
-import prog8.ast.walk.AstWalker
-import prog8.ast.walk.IAstModification
-import prog8.compiler.CompilationOptions
-import prog8.compiler.IErrorReporter
-
-
-internal class SubroutineInliner(private val program: Program, val errors: IErrorReporter, private val compilerOptions: CompilationOptions): AstWalker() {
- private var callsToInlinedSubroutines = mutableListOf>()
-
- fun fixCallsToInlinedSubroutines() {
- for((call, parent) in callsToInlinedSubroutines) {
- val sub = call.target.targetSubroutine(program)!!
- val intermediateReturnValueVar = sub.statements.filterIsInstance().singleOrNull { it.name.endsWith(retvarName) }
- if(intermediateReturnValueVar!=null) {
- val scope = parent.definingScope()
- if(!scope.statements.filterIsInstance().any { it.name==intermediateReturnValueVar.name}) {
- val decl = intermediateReturnValueVar.copy()
- scope.statements.add(0, decl)
- decl.linkParents(scope as Node)
- }
- }
- }
- }
-
- override fun after(subroutine: Subroutine, parent: Node): Iterable {
- return if(compilerOptions.optimize && subroutine.inline && !subroutine.isAsmSubroutine)
- annotateInlinedSubroutineIdentifiers(subroutine)
- else
- noModifications
- }
-
- override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable {
- return after(functionCallStatement as IFunctionCall, parent, functionCallStatement.position)
- }
-
- override fun after(functionCall: FunctionCall, parent: Node): Iterable {
- return after(functionCall as IFunctionCall, parent, functionCall.position)
- }
-
- private fun after(functionCall: IFunctionCall, parent: Node, position: Position): Iterable {
- val sub = functionCall.target.targetSubroutine(program)
- if(sub != null && compilerOptions.optimize && sub.inline && !sub.isAsmSubroutine)
- callsToInlinedSubroutines.add(Pair(functionCall, parent))
-
- return noModifications
- }
-
- private fun annotateInlinedSubroutineIdentifiers(sub: Subroutine): List {
- // this adds name prefixes to the identifiers used in the subroutine,
- // so that the statements can be inlined (=copied) in the call site and still reference
- // the correct symbols as seen from the scope of the subroutine.
-
- class Annotator: AstWalker() {
- var numReturns=0
-
- override fun before(identifier: IdentifierReference, parent: Node): Iterable {
- val stmt = identifier.targetStatement(program)!!
- if(stmt is BuiltinFunctionStatementPlaceholder)
- return noModifications
-
- val prefixed = stmt.makeScopedName(identifier.nameInSource.last()).split('.')
- val withPrefix = IdentifierReference(prefixed, identifier.position)
- return listOf(IAstModification.ReplaceNode(identifier, withPrefix, parent))
- }
-
- override fun before(returnStmt: Return, parent: Node): Iterable {
- numReturns++
- if(parent !== sub || sub.indexOfChild(returnStmt) {
- return this.modifications.map { it.first }.toList()
- }
- }
-
- val annotator = Annotator()
- sub.accept(annotator, sub.parent)
- if(annotator.numReturns>1) {
- errors.err("inlined subroutine can only have one return statement", sub.position)
- return noModifications
- }
- return annotator.theModifications()
- }
-
-}
diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt
index 2a695dee6..7510d048d 100644
--- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt
+++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt
@@ -12,6 +12,14 @@ import prog8.parser.Prog8ANTLRParser
private data class NumericLiteral(val number: Number, val datatype: DataType)
+// TODO [merge conflict]: not sure if this should be kept?? Is it double??
+internal fun Prog8ANTLRParser.ModuleContext.toAst(name: String, source: Path, encoding: IStringEncoding) : Module {
+ val nameWithoutSuffix = if(name.endsWith(".p8")) name.substringBeforeLast('.') else name
+ val directives = this.directive().map { it.toAst() }
+ val blocks = this.block().map { it.toAst(Module.isLibrary(source), encoding) }
+ return Module(nameWithoutSuffix, (directives + blocks).toMutableList(), toPosition(), source)
+}
+
private fun ParserRuleContext.toPosition() : Position {
/*
val customTokensource = this.start.tokenSource as? CustomLexer
diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt
index de7994e4c..d106b7f9a 100644
--- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt
+++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt
@@ -347,7 +347,7 @@ class DirectMemoryRead(var addressExpression: Expression, override val position:
this.addressExpression.linkParents(this)
}
- override val isSimple = true
+ override val isSimple = addressExpression is NumericLiteralValue || addressExpression is IdentifierReference
override fun replaceChildNode(node: Node, replacement: Node) {
require(replacement is Expression && node===addressExpression)
@@ -365,8 +365,6 @@ class DirectMemoryRead(var addressExpression: Expression, override val position:
override fun toString(): String {
return "DirectMemoryRead($addressExpression)"
}
-
- fun copy() = DirectMemoryRead(addressExpression, position)
}
class NumericLiteralValue(val type: DataType, // only numerical types allowed
@@ -375,6 +373,7 @@ class NumericLiteralValue(val type: DataType, // only numerical types allowed
override lateinit var parent: Node
override val isSimple = true
+ fun copy() = NumericLiteralValue(type, number, position)
companion object {
fun fromBoolean(bool: Boolean, position: Position) =
@@ -539,6 +538,7 @@ class StringLiteralValue(val value: String,
}
override val isSimple = true
+ fun copy() = StringLiteralValue(value, altEncoding, position)
override fun replaceChildNode(node: Node, replacement: Node) {
throw FatalAstException("can't replace here")
diff --git a/docs/source/programming.rst b/docs/source/programming.rst
index ad6634869..153789229 100644
--- a/docs/source/programming.rst
+++ b/docs/source/programming.rst
@@ -641,9 +641,13 @@ Subroutines can be defined in a Block, but also nested inside another subroutine
With ``asmsub`` you can define a low-level subroutine that is implemented in inline assembly and takes any parameters
in registers directly.
-Trivial subroutines can be tagged as ``inline`` to tell the compiler to copy their code
+Trivial ``asmsub`` routines can be tagged as ``inline`` to tell the compiler to copy their code
in-place to the locations where the subroutine is called, rather than inserting an actual call and return to the
subroutine. This may increase code size significantly and can only be used in limited scenarios, so YMMV.
+Note that the routine's code is copied verbatim into the place of the subroutine call in this case,
+so pay attention to any jumps and rts instructions in the inlined code!
+
+At this time it is not yet possible to inline regular Prog8 subroutines, this may be added in the future.
Calling a subroutine
diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst
index 2b1e52fb5..8db69295c 100644
--- a/docs/source/syntaxreference.rst
+++ b/docs/source/syntaxreference.rst
@@ -33,13 +33,6 @@ This makes it easier to understand and relate the generated code. Examples::
Directives
-----------
-.. data:: %target
-
- Level: module.
- Global setting, specifies that this module can only work for the given compiler target.
- If compiled with a different target, compilation is aborted with an error message.
-
-
.. data:: %output
Level: module.
@@ -403,7 +396,7 @@ The following names are reserved, they have a special meaning::
Range expression
^^^^^^^^^^^^^^^^
-A special value is the *range expression* which represents a range of numbers or characters,
+A special value is the *range expression* which represents a range of integer numbers or characters,
from the starting value to (and including) the ending value::
to [ step ]
@@ -413,7 +406,7 @@ You an provide a step value if you need something else than the default incremen
in case of downto, a decrement of one). Because a step of minus one is so common you can just use
the downto variant to avoid having to specify the step as well.
-If used in the place of a literal value, it expands into the actual array of values::
+If used in the place of a literal value, it expands into the actual array of integer values::
byte[] array = 100 to 199 ; initialize array with [100, 101, ..., 198, 199]
@@ -559,7 +552,7 @@ Subroutine definitions
The syntax is::
- [inline] sub ( [parameters] ) [ -> returntype ] {
+ sub ( [parameters] ) [ -> returntype ] {
... statements ...
}
@@ -572,9 +565,6 @@ The open curly brace must immediately follow the subroutine result specification
and can have nothing following it. The close curly brace must be on its own line as well.
The parameters is a (possibly empty) comma separated list of " " pairs specifying the input parameters.
The return type has to be specified if the subroutine returns a value.
-The ``inline`` keyword makes their code copied in-place to the locations where the subroutine is called,
-rather than having an actual call and return to the subroutine. This is meant for very small subroutines only
-as it can increase code size significantly.
Assembly / ROM subroutines
diff --git a/examples/balloonflight.p8 b/examples/balloonflight.p8
index a39eac281..eb82e46bb 100644
--- a/examples/balloonflight.p8
+++ b/examples/balloonflight.p8
@@ -1,4 +1,3 @@
-%target c64
%import syslib
%import textio
%import test_stack
diff --git a/examples/bdmusic-irq.p8 b/examples/bdmusic-irq.p8
index 2bb1fb30c..6ed3b0e0f 100644
--- a/examples/bdmusic-irq.p8
+++ b/examples/bdmusic-irq.p8
@@ -1,4 +1,3 @@
-%target c64
%import syslib
%import textio
%zeropage basicsafe
diff --git a/examples/bdmusic.p8 b/examples/bdmusic.p8
index 29b443e38..b96bb83c7 100644
--- a/examples/bdmusic.p8
+++ b/examples/bdmusic.p8
@@ -1,4 +1,3 @@
-%target c64
%import textio
%import syslib
diff --git a/examples/charset.p8 b/examples/charset.p8
index 84214def7..71f10e252 100644
--- a/examples/charset.p8
+++ b/examples/charset.p8
@@ -1,4 +1,3 @@
-%target c64
%import syslib
%import textio
%zeropage basicsafe
diff --git a/examples/cube3d-sprites.p8 b/examples/cube3d-sprites.p8
index 843d6f81f..46091e3e3 100644
--- a/examples/cube3d-sprites.p8
+++ b/examples/cube3d-sprites.p8
@@ -1,4 +1,3 @@
-%target c64
%import syslib
%import textio
%import test_stack
diff --git a/examples/cube3d.p8 b/examples/cube3d.p8
index 65fd9b2e0..44c6cb45b 100644
--- a/examples/cube3d.p8
+++ b/examples/cube3d.p8
@@ -1,4 +1,3 @@
-%target c64
%import syslib
%import test_stack
%import textio
diff --git a/examples/cx16/amiga.p8 b/examples/cx16/amiga.p8
index ddaf57713..47cd11496 100644
--- a/examples/cx16/amiga.p8
+++ b/examples/cx16/amiga.p8
@@ -1,4 +1,3 @@
-%target cx16
%import textio
%import palette
%import string
diff --git a/examples/cx16/bobs.p8 b/examples/cx16/bobs.p8
index f4954e8c3..d15ed0f79 100644
--- a/examples/cx16/bobs.p8
+++ b/examples/cx16/bobs.p8
@@ -1,4 +1,3 @@
-%target cx16
%import palette
%import conv
%import textio
diff --git a/examples/cx16/cobramk3-gfx.p8 b/examples/cx16/cobramk3-gfx.p8
index 2884f0dc3..c72abbcf1 100644
--- a/examples/cx16/cobramk3-gfx.p8
+++ b/examples/cx16/cobramk3-gfx.p8
@@ -1,4 +1,3 @@
-%target cx16
%import syslib
%import test_stack
%import conv
diff --git a/examples/cx16/colorbars.p8 b/examples/cx16/colorbars.p8
index d78eb727e..7bd6dd501 100644
--- a/examples/cx16/colorbars.p8
+++ b/examples/cx16/colorbars.p8
@@ -1,27 +1,24 @@
-%import gfx2
-%import palette
%import textio
-
-; TODO WORK IN PROGRESS...
-; want to make Amiga 'copper' bars color cycling effects
+; Amiga 'copper' bars color cycling effect
main {
sub start() {
- palette.set_all_black()
- gfx2.screen_mode(4)
+ ; make palette color 1 black so we can print black letters over the background color 0
+ void cx16.screen_set_mode(0)
+ cx16.vpoke(1, $fa02, $0)
+ cx16.vpoke(1, $fa03, $0)
+ txt.color(1)
+ txt.plot(13,12)
+ txt.print("amiga-inspired")
+ txt.plot(10,14)
+ txt.print("raster blinds effect")
+ txt.plot(12,16)
+ txt.print("random gradients")
- ubyte yy
- for yy in 0 to 239
- gfx2.horizontal_line(0, yy, 320, yy & 63)
-
- repeat {
- colors.random_bar()
- colors.set_palette()
- repeat 20
- sys.waitvsync()
- }
+ irq.make_new_gradient()
+ cx16.set_rasterirq(&irq.irqhandler, irq.top_scanline)
repeat {
}
@@ -29,99 +26,165 @@ main {
}
+irq {
+ const ubyte top_scanline = 0
+ ubyte blinds_start_ix = 0
+ ubyte color_ix = 0
+ uword next_irq_line = top_scanline
+ ubyte shift_counter = 0
+
+ ubyte[32+32+16] blinds_lines_reds
+ ubyte[32+32+16] blinds_lines_greens
+ ubyte[32+32+16] blinds_lines_blues
+
+
+ sub irqhandler() {
+ set_scanline_color(color_ix)
+ color_ix++
+
+ next_irq_line += 2 ; code needs 2 scanlines per color transition
+
+ if next_irq_line == 480 {
+ ; start over at top
+ next_irq_line = top_scanline
+ blinds_start_ix = 0
+ color_ix = 0
+ shift_counter++
+ if shift_counter == 32+32+32 {
+ make_new_gradient()
+ shift_counter = 0
+ } else if shift_counter & 1 {
+ shift_gradient()
+ }
+ } else if next_irq_line & 15 == 0 {
+ ; start next blinds
+ blinds_start_ix++
+ color_ix = blinds_start_ix
+ }
+
+
+
+ cx16.set_rasterline(next_irq_line)
+ }
+
+ sub make_new_gradient() {
+ colors.random_half_bar()
+ colors.mirror_bar()
+ sys.memcopy(colors.reds, &blinds_lines_reds+32+16, len(colors.reds))
+ sys.memcopy(colors.greens, &blinds_lines_greens+32+16, len(colors.greens))
+ sys.memcopy(colors.blues, &blinds_lines_blues+32+16, len(colors.blues))
+ }
+
+ sub shift_gradient() {
+ sys.memcopy(&blinds_lines_reds+1, blinds_lines_reds, len(blinds_lines_reds)-1)
+ sys.memcopy(&blinds_lines_greens+1, blinds_lines_greens, len(blinds_lines_greens)-1)
+ sys.memcopy(&blinds_lines_blues+1, blinds_lines_blues, len(blinds_lines_blues)-1)
+ }
+
+ asmsub set_scanline_color(ubyte color_ix @Y) {
+ ; uword color = mkword(reds[ix], (greens[ix] << 4) | blues[ix] )
+ %asm {{
+ lda blinds_lines_reds,y
+ pha
+ lda blinds_lines_greens,y
+ asl a
+ asl a
+ asl a
+ asl a
+ ora blinds_lines_blues,y
+ tay
+
+ stz cx16.VERA_CTRL
+ lda #%00010001
+ sta cx16.VERA_ADDR_H
+ lda #$fa
+ sta cx16.VERA_ADDR_M
+ ; lda #$02
+ ; sta cx16.VERA_ADDR_L
+ stz cx16.VERA_ADDR_L
+ sty cx16.VERA_DATA0 ; gb
+ pla
+ sta cx16.VERA_DATA0 ; r
+ stz cx16.VERA_ADDR_H
+ rts
+ }}
+ }
+}
+
+
colors {
- ubyte cr
- ubyte cg
- ubyte cb
- ubyte[48+16] reds
- ubyte[48+16] greens
- ubyte[48+16] blues
- ubyte bar_size
+ ubyte target_red
+ ubyte target_green
+ ubyte target_blue
+ ubyte[32] reds
+ ubyte[32] greens
+ ubyte[32] blues
sub random_rgb12() {
do {
uword rr = rndw()
- cr = msb(rr) & 15
- cg = lsb(rr)
- cb = cg & 15
- cg >>= 4
- } until cr+cg+cb >= 12
+ target_red = msb(rr) & 15
+ target_green = lsb(rr)
+ target_blue = target_green & 15
+ target_green >>= 4
+ } until target_red+target_green+target_blue >= 12
}
- sub random_bar() {
+ sub mirror_bar() {
+ ; mirror the top half bar into the bottom half
+ ubyte ix=14
+ ubyte mix=16
+ do {
+ reds[mix] = reds[ix]
+ greens[mix] = greens[ix]
+ blues[mix] = blues[ix]
+ mix++
+ ix--
+ } until ix==255
+ reds[mix] = 0
+ greens[mix] = 0
+ blues[mix] = 0
+ }
+
+ sub random_half_bar() {
; fade black -> color then fade color -> white
+ ; gradient calculations in 8.8 bits fixed-point
+ ; could theoretically be 4.12 bits for even more fractional accuracy
random_rgb12()
- ubyte r=0
- ubyte g=0
- ubyte b=0
- ubyte different
- bar_size = 0
+ uword r = $000
+ uword g = $000
+ uword b = $000
+ uword dr = target_red
+ uword dg = target_green
+ uword db = target_blue
+ ubyte ix = 1
- repeat {
- different = false
- if r != cr {
- different = true
- r++
- }
- if g != cg {
- different = true
- g++
- }
- if b != cb {
- different = true
- b++
- }
- if not different
- break
- reds[bar_size] = r
- greens[bar_size] = g
- blues[bar_size] = b
- bar_size++
- }
- repeat {
- different = false
- if r != 15 {
- different = true
- r++
- }
- if g != 15 {
- different = true
- g++
- }
- if b != 15 {
- different = true
- b++
- }
- if not different
- break
- reds[bar_size] = r
- greens[bar_size] = g
- blues[bar_size] = b
- bar_size++
- }
- ; mirror bottom half from top half
- ubyte mi = bar_size-1
- repeat mi {
- reds[bar_size] = reds[mi]
- greens[bar_size] = greens[mi]
- blues[bar_size] = blues[mi]
- bar_size++
- mi--
- }
- ; make rest of bar black (bars are not always the same length using the simplistic algorithm above...)
- while bar_size != 48+16 {
- reds[bar_size] = $0
- greens[bar_size] = $0
- blues[bar_size] = $0
- bar_size++
- }
- }
+ ; gradient from black to halfway color
+ reds[0] = 0
+ greens[0] = 0
+ blues[0] = 0
+ dr <<= 5
+ dg <<= 5
+ db <<= 5
+ continue_gradient()
- sub set_palette() {
- ubyte ix
- for ix in 0 to 48+15 {
- uword color = mkword(reds[ix], (greens[ix] << 4) | blues[ix] )
- palette.set_color(ix, color)
+ ; gradient from halfway color to white
+ dr = (($f00 - r) >> 3) - 1
+ dg = (($f00 - g) >> 3) - 1
+ db = (($f00 - b) >> 3) - 1
+ continue_gradient()
+ return
+
+ sub continue_gradient() {
+ repeat 8 {
+ reds[ix] = msb(r)
+ greens[ix] = msb(g)
+ blues[ix] = msb(b)
+ r += dr
+ g += dg
+ b += db
+ ix++
+ }
}
}
}
diff --git a/examples/cx16/cube3d.p8 b/examples/cx16/cube3d.p8
index d4b8a3d37..149e0e7fb 100644
--- a/examples/cx16/cube3d.p8
+++ b/examples/cx16/cube3d.p8
@@ -1,4 +1,3 @@
-%target cx16
%import textio
main {
diff --git a/examples/cx16/datetime.p8 b/examples/cx16/datetime.p8
index 0fa4887b4..8a4e40dd1 100644
--- a/examples/cx16/datetime.p8
+++ b/examples/cx16/datetime.p8
@@ -1,6 +1,5 @@
; CommanderX16 text datetime example!
-%target cx16
%import textio
%zeropage basicsafe
diff --git a/examples/cx16/highresbitmap.p8 b/examples/cx16/highresbitmap.p8
index 49d042e60..4a0f536d1 100644
--- a/examples/cx16/highresbitmap.p8
+++ b/examples/cx16/highresbitmap.p8
@@ -1,4 +1,3 @@
-%target cx16
%import gfx2
%import floats
%import textio
diff --git a/examples/cx16/kefrenbars.p8 b/examples/cx16/kefrenbars.p8
index a3c6ce6be..0b7b31306 100644
--- a/examples/cx16/kefrenbars.p8
+++ b/examples/cx16/kefrenbars.p8
@@ -1,4 +1,3 @@
-%target cx16
%import palette
%option no_sysinit
diff --git a/examples/cx16/mandelbrot-gfx-colors.p8 b/examples/cx16/mandelbrot-gfx-colors.p8
index 844faaef5..b386ee7de 100644
--- a/examples/cx16/mandelbrot-gfx-colors.p8
+++ b/examples/cx16/mandelbrot-gfx-colors.p8
@@ -1,4 +1,3 @@
-%target cx16
%import textio
%import floats
%zeropage basicsafe
diff --git a/examples/cx16/mandelbrot.p8 b/examples/cx16/mandelbrot.p8
index a92e46529..58a1d5dba 100644
--- a/examples/cx16/mandelbrot.p8
+++ b/examples/cx16/mandelbrot.p8
@@ -1,4 +1,3 @@
-%target cx16
%import textio
%import floats
%zeropage basicsafe
diff --git a/examples/cx16/multipalette.p8 b/examples/cx16/multipalette.p8
index a4801d102..28fe57af8 100644
--- a/examples/cx16/multipalette.p8
+++ b/examples/cx16/multipalette.p8
@@ -1,4 +1,3 @@
-%target cx16
%import palette
%import gfx2
%option no_sysinit
diff --git a/examples/cx16/rasterbars.p8 b/examples/cx16/rasterbars.p8
index df73756bc..94b2bf4b2 100644
--- a/examples/cx16/rasterbars.p8
+++ b/examples/cx16/rasterbars.p8
@@ -1,4 +1,3 @@
-%target cx16
%import textio
%import palette
diff --git a/examples/cx16/tehtriz.p8 b/examples/cx16/tehtriz.p8
index a33473236..32cfc5ff7 100644
--- a/examples/cx16/tehtriz.p8
+++ b/examples/cx16/tehtriz.p8
@@ -8,7 +8,6 @@
; simplistic sound effects (Vera PSG)
-%target cx16
%import syslib
%import textio
%import test_stack
diff --git a/examples/cx16/testgfx2.p8 b/examples/cx16/testgfx2.p8
index be8b2a8d9..6317aaa76 100644
--- a/examples/cx16/testgfx2.p8
+++ b/examples/cx16/testgfx2.p8
@@ -1,4 +1,3 @@
-%target cx16
%import gfx2
%import textio
%import test_stack
diff --git a/examples/cx16/vtui/testvtui.p8 b/examples/cx16/vtui/testvtui.p8
index b161e1503..9eb1f6440 100644
--- a/examples/cx16/vtui/testvtui.p8
+++ b/examples/cx16/vtui/testvtui.p8
@@ -1,4 +1,3 @@
-%target cx16
%import textio
%option no_sysinit
%zeropage basicsafe
diff --git a/examples/plasma.p8 b/examples/plasma.p8
index 9c1eaf37e..094765a82 100644
--- a/examples/plasma.p8
+++ b/examples/plasma.p8
@@ -1,4 +1,3 @@
-%target c64
%import syslib
%import test_stack
%import textio
diff --git a/examples/rasterbars.p8 b/examples/rasterbars.p8
index 6057810de..505cc1d16 100644
--- a/examples/rasterbars.p8
+++ b/examples/rasterbars.p8
@@ -1,4 +1,3 @@
-%target c64
%import syslib
main {
diff --git a/examples/sprites.p8 b/examples/sprites.p8
index d336e6a65..b15f92efd 100644
--- a/examples/sprites.p8
+++ b/examples/sprites.p8
@@ -1,4 +1,3 @@
-%target c64
%import textio
%import syslib
%zeropage basicsafe
diff --git a/examples/tehtriz.p8 b/examples/tehtriz.p8
index 3fdffd868..5f75d330f 100644
--- a/examples/tehtriz.p8
+++ b/examples/tehtriz.p8
@@ -8,7 +8,6 @@
; some simple sound effects
-%target c64
%import syslib
%import textio
%import test_stack
diff --git a/examples/turtle-gfx.p8 b/examples/turtle-gfx.p8
index bfefa7115..f3bf3224c 100644
--- a/examples/turtle-gfx.p8
+++ b/examples/turtle-gfx.p8
@@ -1,4 +1,3 @@
-%target c64
%import floats
%import graphics
%import test_stack
diff --git a/examples/wizzine.p8 b/examples/wizzine.p8
index f50946f07..0af5abb4e 100644
--- a/examples/wizzine.p8
+++ b/examples/wizzine.p8
@@ -1,4 +1,3 @@
-%target c64
%import syslib
%zeropage basicsafe
diff --git a/parser/antlr/Prog8ANTLR.g4 b/parser/antlr/Prog8ANTLR.g4
index af05c0aec..2d03cad97 100644
--- a/parser/antlr/Prog8ANTLR.g4
+++ b/parser/antlr/Prog8ANTLR.g4
@@ -8,7 +8,7 @@ NOTES:
*/
-// -> java classes Prog8ANTLRParser and Prog8ANTLRLexer,
+// -> java classes Prog8ANTLRParser and Prog8ANTLRLexer,
// both NOT to be used from Kotlin code, but ONLY through Kotlin class Prog8Parser
grammar Prog8ANTLR;
@@ -137,7 +137,7 @@ unconditionaljump : 'goto' (integerliteral | scoped_identifier) ;
directive :
directivename=('%output' | '%launcher' | '%zeropage' | '%zpreserved' | '%address' | '%import' |
- '%breakpoint' | '%asminclude' | '%asmbinary' | '%option' | '%target' )
+ '%breakpoint' | '%asminclude' | '%asmbinary' | '%option' )
(directivearg? | directivearg (',' directivearg)*)
;
diff --git a/syntax-files/IDEA/Prog8.xml b/syntax-files/IDEA/Prog8.xml
index 0b5629951..6b7feb46e 100644
--- a/syntax-files/IDEA/Prog8.xml
+++ b/syntax-files/IDEA/Prog8.xml
@@ -12,7 +12,7 @@
-
+
@@ -20,4 +20,4 @@
-
\ No newline at end of file
+
diff --git a/syntax-files/NotepadPlusPlus/Prog8.xml b/syntax-files/NotepadPlusPlus/Prog8.xml
index 4b5afe75d..317befee7 100644
--- a/syntax-files/NotepadPlusPlus/Prog8.xml
+++ b/syntax-files/NotepadPlusPlus/Prog8.xml
@@ -25,7 +25,7 @@
void const
str
byte ubyte
word uword
float
zp shared
- %address
%asm
%asmbinary
%asminclude
%breakpoint
%import
%launcher
%option
%output
%target
%zeropage
%zpreserved
+ %address
%asm
%asmbinary
%asminclude
%breakpoint
%import
%launcher
%option
%output
%zeropage
%zpreserved
inline sub asmsub romsub
clobbers
asm
if
when else
if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z
for in step do while repeat
break return goto
abs acos all any asin atan avg callfar callrom ceil cmp cos cos16 cos16u cos8 cos8u deg floor len ln log2 lsb lsl lsr max memory min mkword msb peek peekw poke pokew rad reverse rnd rndf rndw rol rol2 ror ror2 round sgn sin sin16 sin16u sin8 sin8u sizeof sort sqrt sqrt16 sum swap tan
true false
not and or xor
as to downto
diff --git a/syntax-files/NotepadPlusPlus/syntax-test.p8 b/syntax-files/NotepadPlusPlus/syntax-test.p8
index 9435d9f53..a64982a25 100644
--- a/syntax-files/NotepadPlusPlus/syntax-test.p8
+++ b/syntax-files/NotepadPlusPlus/syntax-test.p8
@@ -1,4 +1,3 @@
-%target cx16
%import textio
%zeropage basicsafe
%option no_sysinit
diff --git a/syntax-files/Vim/prog8.vim b/syntax-files/Vim/prog8.vim
index 4401d27a9..57afc410a 100644
--- a/syntax-files/Vim/prog8.vim
+++ b/syntax-files/Vim/prog8.vim
@@ -33,7 +33,7 @@ syn keyword prog8Repeat for while in do until repeat
syn match prog8Label "\<\w\+\>:"
syn keyword prog8Operator and or to downto as void
-syn match prog8Directive "\(^\|\s\)%\(target\|output\|launcher\|zeropage\)\>"
+syn match prog8Directive "\(^\|\s\)%\(output\|launcher\|zeropage\)\>"
syn match prog8Directive "\(^\|\s\)%\(zpreserved\|address\|import\|option\)\>"
syn match prog8Directive "\(^\|\s\)%\(asmbinary\|asminclude\|breakpoint\)\>"
syn match prog8Directive "\(^\|\s\)%asm\>"