Got rid of old Ast transformer Api, some compiler error fixes

This commit is contained in:
Irmen de Jong 2020-06-16 01:25:49 +02:00
parent 75ccac2f2c
commit 52f0222a6d
7 changed files with 36 additions and 60 deletions

View File

@ -2,7 +2,7 @@ package prog8.ast.base
import prog8.ast.expressions.IdentifierReference
class FatalAstException (override var message: String) : Exception(message)
open class FatalAstException (override var message: String) : Exception(message)
open class AstException (override var message: String) : Exception(message)

View File

@ -8,6 +8,7 @@ import prog8.ast.processing.IAstVisitor
import prog8.ast.statements.*
import prog8.compiler.target.CompilationTarget
import prog8.functions.BuiltinFunctions
import prog8.functions.CannotEvaluateException
import prog8.functions.NotConstArgumentException
import prog8.functions.builtinFunctionReturnType
import java.util.*
@ -833,6 +834,10 @@ class FunctionCall(override var target: IdentifierReference,
// const-evaluating the builtin function call failed.
return null
}
catch(x: CannotEvaluateException) {
// const-evaluating the builtin function call failed.
return null
}
}
override fun toString(): String {

View File

@ -1,9 +1,6 @@
package prog8.ast.processing
import prog8.ast.INameScope
import prog8.ast.Module
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.*
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.*
import prog8.ast.statements.*
@ -15,7 +12,7 @@ interface IAstModification {
class Remove(val node: Node, val parent: Node) : IAstModification {
override fun perform() {
if(parent is INameScope) {
if (!parent.statements.remove(node))
if (!parent.statements.remove(node) && parent !is GlobalNamespace)
throw FatalAstException("attempt to remove non-existing node $node")
} else {
throw FatalAstException("parent of a remove modification is not an INameScope")

View File

@ -193,7 +193,7 @@ private fun writeAssembly(programAst: Program, errors: ErrorReporter, outputDir:
programAst.processAstBeforeAsmGeneration(errors)
errors.handle()
printAst(programAst) // TODO weg
// printAst(programAst)
val assembly = CompilationTarget.asmGenerator(
programAst,

View File

@ -185,6 +185,7 @@ fun builtinFunctionReturnType(function: String, args: List<Expression>, program:
class NotConstArgumentException: AstException("not a const argument to a built-in function")
class CannotEvaluateException(func:String, msg: String): FatalAstException("cannot evaluate built-in function $func: $msg")
private fun oneDoubleArg(args: List<Expression>, position: Position, program: Program, function: (arg: Double)->Number): NumericLiteralValue {
@ -265,17 +266,22 @@ private fun builtinLen(args: List<Expression>, position: Position, program: Prog
return NumericLiteralValue.optimalInteger((args[0] as ArrayLiteralValue).value.size, position)
if(args[0] !is IdentifierReference)
throw SyntaxError("len argument should be an identifier, but is ${args[0]}", position)
val target = (args[0] as IdentifierReference).targetVarDecl(program.namespace)!!
val target = (args[0] as IdentifierReference).targetVarDecl(program.namespace)
?: throw CannotEvaluateException("len", "no target vardecl")
return when(target.datatype) {
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W -> {
arraySize = target.arraysize!!.size()!!
arraySize = target.arraysize?.size()
if(arraySize==null)
throw CannotEvaluateException("len", "arraysize unknown")
if(arraySize>256)
throw CompilerException("array length exceeds byte limit ${target.position}")
NumericLiteralValue.optimalInteger(arraySize, args[0].position)
}
DataType.ARRAY_F -> {
arraySize = target.arraysize!!.size()!!
arraySize = target.arraysize?.size()
if(arraySize==null)
throw CannotEvaluateException("len", "arraysize unknown")
if(arraySize>256)
throw CompilerException("array length exceeds byte limit ${target.position}")
NumericLiteralValue.optimalInteger(arraySize, args[0].position)

View File

@ -289,11 +289,21 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va
// was a prefix expression earlier), we recalculate the array's datatype.
if(array.type.isKnown)
return noModifications
val arrayDt = array.guessDatatype(program)
if(arrayDt.isKnown) {
val newArray = array.cast(arrayDt.typeOrElse(DataType.STRUCT))
if(newArray!=null && newArray != array)
// if the array literalvalue is inside an array vardecl, take the type from that
// otherwise infer it from the elements of the array
val vardeclType = (array.parent as? VarDecl)?.datatype
if(vardeclType!=null) {
val newArray = array.cast(vardeclType)
if (newArray != null && newArray != array)
return listOf(IAstModification.ReplaceNode(array, newArray, parent))
} else {
val arrayDt = array.guessDatatype(program)
if (arrayDt.isKnown) {
val newArray = array.cast(arrayDt.typeOrElse(DataType.STRUCT))
if (newArray != null && newArray != array)
return listOf(IAstModification.ReplaceNode(array, newArray, parent))
}
}
return noModifications

View File

@ -17,56 +17,14 @@ blabla:
}
sub func(ubyte arg) -> ubyte {
c64.CHROUT(arg)
return sin8(arg)
}
sub func2(ubyte arg) -> ubyte {
return sin8(arg)
}
sub start() {
ubyte[] a1 = 3 to 20
; ubyte[18] a2 = 3 to 20
; float[18] floats2 = 3 to 20
; ubyte[11] bytes = 22
; float[11] floats = 3.33
;
; float[] array = [1, 1+1, -33]
; byte[] array2 = [1, 1+1, -33, -2]
ubyte[] array = [1,2,3]
ubyte[len(array)] bytesE = 22 ; TODO fix nullpointer error
float[len(array)] floatsE = 3.33 ; TODO fix error
; float[] array2 = 42 ; TODO nice error
;ubyte[len(array)] bytesE = 22 ; TODO fix error
;float[len(array2)] floatsE = 3.33 ; TODO fix error
; const ubyte q = 123
; byte bbb
; float ff
;
; A = bytes[1]
; ff = array[1]
; A = len(array)
; A = len(array2)
; str sss = "zzz"
; str x = "zxcvzxcv"
;
; ff = 1234.44 + 99.0
; float ff2 = -3.3333
; ff=ff2*2
; A = 123+22+11
; bbb = -99
;
; A = q
; A = func(1+q)
; func(1+q)
;
; Y=99
; A = func2(1+q)
; func2(1+q)
;
; x = @(&sss)
}
}