removed some redundant arguments

This commit is contained in:
Irmen de Jong
2025-04-25 22:55:07 +02:00
parent 4d91f92a2e
commit b047731f82
25 changed files with 75 additions and 87 deletions

View File

@@ -129,7 +129,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
return listOf(IAstModification.ReplaceNode(expr, newArray, parent))
}
else {
val leftTarget = (expr.left as? IdentifierReference)?.targetVarDecl(program)
val leftTarget = (expr.left as? IdentifierReference)?.targetVarDecl()
if(leftTarget!=null && leftTarget.origin==VarDeclOrigin.ARRAYLITERAL)
throw FatalAstException("shouldn't see an array literal converted to an autovar here")
}
@@ -332,7 +332,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
val constIndex = arrayIndexedExpression.indexer.constIndex()
if (constIndex != null) {
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl()
if(arrayVar!=null) {
val array =arrayVar.value as? ArrayLiteral
if(array!=null) {
@@ -387,7 +387,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
val rangeTo = iterableRange.to as? NumericLiteral
if(rangeFrom==null || rangeTo==null) return noModifications
val loopvar = forLoop.loopVar.targetVarDecl(program) ?: return noModifications
val loopvar = forLoop.loopVar.targetVarDecl() ?: return noModifications
val stepLiteral = iterableRange.step as? NumericLiteral
require(loopvar.datatype.sub == null)

View File

@@ -560,7 +560,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
}
}
else if(functionCallExpr.target.nameInSource == listOf("strings", "contains")) {
val target = (functionCallExpr.args[0] as? IdentifierReference)?.targetVarDecl(program)
val target = (functionCallExpr.args[0] as? IdentifierReference)?.targetVarDecl()
if(target?.value is StringLiteral) {
errors.info("for actual strings, use a regular containment check instead: 'char in string'", functionCallExpr.position)
val contains = ContainmentCheck(functionCallExpr.args[1], functionCallExpr.args[0], functionCallExpr.position)

View File

@@ -16,7 +16,7 @@ import prog8.code.target.VMTarget
private fun isEmptyReturn(stmt: Statement): Boolean = stmt is Return && stmt.values.isEmpty()
// inliner potentially enables *ONE LINED* subroutines, wihtout to be inlined.
// inliner potentially enables *ONE LINED* subroutines, without to be inlined.
class Inliner(private val program: Program, private val options: CompilationOptions): AstWalker() {
@@ -122,7 +122,7 @@ class Inliner(private val program: Program, private val options: CompilationOpti
private fun makeFullyScoped(call: FunctionCallStatement) {
makeFullyScoped(call.target)
call.target.targetSubroutine(program)?.let { sub ->
call.target.targetSubroutine()?.let { sub ->
val scopedName = IdentifierReference(sub.scopedName, call.target.position)
val scopedArgs = makeScopedArgs(call.args)
if(scopedArgs.any()) {
@@ -134,7 +134,7 @@ class Inliner(private val program: Program, private val options: CompilationOpti
private fun makeFullyScoped(call: FunctionCallExpression) {
makeFullyScoped(call.target)
call.target.targetSubroutine(program)?.let { sub ->
call.target.targetSubroutine()?.let { sub ->
val scopedName = IdentifierReference(sub.scopedName, call.target.position)
val scopedArgs = makeScopedArgs(call.args)
if(scopedArgs.any()) {

View File

@@ -33,8 +33,8 @@ class StatementOptimizer(private val program: Program,
} else {
arg as? IdentifierReference
}
if(stringVar!=null && stringVar.wasStringLiteral(program)) {
val string = stringVar.targetVarDecl(program)?.value as? StringLiteral
if(stringVar!=null && stringVar.wasStringLiteral()) {
val string = stringVar.targetVarDecl()?.value as? StringLiteral
if(string!=null) {
val pos = functionCallStatement.position
if (string.value.length == 1) {
@@ -152,7 +152,7 @@ class StatementOptimizer(private val program: Program,
return listOf(IAstModification.ReplaceNode(forLoop, scope, parent))
}
}
val iterable = (forLoop.iterable as? IdentifierReference)?.targetVarDecl(program)
val iterable = (forLoop.iterable as? IdentifierReference)?.targetVarDecl()
if(iterable!=null) {
if(iterable.datatype.isString) {
val sv = iterable.value as StringLiteral

View File

@@ -1,8 +1,8 @@
package prog8.compiler
import prog8.ast.Program
import prog8.ast.AstException
import prog8.ast.FatalAstException
import prog8.ast.Program
import prog8.ast.SyntaxError
import prog8.ast.expressions.*
import prog8.ast.statements.VarDecl
@@ -119,12 +119,13 @@ private fun builtinSizeof(args: List<Expression>, position: Position, program: P
}
}
@Suppress("unused")
private fun builtinLen(args: List<Expression>, position: Position, program: Program): NumericLiteral {
// note: in some cases the length is > 255, and then we have to return a UWORD type instead of a UBYTE.
if(args.size!=1)
throw SyntaxError("len requires one argument", position)
val directMemVar = ((args[0] as? DirectMemoryRead)?.addressExpression as? IdentifierReference)?.targetVarDecl(program)
val directMemVar = ((args[0] as? DirectMemoryRead)?.addressExpression as? IdentifierReference)?.targetVarDecl()
var arraySize = directMemVar?.arraysize?.constIndex()
if(arraySize != null)
return NumericLiteral.optimalInteger(arraySize, position)
@@ -134,7 +135,7 @@ private fun builtinLen(args: List<Expression>, position: Position, program: Prog
return NumericLiteral.optimalInteger((args[0] as StringLiteral).value.length, position)
if(args[0] !is IdentifierReference)
throw SyntaxError("len argument should be an identifier", position)
val target = (args[0] as IdentifierReference).targetVarDecl(program)
val target = (args[0] as IdentifierReference).targetVarDecl()
?: throw CannotEvaluateException("len", "no target vardecl")
return when {

View File

@@ -189,7 +189,7 @@ internal class AstChecker(private val program: Program,
} else if(!(iterableDt.isIterable) && forLoop.iterable !is RangeExpression) {
errors.err("can only loop over an iterable type", forLoop.position)
} else {
val loopvar = forLoop.loopVar.targetVarDecl(program)
val loopvar = forLoop.loopVar.targetVarDecl()
if(loopvar==null || loopvar.type== VarDeclType.CONST) {
errors.err("for loop requires a variable to loop with", forLoop.position)
} else {
@@ -392,7 +392,7 @@ internal class AstChecker(private val program: Program,
err("variable bank extsub has no romable code-generation for the required jsrfar call, stick to constant bank, or create a system-ram trampoline")
}
if(varbank.targetVarDecl(program)?.datatype?.isUnsignedByte!=true)
if(varbank.targetVarDecl()?.datatype?.isUnsignedByte!=true)
err("bank variable must be ubyte")
}
if(subroutine.inline && subroutine.asmAddress!=null)
@@ -558,7 +558,7 @@ internal class AstChecker(private val program: Program,
val ident = repeatLoop.iterations as? IdentifierReference
if(ident!=null) {
val targetVar = ident.targetVarDecl(program)
val targetVar = ident.targetVarDecl()
if(targetVar==null)
errors.err("invalid assignment value, maybe forgot '&' (address-of)", ident.position)
}
@@ -598,7 +598,7 @@ internal class AstChecker(private val program: Program,
}
val fcall = assignment.value as? IFunctionCall
val fcallTarget = fcall?.target?.targetSubroutine(program)
val fcallTarget = fcall?.target?.targetSubroutine()
if(assignment.target.multi!=null) {
checkMultiAssignment(assignment, fcall, fcallTarget)
} else if(fcallTarget!=null) {
@@ -690,7 +690,7 @@ internal class AstChecker(private val program: Program,
fun checkRomTarget(target: AssignTarget) {
val idx=target.arrayindexed
if(idx!=null) {
val decl = idx.arrayvar.targetVarDecl(program)!!
val decl = idx.arrayvar.targetVarDecl()!!
if(decl.type!=VarDeclType.MEMORY && decl.zeropage!=ZeropageWish.REQUIRE_ZEROPAGE) {
// memory mapped arrays are assumed to be in RAM. If they're not.... well, POOF
errors.err("cannot assign to an array or string that is located in ROM (option romable is enabled)", assignTarget.position)
@@ -708,7 +708,7 @@ internal class AstChecker(private val program: Program,
override fun visit(addressOf: AddressOf) {
checkLongType(addressOf)
val variable=addressOf.identifier.targetVarDecl(program)
val variable=addressOf.identifier.targetVarDecl()
if (variable!=null) {
if (variable.type == VarDeclType.CONST && addressOf.arrayIndex == null)
errors.err("invalid pointer-of operand type", addressOf.position)
@@ -1153,7 +1153,7 @@ internal class AstChecker(private val program: Program,
override fun visit(expr: PrefixExpression) {
if(expr.expression is IFunctionCall) {
val targetStatement = (expr.expression as IFunctionCall).target.targetSubroutine(program)
val targetStatement = (expr.expression as IFunctionCall).target.targetSubroutine()
if(targetStatement?.returntypes?.isEmpty()==true) {
errors.err("subroutine doesn't return a value", expr.expression.position)
}
@@ -1601,7 +1601,7 @@ internal class AstChecker(private val program: Program,
}
private fun checkPointer(pointervar: IdentifierReference) {
val vardecl = pointervar.targetVarDecl(program)
val vardecl = pointervar.targetVarDecl()
if(vardecl?.zeropage == ZeropageWish.NOT_IN_ZEROPAGE)
errors.info("pointer variable should preferrably be in zeropage but is marked nozp", vardecl.position)
}
@@ -1614,7 +1614,7 @@ internal class AstChecker(private val program: Program,
errors.err("indexing requires an iterable or address uword variable", arrayIndexedExpression.position)
val indexVariable = arrayIndexedExpression.indexer.indexExpr as? IdentifierReference
if(indexVariable!=null) {
if(indexVariable.targetVarDecl(program)?.datatype?.isSigned==true) {
if(indexVariable.targetVarDecl()?.datatype?.isSigned==true) {
errors.err("variable array indexing can't be performed with signed variables", indexVariable.position)
return
}

View File

@@ -3,11 +3,7 @@ package prog8.compiler.astprocessing
import prog8.ast.IStatementContainer
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.expressions.BinaryExpression
import prog8.ast.expressions.CharLiteral
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.NumericLiteral
import prog8.ast.expressions.StringLiteral
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
@@ -185,8 +181,8 @@ internal fun Program.moveMainBlockAsFirst(target: ICompilationTarget) {
}
}
internal fun IdentifierReference.isSubroutineParameter(program: Program): Boolean {
val vardecl = this.targetVarDecl(program)
internal fun IdentifierReference.isSubroutineParameter(): Boolean {
val vardecl = this.targetVarDecl()
if(vardecl!=null && vardecl.origin==VarDeclOrigin.SUBROUTINEPARAM) {
return vardecl.definingSubroutine?.parameters?.any { it.name==vardecl.name } == true
}

View File

@@ -1,12 +1,7 @@
package prog8.compiler.astprocessing
import prog8.ast.IFunctionCall
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.FatalAstException
import prog8.ast.SyntaxError
import prog8.ast.*
import prog8.ast.expressions.*
import prog8.ast.findParentNode
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
@@ -181,7 +176,7 @@ class AstPreprocessor(val program: Program,
val nextAssignment = decl.nextSibling() as? Assignment
if(nextAssignment!=null && nextAssignment.origin!=AssignmentOrigin.VARINIT) {
// check if the following assignment initializes the variable
if(decl.value==null && nextAssignment.target.identifier?.targetVarDecl(program)===decl) {
if(decl.value==null && nextAssignment.target.identifier?.targetVarDecl()===decl) {
if(!nextAssignment.value.referencesIdentifier(nextAssignment.target.identifier!!.nameInSource))
nextAssignment.origin = AssignmentOrigin.VARINIT
}

View File

@@ -36,7 +36,7 @@ internal class BeforeAsmTypecastCleaner(val program: Program,
if(typecast.type == BaseDataType.UWORD) {
val identifier = typecast.expression as? IdentifierReference
if(identifier!=null) {
return if(identifier.isSubroutineParameter(program)) {
return if(identifier.isSubroutineParameter()) {
listOf(
IAstModification.ReplaceNode(
typecast,

View File

@@ -205,7 +205,7 @@ _after:
// replace pointervar[word] by @(pointervar+word) to avoid the
// "array indexing is limited to byte size 0..255" error for pointervariables.
val indexExpr = arrayIndexedExpression.indexer.indexExpr
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl()
if(arrayVar!=null && arrayVar.datatype.isUnsignedWord) {
val wordIndex = TypecastExpression(indexExpr, BaseDataType.UWORD, true, indexExpr.position)
val address = BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", wordIndex, arrayIndexedExpression.position)
@@ -279,7 +279,7 @@ _after:
val addressOf = expr.left as? AddressOf
val offset = (expr.right as? NumericLiteral)?.number?.toInt()
if(addressOf!=null && offset==1) {
val variable = addressOf.identifier.targetVarDecl(program)
val variable = addressOf.identifier.targetVarDecl()
if(variable!=null && variable.datatype.isWord) {
val msb = FunctionCallExpression(IdentifierReference(listOf("msb"), memread.position), mutableListOf(addressOf.identifier), memread.position)
return listOf(IAstModification.ReplaceNode(memread, msb, parent))

View File

@@ -9,7 +9,7 @@ import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.code.ast.PtContainmentCheck
import prog8.code.core.*
import prog8.code.core.IErrorReporter
internal class LiteralsToAutoVars(private val program: Program, private val errors: IErrorReporter) : AstWalker() {
@@ -83,7 +83,7 @@ internal class LiteralsToAutoVars(private val program: Program, private val erro
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
if(decl.names.size>1) {
val fcallTarget = (decl.value as? IFunctionCall)?.target?.targetSubroutine(program)
val fcallTarget = (decl.value as? IFunctionCall)?.target?.targetSubroutine()
if(fcallTarget!=null) {
// ubyte a,b,c = multi() --> ubyte a,b,c / a,b,c = multi()
val modifications = mutableListOf<IAstModification>()

View File

@@ -420,7 +420,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
if(binexpr.operator=="==" || binexpr.operator=="!=") {
val fcall = binexpr.left as? FunctionCallExpression
if(fcall!=null) {
val returnRegs = fcall.target.targetSubroutine(program)?.asmReturnvaluesRegisters
val returnRegs = fcall.target.targetSubroutine()?.asmReturnvaluesRegisters
if(returnRegs!=null && returnRegs.size==1 && returnRegs[0].statusflag!=null) {
return codeForStatusflag(fcall, returnRegs[0].statusflag!!, binexpr.operator == "==")
}
@@ -429,7 +429,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
} else {
val fcall = srcIf.condition as? FunctionCallExpression
if (fcall != null) {
val returnRegs = fcall.target.targetSubroutine(program)?.asmReturnvaluesRegisters
val returnRegs = fcall.target.targetSubroutine()?.asmReturnvaluesRegisters
if(returnRegs!=null && returnRegs.size==1 && returnRegs[0].statusflag!=null) {
return codeForStatusflag(fcall, returnRegs[0].statusflag!!, false)
}
@@ -439,7 +439,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
if(prefix!=null && prefix.operator=="not") {
val prefixedFcall = prefix.expression as? FunctionCallExpression
if (prefixedFcall != null) {
val returnRegs = prefixedFcall.target.targetSubroutine(program)?.asmReturnvaluesRegisters
val returnRegs = prefixedFcall.target.targetSubroutine()?.asmReturnvaluesRegisters
if (returnRegs != null && returnRegs.size == 1 && returnRegs[0].statusflag != null) {
return codeForStatusflag(prefixedFcall, returnRegs[0].statusflag!!, true)
}
@@ -622,7 +622,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
}
private fun transform(srcArr: ArrayIndexedExpression): PtArrayIndexer {
val dt = srcArr.arrayvar.targetVarDecl(program)!!.datatype
val dt = srcArr.arrayvar.targetVarDecl()!!.datatype
if(!dt.isArray && !dt.isString)
throw FatalAstException("array indexing can only be used on array or string variables ${srcArr.position}")
val eltType = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }

View File

@@ -95,7 +95,7 @@ internal class StatementReorderer(
// (that code only triggers on regular assignment, not on variable initializers)
val ident = decl.value as? IdentifierReference
if(ident!=null) {
val target = ident.targetVarDecl(program)
val target = ident.targetVarDecl()
if(target!=null && target.isArray) {
val pos = decl.value!!.position
val identifier = IdentifierReference(listOf(decl.name), pos)
@@ -127,14 +127,14 @@ internal class StatementReorderer(
when(stmt) {
is Assignment -> {
if (!stmt.isAugmentable) {
val assignTargets = stmt.target.multi?.mapNotNull { it.identifier?.targetVarDecl(program) }
val assignTargets = stmt.target.multi?.mapNotNull { it.identifier?.targetVarDecl() }
if(assignTargets!=null) {
if(decl in assignTargets) {
stmt.origin = AssignmentOrigin.VARINIT
return true
}
} else {
val assignTgt = stmt.target.identifier?.targetVarDecl(program)
val assignTgt = stmt.target.identifier?.targetVarDecl()
if (assignTgt == decl) {
stmt.origin = AssignmentOrigin.VARINIT
return true
@@ -147,11 +147,11 @@ internal class StatementReorderer(
is ChainedAssignment -> {
var chained: ChainedAssignment? = stmt
while(chained!=null) {
val assignTgt = chained.target.identifier?.targetVarDecl(program)
val assignTgt = chained.target.identifier?.targetVarDecl()
if (assignTgt == decl)
return true
if(chained.nested is Assignment) {
if ((chained.nested as Assignment).target.identifier?.targetVarDecl(program) == decl) {
if ((chained.nested as Assignment).target.identifier?.targetVarDecl() == decl) {
(chained.nested as Assignment).origin = AssignmentOrigin.VARINIT
return true
}
@@ -329,7 +329,7 @@ internal class StatementReorderer(
private fun checkCopyArrayValue(assign: Assignment) {
val identifier = assign.target.identifier!!
val targetVar = identifier.targetVarDecl(program)!!
val targetVar = identifier.targetVarDecl()!!
if(targetVar.arraysize==null) {
errors.err("array has no defined size", assign.position)
@@ -344,7 +344,7 @@ internal class StatementReorderer(
}
val sourceIdent = assign.value as IdentifierReference
val sourceVar = sourceIdent.targetVarDecl(program)!!
val sourceVar = sourceIdent.targetVarDecl()!!
if(!sourceVar.isArray) {
errors.err("value must be an array", sourceIdent.position)
} else {

View File

@@ -251,7 +251,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
if(number!=null) {
addTypecastOrCastedValueModification(modifications, it.second, targetDt, call as Node)
} else if(identifier!=null && targetDt==BaseDataType.UWORD && argDt.isPassByRef) {
if(!identifier.isSubroutineParameter(program)) {
if(!identifier.isSubroutineParameter()) {
// We allow STR/ARRAY values for UWORD parameters.
// If it's an array (not STR), take the address.
if(!argDt.isString) {

View File

@@ -394,7 +394,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
val index = arrayIndexedExpression.indexer.constIndex()
if(index!=null && index<0) {
val target = arrayIndexedExpression.arrayvar.targetVarDecl(program)
val target = arrayIndexedExpression.arrayvar.targetVarDecl()
val arraysize = target?.arraysize?.constIndex()
if(arraysize!=null) {
if(arraysize+index < 0) {

View File

@@ -5,8 +5,8 @@ import prog8.ast.Program
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.IAstVisitor
import prog8.code.core.*
import prog8.code.INTERNED_STRINGS_MODULENAME
import prog8.code.core.*
internal class VerifyFunctionArgTypes(val program: Program, val options: CompilationOptions, val errors: IErrorReporter) : IAstVisitor {
@@ -31,7 +31,7 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila
}
override fun visit(identifier: IdentifierReference) {
if(identifier.wasStringLiteral(program)) {
if(identifier.wasStringLiteral()) {
allStringRefs.add(identifier.nameInSource)
}
}

View File

@@ -8,7 +8,6 @@ import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.instanceOf
import prog8.ast.IFunctionCall
import prog8.ast.IStatementContainer
import prog8.ast.Program
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.NumericLiteral
import prog8.ast.statements.Assignment
@@ -31,11 +30,11 @@ class TestCompilerOnCharLit: FunSpec({
val outputDir = tempdir().toPath()
fun findInitializer(vardecl: VarDecl, program: Program): Assignment? =
fun findInitializer(vardecl: VarDecl): Assignment? =
(vardecl.parent as IStatementContainer).statements
.asSequence()
.filterIsInstance<Assignment>()
.singleOrNull { it.origin== AssignmentOrigin.VARINIT && it.target.identifier?.targetVarDecl(program) === vardecl }
.singleOrNull { it.origin== AssignmentOrigin.VARINIT && it.target.identifier?.targetVarDecl() === vardecl }
test("testCharLitAsExtsubArg") {
@@ -79,14 +78,14 @@ class TestCompilerOnCharLit: FunSpec({
funCall.args[0] shouldBe instanceOf<IdentifierReference>()
val arg = funCall.args[0] as IdentifierReference
val decl = arg.targetVarDecl(program)!!
val decl = arg.targetVarDecl()!!
decl.type shouldBe VarDeclType.VAR
decl.datatype shouldBe DataType.UBYTE
withClue("initializer value should have been moved to separate assignment"){
decl.value shouldBe null
}
val assignInitialValue = findInitializer(decl, program)!!
val assignInitialValue = findInitializer(decl)!!
assignInitialValue.target.identifier!!.nameInSource shouldBe listOf("ch")
withClue("char literal should have been replaced by ubyte literal") {
assignInitialValue.value shouldBe instanceOf<NumericLiteral>()
@@ -115,7 +114,7 @@ class TestCompilerOnCharLit: FunSpec({
// Now, both is ok for the arg: a) still the IdRef or b) replaced by numeric literal
when (val arg = funCall.args[0]) {
is IdentifierReference -> {
val decl = arg.targetVarDecl(program)!!
val decl = arg.targetVarDecl()!!
decl.type shouldBe VarDeclType.CONST
decl.datatype shouldBe DataType.UBYTE
(decl.value as NumericLiteral).number shouldBe platform.encodeString("\n", Encoding.PETSCII)[0]

View File

@@ -34,7 +34,7 @@ class TestCompilerOnImportsAndIncludes: FunSpec({
val strLits = startSub.statements
.filterIsInstance<FunctionCallStatement>()
.map { it.args[0] as IdentifierReference }
.map { it.targetVarDecl(program)!!.value as StringLiteral }
.map { it.targetVarDecl()!!.value as StringLiteral }
strLits[0].value shouldBe "main.bar"
strLits[1].value shouldBe "foo.bar"
@@ -57,7 +57,7 @@ class TestCompilerOnImportsAndIncludes: FunSpec({
.filterIsInstance<FunctionCallStatement>()
.map { it.args[0] }
val str0 = (args[0] as IdentifierReference).targetVarDecl(program)!!.value as StringLiteral
val str0 = (args[0] as IdentifierReference).targetVarDecl()!!.value as StringLiteral
str0.value shouldBe "main.bar"
str0.definingScope.name shouldBe "main"

View File

@@ -62,12 +62,12 @@ class TestIdentifierRef: FunSpec({
val wwref = (stmts[0] as Assignment).target.identifier!!
val mainref = ((stmts[1] as Assignment).value as AddressOf).identifier
wwref.nameInSource shouldBe listOf("ww")
wwref.wasStringLiteral(program) shouldBe false
wwref.wasStringLiteral() shouldBe false
wwref.targetStatement(program) shouldBe instanceOf<VarDecl>()
wwref.targetVarDecl(program)!!.name shouldBe "ww"
wwref.targetVarDecl(program)!!.parent shouldBe instanceOf<Block>()
wwref.targetVarDecl()!!.name shouldBe "ww"
wwref.targetVarDecl()!!.parent shouldBe instanceOf<Block>()
mainref.nameInSource shouldBe listOf("main")
mainref.wasStringLiteral(program) shouldBe false
mainref.wasStringLiteral() shouldBe false
mainref.targetStatement(program) shouldBe instanceOf<Block>()
}
})

View File

@@ -225,8 +225,8 @@ main {
val rept2strcopy = stmts[4] as IFunctionCall
val name2 = name2strcopy.args.first() as IdentifierReference
val rept2 = rept2strcopy.args.first() as IdentifierReference
(name2.targetVarDecl(result.compilerAst)!!.value as StringLiteral).value shouldBe "xx1xx2"
(rept2.targetVarDecl(result.compilerAst)!!.value as StringLiteral).value shouldBe "xyzxyzxyzxyz"
(name2.targetVarDecl()!!.value as StringLiteral).value shouldBe "xx1xx2"
(rept2.targetVarDecl()!!.value as StringLiteral).value shouldBe "xyzxyzxyzxyz"
}
test("char as str param is error") {

View File

@@ -126,7 +126,7 @@ class Program(val name: String,
private class StringSearch(val program: Program): IAstVisitor {
val removals = mutableListOf<List<String>>()
override fun visit(identifier: IdentifierReference) {
if(identifier.wasStringLiteral(program))
if(identifier.wasStringLiteral())
removals.add(identifier.nameInSource)
}

View File

@@ -1164,14 +1164,14 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
override val isSimple = true
fun targetStatement(program: Program) =
if(nameInSource.singleOrNull() in program.builtinFunctions.names)
fun targetStatement(program: Program?) =
if(program!=null && nameInSource.singleOrNull() in program.builtinFunctions.names)
BuiltinFunctionPlaceholder(nameInSource[0], position, parent)
else
definingScope.lookup(nameInSource)
fun targetVarDecl(program: Program): VarDecl? = targetStatement(program) as? VarDecl
fun targetSubroutine(program: Program): Subroutine? = targetStatement(program) as? Subroutine
fun targetVarDecl(): VarDecl? = targetStatement(null) as? VarDecl
fun targetSubroutine(): Subroutine? = targetStatement(null) as? Subroutine
fun targetNameAndType(program: Program): Pair<String, DataType> {
val target = targetStatement(program) as? INamedStatement ?: throw FatalAstException("can't find target for $nameInSource")
@@ -1241,8 +1241,8 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
}
}
fun wasStringLiteral(program: Program): Boolean {
val decl = targetVarDecl(program)
fun wasStringLiteral(): Boolean {
val decl = targetVarDecl()
if(decl == null || decl.origin!=VarDeclOrigin.STRINGLITERAL)
return false

View File

@@ -647,7 +647,7 @@ data class AssignTarget(var identifier: IdentifierReference?,
return target.isIOAddress(addr.number.toUInt())
return when (memAddr.addressExpression) {
is IdentifierReference -> {
val decl = (memAddr.addressExpression as IdentifierReference).targetVarDecl(definingModule.program)
val decl = (memAddr.addressExpression as IdentifierReference).targetVarDecl()
val result = if ((decl?.type == VarDeclType.MEMORY || decl?.type == VarDeclType.CONST) && decl.value is NumericLiteral)
target.isIOAddress((decl.value as NumericLiteral).number.toUInt())
else
@@ -658,7 +658,7 @@ data class AssignTarget(var identifier: IdentifierReference?,
}
}
arrayIdx != null -> {
val targetStmt = arrayIdx.arrayvar.targetVarDecl(definingModule.program)
val targetStmt = arrayIdx.arrayvar.targetVarDecl()
return if (targetStmt?.type == VarDeclType.MEMORY) {
val addr = targetStmt.value as? NumericLiteral
if (addr != null)
@@ -668,7 +668,7 @@ data class AssignTarget(var identifier: IdentifierReference?,
} else false
}
ident != null -> {
val decl = ident.targetVarDecl(definingModule.program) ?: throw FatalAstException("invalid identifier ${ident.nameInSource}")
val decl = ident.targetVarDecl() ?: throw FatalAstException("invalid identifier ${ident.nameInSource}")
return if (decl.type == VarDeclType.MEMORY && decl.value is NumericLiteral)
target.isIOAddress((decl.value as NumericLiteral).number.toUInt())
else

View File

@@ -78,7 +78,7 @@ class CallGraph(private val program: Program) : IAstVisitor {
}
override fun visit(functionCallExpr: FunctionCallExpression) {
val otherSub = functionCallExpr.target.targetSubroutine(program)
val otherSub = functionCallExpr.target.targetSubroutine()
if (otherSub != null) {
val definingSub = functionCallExpr.definingSubroutine
if(definingSub!=null) {
@@ -90,7 +90,7 @@ class CallGraph(private val program: Program) : IAstVisitor {
}
override fun visit(functionCallStatement: FunctionCallStatement) {
val otherSub = functionCallStatement.target.targetSubroutine(program)
val otherSub = functionCallStatement.target.targetSubroutine()
if (otherSub != null) {
functionCallStatement.definingSubroutine?.let { thisSub ->
calls[thisSub] = calls.getValue(thisSub) + otherSub
@@ -101,12 +101,12 @@ class CallGraph(private val program: Program) : IAstVisitor {
}
override fun visit(addressOf: AddressOf) {
addressOf.identifier.targetSubroutine(program)?.let { notCalledButReferenced.add(it) }
addressOf.identifier.targetSubroutine()?.let { notCalledButReferenced.add(it) }
super.visit(addressOf)
}
override fun visit(jump: Jump) {
val otherSub = (jump.target as? IdentifierReference)?.targetSubroutine(program)
val otherSub = (jump.target as? IdentifierReference)?.targetSubroutine()
if (otherSub != null) {
jump.definingSubroutine?.let { thisSub ->
calls[thisSub] = calls.getValue(thisSub) + otherSub
@@ -225,8 +225,6 @@ class CallGraph(private val program: Program) : IAstVisitor {
}
}
inline fun unused(label: Label) = false // just always output labels
fun unused(stmt: INamedStatement): Boolean {
return when(stmt) {
is Subroutine -> unused(stmt)

View File

@@ -8,7 +8,6 @@ Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^
- STRUCTS: are now being developed in their own separate branch "structs". This will be for the next major version of the compiler (v12)
- targetStatement() method could only take IBuiltinFunctions rather than program, optionally even if you don't want/have to check the builtin functions
- is "checkAssignmentCompatible" redundant (gets called just 1 time!) when we also have "checkValueTypeAndRange" ?
- romable: should we have a way to explicitly set the memory address for the BSS area (instead of only the highram bank number on X16, allow a memory address too for the -varshigh option?)
- Kotlin: can we use inline value classes in certain spots?