mirror of
https://github.com/irmen/prog8.git
synced 2025-07-22 22:24:10 +00:00
removed some redundant arguments
This commit is contained in:
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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()) {
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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))
|
||||
|
@@ -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>()
|
||||
|
@@ -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") }
|
||||
|
@@ -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 {
|
||||
|
@@ -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) {
|
||||
|
@@ -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) {
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
@@ -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]
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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>()
|
||||
}
|
||||
})
|
||||
|
@@ -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") {
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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?
|
||||
|
Reference in New Issue
Block a user