mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 08:29:25 +00:00
stuff
This commit is contained in:
parent
ea94063689
commit
3228fa4c76
@ -103,14 +103,10 @@
|
|||||||
const byte equalQQ2 = (4+hopla)>0
|
const byte equalQQ2 = (4+hopla)>0
|
||||||
|
|
||||||
equalQQ++
|
equalQQ++
|
||||||
cos(2) ; @todo warning statement has no effect (returnvalue of builtin function not used) (remove statement)
|
|
||||||
cos(A) ; @todo warning statement has no effect (returnvalue of builtin function not used) (remove statement)
|
|
||||||
AX++
|
AX++
|
||||||
A=X + round(sin(Y))
|
A=X + round(sin(Y))
|
||||||
equalQQ= X
|
equalQQ= X
|
||||||
equalQQ= len([X, Y, AX])
|
equalQQ= len([X, Y, AX])
|
||||||
len([X, Y, AX]) ; @todo warning statement has no effect (returnvalue of builtin function not used) (remove statement)
|
|
||||||
sin(1) ; @todo warning statement has no effect (returnvalue of builtin function not used) (remove statement)
|
|
||||||
P_carry(1)
|
P_carry(1)
|
||||||
P_irqd(0)
|
P_irqd(0)
|
||||||
|
|
||||||
|
29
il65/examples/todos.ill
Normal file
29
il65/examples/todos.ill
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
%output prg
|
||||||
|
%launcher basic
|
||||||
|
|
||||||
|
~ main {
|
||||||
|
; memory byte derp = max([$ffdd]) ; @todo implement memory vars in stackvm
|
||||||
|
; memory byte derpA = abs(-20000)
|
||||||
|
; memory byte derpB = max([1, 2.2, 4.4, 100])
|
||||||
|
; memory byte cderp = min([$ffdd])+ (1/1)
|
||||||
|
; memory byte cderpA = min([$ffdd, 10, 20, 30])
|
||||||
|
; memory byte cderpB = min([1, 2.2, 4.4, 100])
|
||||||
|
; memory byte derp2 = 2+$ffdd+round(10*sin(3.1))
|
||||||
|
|
||||||
|
sub start() -> () {
|
||||||
|
P_irqd(1) ; is okay. (has side-effects, is not a pure function)
|
||||||
|
|
||||||
|
word dinges = 0
|
||||||
|
word blerp1 =999
|
||||||
|
word blerp3 = 1
|
||||||
|
byte blerp2 =99
|
||||||
|
dinges=blerp1
|
||||||
|
blerp3 = blerp2
|
||||||
|
A=blerp2
|
||||||
|
A=X
|
||||||
|
XY=X
|
||||||
|
XY=AX
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
@ -117,7 +117,7 @@ interface IAstProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun process(subroutine: Subroutine): IStatement {
|
fun process(subroutine: Subroutine): IStatement {
|
||||||
subroutine.statements = subroutine.statements.asSequence().map { it.process(this) }.toMutableList()
|
subroutine.statements = subroutine.statements.map { it.process(this) }.toMutableList()
|
||||||
return subroutine
|
return subroutine
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,6 +630,7 @@ interface IExpression: Node {
|
|||||||
fun constValue(namespace: INameScope): LiteralValue?
|
fun constValue(namespace: INameScope): LiteralValue?
|
||||||
fun process(processor: IAstProcessor): IExpression
|
fun process(processor: IAstProcessor): IExpression
|
||||||
fun referencesIdentifier(name: String): Boolean
|
fun referencesIdentifier(name: String): Boolean
|
||||||
|
// TODO fun resultingDatatype(): DataType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -771,6 +772,10 @@ class RegisterExpr(val register: Register) : IExpression {
|
|||||||
override fun constValue(namespace: INameScope): LiteralValue? = null
|
override fun constValue(namespace: INameScope): LiteralValue? = null
|
||||||
override fun process(processor: IAstProcessor) = this
|
override fun process(processor: IAstProcessor) = this
|
||||||
override fun referencesIdentifier(name: String): Boolean = false
|
override fun referencesIdentifier(name: String): Boolean = false
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "RegisterExpr(register=$register, pos=$position)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,13 +160,35 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(assignment.value is LiteralValue) {
|
val targetDatatype = assignment.target.determineDatatype(namespace, assignment)
|
||||||
val targetDatatype = assignment.target.determineDatatype(namespace, assignment)
|
val constVal = assignment.value.constValue(namespace)
|
||||||
|
if(constVal!=null) {
|
||||||
checkValueTypeAndRange(targetDatatype, null, assignment.value as LiteralValue, assignment.position)
|
checkValueTypeAndRange(targetDatatype, null, assignment.value as LiteralValue, assignment.position)
|
||||||
|
} else {
|
||||||
|
val sourceDatatype: DataType = when(assignment.value) {
|
||||||
|
is RegisterExpr -> {
|
||||||
|
when((assignment.value as RegisterExpr).register) {
|
||||||
|
Register.A, Register.X, Register.Y -> DataType.BYTE
|
||||||
|
Register.AX, Register.AY, Register.XY -> DataType.WORD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is IdentifierReference -> {
|
||||||
|
val targetStmt = (assignment.value as IdentifierReference).targetStatement(namespace)
|
||||||
|
if(targetStmt is VarDecl) {
|
||||||
|
targetStmt.datatype
|
||||||
|
} else {
|
||||||
|
throw FatalAstException("cannot get datatype from assignment value ${assignment.value}, pos=${assignment.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> TODO("check assignment compatibility for value ${assignment.value}, pos=${assignment.position}")
|
||||||
|
}
|
||||||
|
checkAssignmentCompatible(targetDatatype, sourceDatatype, assignment.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.process(assignment)
|
return super.process(assignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the variable declarations (values within range etc)
|
* Check the variable declarations (values within range etc)
|
||||||
*/
|
*/
|
||||||
@ -499,4 +521,25 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkAssignmentCompatible(targetDatatype: DataType, sourceDatatype: DataType, position: Position?) : Boolean {
|
||||||
|
val result = when(targetDatatype) {
|
||||||
|
DataType.BYTE -> sourceDatatype==DataType.BYTE
|
||||||
|
DataType.WORD -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD
|
||||||
|
DataType.FLOAT -> sourceDatatype==DataType.BYTE || sourceDatatype==DataType.WORD || sourceDatatype==DataType.FLOAT
|
||||||
|
DataType.STR -> sourceDatatype==DataType.STR
|
||||||
|
DataType.STR_P -> sourceDatatype==DataType.STR_P
|
||||||
|
DataType.STR_S -> sourceDatatype==DataType.STR_S
|
||||||
|
DataType.STR_PS -> sourceDatatype==DataType.STR_PS
|
||||||
|
DataType.ARRAY -> sourceDatatype==DataType.ARRAY
|
||||||
|
DataType.ARRAY_W -> sourceDatatype==DataType.ARRAY_W
|
||||||
|
DataType.MATRIX -> sourceDatatype==DataType.MATRIX
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
return true
|
||||||
|
|
||||||
|
checkResult.add(ExpressionError("cannot assign ${sourceDatatype.toString().toLowerCase()} to ${targetDatatype.toString().toLowerCase()}", position))
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ val BuiltinFunctionNames = setOf(
|
|||||||
"log", "log10", "sqrt", "rad", "deg", "round", "floor", "ceil",
|
"log", "log10", "sqrt", "rad", "deg", "round", "floor", "ceil",
|
||||||
"max", "min", "avg", "sum", "len", "any", "all", "lsb", "msb")
|
"max", "min", "avg", "sum", "len", "any", "all", "lsb", "msb")
|
||||||
|
|
||||||
|
val BuiltinFunctionsWithoutSideEffects = BuiltinFunctionNames - setOf("P_carry", "P_irqd")
|
||||||
|
|
||||||
|
|
||||||
class NotConstArgumentException: AstException("not a const argument to a built-in function")
|
class NotConstArgumentException: AstException("not a const argument to a built-in function")
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package il65.optimizing
|
package il65.optimizing
|
||||||
|
|
||||||
import il65.ast.*
|
import il65.ast.*
|
||||||
|
import il65.functions.BuiltinFunctionNames
|
||||||
|
import il65.functions.BuiltinFunctionsWithoutSideEffects
|
||||||
|
|
||||||
|
|
||||||
fun Module.optimizeStatements(globalNamespace: INameScope, allScopedSymbolDefinitions: MutableMap<String, IStatement>) {
|
fun Module.optimizeStatements(globalNamespace: INameScope, allScopedSymbolDefinitions: MutableMap<String, IStatement>) {
|
||||||
@ -33,6 +35,8 @@ class StatementOptimizer(private val globalNamespace: INameScope) : IAstProcesso
|
|||||||
var optimizationsDone: Int = 0
|
var optimizationsDone: Int = 0
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
private var statementsToRemove = mutableListOf<IStatement>()
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
optimizationsDone = 0
|
optimizationsDone = 0
|
||||||
}
|
}
|
||||||
@ -48,6 +52,15 @@ class StatementOptimizer(private val globalNamespace: INameScope) : IAstProcesso
|
|||||||
val target = globalNamespace.lookup(functionCall.target.nameInSource, functionCall)
|
val target = globalNamespace.lookup(functionCall.target.nameInSource, functionCall)
|
||||||
if(target!=null)
|
if(target!=null)
|
||||||
used(target)
|
used(target)
|
||||||
|
|
||||||
|
if(functionCall.target.nameInSource.size==1 && BuiltinFunctionNames.contains(functionCall.target.nameInSource[0])) {
|
||||||
|
val functionName = functionCall.target.nameInSource[0]
|
||||||
|
if (BuiltinFunctionsWithoutSideEffects.contains(functionName)) {
|
||||||
|
println("${functionCall.position} Warning: statement has no effect (function return value is discarded)")
|
||||||
|
statementsToRemove.add(functionCall)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return super.process(functionCall)
|
return super.process(functionCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,5 +112,9 @@ class StatementOptimizer(private val globalNamespace: INameScope) : IAstProcesso
|
|||||||
optimizationsDone++
|
optimizationsDone++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(stmt in statementsToRemove) {
|
||||||
|
stmt.definingScope().removeStatement(stmt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user