mirror of
https://github.com/irmen/prog8.git
synced 2025-02-18 05:30:34 +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)
|
P_irqd(1)
|
||||||
} else X=33
|
} else X=33
|
||||||
|
|
||||||
X= extra233.thingy() ; TODO EHHHH, should be counted as used?
|
X= extra233.thingy()
|
||||||
|
|
||||||
|
|
||||||
if(6>36) {
|
if(6>36) {
|
||||||
@ -131,7 +131,7 @@ cool:
|
|||||||
mega:
|
mega:
|
||||||
cool:
|
cool:
|
||||||
sub ultrafoo() -> () {
|
sub ultrafoo() -> () {
|
||||||
X= extra233.thingy() ; TODO EHHHH, should be counted as used?
|
X= extra233.thingy()
|
||||||
return 33
|
return 33
|
||||||
goto main.mega
|
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()
|
moduleAst.linkParents()
|
||||||
val globalNameSpaceBeforeOptimization = moduleAst.definingScope()
|
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
|
// determine special compiler options
|
||||||
|
|
||||||
val options = moduleAst.statements.filter { it is Directive && it.directive=="%option" }.flatMap { (it as Directive).args }.toSet()
|
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
|
// compile the syntax tree into intermediate form, and optimize that
|
||||||
|
|
||||||
val compiler = Compiler(compilerOptions, globalNamespaceAfterOptimize)
|
val compiler = Compiler(compilerOptions, globalNamespaceAfterOptimize)
|
||||||
|
@ -383,7 +383,10 @@ class Module(override val name: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun registerUsedName(name: String) {
|
override fun registerUsedName(name: String) {
|
||||||
|
// make sure to also register each scope separately
|
||||||
scopedNamesUsed.add(name)
|
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 var position: Position? = null
|
||||||
override lateinit var parent: Node
|
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 var position: Position? = null
|
||||||
override lateinit var parent: Node
|
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 var position: Position? = null
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
val scopedname: List<String> by lazy { makeScopedName(name) }
|
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 var position: Position? = null
|
||||||
override lateinit var parent: Node
|
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)
|
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 floatvalue: Double? = null,
|
||||||
val strvalue: String? = null,
|
val strvalue: String? = null,
|
||||||
val arrayvalue: MutableList<IExpression>? = null) : IExpression {
|
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 var position: Position? = null
|
||||||
override lateinit var parent: Node
|
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 var position: Position? = null
|
||||||
override lateinit var parent: Node
|
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 var position: Position? = null
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package il65.ast
|
package il65.ast
|
||||||
|
|
||||||
|
import il65.compiler.CompilationOptions
|
||||||
import il65.functions.BuiltIns
|
import il65.functions.BuiltIns
|
||||||
import il65.parser.ParsingFailedError
|
import il65.parser.ParsingFailedError
|
||||||
|
|
||||||
@ -7,8 +8,8 @@ import il65.parser.ParsingFailedError
|
|||||||
* General checks on the Ast
|
* General checks on the Ast
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fun Module.checkValid(globalNamespace: INameScope) {
|
fun Module.checkValid(globalNamespace: INameScope, compilerOptions: CompilationOptions) {
|
||||||
val checker = AstChecker(globalNamespace)
|
val checker = AstChecker(globalNamespace, compilerOptions)
|
||||||
this.process(checker)
|
this.process(checker)
|
||||||
val checkResult = checker.result()
|
val checkResult = checker.result()
|
||||||
checkResult.forEach {
|
checkResult.forEach {
|
||||||
@ -24,7 +25,7 @@ fun Module.checkValid(globalNamespace: INameScope) {
|
|||||||
* todo check subroutine return values against the call's result assignments
|
* 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()
|
private val checkResult: MutableList<SyntaxError> = mutableListOf()
|
||||||
|
|
||||||
fun result(): List<SyntaxError> {
|
fun result(): List<SyntaxError> {
|
||||||
@ -121,6 +122,10 @@ class AstChecker(private val globalNamespace: INameScope) : IAstProcessor {
|
|||||||
err("recursive var declaration")
|
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) {
|
when(decl.type) {
|
||||||
VarDeclType.VAR, VarDeclType.CONST -> {
|
VarDeclType.VAR, VarDeclType.CONST -> {
|
||||||
when {
|
when {
|
||||||
@ -233,6 +238,13 @@ class AstChecker(private val globalNamespace: INameScope) : IAstProcessor {
|
|||||||
return super.process(directive)
|
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) {
|
private fun checkConstInitializerValueArray(decl: VarDecl) {
|
||||||
val value = decl.value as LiteralValue
|
val value = decl.value as LiteralValue
|
||||||
// init value should either be a scalar or an array with the same dimensions as the arrayspec.
|
// 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) {
|
class Compiler(private val options: CompilationOptions, val namespace: INameScope) {
|
||||||
init {
|
|
||||||
val zeropage = Zeropage(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun compile(module: Module) : IntermediateForm {
|
fun compile(module: Module) : IntermediateForm {
|
||||||
println("\nCompiling parsed source code to intermediate code...")
|
println("\nCompiling parsed source code to intermediate code...")
|
||||||
// todo
|
// todo
|
||||||
|
Loading…
x
Reference in New Issue
Block a user