note about removing VarDecls

This commit is contained in:
Irmen de Jong 2022-02-10 23:20:19 +01:00
parent bd0dee5db5
commit f95fe8f1da
4 changed files with 42 additions and 6 deletions

View File

@ -33,7 +33,7 @@ internal class ProgramAndVarsGen(
private val zeropage: Zeropage
) {
private val compTarget = options.compTarget
private val callGraph = CallGraph(program)
private val callGraph = CallGraph(program, true)
private val blockVariableInitializers = program.allBlocks.associateWith { it.statements.filterIsInstance<Assignment>() }
internal fun generate() {

View File

@ -3,12 +3,15 @@ package prog8.compiler
import com.github.michaelbull.result.onFailure
import prog8.ast.AstToSourceTextConverter
import prog8.ast.IBuiltinFunctions
import prog8.ast.IStatementContainer
import prog8.ast.Program
import prog8.ast.base.AstException
import prog8.ast.base.Position
import prog8.ast.expressions.Expression
import prog8.ast.expressions.NumericLiteralValue
import prog8.ast.statements.Directive
import prog8.ast.statements.VarDecl
import prog8.ast.walk.IAstVisitor
import prog8.codegen.target.C128Target
import prog8.codegen.target.C64Target
import prog8.codegen.target.Cx16Target
@ -348,6 +351,12 @@ private fun writeAssembly(program: Program,
program.processAstBeforeAsmGeneration(compilerOptions, variables, errors)
errors.report()
// TODO make removing all VarDecls work, but this needs inferType to be able to get its information from somewhere else as the VarDecl nodes in the Ast,
// or don't use inferType at all anymore and "bake the type information" into the Ast somehow.
// Note: we don't actually *need* to remove the VarDecl nodes, but it is nice as a temporary measure
// to help clean up the code that still depends on them.
// removeAllVardeclsFromAst(program)
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
// printProgram(program)
@ -364,6 +373,26 @@ private fun writeAssembly(program: Program,
}
}
private fun removeAllVardeclsFromAst(program: Program) {
// remove all VarDecl nodes from the AST.
// code generation doesn't require them anymore, it operates only on the 'variables' collection.
class SearchAndRemove: IAstVisitor {
private val allVars = mutableListOf<VarDecl>()
init {
visit(program)
for (it in allVars) {
require((it.parent as IStatementContainer).statements.remove(it))
}
}
override fun visit(decl: VarDecl) {
allVars.add(decl)
}
}
SearchAndRemove()
}
fun printProgram(program: Program) {
println()
val printer = AstToSourceTextConverter(::print, program)

View File

@ -55,9 +55,6 @@ internal class BeforeAsmAstChanger(val program: Program,
throw FatalAstException("vardecls for variables, with initial numerical value, should have been rewritten as plain vardecl + assignment $decl")
}
// TODO get rid of the vardecl inside the ast - codegen should depend on the IVariableAllocation object
// but if we do this now, all variable name lookups break because these are still done on the Ast directly rather than on a separate symbol table
// return listOf(IAstModification.Remove(decl, parent as IStatementContainer))
return noModifications
}

View File

@ -3,13 +3,14 @@ package prog8.compilerinterface
import prog8.ast.Module
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.FatalAstException
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.IAstVisitor
class CallGraph(private val program: Program) : IAstVisitor {
class CallGraph(private val program: Program, private val allowMissingIdentifierTargetVarDecls: Boolean=false) : IAstVisitor {
val imports = mutableMapOf<Module, Set<Module>>().withDefault { setOf() }
val importedBy = mutableMapOf<Module, Set<Module>>().withDefault { setOf() }
@ -109,7 +110,16 @@ class CallGraph(private val program: Program) : IAstVisitor {
}
override fun visit(identifier: IdentifierReference) {
allIdentifiersAndTargets[identifier] = identifier.targetStatement(program)!!
val target = identifier.targetStatement(program)
if(allowMissingIdentifierTargetVarDecls) {
if(target!=null)
allIdentifiersAndTargets[identifier] = target
} else {
if(target==null)
throw FatalAstException("missing target stmt for $identifier")
else
allIdentifiersAndTargets[identifier] = target
}
}
override fun visit(inlineAssembly: InlineAssembly) {