more consistent naming of the statement classes

This commit is contained in:
Irmen de Jong 2021-12-28 13:56:47 +01:00
parent 6e11b8ada1
commit 7b54aa0c7d
30 changed files with 340 additions and 317 deletions

View File

@ -760,7 +760,7 @@ class AsmGen(private val program: Program,
outputSourceLine(stmt)
when(stmt) {
is VarDecl -> translate(stmt)
is NopStatement -> {}
is Nop -> {}
is Directive -> translate(stmt)
is Return -> translate(stmt)
is Subroutine -> translateSubroutine(stmt)
@ -779,13 +779,13 @@ class AsmGen(private val program: Program,
is GoSub -> translate(stmt)
is PostIncrDecr -> postincrdecrAsmGen.translate(stmt)
is Label -> translate(stmt)
is BranchStatement -> translate(stmt)
is IfStatement -> translate(stmt)
is Branch -> translate(stmt)
is IfElse -> translate(stmt)
is ForLoop -> forloopsAsmGen.translate(stmt)
is RepeatLoop -> translate(stmt)
is WhenStatement -> translate(stmt)
is When -> translate(stmt)
is AnonymousScope -> translate(stmt)
is BuiltinFunctionStatementPlaceholder -> throw AssemblyError("builtin function should not have placeholder anymore")
is BuiltinFunctionPlaceholder -> throw AssemblyError("builtin function should not have placeholder anymore")
is UntilLoop -> throw AssemblyError("do..until should have been desugared to jumps")
is WhileLoop -> throw AssemblyError("while should have been desugared to jumps")
is Block -> throw AssemblyError("block should have been handled elsewhere")
@ -890,11 +890,11 @@ class AsmGen(private val program: Program,
internal fun translateExpression(expression: Expression) =
expressionsAsmGen.translateExpression(expression)
internal fun translateBuiltinFunctionCallExpression(functionCall: FunctionCall, signature: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?) =
builtinFunctionsAsmGen.translateFunctioncallExpression(functionCall, signature, resultToStack, resultRegister)
internal fun translateBuiltinFunctionCallExpression(functionCallExpr: FunctionCallExpr, signature: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?) =
builtinFunctionsAsmGen.translateFunctioncallExpression(functionCallExpr, signature, resultToStack, resultRegister)
internal fun translateFunctionCall(functionCall: FunctionCall, isExpression: Boolean) =
functioncallAsmGen.translateFunctionCall(functionCall, isExpression)
internal fun translateFunctionCall(functionCallExpr: FunctionCallExpr, isExpression: Boolean) =
functioncallAsmGen.translateFunctionCall(functionCallExpr, isExpression)
internal fun saveXbeforeCall(functionCall: IFunctionCall) =
functioncallAsmGen.saveXbeforeCall(functionCall)
@ -1094,7 +1094,7 @@ class AsmGen(private val program: Program,
}
}
private fun translate(stmt: IfStatement) {
private fun translate(stmt: IfElse) {
requireComparisonExpression(stmt.condition) // IfStatement: condition must be of form 'x <comparison> <value>'
val booleanCondition = stmt.condition as BinaryExpression
@ -1274,7 +1274,7 @@ $repeatLabel lda $counterVar
return counterVar
}
private fun translate(stmt: WhenStatement) {
private fun translate(stmt: When) {
val endLabel = makeLabel("choice_end")
val choiceBlocks = mutableListOf<Pair<String, AnonymousScope>>()
val conditionDt = stmt.condition.inferType(program)
@ -1328,7 +1328,7 @@ $repeatLabel lda $counterVar
scope.statements.forEach{ translate(it) }
}
private fun translate(stmt: BranchStatement) {
private fun translate(stmt: Branch) {
if(stmt.truepart.isEmpty() && stmt.elsepart.isNotEmpty())
throw AssemblyError("only else part contains code, shoud have been switched already")
@ -1674,7 +1674,7 @@ $label nop""")
}
if(dt==DataType.UBYTE) {
assignExpressionToRegister(left, RegisterOrPair.A, false)
if (left is FunctionCall && !left.isSimple)
if (left is FunctionCallExpr && !left.isSimple)
out(" cmp #0")
} else {
assignExpressionToRegister(left, RegisterOrPair.AY, false)
@ -1690,7 +1690,7 @@ $label nop""")
}
DataType.BYTE -> {
assignExpressionToRegister(left, RegisterOrPair.A, true)
if (left is FunctionCall && !left.isSimple)
if (left is FunctionCallExpr && !left.isSimple)
out(" cmp #0")
when (operator) {
"==" -> out(" bne $jumpIfFalseLabel")

View File

@ -44,7 +44,7 @@ internal fun asmsub6502ArgsHaveRegisterClobberRisk(args: List<Expression>,
it.registerOrPair in listOf(RegisterOrPair.Y, RegisterOrPair.AY, RegisterOrPair.XY)
}
}
is FunctionCall -> {
is FunctionCallExpr -> {
if (expr.target.nameInSource == listOf("lsb") || expr.target.nameInSource == listOf("msb"))
return isClobberRisk(expr.args[0])
if (expr.target.nameInSource == listOf("mkword"))

View File

@ -19,7 +19,7 @@ import prog8.compilerinterface.subroutineFloatEvalResultVar2
internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val assignAsmGen: AssignmentAsmGen) {
internal fun translateFunctioncallExpression(fcall: FunctionCall, func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?) {
internal fun translateFunctioncallExpression(fcall: FunctionCallExpr, func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?) {
translateFunctioncall(fcall, func, discardResult = false, resultToStack = resultToStack, resultRegister = resultRegister)
}
@ -414,7 +414,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
}
private fun funcMemory(fcall: IFunctionCall, discardResult: Boolean, resultToStack: Boolean, resultRegister: RegisterOrPair?) {
if(discardResult || fcall !is FunctionCall)
if(discardResult || fcall !is FunctionCallExpr)
throw AssemblyError("should not discard result of memory allocation at $fcall")
val nameRef = fcall.args[0] as IdentifierReference
val name = (nameRef.targetVarDecl(program)!!.value as StringLiteralValue).value

View File

@ -3,7 +3,7 @@ package prog8.compiler.target.cpu6502.codegen
import prog8.ast.Program
import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.statements.BuiltinFunctionStatementPlaceholder
import prog8.ast.statements.BuiltinFunctionPlaceholder
import prog8.ast.statements.Subroutine
import prog8.ast.toHex
import prog8.compiler.target.AssemblyError
@ -36,18 +36,18 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
is DirectMemoryRead -> asmgen.translateDirectMemReadExpressionToRegAorStack(expression, true)
is NumericLiteralValue -> translateExpression(expression)
is IdentifierReference -> translateExpression(expression)
is FunctionCall -> translateFunctionCallResultOntoStack(expression)
is FunctionCallExpr -> translateFunctionCallResultOntoStack(expression)
is ArrayLiteralValue, is StringLiteralValue -> throw AssemblyError("no asm gen for string/array literal value assignment - should have been replaced by a variable")
is RangeExpr -> throw AssemblyError("range expression should have been changed into array values")
is CharLiteral -> throw AssemblyError("charliteral should have been replaced by ubyte using certain encoding")
}
}
private fun translateFunctionCallResultOntoStack(call: FunctionCall) {
private fun translateFunctionCallResultOntoStack(call: FunctionCallExpr) {
// only for use in nested expression evaluation
val sub = call.target.targetStatement(program)
if(sub is BuiltinFunctionStatementPlaceholder) {
if(sub is BuiltinFunctionPlaceholder) {
val builtinFunc = BuiltinFunctions.getValue(sub.name)
asmgen.translateBuiltinFunctionCallExpression(call, builtinFunc, true, null)
} else {

View File

@ -167,7 +167,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
val dt = value.inferType(program).getOrElse { throw AssemblyError("unknown dt") }
AsmAssignSource(SourceStorageKind.ARRAY, program, asmgen, dt, array = value)
}
is FunctionCall -> {
is FunctionCallExpr -> {
when (val sub = value.target.targetStatement(program)) {
is Subroutine -> {
val returnType = sub.returntypes.zip(sub.asmReturnvaluesRegisters).firstOrNull { rr -> rr.second.registerOrPair != null || rr.second.statusflag!=null }?.first
@ -175,7 +175,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, returnType, expression = value)
}
is BuiltinFunctionStatementPlaceholder -> {
is BuiltinFunctionPlaceholder -> {
val returnType = value.inferType(program)
AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, returnType.getOrElse { throw AssemblyError("unknown dt") }, expression = value)
}

View File

@ -159,7 +159,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
is ArrayIndexedExpression -> throw AssemblyError("source kind should have been array")
is DirectMemoryRead -> throw AssemblyError("source kind should have been memory")
is TypecastExpression -> assignTypeCastedValue(assign.target, value.type, value.expression, value)
is FunctionCall -> {
is FunctionCallExpr -> {
when (val sub = value.target.targetStatement(program)) {
is Subroutine -> {
asmgen.saveXbeforeCall(value)
@ -215,7 +215,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
}
}
is BuiltinFunctionStatementPlaceholder -> {
is BuiltinFunctionPlaceholder -> {
val signature = BuiltinFunctions.getValue(sub.name)
asmgen.translateBuiltinFunctionCallExpression(value, signature, false, assign.target.register)
if(assign.target.register==null) {
@ -474,7 +474,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
private fun assignCastViaLsbFunc(value: Expression, target: AsmAssignTarget) {
val lsb = FunctionCall(IdentifierReference(listOf("lsb"), value.position), mutableListOf(value), value.position)
val lsb = FunctionCallExpr(IdentifierReference(listOf("lsb"), value.position), mutableListOf(value), value.position)
lsb.linkParents(value.parent)
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = lsb)
val assign = AsmAssignment(src, target, false, program.memsizer, value.position)

View File

@ -303,11 +303,11 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
return noModifications
}
override fun after(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
override fun after(functionCallExpr: FunctionCallExpr, parent: Node): Iterable<IAstModification> {
// the args of a fuction are constfolded via recursion already.
val constvalue = functionCall.constValue(program)
val constvalue = functionCallExpr.constValue(program)
return if(constvalue!=null)
listOf(IAstModification.ReplaceNode(functionCall, constvalue, parent))
listOf(IAstModification.ReplaceNode(functionCallExpr, constvalue, parent))
else
noModifications
}

View File

@ -10,7 +10,7 @@ import prog8.ast.base.NumericDatatypes
import prog8.ast.expressions.*
import prog8.ast.statements.AnonymousScope
import prog8.ast.statements.Assignment
import prog8.ast.statements.IfStatement
import prog8.ast.statements.IfElse
import prog8.ast.statements.Jump
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
@ -58,24 +58,24 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
return mods
}
override fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
val truepart = ifStatement.truepart
val elsepart = ifStatement.elsepart
override fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> {
val truepart = ifElse.truepart
val elsepart = ifElse.elsepart
if(truepart.isNotEmpty() && elsepart.isNotEmpty()) {
if(truepart.statements.singleOrNull() is Jump) {
return listOf(
IAstModification.InsertAfter(ifStatement, elsepart, parent as IStatementContainer),
IAstModification.ReplaceNode(elsepart, AnonymousScope(mutableListOf(), elsepart.position), ifStatement)
IAstModification.InsertAfter(ifElse, elsepart, parent as IStatementContainer),
IAstModification.ReplaceNode(elsepart, AnonymousScope(mutableListOf(), elsepart.position), ifElse)
)
}
if(elsepart.statements.singleOrNull() is Jump) {
val invertedCondition = invertCondition(ifStatement.condition)
val invertedCondition = invertCondition(ifElse.condition)
if(invertedCondition!=null) {
return listOf(
IAstModification.ReplaceNode(ifStatement.condition, invertedCondition, ifStatement),
IAstModification.InsertAfter(ifStatement, truepart, parent as IStatementContainer),
IAstModification.ReplaceNode(elsepart, AnonymousScope(mutableListOf(), elsepart.position), ifStatement),
IAstModification.ReplaceNode(truepart, elsepart, ifStatement)
IAstModification.ReplaceNode(ifElse.condition, invertedCondition, ifElse),
IAstModification.InsertAfter(ifElse, truepart, parent as IStatementContainer),
IAstModification.ReplaceNode(elsepart, AnonymousScope(mutableListOf(), elsepart.position), ifElse),
IAstModification.ReplaceNode(truepart, elsepart, ifElse)
)
}
}
@ -211,7 +211,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
// signedw < 0 --> msb(signedw) & $80
return listOf(IAstModification.ReplaceNode(
expr,
BinaryExpression(FunctionCall(IdentifierReference(listOf("msb"), expr.position),
BinaryExpression(FunctionCallExpr(IdentifierReference(listOf("msb"), expr.position),
mutableListOf(expr.left),
expr.position
), "&", NumericLiteralValue.optimalInteger(0x80, expr.position), expr.position),
@ -301,31 +301,31 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
return noModifications
}
override fun after(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
if(functionCall.target.nameInSource == listOf("lsb")) {
val arg = functionCall.args[0]
override fun after(functionCallExpr: FunctionCallExpr, parent: Node): Iterable<IAstModification> {
if(functionCallExpr.target.nameInSource == listOf("lsb")) {
val arg = functionCallExpr.args[0]
if(arg is TypecastExpression) {
val valueDt = arg.expression.inferType(program)
if (valueDt istype DataType.BYTE || valueDt istype DataType.UBYTE) {
// useless lsb() of byte value that was typecasted to word
return listOf(IAstModification.ReplaceNode(functionCall, arg.expression, parent))
return listOf(IAstModification.ReplaceNode(functionCallExpr, arg.expression, parent))
}
} else {
val argDt = arg.inferType(program)
if (argDt istype DataType.BYTE || argDt istype DataType.UBYTE) {
// useless lsb() of byte value
return listOf(IAstModification.ReplaceNode(functionCall, arg, parent))
return listOf(IAstModification.ReplaceNode(functionCallExpr, arg, parent))
}
}
}
else if(functionCall.target.nameInSource == listOf("msb")) {
val arg = functionCall.args[0]
else if(functionCallExpr.target.nameInSource == listOf("msb")) {
val arg = functionCallExpr.args[0]
if(arg is TypecastExpression) {
val valueDt = arg.expression.inferType(program)
if (valueDt istype DataType.BYTE || valueDt istype DataType.UBYTE) {
// useless msb() of byte value that was typecasted to word, replace with 0
return listOf(IAstModification.ReplaceNode(
functionCall,
functionCallExpr,
NumericLiteralValue(valueDt.getOr(DataType.UBYTE), 0.0, arg.expression.position),
parent))
}
@ -334,7 +334,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
if (argDt istype DataType.BYTE || argDt istype DataType.UBYTE) {
// useless msb() of byte value, replace with 0
return listOf(IAstModification.ReplaceNode(
functionCall,
functionCallExpr,
NumericLiteralValue(argDt.getOr(DataType.UBYTE), 0.0, arg.position),
parent))
}
@ -455,7 +455,7 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
}
0.5 -> {
// sqrt(left)
return FunctionCall(IdentifierReference(listOf("sqrt"), expr.position), mutableListOf(expr.left), expr.position)
return FunctionCallExpr(IdentifierReference(listOf("sqrt"), expr.position), mutableListOf(expr.left), expr.position)
}
1.0 -> {
// left
@ -648,12 +648,12 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
if (amount >= 16) {
return NumericLiteralValue(targetDt, 0.0, expr.position)
} else if (amount >= 8) {
val lsb = FunctionCall(IdentifierReference(listOf("lsb"), expr.position), mutableListOf(expr.left), expr.position)
val lsb = FunctionCallExpr(IdentifierReference(listOf("lsb"), expr.position), mutableListOf(expr.left), expr.position)
if (amount == 8) {
return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(lsb, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position)
return FunctionCallExpr(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(lsb, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position)
}
val shifted = BinaryExpression(lsb, "<<", NumericLiteralValue.optimalInteger(amount - 8, expr.position), expr.position)
return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(shifted, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position)
return FunctionCallExpr(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(shifted, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position)
}
}
else -> {
@ -690,11 +690,11 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
return NumericLiteralValue.optimalInteger(0, expr.position)
}
else if (amount >= 8) {
val msb = FunctionCall(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position)
val msb = FunctionCallExpr(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position)
if (amount == 8) {
// mkword(0, msb(v))
val zero = NumericLiteralValue(DataType.UBYTE, 0.0, expr.position)
return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(zero, msb), expr.position)
return FunctionCallExpr(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(zero, msb), expr.position)
}
return TypecastExpression(BinaryExpression(msb, ">>", NumericLiteralValue.optimalInteger(amount - 8, expr.position), expr.position), DataType.UWORD, true, expr.position)
}

View File

@ -18,7 +18,7 @@ class StatementOptimizer(private val program: Program,
private val compTarget: ICompilationTarget
) : AstWalker() {
override fun before(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
override fun before(functionCallExpr: FunctionCallExpr, parent: Node): Iterable<IAstModification> {
// 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.
@ -27,7 +27,7 @@ class StatementOptimizer(private val program: Program,
return IdentifierReference(target.scopedName, variable.position)
}
val subroutine = functionCall.target.targetSubroutine(program)
val subroutine = functionCallExpr.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) {
@ -47,7 +47,7 @@ class StatementOptimizer(private val program: Program,
is StringLiteralValue -> orig.copy()
else -> return noModifications
}
return listOf(IAstModification.ReplaceNode(functionCall, copy, parent))
return listOf(IAstModification.ReplaceNode(functionCallExpr, copy, parent))
}
}
return noModifications
@ -56,7 +56,7 @@ class StatementOptimizer(private val program: Program,
override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
if(functionCallStatement.target.targetStatement(program) is BuiltinFunctionStatementPlaceholder) {
if(functionCallStatement.target.targetStatement(program) is BuiltinFunctionPlaceholder) {
val functionName = functionCallStatement.target.nameInSource[0]
if (functionName in functions.purefunctionNames) {
errors.warn("statement has no effect (function return value is discarded)", functionCallStatement.position)
@ -133,33 +133,33 @@ class StatementOptimizer(private val program: Program,
return noModifications
}
override fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
override fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> {
// remove empty if statements
if(ifStatement.truepart.isEmpty() && ifStatement.elsepart.isEmpty())
return listOf(IAstModification.Remove(ifStatement, parent as IStatementContainer))
if(ifElse.truepart.isEmpty() && ifElse.elsepart.isEmpty())
return listOf(IAstModification.Remove(ifElse, parent as IStatementContainer))
// empty true part? switch with the else part
if(ifStatement.truepart.isEmpty() && ifStatement.elsepart.isNotEmpty()) {
val invertedCondition = PrefixExpression("not", ifStatement.condition, ifStatement.condition.position)
val emptyscope = AnonymousScope(mutableListOf(), ifStatement.elsepart.position)
val truepart = AnonymousScope(ifStatement.elsepart.statements, ifStatement.truepart.position)
if(ifElse.truepart.isEmpty() && ifElse.elsepart.isNotEmpty()) {
val invertedCondition = PrefixExpression("not", ifElse.condition, ifElse.condition.position)
val emptyscope = AnonymousScope(mutableListOf(), ifElse.elsepart.position)
val truepart = AnonymousScope(ifElse.elsepart.statements, ifElse.truepart.position)
return listOf(
IAstModification.ReplaceNode(ifStatement.condition, invertedCondition, ifStatement),
IAstModification.ReplaceNode(ifStatement.truepart, truepart, ifStatement),
IAstModification.ReplaceNode(ifStatement.elsepart, emptyscope, ifStatement)
IAstModification.ReplaceNode(ifElse.condition, invertedCondition, ifElse),
IAstModification.ReplaceNode(ifElse.truepart, truepart, ifElse),
IAstModification.ReplaceNode(ifElse.elsepart, emptyscope, ifElse)
)
}
val constvalue = ifStatement.condition.constValue(program)
val constvalue = ifElse.condition.constValue(program)
if(constvalue!=null) {
return if(constvalue.asBooleanValue){
// always true -> keep only if-part
errors.warn("condition is always true", ifStatement.position)
listOf(IAstModification.ReplaceNode(ifStatement, ifStatement.truepart, parent))
errors.warn("condition is always true", ifElse.position)
listOf(IAstModification.ReplaceNode(ifElse, ifElse.truepart, parent))
} else {
// always false -> keep only else-part
errors.warn("condition is always false", ifStatement.position)
listOf(IAstModification.ReplaceNode(ifStatement, ifStatement.elsepart, parent))
errors.warn("condition is always false", ifElse.position)
listOf(IAstModification.ReplaceNode(ifElse, ifElse.elsepart, parent))
}
}

View File

@ -234,7 +234,7 @@ class UnusedCodeRemover(private val program: Program,
is PrefixExpression,
is BinaryExpression,
is TypecastExpression,
is FunctionCall -> { /* don't remove */ }
is FunctionCallExpr -> { /* don't remove */ }
else -> linesToRemove.add(assign1)
}
}

View File

@ -193,19 +193,19 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
return noModifications
}
override fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
val prefixExpr = ifStatement.condition as? PrefixExpression
override fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> {
val prefixExpr = ifElse.condition as? PrefixExpression
if(prefixExpr!=null && prefixExpr.operator=="not") {
// if not x -> if x==0
val booleanExpr = BinaryExpression(prefixExpr.expression, "==", NumericLiteralValue.optimalInteger(0, ifStatement.condition.position), ifStatement.condition.position)
return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement))
val booleanExpr = BinaryExpression(prefixExpr.expression, "==", NumericLiteralValue.optimalInteger(0, ifElse.condition.position), ifElse.condition.position)
return listOf(IAstModification.ReplaceNode(ifElse.condition, booleanExpr, ifElse))
}
val binExpr = ifStatement.condition as? BinaryExpression
val binExpr = ifElse.condition as? BinaryExpression
if(binExpr==null || binExpr.operator !in ComparisonOperators) {
// if x -> if x!=0, if x+5 -> if x+5 != 0
val booleanExpr = BinaryExpression(ifStatement.condition, "!=", NumericLiteralValue.optimalInteger(0, ifStatement.condition.position), ifStatement.condition.position)
return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement))
val booleanExpr = BinaryExpression(ifElse.condition, "!=", NumericLiteralValue.optimalInteger(0, ifElse.condition.position), ifElse.condition.position)
return listOf(IAstModification.ReplaceNode(ifElse.condition, booleanExpr, ifElse))
}
if((binExpr.left as? NumericLiteralValue)?.number==0.0 &&
@ -219,11 +219,11 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
val modifications = mutableListOf<IAstModification>()
if(simplify.rightVarAssignment!=null) {
modifications += IAstModification.ReplaceNode(binExpr.right, simplify.rightOperandReplacement!!, binExpr)
modifications += IAstModification.InsertBefore(ifStatement, simplify.rightVarAssignment, parent as IStatementContainer)
modifications += IAstModification.InsertBefore(ifElse, simplify.rightVarAssignment, parent as IStatementContainer)
}
if(simplify.leftVarAssignment!=null) {
modifications += IAstModification.ReplaceNode(binExpr.left, simplify.leftOperandReplacement!!, binExpr)
modifications += IAstModification.InsertBefore(ifStatement, simplify.leftVarAssignment, parent as IStatementContainer)
modifications += IAstModification.InsertBefore(ifElse, simplify.leftVarAssignment, parent as IStatementContainer)
}
return modifications
@ -341,12 +341,12 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
complexArrayIndexedExpressions.add(arrayIndexedExpression)
}
override fun visit(branchStatement: BranchStatement) {}
override fun visit(branch: Branch) {}
override fun visit(forLoop: ForLoop) {}
override fun visit(ifStatement: IfStatement) {
ifStatement.condition.accept(this)
override fun visit(ifElse: IfElse) {
ifElse.condition.accept(this)
}
override fun visit(untilLoop: UntilLoop) {

View File

@ -80,10 +80,10 @@ internal class AstChecker(private val program: Program,
super.visit(returnStmt)
}
override fun visit(ifStatement: IfStatement) {
if(!ifStatement.condition.inferType(program).isInteger)
errors.err("condition value should be an integer type", ifStatement.condition.position)
super.visit(ifStatement)
override fun visit(ifElse: IfElse) {
if(!ifElse.condition.inferType(program).isInteger)
errors.err("condition value should be an integer type", ifElse.condition.position)
super.visit(ifElse)
}
override fun visit(forLoop: ForLoop) {
@ -165,7 +165,7 @@ internal class AstChecker(private val program: Program,
if(ident!=null) {
val targetStatement = checkFunctionOrLabelExists(ident, jump)
if(targetStatement!=null) {
if(targetStatement is BuiltinFunctionStatementPlaceholder)
if(targetStatement is BuiltinFunctionPlaceholder)
errors.err("can't jump to a builtin function", jump.position)
}
if(targetStatement is Subroutine && targetStatement.parameters.any()) {
@ -184,7 +184,7 @@ internal class AstChecker(private val program: Program,
if(ident!=null) {
val targetStatement = checkFunctionOrLabelExists(ident, gosub)
if(targetStatement!=null) {
if(targetStatement is BuiltinFunctionStatementPlaceholder)
if(targetStatement is BuiltinFunctionPlaceholder)
errors.err("can't gosub to a builtin function", gosub.position)
}
}
@ -209,7 +209,7 @@ internal class AstChecker(private val program: Program,
is VarDecl,
is InlineAssembly,
is IStatementContainer,
is NopStatement -> true
is Nop -> true
is Assignment -> {
val target = statement.target.identifier!!.targetStatement(program)
target === statement.previousSibling() // an initializer assignment is okay
@ -503,7 +503,7 @@ internal class AstChecker(private val program: Program,
} else {
val sourceDatatype = assignment.value.inferType(program)
if (sourceDatatype.isUnknown) {
if (assignment.value !is FunctionCall)
if (assignment.value !is FunctionCallExpr)
errors.err("assignment value is invalid or has no proper datatype", assignment.value.position)
} else {
checkAssignmentCompatible(targetDatatype.getOr(DataType.BYTE),
@ -935,28 +935,28 @@ internal class AstChecker(private val program: Program,
}
}
override fun visit(functionCall: FunctionCall) {
override fun visit(functionCallExpr: FunctionCallExpr) {
// this function call is (part of) an expression, which should be in a statement somewhere.
val stmtOfExpression = findParentNode<Statement>(functionCall)
?: throw FatalAstException("cannot determine statement scope of function call expression at ${functionCall.position}")
val stmtOfExpression = findParentNode<Statement>(functionCallExpr)
?: throw FatalAstException("cannot determine statement scope of function call expression at ${functionCallExpr.position}")
val targetStatement = checkFunctionOrLabelExists(functionCall.target, stmtOfExpression)
val targetStatement = checkFunctionOrLabelExists(functionCallExpr.target, stmtOfExpression)
if(targetStatement!=null)
checkFunctionCall(targetStatement, functionCall.args, functionCall.position)
checkFunctionCall(targetStatement, functionCallExpr.args, functionCallExpr.position)
// warn about sgn(unsigned) this is likely a mistake
if(functionCall.target.nameInSource.last()=="sgn") {
val sgnArgType = functionCall.args.first().inferType(program)
if(functionCallExpr.target.nameInSource.last()=="sgn") {
val sgnArgType = functionCallExpr.args.first().inferType(program)
if(sgnArgType istype DataType.UBYTE || sgnArgType istype DataType.UWORD)
errors.warn("sgn() of unsigned type is always 0 or 1, this is perhaps not what was intended", functionCall.args.first().position)
errors.warn("sgn() of unsigned type is always 0 or 1, this is perhaps not what was intended", functionCallExpr.args.first().position)
}
val error = VerifyFunctionArgTypes.checkTypes(functionCall, program)
val error = VerifyFunctionArgTypes.checkTypes(functionCallExpr, program)
if(error!=null)
errors.err(error, functionCall.position)
errors.err(error, functionCallExpr.position)
// check the functions that return multiple returnvalues.
val stmt = functionCall.target.targetStatement(program)
val stmt = functionCallExpr.target.targetStatement(program)
if (stmt is Subroutine) {
if (stmt.returntypes.size > 1) {
// Currently, it's only possible to handle ONE (or zero) return values from a subroutine.
@ -969,7 +969,7 @@ internal class AstChecker(private val program: Program,
// dealing with the status bit as just being that, the status bit after the call.
val (returnRegisters, _) = stmt.asmReturnvaluesRegisters.partition { rr -> rr.registerOrPair != null }
if (returnRegisters.size>1) {
errors.err("It's not possible to store the multiple result values of this asmsub call; you should use a small block of custom inline assembly for this.", functionCall.position)
errors.err("It's not possible to store the multiple result values of this asmsub call; you should use a small block of custom inline assembly for this.", functionCallExpr.position)
}
}
}
@ -977,18 +977,18 @@ internal class AstChecker(private val program: Program,
// functions that don't return a value, can't be used in an expression or assignment
if(targetStatement is Subroutine) {
if(targetStatement.returntypes.isEmpty()) {
if(functionCall.parent is Expression || functionCall.parent is Assignment)
errors.err("subroutine doesn't return a value", functionCall.position)
if(functionCallExpr.parent is Expression || functionCallExpr.parent is Assignment)
errors.err("subroutine doesn't return a value", functionCallExpr.position)
}
}
else if(targetStatement is BuiltinFunctionStatementPlaceholder) {
if(builtinFunctionReturnType(targetStatement.name, functionCall.args, program).isUnknown) {
if(functionCall.parent is Expression || functionCall.parent is Assignment)
errors.err("function doesn't return a value", functionCall.position)
else if(targetStatement is BuiltinFunctionPlaceholder) {
if(builtinFunctionReturnType(targetStatement.name, functionCallExpr.args, program).isUnknown) {
if(functionCallExpr.parent is Expression || functionCallExpr.parent is Assignment)
errors.err("function doesn't return a value", functionCallExpr.position)
}
}
super.visit(functionCall)
super.visit(functionCallExpr)
}
override fun visit(functionCallStatement: FunctionCallStatement) {
@ -1044,7 +1044,7 @@ internal class AstChecker(private val program: Program,
if(target is Label && args.isNotEmpty())
errors.err("cannot use arguments when calling a label", position)
if(target is BuiltinFunctionStatementPlaceholder) {
if(target is BuiltinFunctionPlaceholder) {
if(target.name=="swap") {
// swap() is a bit weird because this one is translated into an operations directly, instead of being a function call
val dt1 = args[0].inferType(program)
@ -1080,8 +1080,8 @@ internal class AstChecker(private val program: Program,
var ident: IdentifierReference? = null
if(arg.value is IdentifierReference)
ident = arg.value as IdentifierReference
else if(arg.value is FunctionCall) {
val fcall = arg.value as FunctionCall
else if(arg.value is FunctionCallExpr) {
val fcall = arg.value as FunctionCallExpr
if(fcall.target.nameInSource == listOf("lsb") || fcall.target.nameInSource == listOf("msb"))
ident = fcall.args[0] as? IdentifierReference
}
@ -1164,11 +1164,11 @@ internal class AstChecker(private val program: Program,
super.visit(arrayIndexedExpression)
}
override fun visit(whenStatement: WhenStatement) {
if(!whenStatement.condition.inferType(program).isInteger)
errors.err("when condition must be an integer value", whenStatement.position)
override fun visit(whenStmt: When) {
if(!whenStmt.condition.inferType(program).isInteger)
errors.err("when condition must be an integer value", whenStmt.position)
val tally = mutableSetOf<Int>()
for((choices, choiceNode) in whenStatement.choiceValues(program)) {
for((choices, choiceNode) in whenStmt.choiceValues(program)) {
if(choices!=null) {
for (c in choices) {
if(c in tally)
@ -1179,14 +1179,14 @@ internal class AstChecker(private val program: Program,
}
}
if(whenStatement.choices.isEmpty())
errors.err("empty when statement", whenStatement.position)
if(whenStmt.choices.isEmpty())
errors.err("empty when statement", whenStmt.position)
super.visit(whenStatement)
super.visit(whenStmt)
}
override fun visit(whenChoice: WhenChoice) {
val whenStmt = whenChoice.parent as WhenStatement
val whenStmt = whenChoice.parent as When
if(whenChoice.values!=null) {
val conditionType = whenStmt.condition.inferType(program)
if(!conditionType.isKnown)
@ -1208,7 +1208,7 @@ internal class AstChecker(private val program: Program,
private fun checkFunctionOrLabelExists(target: IdentifierReference, statement: Statement): Statement? {
when (val targetStatement = target.targetStatement(program)) {
is Label, is Subroutine, is BuiltinFunctionStatementPlaceholder -> return targetStatement
is Label, is Subroutine, is BuiltinFunctionPlaceholder -> return targetStatement
null -> errors.err("undefined function or subroutine: ${target.nameInSource.joinToString(".")}", statement.position)
else -> errors.err("cannot call that: ${target.nameInSource.joinToString(".")}", statement.position)
}
@ -1432,7 +1432,7 @@ internal fun checkUnusedReturnValues(call: FunctionCallStatement, target: Statem
errors.warn("result value of subroutine call is discarded (use void?)", call.position)
else
errors.warn("result values of subroutine call are discarded (use void?)", call.position)
} else if (target is BuiltinFunctionStatementPlaceholder) {
} else if (target is BuiltinFunctionPlaceholder) {
val rt = builtinFunctionReturnType(target.name, call.args, program)
if (rt.isKnown)
errors.warn("result value of a function call is discarded (use void?)", call.position)

View File

@ -3,9 +3,8 @@ package prog8.compiler.astprocessing
import prog8.ast.IFunctionCall
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.FatalAstException
import prog8.ast.base.Position
import prog8.ast.expressions.FunctionCall
import prog8.ast.expressions.FunctionCallExpr
import prog8.ast.expressions.StringLiteralValue
import prog8.ast.statements.*
import prog8.ast.walk.IAstVisitor
@ -129,7 +128,7 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter,
super.visit(string)
}
override fun visit(functionCall: FunctionCall) = visitFunctionCall(functionCall)
override fun visit(functionCallExpr: FunctionCallExpr) = visitFunctionCall(functionCallExpr)
override fun visit(functionCallStatement: FunctionCallStatement) = visitFunctionCall(functionCallStatement)
private fun visitFunctionCall(call: IFunctionCall) {
@ -140,7 +139,7 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter,
errors.err("invalid number of arguments", pos)
}
}
is BuiltinFunctionStatementPlaceholder -> {
is BuiltinFunctionPlaceholder -> {
val func = BuiltinFunctions.getValue(target.name)
if(call.args.size != func.parameters.size) {
val pos = (if(call.args.any()) call.args[0] else (call as Node)).position

View File

@ -7,7 +7,7 @@ import prog8.ast.Program
import prog8.ast.base.ParentSentinel
import prog8.ast.base.Position
import prog8.ast.expressions.DirectMemoryRead
import prog8.ast.expressions.FunctionCall
import prog8.ast.expressions.FunctionCallExpr
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.PrefixExpression
import prog8.ast.statements.*
@ -80,7 +80,7 @@ if not CONDITION
val replacement = AnonymousScope(mutableListOf(
loopLabel,
untilLoop.body,
IfStatement(notCondition,
IfElse(notCondition,
AnonymousScope(mutableListOf(jumpLabel(loopLabel)), pos),
AnonymousScope(mutableListOf(), pos),
pos)
@ -104,7 +104,7 @@ _after:
val notCondition = PrefixExpression("not", whileLoop.condition, pos)
val replacement = AnonymousScope(mutableListOf(
loopLabel,
IfStatement(notCondition,
IfElse(notCondition,
AnonymousScope(mutableListOf(jumpLabel(afterLabel)), pos),
AnonymousScope(mutableListOf(), pos),
pos),
@ -118,8 +118,8 @@ _after:
override fun before(functionCallStatement: FunctionCallStatement, parent: Node) =
before(functionCallStatement as IFunctionCall, parent, functionCallStatement.position)
override fun before(functionCall: FunctionCall, parent: Node) =
before(functionCall as IFunctionCall, parent, functionCall.position)
override fun before(functionCallExpr: FunctionCallExpr, parent: Node) =
before(functionCallExpr as IFunctionCall, parent, functionCallExpr.position)
private fun before(functionCall: IFunctionCall, parent: Node, position: Position): Iterable<IAstModification> {
if(functionCall.target.nameInSource==listOf("peek")) {

View File

@ -47,9 +47,9 @@ internal class ParentNodeChecker: AstWalker() {
return noModifications
}
override fun before(branchStatement: BranchStatement, parent: Node): Iterable<IAstModification> {
if(branchStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $branchStatement")
override fun before(branch: Branch, parent: Node): Iterable<IAstModification> {
if(branch.parent!==parent)
throw FatalAstException("parent node mismatch at $branch")
return noModifications
}
@ -101,9 +101,9 @@ internal class ParentNodeChecker: AstWalker() {
return noModifications
}
override fun before(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
if(ifStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $ifStatement")
override fun before(ifElse: IfElse, parent: Node): Iterable<IAstModification> {
if(ifElse.parent!==parent)
throw FatalAstException("parent node mismatch at $ifElse")
return noModifications
}
@ -209,9 +209,9 @@ internal class ParentNodeChecker: AstWalker() {
return noModifications
}
override fun before(whenStatement: WhenStatement, parent: Node): Iterable<IAstModification> {
if(whenStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $whenStatement")
override fun before(`when`: When, parent: Node): Iterable<IAstModification> {
if(`when`.parent!==parent)
throw FatalAstException("parent node mismatch at $`when`")
return noModifications
}
@ -221,9 +221,9 @@ internal class ParentNodeChecker: AstWalker() {
return noModifications
}
override fun before(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
if(functionCall.parent!==parent)
throw FatalAstException("parent node mismatch at $functionCall")
override fun before(functionCallExpr: FunctionCallExpr, parent: Node): Iterable<IAstModification> {
if(functionCallExpr.parent!==parent)
throw FatalAstException("parent node mismatch at $functionCallExpr")
return noModifications
}
@ -233,9 +233,9 @@ internal class ParentNodeChecker: AstWalker() {
return noModifications
}
override fun before(nopStatement: NopStatement, parent: Node): Iterable<IAstModification> {
if(nopStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $nopStatement")
override fun before(nop: Nop, parent: Node): Iterable<IAstModification> {
if(nop.parent!==parent)
throw FatalAstException("parent node mismatch at $nop")
return noModifications
}

View File

@ -210,7 +210,7 @@ internal class StatementReorderer(val program: Program,
return listOf(IAstModification.ReplaceNode(expr.left, cast, expr))
}
}
is BuiltinFunctionStatementPlaceholder -> {
is BuiltinFunctionPlaceholder -> {
val func = BuiltinFunctions.getValue(callee.name)
val paramTypes = func.parameters[argnum].possibleDatatypes
for(type in paramTypes) {
@ -262,19 +262,19 @@ internal class StatementReorderer(val program: Program,
return noModifications
}
override fun after(whenStatement: WhenStatement, parent: Node): Iterable<IAstModification> {
val lastChoiceValues = whenStatement.choices.lastOrNull()?.values
override fun after(`when`: When, parent: Node): Iterable<IAstModification> {
val lastChoiceValues = `when`.choices.lastOrNull()?.values
if(lastChoiceValues?.isNotEmpty()==true) {
val elseChoice = whenStatement.choices.indexOfFirst { it.values==null || it.values?.isEmpty()==true }
val elseChoice = `when`.choices.indexOfFirst { it.values==null || it.values?.isEmpty()==true }
if(elseChoice>=0)
errors.err("else choice must be the last one", whenStatement.choices[elseChoice].position)
errors.err("else choice must be the last one", `when`.choices[elseChoice].position)
}
val choices = whenStatement.choiceValues(program).sortedBy {
val choices = `when`.choiceValues(program).sortedBy {
it.first?.first() ?: Int.MAX_VALUE
}
whenStatement.choices.clear()
choices.mapTo(whenStatement.choices) { it.second }
`when`.choices.clear()
choices.mapTo(`when`.choices) { it.second }
return noModifications
}

View File

@ -135,8 +135,8 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
return afterFunctionCallArgs(functionCallStatement)
}
override fun after(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
return afterFunctionCallArgs(functionCall)
override fun after(functionCallExpr: FunctionCallExpr, parent: Node): Iterable<IAstModification> {
return afterFunctionCallArgs(functionCallExpr)
}
private fun afterFunctionCallArgs(call: IFunctionCall): Iterable<IAstModification> {
@ -180,7 +180,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
}
}
}
is BuiltinFunctionStatementPlaceholder -> {
is BuiltinFunctionPlaceholder -> {
val func = BuiltinFunctions.getValue(sub.name)
func.parameters.zip(call.args).forEachIndexed { index, pair ->
val argItype = pair.second.inferType(program)

View File

@ -13,8 +13,8 @@ import prog8.compilerinterface.IErrorReporter
internal class VariousCleanups(val program: Program, val errors: IErrorReporter): AstWalker() {
override fun before(nopStatement: NopStatement, parent: Node): Iterable<IAstModification> {
return listOf(IAstModification.Remove(nopStatement, parent as IStatementContainer))
override fun before(nop: Nop, parent: Node): Iterable<IAstModification> {
return listOf(IAstModification.Remove(nop, parent as IStatementContainer))
}
override fun after(scope: AnonymousScope, parent: Node): Iterable<IAstModification> {

View File

@ -4,7 +4,7 @@ import prog8.ast.IFunctionCall
import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.expressions.Expression
import prog8.ast.expressions.FunctionCall
import prog8.ast.expressions.FunctionCallExpr
import prog8.ast.expressions.TypecastExpression
import prog8.ast.statements.*
import prog8.ast.walk.IAstVisitor
@ -13,8 +13,8 @@ import prog8.compilerinterface.InternalCompilerException
internal class VerifyFunctionArgTypes(val program: Program) : IAstVisitor {
override fun visit(functionCall: FunctionCall) {
val error = checkTypes(functionCall as IFunctionCall, program)
override fun visit(functionCallExpr: FunctionCallExpr) {
val error = checkTypes(functionCallExpr as IFunctionCall, program)
if(error!=null)
throw InternalCompilerException(error)
}
@ -76,7 +76,7 @@ internal class VerifyFunctionArgTypes(val program: Program) : IAstVisitor {
}
}
}
else if (target is BuiltinFunctionStatementPlaceholder) {
else if (target is BuiltinFunctionPlaceholder) {
val func = BuiltinFunctions.getValue(target.name)
if(call.args.size != func.parameters.size)
return "invalid number of arguments"

View File

@ -444,7 +444,7 @@ class TestOptimization: FunSpec({
}"""
val result = compileText(C64Target, optimize=true, src, writeAssembly=false).assertSuccess()
result.program.entrypoint.statements.size shouldBe 3
val ifstmt = result.program.entrypoint.statements[0] as IfStatement
val ifstmt = result.program.entrypoint.statements[0] as IfElse
ifstmt.truepart.statements.size shouldBe 1
(ifstmt.truepart.statements[0] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "r0")
val func2 = result.program.entrypoint.statements[2] as Subroutine

View File

@ -19,7 +19,6 @@ import prog8.ast.base.DataType
import prog8.ast.base.Position
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.compiler.printProgram
import prog8.compiler.target.C64Target
import prog8.compiler.target.cbm.Petscii
import prog8.parser.ParseError
@ -334,7 +333,7 @@ class TestProg8Parser: FunSpec( {
assertPositionOf(rhsFoo, mpf, 4, 21, 22)
val declBar = startSub.statements.filterIsInstance<VarDecl>()[1]
assertPositionOf(declBar, mpf, 5, 9, 13)
val whenStmt = startSub.statements.filterIsInstance<WhenStatement>()[0]
val whenStmt = startSub.statements.filterIsInstance<When>()[0]
assertPositionOf(whenStmt, mpf, 6, 9, 12)
assertPositionOf(whenStmt.choices[0], mpf, 7, 13, 14)
assertPositionOf(whenStmt.choices[1], mpf, 8, 13, 14)

View File

@ -195,8 +195,8 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
}
}
override fun visit(functionCall: FunctionCall) {
printout(functionCall as IFunctionCall)
override fun visit(functionCallExpr: FunctionCallExpr) {
printout(functionCallExpr as IFunctionCall)
}
override fun visit(functionCallStatement: FunctionCallStatement) {
@ -236,23 +236,23 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
}
}
override fun visit(ifStatement: IfStatement) {
override fun visit(ifElse: IfElse) {
output("if ")
ifStatement.condition.accept(this)
ifElse.condition.accept(this)
output(" ")
ifStatement.truepart.accept(this)
if(ifStatement.elsepart.statements.isNotEmpty()) {
ifElse.truepart.accept(this)
if(ifElse.elsepart.statements.isNotEmpty()) {
output(" else ")
ifStatement.elsepart.accept(this)
ifElse.elsepart.accept(this)
}
}
override fun visit(branchStatement: BranchStatement) {
output("if_${branchStatement.condition.toString().lowercase()} ")
branchStatement.truepart.accept(this)
if(branchStatement.elsepart.statements.isNotEmpty()) {
override fun visit(branch: Branch) {
output("if_${branch.condition.toString().lowercase()} ")
branch.truepart.accept(this)
if(branch.elsepart.statements.isNotEmpty()) {
output(" else ")
branchStatement.elsepart.accept(this)
branch.elsepart.accept(this)
}
}
@ -422,12 +422,12 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
outputlni("}}")
}
override fun visit(whenStatement: WhenStatement) {
override fun visit(`when`: When) {
output("when ")
whenStatement.condition.accept(this)
`when`.condition.accept(this)
outputln(" {")
scopelevel++
whenStatement.choices.forEach { it.accept(this) }
`when`.choices.forEach { it.accept(this) }
scopelevel--
outputlni("}")
}

View File

@ -39,14 +39,14 @@ interface IStatementContainer {
when(it) {
is Label -> result.add(it)
is IStatementContainer -> find(it)
is IfStatement -> {
is IfElse -> {
find(it.truepart)
find(it.elsepart)
}
is UntilLoop -> find(it.body)
is RepeatLoop -> find(it.body)
is WhileLoop -> find(it.body)
is WhenStatement -> it.choices.forEach { choice->find(choice.statements) }
is When -> it.choices.forEach { choice->find(choice.statements) }
else -> { /* do nothing */ }
}
}
@ -87,12 +87,12 @@ interface IStatementContainer {
if(found!=null)
return found
}
is IfStatement -> {
is IfElse -> {
val found = stmt.truepart.searchSymbol(name) ?: stmt.elsepart.searchSymbol(name)
if(found!=null)
return found
}
is BranchStatement -> {
is Branch -> {
val found = stmt.truepart.searchSymbol(name) ?: stmt.elsepart.searchSymbol(name)
if(found!=null)
return found
@ -117,7 +117,7 @@ interface IStatementContainer {
if(found!=null)
return found
}
is WhenStatement -> {
is When -> {
stmt.choices.forEach {
val found = it.statements.searchSymbol(name)
if(found!=null)

View File

@ -280,12 +280,12 @@ private fun Prog8ANTLRParser.Functioncall_stmtContext.toAst(): Statement {
FunctionCallStatement(location, expression_list().toAst().toMutableList(), void, toPosition())
}
private fun Prog8ANTLRParser.FunctioncallContext.toAst(): FunctionCall {
private fun Prog8ANTLRParser.FunctioncallContext.toAst(): FunctionCallExpr {
val location = scoped_identifier().toAst()
return if(expression_list() == null)
FunctionCall(location, mutableListOf(), toPosition())
FunctionCallExpr(location, mutableListOf(), toPosition())
else
FunctionCall(location, expression_list().toAst().toMutableList(), toPosition())
FunctionCallExpr(location, expression_list().toAst().toMutableList(), toPosition())
}
private fun Prog8ANTLRParser.InlineasmContext.toAst(): InlineAssembly {
@ -516,28 +516,28 @@ private fun Prog8ANTLRParser.BooleanliteralContext.toAst() = when(text) {
private fun Prog8ANTLRParser.ArrayliteralContext.toAst() : Array<Expression> =
expression().map { it.toAst() }.toTypedArray()
private fun Prog8ANTLRParser.If_stmtContext.toAst(): IfStatement {
private fun Prog8ANTLRParser.If_stmtContext.toAst(): IfElse {
val condition = expression().toAst()
val trueStatements = statement_block()?.toAst() ?: mutableListOf(statement().toAst())
val elseStatements = else_part()?.toAst() ?: mutableListOf()
val trueScope = AnonymousScope(trueStatements, statement_block()?.toPosition()
?: statement().toPosition())
val elseScope = AnonymousScope(elseStatements, else_part()?.toPosition() ?: toPosition())
return IfStatement(condition, trueScope, elseScope, toPosition())
return IfElse(condition, trueScope, elseScope, toPosition())
}
private fun Prog8ANTLRParser.Else_partContext.toAst(): MutableList<Statement> {
return statement_block()?.toAst() ?: mutableListOf(statement().toAst())
}
private fun Prog8ANTLRParser.Branch_stmtContext.toAst(): BranchStatement {
private fun Prog8ANTLRParser.Branch_stmtContext.toAst(): Branch {
val branchcondition = branchcondition().toAst()
val trueStatements = statement_block()?.toAst() ?: mutableListOf(statement().toAst())
val elseStatements = else_part()?.toAst() ?: mutableListOf()
val trueScope = AnonymousScope(trueStatements, statement_block()?.toPosition()
?: statement().toPosition())
val elseScope = AnonymousScope(elseStatements, else_part()?.toPosition() ?: toPosition())
return BranchStatement(branchcondition, trueScope, elseScope, toPosition())
return Branch(branchcondition, trueScope, elseScope, toPosition())
}
private fun Prog8ANTLRParser.BranchconditionContext.toAst() = BranchCondition.valueOf(
@ -581,10 +581,10 @@ private fun Prog8ANTLRParser.UntilloopContext.toAst(): UntilLoop {
return UntilLoop(scope, untilCondition, toPosition())
}
private fun Prog8ANTLRParser.WhenstmtContext.toAst(): WhenStatement {
private fun Prog8ANTLRParser.WhenstmtContext.toAst(): When {
val condition = expression().toAst()
val choices = this.when_choice()?.map { it.toAst() }?.toMutableList() ?: mutableListOf()
return WhenStatement(condition, choices, toPosition())
return When(condition, choices, toPosition())
}
private fun Prog8ANTLRParser.When_choiceContext.toAst(): WhenChoice {

View File

@ -66,8 +66,8 @@ sealed class Expression: Node {
is RangeExpr -> {
(other is RangeExpr && other.from==from && other.to==to && other.step==step)
}
is FunctionCall -> {
(other is FunctionCall && other.target.nameInSource == target.nameInSource
is FunctionCallExpr -> {
(other is FunctionCallExpr && other.target.nameInSource == target.nameInSource
&& other.args.size == args.size
&& other.args.zip(args).all { it.first isSameAs it.second } )
}
@ -811,7 +811,7 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
fun targetStatement(program: Program) =
if(nameInSource.size==1 && nameInSource[0] in program.builtinFunctions.names)
BuiltinFunctionStatementPlaceholder(nameInSource[0], position, parent)
BuiltinFunctionPlaceholder(nameInSource[0], position, parent)
else
definingScope.lookup(nameInSource)
@ -868,9 +868,9 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
}
}
class FunctionCall(override var target: IdentifierReference,
override var args: MutableList<Expression>,
override val position: Position) : Expression(), IFunctionCall {
class FunctionCallExpr(override var target: IdentifierReference,
override var args: MutableList<Expression>,
override val position: Position) : Expression(), IFunctionCall {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
@ -879,7 +879,7 @@ class FunctionCall(override var target: IdentifierReference,
args.forEach { it.linkParents(this) }
}
override fun copy() = FunctionCall(target.copy(), args.map { it.copy() }.toMutableList(), position)
override fun copy() = FunctionCallExpr(target.copy(), args.map { it.copy() }.toMutableList(), position)
override val isSimple = target.nameInSource.size==1 && (target.nameInSource[0] in arrayOf("msb", "lsb", "peek", "peekw"))
override fun replaceChildNode(node: Node, replacement: Node) {
@ -925,7 +925,7 @@ class FunctionCall(override var target: IdentifierReference,
return InferredTypes.knownFor(constVal.type)
val stmt = target.targetStatement(program) ?: return InferredTypes.unknown()
when (stmt) {
is BuiltinFunctionStatementPlaceholder -> {
is BuiltinFunctionPlaceholder -> {
if(target.nameInSource[0] == "set_carry" || target.nameInSource[0]=="set_irqd" ||
target.nameInSource[0] == "clear_carry" || target.nameInSource[0]=="clear_irqd") {
return InferredTypes.void() // these have no return value

View File

@ -49,7 +49,7 @@ sealed class Statement : Node {
}
class BuiltinFunctionStatementPlaceholder(val name: String, override val position: Position, override var parent: Node) : Statement() {
class BuiltinFunctionPlaceholder(val name: String, override val position: Position, override var parent: Node) : Statement() {
override fun linkParents(parent: Node) {}
override fun accept(visitor: IAstVisitor) = throw FatalAstException("should not iterate over this node")
override fun accept(visitor: AstWalker, parent: Node) = throw FatalAstException("should not iterate over this node")
@ -605,7 +605,7 @@ class AnonymousScope(override var statements: MutableList<Statement>,
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
}
class NopStatement(override val position: Position): Statement() {
class Nop(override val position: Position): Statement() {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
@ -613,7 +613,7 @@ class NopStatement(override val position: Position): Statement() {
}
override fun replaceChildNode(node: Node, replacement: Node) = throw FatalAstException("can't replace here")
override fun copy() = NopStatement(position)
override fun copy() = Nop(position)
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
}
@ -754,10 +754,10 @@ open class SubroutineParameter(val name: String,
override fun toString() = "Param($type:$name)"
}
class IfStatement(var condition: Expression,
var truepart: AnonymousScope,
var elsepart: AnonymousScope,
override val position: Position) : Statement() {
class IfElse(var condition: Expression,
var truepart: AnonymousScope,
var elsepart: AnonymousScope,
override val position: Position) : Statement() {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
@ -784,10 +784,10 @@ class IfStatement(var condition: Expression,
}
class BranchStatement(var condition: BranchCondition,
var truepart: AnonymousScope,
var elsepart: AnonymousScope,
override val position: Position) : Statement() {
class Branch(var condition: BranchCondition,
var truepart: AnonymousScope,
var elsepart: AnonymousScope,
override val position: Position) : Statement() {
override lateinit var parent: Node
override fun linkParents(parent: Node) {
@ -919,9 +919,9 @@ class UntilLoop(var body: AnonymousScope,
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
}
class WhenStatement(var condition: Expression,
var choices: MutableList<WhenChoice>,
override val position: Position): Statement() {
class When(var condition: Expression,
var choices: MutableList<WhenChoice>,
override val position: Position): Statement() {
override lateinit var parent: Node
override fun linkParents(parent: Node) {

View File

@ -85,7 +85,7 @@ abstract class AstWalker {
open fun before(assignTarget: AssignTarget, parent: Node): Iterable<IAstModification> = noModifications
open fun before(assignment: Assignment, parent: Node): Iterable<IAstModification> = noModifications
open fun before(block: Block, parent: Node): Iterable<IAstModification> = noModifications
open fun before(branchStatement: BranchStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun before(branch: Branch, parent: Node): Iterable<IAstModification> = noModifications
open fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> = noModifications
open fun before(decl: VarDecl, parent: Node): Iterable<IAstModification> = noModifications
open fun before(directive: Directive, parent: Node): Iterable<IAstModification> = noModifications
@ -93,10 +93,10 @@ abstract class AstWalker {
open fun before(expr: PrefixExpression, parent: Node): Iterable<IAstModification> = noModifications
open fun before(forLoop: ForLoop, parent: Node): Iterable<IAstModification> = noModifications
open fun before(repeatLoop: RepeatLoop, parent: Node): Iterable<IAstModification> = noModifications
open fun before(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> = noModifications
open fun before(functionCallExpr: FunctionCallExpr, parent: Node): Iterable<IAstModification> = noModifications
open fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun before(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> = noModifications
open fun before(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun before(ifElse: IfElse, parent: Node): Iterable<IAstModification> = noModifications
open fun before(inlineAssembly: InlineAssembly, parent: Node): Iterable<IAstModification> = noModifications
open fun before(jump: Jump, parent: Node): Iterable<IAstModification> = noModifications
open fun before(gosub: GoSub, parent: Node): Iterable<IAstModification> = noModifications
@ -104,7 +104,7 @@ abstract class AstWalker {
open fun before(memread: DirectMemoryRead, parent: Node): Iterable<IAstModification> = noModifications
open fun before(memwrite: DirectMemoryWrite, parent: Node): Iterable<IAstModification> = noModifications
open fun before(module: Module, parent: Node): Iterable<IAstModification> = noModifications
open fun before(nopStatement: NopStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun before(nop: Nop, parent: Node): Iterable<IAstModification> = noModifications
open fun before(numLiteral: NumericLiteralValue, parent: Node): Iterable<IAstModification> = noModifications
open fun before(postIncrDecr: PostIncrDecr, parent: Node): Iterable<IAstModification> = noModifications
open fun before(program: Program): Iterable<IAstModification> = noModifications
@ -117,7 +117,7 @@ abstract class AstWalker {
open fun before(subroutine: Subroutine, parent: Node): Iterable<IAstModification> = noModifications
open fun before(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> = noModifications
open fun before(whenChoice: WhenChoice, parent: Node): Iterable<IAstModification> = noModifications
open fun before(whenStatement: WhenStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun before(whenStmt: When, parent: Node): Iterable<IAstModification> = noModifications
open fun before(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> = noModifications
open fun after(addressOf: AddressOf, parent: Node): Iterable<IAstModification> = noModifications
@ -126,19 +126,19 @@ abstract class AstWalker {
open fun after(assignTarget: AssignTarget, parent: Node): Iterable<IAstModification> = noModifications
open fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> = noModifications
open fun after(block: Block, parent: Node): Iterable<IAstModification> = noModifications
open fun after(branchStatement: BranchStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun after(branch: Branch, parent: Node): Iterable<IAstModification> = noModifications
open fun after(breakStmt: Break, parent: Node): Iterable<IAstModification> = noModifications
open fun after(builtinFunctionStatementPlaceholder: BuiltinFunctionStatementPlaceholder, parent: Node): Iterable<IAstModification> = noModifications
open fun after(builtinFunctionPlaceholder: BuiltinFunctionPlaceholder, parent: Node): Iterable<IAstModification> = noModifications
open fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> = noModifications
open fun after(directive: Directive, parent: Node): Iterable<IAstModification> = noModifications
open fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> = noModifications
open fun after(expr: PrefixExpression, parent: Node): Iterable<IAstModification> = noModifications
open fun after(forLoop: ForLoop, parent: Node): Iterable<IAstModification> = noModifications
open fun after(repeatLoop: RepeatLoop, parent: Node): Iterable<IAstModification> = noModifications
open fun after(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> = noModifications
open fun after(functionCallExpr: FunctionCallExpr, parent: Node): Iterable<IAstModification> = noModifications
open fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> = noModifications
open fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> = noModifications
open fun after(inlineAssembly: InlineAssembly, parent: Node): Iterable<IAstModification> = noModifications
open fun after(jump: Jump, parent: Node): Iterable<IAstModification> = noModifications
open fun after(gosub: GoSub, parent: Node): Iterable<IAstModification> = noModifications
@ -146,7 +146,7 @@ abstract class AstWalker {
open fun after(memread: DirectMemoryRead, parent: Node): Iterable<IAstModification> = noModifications
open fun after(memwrite: DirectMemoryWrite, parent: Node): Iterable<IAstModification> = noModifications
open fun after(module: Module, parent: Node): Iterable<IAstModification> = noModifications
open fun after(nopStatement: NopStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun after(nop: Nop, parent: Node): Iterable<IAstModification> = noModifications
open fun after(numLiteral: NumericLiteralValue, parent: Node): Iterable<IAstModification> = noModifications
open fun after(postIncrDecr: PostIncrDecr, parent: Node): Iterable<IAstModification> = noModifications
open fun after(program: Program): Iterable<IAstModification> = noModifications
@ -159,7 +159,7 @@ abstract class AstWalker {
open fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> = noModifications
open fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> = noModifications
open fun after(whenChoice: WhenChoice, parent: Node): Iterable<IAstModification> = noModifications
open fun after(whenStatement: WhenStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun after(whenStmt: When, parent: Node): Iterable<IAstModification> = noModifications
open fun after(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> = noModifications
protected val modifications = mutableListOf<Triple<IAstModification, Node, Node>>()
@ -247,11 +247,11 @@ abstract class AstWalker {
track(after(subroutine, parent), subroutine, parent)
}
fun visit(functionCall: FunctionCall, parent: Node) {
track(before(functionCall, parent), functionCall, parent)
functionCall.target.accept(this, functionCall)
functionCall.args.forEach { it.accept(this, functionCall) }
track(after(functionCall, parent), functionCall, parent)
fun visit(functionCallExpr: FunctionCallExpr, parent: Node) {
track(before(functionCallExpr, parent), functionCallExpr, parent)
functionCallExpr.target.accept(this, functionCallExpr)
functionCallExpr.args.forEach { it.accept(this, functionCallExpr) }
track(after(functionCallExpr, parent), functionCallExpr, parent)
}
fun visit(functionCallStatement: FunctionCallStatement, parent: Node) {
@ -278,19 +278,19 @@ abstract class AstWalker {
track(after(gosub, parent), gosub, parent)
}
fun visit(ifStatement: IfStatement, parent: Node) {
track(before(ifStatement, parent), ifStatement, parent)
ifStatement.condition.accept(this, ifStatement)
ifStatement.truepart.accept(this, ifStatement)
ifStatement.elsepart.accept(this, ifStatement)
track(after(ifStatement, parent), ifStatement, parent)
fun visit(ifElse: IfElse, parent: Node) {
track(before(ifElse, parent), ifElse, parent)
ifElse.condition.accept(this, ifElse)
ifElse.truepart.accept(this, ifElse)
ifElse.elsepart.accept(this, ifElse)
track(after(ifElse, parent), ifElse, parent)
}
fun visit(branchStatement: BranchStatement, parent: Node) {
track(before(branchStatement, parent), branchStatement, parent)
branchStatement.truepart.accept(this, branchStatement)
branchStatement.elsepart.accept(this, branchStatement)
track(after(branchStatement, parent), branchStatement, parent)
fun visit(branch: Branch, parent: Node) {
track(before(branch, parent), branch, parent)
branch.truepart.accept(this, branch)
branch.elsepart.accept(this, branch)
track(after(branch, parent), branch, parent)
}
fun visit(range: RangeExpr, parent: Node) {
@ -430,16 +430,16 @@ abstract class AstWalker {
track(after(inlineAssembly, parent), inlineAssembly, parent)
}
fun visit(nopStatement: NopStatement, parent: Node) {
track(before(nopStatement, parent), nopStatement, parent)
track(after(nopStatement, parent), nopStatement, parent)
fun visit(nop: Nop, parent: Node) {
track(before(nop, parent), nop, parent)
track(after(nop, parent), nop, parent)
}
fun visit(whenStatement: WhenStatement, parent: Node) {
track(before(whenStatement, parent), whenStatement, parent)
whenStatement.condition.accept(this, whenStatement)
whenStatement.choices.forEach { it.accept(this, whenStatement) }
track(after(whenStatement, parent), whenStatement, parent)
fun visit(whenStmt: When, parent: Node) {
track(before(whenStmt, parent), whenStmt, parent)
whenStmt.condition.accept(this, whenStmt)
whenStmt.choices.forEach { it.accept(this, whenStmt) }
track(after(whenStmt, parent), whenStmt, parent)
}
fun visit(whenChoice: WhenChoice, parent: Node) {

View File

@ -39,9 +39,9 @@ interface IAstVisitor {
subroutine.statements.forEach { it.accept(this) }
}
fun visit(functionCall: FunctionCall) {
functionCall.target.accept(this)
functionCall.args.forEach { it.accept(this) }
fun visit(functionCallExpr: FunctionCallExpr) {
functionCallExpr.target.accept(this)
functionCallExpr.args.forEach { it.accept(this) }
}
fun visit(functionCallStatement: FunctionCallStatement) {
@ -60,15 +60,15 @@ interface IAstVisitor {
gosub.identifier?.accept(this)
}
fun visit(ifStatement: IfStatement) {
ifStatement.condition.accept(this)
ifStatement.truepart.accept(this)
ifStatement.elsepart.accept(this)
fun visit(ifElse: IfElse) {
ifElse.condition.accept(this)
ifElse.truepart.accept(this)
ifElse.elsepart.accept(this)
}
fun visit(branchStatement: BranchStatement) {
branchStatement.truepart.accept(this)
branchStatement.elsepart.accept(this)
fun visit(branch: Branch) {
branch.truepart.accept(this)
branch.elsepart.accept(this)
}
fun visit(range: RangeExpr) {
@ -164,12 +164,12 @@ interface IAstVisitor {
fun visit(inlineAssembly: InlineAssembly) {
}
fun visit(nopStatement: NopStatement) {
fun visit(nop: Nop) {
}
fun visit(whenStatement: WhenStatement) {
whenStatement.condition.accept(this)
whenStatement.choices.forEach { it.accept(this) }
fun visit(`when`: When) {
`when`.condition.accept(this)
`when`.choices.forEach { it.accept(this) }
}
fun visit(whenChoice: WhenChoice) {

View File

@ -6,7 +6,7 @@ import prog8.ast.Program
import prog8.ast.base.Position
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.AddressOf
import prog8.ast.expressions.FunctionCall
import prog8.ast.expressions.FunctionCallExpr
import prog8.ast.expressions.IdentifierReference
import prog8.ast.statements.*
import prog8.ast.walk.IAstVisitor
@ -59,15 +59,15 @@ class CallGraph(private val program: Program) : IAstVisitor {
super.visit(directive)
}
override fun visit(functionCall: FunctionCall) {
val otherSub = functionCall.target.targetSubroutine(program)
override fun visit(functionCallExpr: FunctionCallExpr) {
val otherSub = functionCallExpr.target.targetSubroutine(program)
if (otherSub != null) {
functionCall.definingSubroutine?.let { thisSub ->
functionCallExpr.definingSubroutine?.let { thisSub ->
calls[thisSub] = calls.getValue(thisSub) + otherSub
calledBy[otherSub] = calledBy.getValue(otherSub) + functionCall
calledBy[otherSub] = calledBy.getValue(otherSub) + functionCallExpr
}
}
super.visit(functionCall)
super.visit(functionCallExpr)
}
override fun visit(functionCallStatement: FunctionCallStatement) {

View File

@ -1,49 +1,74 @@
%import textio
%zeropage basicsafe
main {
ubyte @shared foo=99
sub thing(uword rr) {
ubyte @shared xx = rr[1] ; should still work as var initializer that will be rewritten
ubyte @shared yy
yy = rr[2]
uword @shared other
ubyte @shared zz = other[3]
}
sub start() {
txt.print("should print: 10 40 80 20\n")
ubyte @shared xx
repeat {
xx++
if xx==10
break
}
txt.print_ub(xx)
txt.nl()
while xx<50 {
xx++
if xx==40
break
if xx<100 {
foobar()
}
txt.print_ub(xx)
txt.nl()
do {
xx++
if xx==80
break
} until xx>100
txt.print_ub(xx)
txt.nl()
for xx in 0 to 25 {
if xx==20
break
}
txt.print_ub(xx)
txt.nl()
txt.print("\nthe end\n")
}
sub foobar() {
txt.print("foobar\n")
}
}
;
;
;main {
; ubyte @shared foo=99
; sub thing(uword rr) {
; ubyte @shared xx = rr[1] ; should still work as var initializer that will be rewritten
; ubyte @shared yy
; yy = rr[2]
; uword @shared other
; ubyte @shared zz = other[3]
; }
; sub start() {
;
; txt.print("should print: 10 40 80 20\n")
;
; ubyte @shared xx
;
; if xx >0
; goto $c000
; else
; xx++
;labeltje:
;
; repeat {
; xx++
; if xx==10
; break
; }
; txt.print_ub(xx)
; txt.nl()
;
; while xx<50 {
; xx++
; if xx==40
; break
; }
; txt.print_ub(xx)
; txt.nl()
;
; do {
; xx++
; if xx==80
; break
; } until xx>100
; txt.print_ub(xx)
; txt.nl()
;
; for xx in 0 to 25 {
; if xx==20
; break
; }
; txt.print_ub(xx)
; txt.nl()
; }
;}