mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
stuff
This commit is contained in:
parent
ea94063689
commit
3228fa4c76
@ -103,14 +103,10 @@
|
||||
const byte equalQQ2 = (4+hopla)>0
|
||||
|
||||
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++
|
||||
A=X + round(sin(Y))
|
||||
equalQQ= X
|
||||
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_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 {
|
||||
subroutine.statements = subroutine.statements.asSequence().map { it.process(this) }.toMutableList()
|
||||
subroutine.statements = subroutine.statements.map { it.process(this) }.toMutableList()
|
||||
return subroutine
|
||||
}
|
||||
|
||||
@ -630,6 +630,7 @@ interface IExpression: Node {
|
||||
fun constValue(namespace: INameScope): LiteralValue?
|
||||
fun process(processor: IAstProcessor): IExpression
|
||||
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 process(processor: IAstProcessor) = this
|
||||
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 constVal = assignment.value.constValue(namespace)
|
||||
if(constVal!=null) {
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the variable declarations (values within range etc)
|
||||
*/
|
||||
@ -499,4 +521,25 @@ class AstChecker(private val namespace: INameScope, private val compilerOptions:
|
||||
}
|
||||
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",
|
||||
"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")
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package il65.optimizing
|
||||
|
||||
import il65.ast.*
|
||||
import il65.functions.BuiltinFunctionNames
|
||||
import il65.functions.BuiltinFunctionsWithoutSideEffects
|
||||
|
||||
|
||||
fun Module.optimizeStatements(globalNamespace: INameScope, allScopedSymbolDefinitions: MutableMap<String, IStatement>) {
|
||||
@ -33,6 +35,8 @@ class StatementOptimizer(private val globalNamespace: INameScope) : IAstProcesso
|
||||
var optimizationsDone: Int = 0
|
||||
private set
|
||||
|
||||
private var statementsToRemove = mutableListOf<IStatement>()
|
||||
|
||||
fun reset() {
|
||||
optimizationsDone = 0
|
||||
}
|
||||
@ -48,6 +52,15 @@ class StatementOptimizer(private val globalNamespace: INameScope) : IAstProcesso
|
||||
val target = globalNamespace.lookup(functionCall.target.nameInSource, functionCall)
|
||||
if(target!=null)
|
||||
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)
|
||||
}
|
||||
|
||||
@ -99,5 +112,9 @@ class StatementOptimizer(private val globalNamespace: INameScope) : IAstProcesso
|
||||
optimizationsDone++
|
||||
}
|
||||
}
|
||||
|
||||
for(stmt in statementsToRemove) {
|
||||
stmt.definingScope().removeStatement(stmt)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user