mirror of
https://github.com/irmen/prog8.git
synced 2024-10-07 00:55:33 +00:00
reducing dependencies
This commit is contained in:
parent
d23c2eed86
commit
f4cef3eaf2
@ -11,7 +11,7 @@ import prog8.ast.walk.IAstModification
|
|||||||
import prog8.compiler.target.ICompilationTarget
|
import prog8.compiler.target.ICompilationTarget
|
||||||
|
|
||||||
|
|
||||||
internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: ErrorReporter, private val compTarget: ICompilationTarget) : AstWalker() {
|
internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: IErrorReporter, private val compTarget: ICompilationTarget) : AstWalker() {
|
||||||
|
|
||||||
private val noModifications = emptyList<IAstModification>()
|
private val noModifications = emptyList<IAstModification>()
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ private class BuiltinFunctionsFacade(functions: Map<String, FSignature>): IBuilt
|
|||||||
builtinFunctionReturnType(name, args, program)
|
builtinFunctionReturnType(name, args, program)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseImports(filepath: Path, errors: ErrorReporter, compTarget: ICompilationTarget): Triple<Program, CompilationOptions, List<Path>> {
|
private fun parseImports(filepath: Path, errors: IErrorReporter, compTarget: ICompilationTarget): Triple<Program, CompilationOptions, List<Path>> {
|
||||||
val compilationTargetName = compTarget.name
|
val compilationTargetName = compTarget.name
|
||||||
println("Compiler target: $compilationTargetName. Parsing...")
|
println("Compiler target: $compilationTargetName. Parsing...")
|
||||||
val importer = ModuleImporter()
|
val importer = ModuleImporter()
|
||||||
@ -173,7 +173,7 @@ private fun parseImports(filepath: Path, errors: ErrorReporter, compTarget: ICom
|
|||||||
val programAst = Program(moduleName(filepath.fileName), mutableListOf(), bf, compTarget)
|
val programAst = Program(moduleName(filepath.fileName), mutableListOf(), bf, compTarget)
|
||||||
bf.program = programAst
|
bf.program = programAst
|
||||||
importer.importModule(programAst, filepath, compTarget, compilationTargetName)
|
importer.importModule(programAst, filepath, compTarget, compilationTargetName)
|
||||||
errors.handle()
|
errors.report()
|
||||||
|
|
||||||
val importedFiles = programAst.modules.filter { !it.source.startsWith("@embedded@") }.map { it.source }
|
val importedFiles = programAst.modules.filter { !it.source.startsWith("@embedded@") }.map { it.source }
|
||||||
val compilerOptions = determineCompilationOptions(programAst, compTarget)
|
val compilerOptions = determineCompilationOptions(programAst, compTarget)
|
||||||
@ -187,7 +187,7 @@ private fun parseImports(filepath: Path, errors: ErrorReporter, compTarget: ICom
|
|||||||
// always import prog8_lib and math
|
// always import prog8_lib and math
|
||||||
importer.importLibraryModule(programAst, "math", compTarget, compilationTargetName)
|
importer.importLibraryModule(programAst, "math", compTarget, compilationTargetName)
|
||||||
importer.importLibraryModule(programAst, "prog8_lib", compTarget, compilationTargetName)
|
importer.importLibraryModule(programAst, "prog8_lib", compTarget, compilationTargetName)
|
||||||
errors.handle()
|
errors.report()
|
||||||
return Triple(programAst, compilerOptions, importedFiles)
|
return Triple(programAst, compilerOptions, importedFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,25 +242,25 @@ private fun determineCompilationOptions(program: Program, compTarget: ICompilati
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processAst(programAst: Program, errors: ErrorReporter, compilerOptions: CompilationOptions) {
|
private fun processAst(programAst: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) {
|
||||||
// perform initial syntax checks and processings
|
// perform initial syntax checks and processings
|
||||||
println("Processing for target ${compilerOptions.compTarget.name}...")
|
println("Processing for target ${compilerOptions.compTarget.name}...")
|
||||||
programAst.checkIdentifiers(errors, compilerOptions.compTarget)
|
programAst.checkIdentifiers(errors, compilerOptions.compTarget)
|
||||||
errors.handle()
|
errors.report()
|
||||||
programAst.constantFold(errors, compilerOptions.compTarget)
|
programAst.constantFold(errors, compilerOptions.compTarget)
|
||||||
errors.handle()
|
errors.report()
|
||||||
programAst.reorderStatements(errors)
|
programAst.reorderStatements(errors)
|
||||||
errors.handle()
|
errors.report()
|
||||||
programAst.addTypecasts(errors)
|
programAst.addTypecasts(errors)
|
||||||
errors.handle()
|
errors.report()
|
||||||
programAst.variousCleanups()
|
programAst.variousCleanups()
|
||||||
programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget)
|
programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget)
|
||||||
errors.handle()
|
errors.report()
|
||||||
programAst.checkIdentifiers(errors, compilerOptions.compTarget)
|
programAst.checkIdentifiers(errors, compilerOptions.compTarget)
|
||||||
errors.handle()
|
errors.report()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun optimizeAst(programAst: Program, errors: ErrorReporter, functions: IBuiltinFunctions, compTarget: ICompilationTarget) {
|
private fun optimizeAst(programAst: Program, errors: IErrorReporter, functions: IBuiltinFunctions, compTarget: ICompilationTarget) {
|
||||||
// optimize the parse tree
|
// optimize the parse tree
|
||||||
println("Optimizing...")
|
println("Optimizing...")
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -269,7 +269,7 @@ private fun optimizeAst(programAst: Program, errors: ErrorReporter, functions: I
|
|||||||
val optsDone2 = programAst.splitBinaryExpressions(compTarget)
|
val optsDone2 = programAst.splitBinaryExpressions(compTarget)
|
||||||
val optsDone3 = programAst.optimizeStatements(errors, functions, compTarget)
|
val optsDone3 = programAst.optimizeStatements(errors, functions, compTarget)
|
||||||
programAst.constantFold(errors, compTarget) // because simplified statements and expressions can result in more constants that can be folded away
|
programAst.constantFold(errors, compTarget) // because simplified statements and expressions can result in more constants that can be folded away
|
||||||
errors.handle()
|
errors.report()
|
||||||
if (optsDone1 + optsDone2 + optsDone3 == 0)
|
if (optsDone1 + optsDone2 + optsDone3 == 0)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -277,29 +277,29 @@ private fun optimizeAst(programAst: Program, errors: ErrorReporter, functions: I
|
|||||||
val remover = UnusedCodeRemover(programAst, errors, compTarget)
|
val remover = UnusedCodeRemover(programAst, errors, compTarget)
|
||||||
remover.visit(programAst)
|
remover.visit(programAst)
|
||||||
remover.applyModifications()
|
remover.applyModifications()
|
||||||
errors.handle()
|
errors.report()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postprocessAst(programAst: Program, errors: ErrorReporter, compilerOptions: CompilationOptions) {
|
private fun postprocessAst(programAst: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) {
|
||||||
programAst.addTypecasts(errors)
|
programAst.addTypecasts(errors)
|
||||||
errors.handle()
|
errors.report()
|
||||||
programAst.variousCleanups()
|
programAst.variousCleanups()
|
||||||
programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget) // check if final tree is still valid
|
programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget) // check if final tree is still valid
|
||||||
errors.handle()
|
errors.report()
|
||||||
val callGraph = CallGraph(programAst)
|
val callGraph = CallGraph(programAst)
|
||||||
callGraph.checkRecursiveCalls(errors)
|
callGraph.checkRecursiveCalls(errors)
|
||||||
errors.handle()
|
errors.report()
|
||||||
programAst.verifyFunctionArgTypes()
|
programAst.verifyFunctionArgTypes()
|
||||||
programAst.moveMainAndStartToFirst()
|
programAst.moveMainAndStartToFirst()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeAssembly(programAst: Program,
|
private fun writeAssembly(programAst: Program,
|
||||||
errors: ErrorReporter,
|
errors: IErrorReporter,
|
||||||
outputDir: Path,
|
outputDir: Path,
|
||||||
compilerOptions: CompilationOptions): String {
|
compilerOptions: CompilationOptions): String {
|
||||||
// asm generation directly from the Ast,
|
// asm generation directly from the Ast,
|
||||||
programAst.processAstBeforeAsmGeneration(errors, compilerOptions.compTarget)
|
programAst.processAstBeforeAsmGeneration(errors, compilerOptions.compTarget)
|
||||||
errors.handle()
|
errors.report()
|
||||||
|
|
||||||
// printAst(programAst)
|
// printAst(programAst)
|
||||||
|
|
||||||
@ -311,7 +311,7 @@ private fun writeAssembly(programAst: Program,
|
|||||||
compilerOptions,
|
compilerOptions,
|
||||||
outputDir).compileToAssembly()
|
outputDir).compileToAssembly()
|
||||||
assembly.assemble(compilerOptions)
|
assembly.assemble(compilerOptions)
|
||||||
errors.handle()
|
errors.report()
|
||||||
return assembly.name
|
return assembly.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,16 @@ package prog8.compiler
|
|||||||
import prog8.ast.base.Position
|
import prog8.ast.base.Position
|
||||||
import prog8.parser.ParsingFailedError
|
import prog8.parser.ParsingFailedError
|
||||||
|
|
||||||
class ErrorReporter {
|
|
||||||
|
interface IErrorReporter {
|
||||||
|
fun err(msg: String, position: Position)
|
||||||
|
fun warn(msg: String, position: Position)
|
||||||
|
fun isEmpty(): Boolean
|
||||||
|
fun report()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal class ErrorReporter: IErrorReporter {
|
||||||
private enum class MessageSeverity {
|
private enum class MessageSeverity {
|
||||||
WARNING,
|
WARNING,
|
||||||
ERROR
|
ERROR
|
||||||
@ -13,10 +22,14 @@ class ErrorReporter {
|
|||||||
private val messages = mutableListOf<CompilerMessage>()
|
private val messages = mutableListOf<CompilerMessage>()
|
||||||
private val alreadyReportedMessages = mutableSetOf<String>()
|
private val alreadyReportedMessages = mutableSetOf<String>()
|
||||||
|
|
||||||
fun err(msg: String, position: Position) = messages.add(CompilerMessage(MessageSeverity.ERROR, msg, position))
|
override fun err(msg: String, position: Position) {
|
||||||
fun warn(msg: String, position: Position) = messages.add(CompilerMessage(MessageSeverity.WARNING, msg, position))
|
messages.add(CompilerMessage(MessageSeverity.ERROR, msg, position))
|
||||||
|
}
|
||||||
|
override fun warn(msg: String, position: Position) {
|
||||||
|
messages.add(CompilerMessage(MessageSeverity.WARNING, msg, position))
|
||||||
|
}
|
||||||
|
|
||||||
fun handle() {
|
override fun report() {
|
||||||
var numErrors = 0
|
var numErrors = 0
|
||||||
var numWarnings = 0
|
var numWarnings = 0
|
||||||
messages.forEach {
|
messages.forEach {
|
||||||
@ -40,5 +53,5 @@ class ErrorReporter {
|
|||||||
throw ParsingFailedError("There are $numErrors errors and $numWarnings warnings.")
|
throw ParsingFailedError("There are $numErrors errors and $numWarnings warnings.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isEmpty() = messages.isEmpty()
|
override fun isEmpty() = messages.isEmpty()
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
|||||||
|
|
||||||
fun available() = if(options.zeropage==ZeropageType.DONTUSE) 0 else free.size
|
fun available() = if(options.zeropage==ZeropageType.DONTUSE) 0 else free.size
|
||||||
|
|
||||||
fun allocate(scopedname: String, datatype: DataType, position: Position?, errors: ErrorReporter): Int {
|
fun allocate(scopedname: String, datatype: DataType, position: Position?, errors: IErrorReporter): Int {
|
||||||
assert(scopedname.isEmpty() || !allocations.values.any { it.first==scopedname } ) {"scopedname can't be allocated twice"}
|
assert(scopedname.isEmpty() || !allocations.values.any { it.first==scopedname } ) {"scopedname can't be allocated twice"}
|
||||||
|
|
||||||
if(options.zeropage==ZeropageType.DONTUSE)
|
if(options.zeropage==ZeropageType.DONTUSE)
|
||||||
|
@ -8,7 +8,7 @@ import prog8.ast.expressions.*
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.compiler.CompilationOptions
|
import prog8.compiler.CompilationOptions
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
import prog8.compiler.functions.BuiltinFunctions
|
||||||
import prog8.compiler.functions.builtinFunctionReturnType
|
import prog8.compiler.functions.builtinFunctionReturnType
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
@ -18,7 +18,7 @@ import java.io.File
|
|||||||
|
|
||||||
internal class AstChecker(private val program: Program,
|
internal class AstChecker(private val program: Program,
|
||||||
private val compilerOptions: CompilationOptions,
|
private val compilerOptions: CompilationOptions,
|
||||||
private val errors: ErrorReporter,
|
private val errors: IErrorReporter,
|
||||||
private val compTarget: ICompilationTarget
|
private val compTarget: ICompilationTarget
|
||||||
) : IAstVisitor {
|
) : IAstVisitor {
|
||||||
|
|
||||||
@ -1416,7 +1416,10 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
else -> errors.err("cannot assign new value to variable of type $targetDatatype", position)
|
else -> {
|
||||||
|
errors.err("cannot assign new value to variable of type $targetDatatype", position)
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
|
@ -5,28 +5,28 @@ import prog8.ast.base.FatalAstException
|
|||||||
import prog8.ast.statements.Directive
|
import prog8.ast.statements.Directive
|
||||||
import prog8.compiler.BeforeAsmGenerationAstChanger
|
import prog8.compiler.BeforeAsmGenerationAstChanger
|
||||||
import prog8.compiler.CompilationOptions
|
import prog8.compiler.CompilationOptions
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.target.ICompilationTarget
|
import prog8.compiler.target.ICompilationTarget
|
||||||
|
|
||||||
|
|
||||||
internal fun Program.checkValid(compilerOptions: CompilationOptions, errors: ErrorReporter, compTarget: ICompilationTarget) {
|
internal fun Program.checkValid(compilerOptions: CompilationOptions, errors: IErrorReporter, compTarget: ICompilationTarget) {
|
||||||
val checker = AstChecker(this, compilerOptions, errors, compTarget)
|
val checker = AstChecker(this, compilerOptions, errors, compTarget)
|
||||||
checker.visit(this)
|
checker.visit(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Program.processAstBeforeAsmGeneration(errors: ErrorReporter, compTarget: ICompilationTarget) {
|
internal fun Program.processAstBeforeAsmGeneration(errors: IErrorReporter, compTarget: ICompilationTarget) {
|
||||||
val fixer = BeforeAsmGenerationAstChanger(this, errors, compTarget)
|
val fixer = BeforeAsmGenerationAstChanger(this, errors, compTarget)
|
||||||
fixer.visit(this)
|
fixer.visit(this)
|
||||||
fixer.applyModifications()
|
fixer.applyModifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Program.reorderStatements(errors: ErrorReporter) {
|
internal fun Program.reorderStatements(errors: IErrorReporter) {
|
||||||
val reorder = StatementReorderer(this, errors)
|
val reorder = StatementReorderer(this, errors)
|
||||||
reorder.visit(this)
|
reorder.visit(this)
|
||||||
reorder.applyModifications()
|
reorder.applyModifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Program.addTypecasts(errors: ErrorReporter) {
|
internal fun Program.addTypecasts(errors: IErrorReporter) {
|
||||||
val caster = TypecastsAdder(this, errors)
|
val caster = TypecastsAdder(this, errors)
|
||||||
caster.visit(this)
|
caster.visit(this)
|
||||||
caster.applyModifications()
|
caster.applyModifications()
|
||||||
@ -37,7 +37,7 @@ internal fun Program.verifyFunctionArgTypes() {
|
|||||||
fixer.visit(this)
|
fixer.visit(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Program.checkIdentifiers(errors: ErrorReporter, compTarget: ICompilationTarget) {
|
internal fun Program.checkIdentifiers(errors: IErrorReporter, compTarget: ICompilationTarget) {
|
||||||
|
|
||||||
val checker2 = AstIdentifiersChecker(this, errors, compTarget)
|
val checker2 = AstIdentifiersChecker(this, errors, compTarget)
|
||||||
checker2.visit(this)
|
checker2.visit(this)
|
||||||
|
@ -10,11 +10,11 @@ import prog8.ast.expressions.NumericLiteralValue
|
|||||||
import prog8.ast.expressions.StringLiteralValue
|
import prog8.ast.expressions.StringLiteralValue
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
import prog8.compiler.functions.BuiltinFunctions
|
||||||
import prog8.compiler.target.ICompilationTarget
|
import prog8.compiler.target.ICompilationTarget
|
||||||
|
|
||||||
internal class AstIdentifiersChecker(private val program: Program, private val errors: ErrorReporter, private val compTarget: ICompilationTarget) : IAstVisitor {
|
internal class AstIdentifiersChecker(private val program: Program, private val errors: IErrorReporter, private val compTarget: ICompilationTarget) : IAstVisitor {
|
||||||
private var blocks = mutableMapOf<String, Block>()
|
private var blocks = mutableMapOf<String, Block>()
|
||||||
|
|
||||||
private fun nameError(name: String, position: Position, existing: Statement) {
|
private fun nameError(name: String, position: Position, existing: Statement) {
|
||||||
|
@ -6,11 +6,11 @@ import prog8.ast.expressions.*
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
import prog8.compiler.functions.BuiltinFunctions
|
||||||
|
|
||||||
|
|
||||||
internal class StatementReorderer(val program: Program, val errors: ErrorReporter) : AstWalker() {
|
internal class StatementReorderer(val program: Program, val errors: IErrorReporter) : AstWalker() {
|
||||||
// Reorders the statements in a way the compiler needs.
|
// Reorders the statements in a way the compiler needs.
|
||||||
// - 'main' block must be the very first statement UNLESS it has an address set.
|
// - 'main' block must be the very first statement UNLESS it has an address set.
|
||||||
// - library blocks are put last.
|
// - library blocks are put last.
|
||||||
|
@ -8,11 +8,11 @@ import prog8.ast.expressions.*
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
import prog8.compiler.functions.BuiltinFunctions
|
||||||
|
|
||||||
|
|
||||||
class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalker() {
|
class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalker() {
|
||||||
/*
|
/*
|
||||||
* Make sure any value assignments get the proper type casts if needed to cast them into the target variable's type.
|
* Make sure any value assignments get the proper type casts if needed to cast them into the target variable's type.
|
||||||
* (this includes function call arguments)
|
* (this includes function call arguments)
|
||||||
|
@ -8,7 +8,7 @@ import prog8.ast.expressions.IdentifierReference
|
|||||||
import prog8.ast.expressions.NumericLiteralValue
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
import prog8.ast.statements.AssignTarget
|
import prog8.ast.statements.AssignTarget
|
||||||
import prog8.compiler.CompilationOptions
|
import prog8.compiler.CompilationOptions
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.Zeropage
|
import prog8.compiler.Zeropage
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition
|
import prog8.compiler.target.c64.C64MachineDefinition
|
||||||
import prog8.compiler.target.c64.Petscii
|
import prog8.compiler.target.c64.Petscii
|
||||||
@ -108,7 +108,7 @@ internal object Cx16Target: ICompilationTarget {
|
|||||||
internal fun asmGeneratorFor(
|
internal fun asmGeneratorFor(
|
||||||
compTarget: ICompilationTarget,
|
compTarget: ICompilationTarget,
|
||||||
program: Program,
|
program: Program,
|
||||||
errors: ErrorReporter,
|
errors: IErrorReporter,
|
||||||
zp: Zeropage,
|
zp: Zeropage,
|
||||||
options: CompilationOptions,
|
options: CompilationOptions,
|
||||||
outputDir: Path
|
outputDir: Path
|
||||||
|
@ -23,7 +23,7 @@ import kotlin.math.absoluteValue
|
|||||||
|
|
||||||
|
|
||||||
internal class AsmGen(private val program: Program,
|
internal class AsmGen(private val program: Program,
|
||||||
val errors: ErrorReporter,
|
val errors: IErrorReporter,
|
||||||
val zeropage: Zeropage,
|
val zeropage: Zeropage,
|
||||||
val options: CompilationOptions,
|
val options: CompilationOptions,
|
||||||
private val compTarget: ICompilationTarget,
|
private val compTarget: ICompilationTarget,
|
||||||
@ -263,7 +263,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
try {
|
try {
|
||||||
val errors = ErrorReporter()
|
val errors = ErrorReporter()
|
||||||
val address = zeropage.allocate(fullName, variable.datatype, null, errors)
|
val address = zeropage.allocate(fullName, variable.datatype, null, errors)
|
||||||
errors.handle()
|
errors.report()
|
||||||
out("${variable.name} = $address\t; auto zp ${variable.datatype}")
|
out("${variable.name} = $address\t; auto zp ${variable.datatype}")
|
||||||
// make sure we add the var to the set of zpvars for this block
|
// make sure we add the var to the set of zpvars for this block
|
||||||
allocatedZeropageVariables[fullName] = address to variable.datatype
|
allocatedZeropageVariables[fullName] = address to variable.datatype
|
||||||
|
@ -11,7 +11,7 @@ import prog8.ast.expressions.FunctionCall
|
|||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.loadAsmIncludeFile
|
import prog8.compiler.loadAsmIncludeFile
|
||||||
|
|
||||||
private val alwaysKeepSubroutines = setOf(
|
private val alwaysKeepSubroutines = setOf(
|
||||||
@ -213,7 +213,7 @@ class CallGraph(private val program: Program) : IAstVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkRecursiveCalls(errors: ErrorReporter) {
|
fun checkRecursiveCalls(errors: IErrorReporter) {
|
||||||
val cycles = recursionCycles()
|
val cycles = recursionCycles()
|
||||||
if(cycles.any()) {
|
if(cycles.any()) {
|
||||||
errors.warn("Program contains recursive subroutine calls. These only works in very specific limited scenarios!", Position.DUMMY)
|
errors.warn("Program contains recursive subroutine calls. These only works in very specific limited scenarios!", Position.DUMMY)
|
||||||
|
@ -10,11 +10,11 @@ import prog8.ast.statements.ForLoop
|
|||||||
import prog8.ast.statements.VarDecl
|
import prog8.ast.statements.VarDecl
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.target.ICompilationTarget
|
import prog8.compiler.target.ICompilationTarget
|
||||||
|
|
||||||
// Fix up the literal value's type to match that of the vardecl
|
// Fix up the literal value's type to match that of the vardecl
|
||||||
internal class VarConstantValueTypeAdjuster(private val program: Program, private val errors: ErrorReporter) : AstWalker() {
|
internal class VarConstantValueTypeAdjuster(private val program: Program, private val errors: IErrorReporter) : AstWalker() {
|
||||||
private val noModifications = emptyList<IAstModification>()
|
private val noModifications = emptyList<IAstModification>()
|
||||||
|
|
||||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||||
@ -39,7 +39,7 @@ internal class VarConstantValueTypeAdjuster(private val program: Program, privat
|
|||||||
// Replace all constant identifiers with their actual value,
|
// Replace all constant identifiers with their actual value,
|
||||||
// and the array var initializer values and sizes.
|
// and the array var initializer values and sizes.
|
||||||
// This is needed because further constant optimizations depend on those.
|
// This is needed because further constant optimizations depend on those.
|
||||||
internal class ConstantIdentifierReplacer(private val program: Program, private val errors: ErrorReporter, private val compTarget: ICompilationTarget) : AstWalker() {
|
internal class ConstantIdentifierReplacer(private val program: Program, private val errors: IErrorReporter, private val compTarget: ICompilationTarget) : AstWalker() {
|
||||||
private val noModifications = emptyList<IAstModification>()
|
private val noModifications = emptyList<IAstModification>()
|
||||||
|
|
||||||
override fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> {
|
override fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> {
|
||||||
|
@ -2,11 +2,11 @@ package prog8.optimizer
|
|||||||
|
|
||||||
import prog8.ast.IBuiltinFunctions
|
import prog8.ast.IBuiltinFunctions
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.target.ICompilationTarget
|
import prog8.compiler.target.ICompilationTarget
|
||||||
|
|
||||||
|
|
||||||
internal fun Program.constantFold(errors: ErrorReporter, compTarget: ICompilationTarget) {
|
internal fun Program.constantFold(errors: IErrorReporter, compTarget: ICompilationTarget) {
|
||||||
val valuetypefixer = VarConstantValueTypeAdjuster(this, errors)
|
val valuetypefixer = VarConstantValueTypeAdjuster(this, errors)
|
||||||
valuetypefixer.visit(this)
|
valuetypefixer.visit(this)
|
||||||
if(errors.isEmpty()) {
|
if(errors.isEmpty()) {
|
||||||
@ -40,7 +40,7 @@ internal fun Program.constantFold(errors: ErrorReporter, compTarget: ICompilatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal fun Program.optimizeStatements(errors: ErrorReporter, functions: IBuiltinFunctions, compTarget: ICompilationTarget): Int {
|
internal fun Program.optimizeStatements(errors: IErrorReporter, functions: IBuiltinFunctions, compTarget: ICompilationTarget): Int {
|
||||||
val optimizer = StatementOptimizer(this, errors, functions, compTarget)
|
val optimizer = StatementOptimizer(this, errors, functions, compTarget)
|
||||||
optimizer.visit(this)
|
optimizer.visit(this)
|
||||||
val optimizationCount = optimizer.applyModifications()
|
val optimizationCount = optimizer.applyModifications()
|
||||||
|
@ -10,13 +10,13 @@ import prog8.ast.statements.*
|
|||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.target.ICompilationTarget
|
import prog8.compiler.target.ICompilationTarget
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
|
|
||||||
internal class StatementOptimizer(private val program: Program,
|
internal class StatementOptimizer(private val program: Program,
|
||||||
private val errors: ErrorReporter,
|
private val errors: IErrorReporter,
|
||||||
private val functions: IBuiltinFunctions,
|
private val functions: IBuiltinFunctions,
|
||||||
private val compTarget: ICompilationTarget
|
private val compTarget: ICompilationTarget
|
||||||
) : AstWalker() {
|
) : AstWalker() {
|
||||||
|
@ -10,11 +10,11 @@ import prog8.ast.expressions.TypecastExpression
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.compiler.ErrorReporter
|
import prog8.compiler.IErrorReporter
|
||||||
import prog8.compiler.target.ICompilationTarget
|
import prog8.compiler.target.ICompilationTarget
|
||||||
|
|
||||||
|
|
||||||
internal class UnusedCodeRemover(private val program: Program, private val errors: ErrorReporter, private val compTarget: ICompilationTarget): AstWalker() {
|
internal class UnusedCodeRemover(private val program: Program, private val errors: IErrorReporter, private val compTarget: ICompilationTarget): AstWalker() {
|
||||||
|
|
||||||
override fun before(program: Program, parent: Node): Iterable<IAstModification> {
|
override fun before(program: Program, parent: Node): Iterable<IAstModification> {
|
||||||
val callgraph = CallGraph(program)
|
val callgraph = CallGraph(program)
|
||||||
|
Loading…
Reference in New Issue
Block a user