This commit is contained in:
Irmen de Jong 2018-08-14 12:00:45 +02:00
parent 69ff680eaf
commit bd6a05df73
6 changed files with 76 additions and 37 deletions

5
il65/src/compile.sh Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh
mkdir -p compiled_java
javac -d compiled_java -cp ../antlr/lib/antlr-runtime-4.7.1.jar $(find . -name \*.java)
jar cf parser.jar -C compiled_java il65
kotlinc -d il65_kotlin.jar -include-runtime -cp ../antlr/lib/antlr-runtime-4.7.1.jar:parser.jar il65

View File

@ -1,6 +1,7 @@
package il65
import il65.ast.*
import il65.optimizing.optimize
import il65.parser.il65Lexer
import il65.parser.il65Parser
import org.antlr.v4.runtime.CharStreams
@ -87,10 +88,10 @@ fun discoverImportedModule(name: String, importedFrom: Path, position: Position?
val fileName = name + ".ill"
val locations = mutableListOf(Paths.get(importedFrom.parent.toString()))
val propPath = System.getProperty("il65.libpath")
val propPath = System.getProperty("il65.libdir")
if(propPath!=null)
locations.add(Paths.get(propPath))
val envPath = System.getenv("IL65_LIBPATH")
val envPath = System.getenv("IL65_LIBDIR")
if(envPath!=null)
locations.add(Paths.get(envPath))
locations.add(Paths.get(Paths.get("").toAbsolutePath().toString(), "lib65"))
@ -113,7 +114,7 @@ fun executeImportDirective(import: Directive, importedFrom: Path): Module? {
val modulePath = discoverImportedModule(moduleName, importedFrom, import.position)
val importedModule = loadModule(modulePath)
importedModule.checkImportValid()
importedModule.checkImportedValid()
return importedModule
}

View File

@ -2,6 +2,9 @@ package il65.ast
import il65.ParsingFailedError
/**
* General checks on the Ast
*/
fun Module.checkValid(globalNamespace: INameScope) {
val checker = AstChecker(globalNamespace)

View File

@ -2,8 +2,11 @@ package il65.ast
import il65.ParsingFailedError
/**
* Checks that are specific for imported modules.
*/
fun Module.checkImportValid() {
fun Module.checkImportedValid() {
val checker = ImportedAstChecker()
this.process(checker)
val result = checker.result()
@ -11,7 +14,7 @@ fun Module.checkImportValid() {
it.printError()
}
if(result.isNotEmpty())
throw ParsingFailedError("There are ${result.size} errors in module '$name'.")
throw ParsingFailedError("There are ${result.size} errors in imported module '$name'.")
}
@ -22,6 +25,9 @@ class ImportedAstChecker : IAstProcessor {
return checkResult
}
/**
* Module check: most global directives don't apply for imported modules
*/
override fun process(module: Module) {
super.process(module)
val newStatements : MutableList<IStatement> = mutableListOf()

View File

@ -48,18 +48,41 @@ private fun twoDoubleArg(args: List<IExpression>, namespace: INameScope, functio
throw UnsupportedOperationException("built-in function requires two floating point values as argument")
}
fun builtin_round(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArgOutputInt(args, namespace) { it -> Math.round(it).toInt() }
fun builtin_sin(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::sin)
fun builtin_cos(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::cos)
fun builtin_acos(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::acos)
fun builtin_asin(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::asin)
fun builtin_tan(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::tan)
fun builtin_atan(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::atan)
fun builtin_log(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::log)
fun builtin_log10(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::log10)
fun builtin_sqrt(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::sqrt)
fun builtin_rad(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::toRadians)
fun builtin_deg(args: List<IExpression>, namespace: INameScope): LiteralValue = oneDoubleArg(args, namespace, Math::toDegrees)
fun builtin_round(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArgOutputInt(args, namespace) { it -> Math.round(it).toInt() }
fun builtin_sin(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::sin)
fun builtin_cos(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::cos)
fun builtin_acos(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::acos)
fun builtin_asin(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::asin)
fun builtin_tan(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::tan)
fun builtin_atan(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::atan)
fun builtin_log(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::log)
fun builtin_log10(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::log10)
fun builtin_sqrt(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::sqrt)
fun builtin_rad(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::toRadians)
fun builtin_deg(args: List<IExpression>, namespace: INameScope): LiteralValue
= oneDoubleArg(args, namespace, Math::toDegrees)
fun builtin_abs(args: List<IExpression>, namespace: INameScope): LiteralValue {
if(args.size!=1)

View File

@ -1,10 +1,11 @@
package il65.ast
package il65.optimizing
import il65.ast.*
import kotlin.math.pow
fun Module.optimize(globalNamespace: INameScope) {
val optimizer = AstOptimizer(globalNamespace)
val optimizer = ExpressionOptimizer(globalNamespace)
this.process(optimizer)
if(optimizer.optimizationsDone==0)
println("[${this.name}] 0 optimizations performed")
@ -18,7 +19,7 @@ fun Module.optimize(globalNamespace: INameScope) {
}
class AstOptimizer(private val globalNamespace: INameScope) : IAstProcessor {
class ExpressionOptimizer(private val globalNamespace: INameScope) : IAstProcessor {
var optimizationsDone: Int = 0
private set
@ -27,7 +28,7 @@ class AstOptimizer(private val globalNamespace: INameScope) : IAstProcessor {
}
/**
* some identifiers can be replaced with the constant value they refer to
* replace identifiers that refer to const value, with the value itself
*/
override fun process(identifier: Identifier): IExpression {
return identifier.constValue(globalNamespace) ?: identifier
@ -141,7 +142,7 @@ class ConstExprEvaluator {
private fun comparenotequal(left: LiteralValue, right: LiteralValue): LiteralValue {
val leq = compareequal(left, right)
val litval = LiteralValue(intvalue = if(leq.intvalue==1) 0 else 1)
val litval = LiteralValue(intvalue = if (leq.intvalue == 1) 0 else 1)
litval.position = left.position
return litval
}
@ -161,7 +162,7 @@ class ConstExprEvaluator {
right.arrayvalue!=null -> right.arrayvalue
else -> throw AstException("missing literal value")
}
val litval = LiteralValue(intvalue = if(leftvalue==rightvalue) 1 else 0)
val litval = LiteralValue(intvalue = if (leftvalue == rightvalue) 1 else 0)
litval.position = left.position
return litval
}
@ -214,14 +215,14 @@ class ConstExprEvaluator {
private fun comparegreater(left: LiteralValue, right: LiteralValue): LiteralValue {
val leq = comparelessequal(left, right)
val litval = LiteralValue(intvalue = if(leq.intvalue==1) 0 else 1)
val litval = LiteralValue(intvalue = if (leq.intvalue == 1) 0 else 1)
litval.position = left.position
return litval
}
private fun compareless(left: LiteralValue, right: LiteralValue): LiteralValue {
val leq = comparegreaterequal(left, right)
val litval = LiteralValue(intvalue = if(leq.intvalue==1) 0 else 1)
val litval = LiteralValue(intvalue = if (leq.intvalue == 1) 0 else 1)
litval.position = left.position
return litval
}
@ -231,16 +232,16 @@ class ConstExprEvaluator {
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if ((left.intvalue!=0).xor(right.intvalue!=0)) 1 else 0)
intvalue = if ((left.intvalue != 0).xor(right.intvalue != 0)) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if ((left.intvalue!=0).xor(right.floatvalue!=0.0)) 1 else 0)
intvalue = if ((left.intvalue != 0).xor(right.floatvalue != 0.0)) 1 else 0)
else -> throw ExpressionException(error)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if ((left.floatvalue!=0.0).xor(right.intvalue!=0)) 1 else 0)
intvalue = if ((left.floatvalue != 0.0).xor(right.intvalue != 0)) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if ((left.floatvalue!=0.0).xor(right.floatvalue!=0.0)) 1 else 0)
intvalue = if ((left.floatvalue != 0.0).xor(right.floatvalue != 0.0)) 1 else 0)
else -> throw ExpressionException(error)
}
else -> throw ExpressionException(error)
@ -254,16 +255,16 @@ class ConstExprEvaluator {
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.intvalue!=0 || right.intvalue!=0) 1 else 0)
intvalue = if (left.intvalue != 0 || right.intvalue != 0) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.intvalue!=0 || right.floatvalue!=0.0) 1 else 0)
intvalue = if (left.intvalue != 0 || right.floatvalue != 0.0) 1 else 0)
else -> throw ExpressionException(error)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue!=0.0 || right.intvalue!=0) 1 else 0)
intvalue = if (left.floatvalue != 0.0 || right.intvalue != 0) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue!=0.0 || right.floatvalue!=0.0) 1 else 0)
intvalue = if (left.floatvalue != 0.0 || right.floatvalue != 0.0) 1 else 0)
else -> throw ExpressionException(error)
}
else -> throw ExpressionException(error)
@ -277,16 +278,16 @@ class ConstExprEvaluator {
val litval = when {
left.intvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.intvalue!=0 && right.intvalue!=0) 1 else 0)
intvalue = if (left.intvalue != 0 && right.intvalue != 0) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.intvalue!=0 && right.floatvalue!=0.0) 1 else 0)
intvalue = if (left.intvalue != 0 && right.floatvalue != 0.0) 1 else 0)
else -> throw ExpressionException(error)
}
left.floatvalue!=null -> when {
right.intvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue!=0.0 && right.intvalue!=0) 1 else 0)
intvalue = if (left.floatvalue != 0.0 && right.intvalue != 0) 1 else 0)
right.floatvalue!=null -> LiteralValue(
intvalue = if (left.floatvalue!=0.0 && right.floatvalue!=0.0) 1 else 0)
intvalue = if (left.floatvalue != 0.0 && right.floatvalue != 0.0) 1 else 0)
else -> throw ExpressionException(error)
}
else -> throw ExpressionException(error)