mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
fix symbol usage tracking, also track scopes themselves. Fix directive option comparisons.
This commit is contained in:
parent
cd6327850e
commit
28ab7bbe34
@ -106,7 +106,7 @@
|
||||
P_irqd(1)
|
||||
} else X=33
|
||||
|
||||
X= extra233.thingy() ; TODO EHHHH, should be counted as used?
|
||||
X= extra233.thingy()
|
||||
|
||||
|
||||
if(6>36) {
|
||||
@ -131,7 +131,7 @@ cool:
|
||||
mega:
|
||||
cool:
|
||||
sub ultrafoo() -> () {
|
||||
X= extra233.thingy() ; TODO EHHHH, should be counted as used?
|
||||
X= extra233.thingy()
|
||||
return 33
|
||||
goto main.mega
|
||||
}
|
||||
|
7
il65/il65.sh
Executable file
7
il65/il65.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#/bin/env sh
|
||||
|
||||
IL65_LIBDIR=../lib65
|
||||
IL65CLASSPATH=out/production/il65
|
||||
LIBJARS=/opt/irmen/idea-2018/plugins/Kotlin/lib/kotlin-stdlib.jar:antlr/lib/antlr-runtime-4.7.1.jar
|
||||
|
||||
java -Dil65.libdir=${IL65_LIBDIR} -cp ${IL65CLASSPATH}:${LIBJARS} il65.MainKt $*
|
@ -27,19 +27,6 @@ fun main(args: Array<String>) {
|
||||
moduleAst.linkParents()
|
||||
val globalNameSpaceBeforeOptimization = moduleAst.definingScope()
|
||||
|
||||
|
||||
// perform syntax checks and optimizations
|
||||
moduleAst.checkIdentifiers()
|
||||
moduleAst.optimizeExpressions(globalNameSpaceBeforeOptimization)
|
||||
moduleAst.checkValid(globalNameSpaceBeforeOptimization) // check if tree is valid
|
||||
val allScopedSymbolDefinitions = moduleAst.checkIdentifiers()
|
||||
moduleAst.optimizeStatements(globalNameSpaceBeforeOptimization, allScopedSymbolDefinitions)
|
||||
val globalNamespaceAfterOptimize = moduleAst.definingScope() // it could have changed in the meantime
|
||||
moduleAst.checkValid(globalNamespaceAfterOptimize) // check if final tree is valid
|
||||
moduleAst.checkRecursion() // check if there are recursive subroutine calls
|
||||
|
||||
// globalNamespaceAfterOptimize.debugPrint()
|
||||
|
||||
// determine special compiler options
|
||||
|
||||
val options = moduleAst.statements.filter { it is Directive && it.directive=="%option" }.flatMap { (it as Directive).args }.toSet()
|
||||
@ -58,6 +45,19 @@ fun main(args: Array<String>) {
|
||||
)
|
||||
|
||||
|
||||
// perform syntax checks and optimizations
|
||||
moduleAst.checkIdentifiers()
|
||||
moduleAst.optimizeExpressions(globalNameSpaceBeforeOptimization)
|
||||
moduleAst.checkValid(globalNameSpaceBeforeOptimization, compilerOptions) // check if tree is valid
|
||||
val allScopedSymbolDefinitions = moduleAst.checkIdentifiers()
|
||||
moduleAst.optimizeStatements(globalNameSpaceBeforeOptimization, allScopedSymbolDefinitions)
|
||||
val globalNamespaceAfterOptimize = moduleAst.definingScope() // it could have changed in the meantime
|
||||
moduleAst.checkValid(globalNamespaceAfterOptimize, compilerOptions) // check if final tree is valid
|
||||
moduleAst.checkRecursion() // check if there are recursive subroutine calls
|
||||
|
||||
// globalNamespaceAfterOptimize.debugPrint()
|
||||
|
||||
|
||||
// compile the syntax tree into intermediate form, and optimize that
|
||||
|
||||
val compiler = Compiler(compilerOptions, globalNamespaceAfterOptimize)
|
||||
|
@ -383,7 +383,10 @@ class Module(override val name: String,
|
||||
}
|
||||
|
||||
override fun registerUsedName(name: String) {
|
||||
// make sure to also register each scope separately
|
||||
scopedNamesUsed.add(name)
|
||||
if(name.contains('.'))
|
||||
registerUsedName(name.substringBeforeLast('.'))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -412,7 +415,7 @@ class Block(override val name: String,
|
||||
}
|
||||
|
||||
|
||||
class Directive(val directive: String, val args: List<DirectiveArg>) : IStatement {
|
||||
data class Directive(val directive: String, val args: List<DirectiveArg>) : IStatement {
|
||||
override var position: Position? = null
|
||||
override lateinit var parent: Node
|
||||
|
||||
@ -425,7 +428,7 @@ class Directive(val directive: String, val args: List<DirectiveArg>) : IStatemen
|
||||
}
|
||||
|
||||
|
||||
class DirectiveArg(val str: String?, val name: String?, val int: Int?) : Node {
|
||||
data class DirectiveArg(val str: String?, val name: String?, val int: Int?) : Node {
|
||||
override var position: Position? = null
|
||||
override lateinit var parent: Node
|
||||
|
||||
@ -435,7 +438,7 @@ class DirectiveArg(val str: String?, val name: String?, val int: Int?) : Node {
|
||||
}
|
||||
|
||||
|
||||
class Label(val name: String) : IStatement {
|
||||
data class Label(val name: String) : IStatement {
|
||||
override var position: Position? = null
|
||||
override lateinit var parent: Node
|
||||
val scopedname: List<String> by lazy { makeScopedName(name) }
|
||||
@ -542,7 +545,7 @@ class Assignment(var target: AssignTarget, val aug_op : String?, var value: IExp
|
||||
}
|
||||
}
|
||||
|
||||
class AssignTarget(val register: Register?, val identifier: IdentifierReference?) : Node {
|
||||
data class AssignTarget(val register: Register?, val identifier: IdentifierReference?) : Node {
|
||||
override var position: Position? = null
|
||||
override lateinit var parent: Node
|
||||
|
||||
@ -597,7 +600,7 @@ class BinaryExpression(var left: IExpression, val operator: String, var right: I
|
||||
override fun referencesIdentifier(name: String) = left.referencesIdentifier(name) || right.referencesIdentifier(name)
|
||||
}
|
||||
|
||||
class LiteralValue(val intvalue: Int? = null,
|
||||
data class LiteralValue(val intvalue: Int? = null,
|
||||
val floatvalue: Double? = null,
|
||||
val strvalue: String? = null,
|
||||
val arrayvalue: MutableList<IExpression>? = null) : IExpression {
|
||||
@ -667,7 +670,7 @@ class RegisterExpr(val register: Register) : IExpression {
|
||||
}
|
||||
|
||||
|
||||
class IdentifierReference(val nameInSource: List<String>) : IExpression {
|
||||
data class IdentifierReference(val nameInSource: List<String>) : IExpression {
|
||||
override var position: Position? = null
|
||||
override lateinit var parent: Node
|
||||
|
||||
@ -849,7 +852,7 @@ class Subroutine(override val name: String,
|
||||
}
|
||||
|
||||
|
||||
class SubroutineParameter(val name: String, val register: Register?, val statusflag: Statusflag?) : Node {
|
||||
data class SubroutineParameter(val name: String, val register: Register?, val statusflag: Statusflag?) : Node {
|
||||
override var position: Position? = null
|
||||
override lateinit var parent: Node
|
||||
|
||||
@ -859,7 +862,7 @@ class SubroutineParameter(val name: String, val register: Register?, val statusf
|
||||
}
|
||||
|
||||
|
||||
class SubroutineReturnvalue(val register: Register?, val statusflag: Statusflag?, val clobbered: Boolean) : Node {
|
||||
data class SubroutineReturnvalue(val register: Register?, val statusflag: Statusflag?, val clobbered: Boolean) : Node {
|
||||
override var position: Position? = null
|
||||
override lateinit var parent: Node
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package il65.ast
|
||||
|
||||
import il65.compiler.CompilationOptions
|
||||
import il65.functions.BuiltIns
|
||||
import il65.parser.ParsingFailedError
|
||||
|
||||
@ -7,8 +8,8 @@ import il65.parser.ParsingFailedError
|
||||
* General checks on the Ast
|
||||
*/
|
||||
|
||||
fun Module.checkValid(globalNamespace: INameScope) {
|
||||
val checker = AstChecker(globalNamespace)
|
||||
fun Module.checkValid(globalNamespace: INameScope, compilerOptions: CompilationOptions) {
|
||||
val checker = AstChecker(globalNamespace, compilerOptions)
|
||||
this.process(checker)
|
||||
val checkResult = checker.result()
|
||||
checkResult.forEach {
|
||||
@ -24,7 +25,7 @@ fun Module.checkValid(globalNamespace: INameScope) {
|
||||
* todo check subroutine return values against the call's result assignments
|
||||
*/
|
||||
|
||||
class AstChecker(private val globalNamespace: INameScope) : IAstProcessor {
|
||||
class AstChecker(private val globalNamespace: INameScope, val compilerOptions: CompilationOptions) : IAstProcessor {
|
||||
private val checkResult: MutableList<SyntaxError> = mutableListOf()
|
||||
|
||||
fun result(): List<SyntaxError> {
|
||||
@ -121,6 +122,10 @@ class AstChecker(private val globalNamespace: INameScope) : IAstProcessor {
|
||||
err("recursive var declaration")
|
||||
}
|
||||
|
||||
if(!compilerOptions.floats && decl.datatype==DataType.FLOAT) {
|
||||
err("float var/const declaration, but floating point is not enabled via options")
|
||||
}
|
||||
|
||||
when(decl.type) {
|
||||
VarDeclType.VAR, VarDeclType.CONST -> {
|
||||
when {
|
||||
@ -233,6 +238,13 @@ class AstChecker(private val globalNamespace: INameScope) : IAstProcessor {
|
||||
return super.process(directive)
|
||||
}
|
||||
|
||||
override fun process(literalValue: LiteralValue): LiteralValue {
|
||||
if(!compilerOptions.floats && literalValue.isFloat) {
|
||||
checkResult.add(SyntaxError("floating point value used, but floating point is not enabled via options", literalValue.position))
|
||||
}
|
||||
return super.process(literalValue)
|
||||
}
|
||||
|
||||
private fun checkConstInitializerValueArray(decl: VarDecl) {
|
||||
val value = decl.value as LiteralValue
|
||||
// init value should either be a scalar or an array with the same dimensions as the arrayspec.
|
||||
|
@ -89,10 +89,6 @@ data class Mflpt5(val b0: Short, val b1: Short, val b2: Short, val b3: Short, va
|
||||
|
||||
|
||||
class Compiler(private val options: CompilationOptions, val namespace: INameScope) {
|
||||
init {
|
||||
val zeropage = Zeropage(options)
|
||||
}
|
||||
|
||||
fun compile(module: Module) : IntermediateForm {
|
||||
println("\nCompiling parsed source code to intermediate code...")
|
||||
// todo
|
||||
|
Loading…
Reference in New Issue
Block a user