mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
wrd and wrdhi functions added for byte-word conversion, more constant folding optimizations
This commit is contained in:
parent
d13ced6d95
commit
a7abc32368
@ -39,7 +39,7 @@
|
||||
_vm_gfx_text(14, 5, 5, "Spin to Win !!!")
|
||||
|
||||
for i in 0 to width//10 {
|
||||
_vm_gfx_line(i*2+width//2-width//10, 130, i*10, 199, 6)
|
||||
_vm_gfx_line(i*2+width//2-width//10, 130, i*10.w, 199, 6)
|
||||
}
|
||||
|
||||
rotate_vertices(flt(irq.global_time) / 30.0)
|
||||
|
@ -25,9 +25,9 @@
|
||||
}
|
||||
|
||||
sub screenx(x: float) -> word {
|
||||
return floor(x * flt(width)/4.1) + width // 2 ; @todo const-fold x*y/z
|
||||
return floor(x * flt(width)/4.1) + width // 2
|
||||
}
|
||||
sub screeny(y: float) -> word {
|
||||
return floor(y * flt(height)/4.1) + height // 2 ; @todo const-fold x*y/z
|
||||
return floor(y * flt(height)/4.1) + height // 2
|
||||
}
|
||||
}
|
||||
|
@ -6,16 +6,18 @@
|
||||
|
||||
sub start() {
|
||||
|
||||
const byte b1 = 20//7
|
||||
const word w1 = 20//7
|
||||
const float f1 = 20/7
|
||||
const float c1 = 11.11
|
||||
const float c2 = 22.22
|
||||
float v
|
||||
float r
|
||||
byte x
|
||||
word w
|
||||
|
||||
r=flt(x)
|
||||
w=wrd(x)
|
||||
w=wrdhi(x)
|
||||
|
||||
|
||||
_vm_write_num(b1)
|
||||
_vm_write_char('\n')
|
||||
_vm_write_num(w1)
|
||||
_vm_write_char('\n')
|
||||
_vm_write_num(f1)
|
||||
_vm_write_char('\n')
|
||||
return
|
||||
|
||||
}
|
||||
|
@ -826,6 +826,8 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
"msb" -> stackvmProg.instr(Opcode.MSB)
|
||||
"lsb" -> stackvmProg.instr(Opcode.LSB)
|
||||
"wrd" -> stackvmProg.instr(Opcode.B2WORD)
|
||||
"wrdhi" -> stackvmProg.instr(Opcode.MSB2WORD)
|
||||
"lsl" -> {
|
||||
val arg = args.single()
|
||||
when (arg.resultingDatatype(namespace, heap)) {
|
||||
|
@ -47,6 +47,8 @@ val BuiltinFunctions = mapOf(
|
||||
"lsb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.WORD))), DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
|
||||
"msb" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.WORD))), DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}},
|
||||
"flt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE, DataType.WORD))), DataType.FLOAT, ::builtinFlt),
|
||||
"wrd" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE))), DataType.WORD, ::builtinWrd),
|
||||
"wrdhi" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.BYTE))), DataType.WORD, ::builtinWrdHi),
|
||||
"rnd" to FunctionSignature(true, emptyList(), DataType.BYTE),
|
||||
"rndw" to FunctionSignature(true, emptyList(), DataType.WORD),
|
||||
"rndf" to FunctionSignature(true, emptyList(), DataType.FLOAT),
|
||||
@ -266,6 +268,28 @@ private fun builtinFlt(args: List<IExpression>, position: Position, namespace:IN
|
||||
return LiteralValue(DataType.FLOAT, floatvalue = number.toDouble(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinWrd(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 byte arg, convert to word
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("wrd requires one numeric argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.BYTE)
|
||||
throw SyntaxError("wrd requires one byte argument", position)
|
||||
return LiteralValue(DataType.WORD, wordvalue = constval.bytevalue!!.toInt(), position = position)
|
||||
}
|
||||
|
||||
private fun builtinWrdHi(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 byte arg, convert to word (in hi byte)
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("wrdhi requires one numeric argument", position)
|
||||
|
||||
val constval = args[0].constValue(namespace, heap) ?: throw NotConstArgumentException()
|
||||
if(constval.type!=DataType.BYTE)
|
||||
throw SyntaxError("wrdhi requires one byte argument", position)
|
||||
return LiteralValue(DataType.WORD, wordvalue = constval.bytevalue!!.toInt() shl 8, position = position)
|
||||
}
|
||||
|
||||
private fun builtinAbs(args: List<IExpression>, position: Position, namespace:INameScope, heap: HeapValues): LiteralValue {
|
||||
// 1 arg, type = float or int, result type= same as argument type
|
||||
if(args.size!=1)
|
||||
|
@ -278,11 +278,134 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
}
|
||||
return expr
|
||||
}
|
||||
|
||||
// todo: other cases where both operators are identical
|
||||
return expr
|
||||
|
||||
} else {
|
||||
// todo: other combinations of operators and constants (with different operator in subexpr)
|
||||
|
||||
if(expr.operator=="/" && subExpr.operator=="*") {
|
||||
optimizationsDone++
|
||||
if(leftIsConst) {
|
||||
return if(subleftIsConst) {
|
||||
// C1/(C2*V) -> (C1/C2)/V
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, "/", subExpr.left, subExpr.position),
|
||||
"/",
|
||||
subExpr.right, expr.position)
|
||||
} else {
|
||||
// C1/(V*C2) -> (C1/C2)/V
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, "/", subExpr.right, subExpr.position),
|
||||
"/",
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
} else {
|
||||
return if(subleftIsConst) {
|
||||
// (C1*V)/C2 -> (C1/C2)*V
|
||||
BinaryExpression(
|
||||
BinaryExpression(subExpr.left, "/", expr.right, subExpr.position),
|
||||
"*",
|
||||
subExpr.right, expr.position)
|
||||
} else {
|
||||
// (V*C1)/C2 -> (C1/C2)*V
|
||||
BinaryExpression(
|
||||
BinaryExpression(subExpr.right, "/", expr.right, subExpr.position),
|
||||
"*",
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
}
|
||||
} else if(expr.operator=="*" && subExpr.operator=="/") {
|
||||
optimizationsDone++
|
||||
if(leftIsConst) {
|
||||
return if(subleftIsConst) {
|
||||
// C1*(C2/V) -> (C1*C2)/V
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, "*", subExpr.left, subExpr.position),
|
||||
"/",
|
||||
subExpr.right, expr.position)
|
||||
} else {
|
||||
// C1*(V/C2) -> (C1/C2)*V
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, "/", subExpr.right, subExpr.position),
|
||||
"*",
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
} else {
|
||||
return if(subleftIsConst) {
|
||||
// (C1/V)*C2 -> (C1*C2)/V
|
||||
BinaryExpression(
|
||||
BinaryExpression(subExpr.left, "*", expr.right, subExpr.position),
|
||||
"/",
|
||||
subExpr.right, expr.position)
|
||||
} else {
|
||||
// (V/C1)*C2 -> (C2/C1)*V
|
||||
BinaryExpression(
|
||||
BinaryExpression(subExpr.right, "/", expr.right, subExpr.position),
|
||||
"*",
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
}
|
||||
} else if(expr.operator=="+" && subExpr.operator=="-") {
|
||||
if(leftIsConst){
|
||||
return if(subleftIsConst){
|
||||
// c1+(c2-v) -> (c1+c2)-v
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, "+", subExpr.left, subExpr.position),
|
||||
"-",
|
||||
subExpr.right, expr.position)
|
||||
} else {
|
||||
// c1+(v-c2) -> v+(c1-c2)
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, "-", subExpr.right, subExpr.position),
|
||||
"+",
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
} else {
|
||||
return if(subleftIsConst) {
|
||||
// (c1-v)+c2 -> (c1+c2)-v
|
||||
BinaryExpression(
|
||||
BinaryExpression(subExpr.left, "+", expr.right, subExpr.position),
|
||||
"-",
|
||||
subExpr.right, expr.position)
|
||||
} else {
|
||||
// (v-c1)+c2 -> v+(c2-c1)
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.right, "-", subExpr.right, subExpr.position),
|
||||
"+",
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
}
|
||||
} else if(expr.operator=="-" && subExpr.operator=="+") {
|
||||
if(leftIsConst) {
|
||||
return if(subleftIsConst) {
|
||||
// c1-(c2+v) -> (c1-c2)-v
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, "-", subExpr.left, subExpr.position),
|
||||
"-",
|
||||
subExpr.right, expr.position)
|
||||
} else {
|
||||
// c1-(v+c2) -> (c1-c2)-v
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, "-", subExpr.right, subExpr.position),
|
||||
"-",
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
} else {
|
||||
return if(subleftIsConst) {
|
||||
// (c1+v)-c2 -> v+(c1-c2)
|
||||
BinaryExpression(
|
||||
BinaryExpression(subExpr.left, "-", expr.right, subExpr.position),
|
||||
"+",
|
||||
subExpr.right, expr.position)
|
||||
} else {
|
||||
// (v+c1)-c2 -> v+(c1-c2)
|
||||
BinaryExpression(
|
||||
BinaryExpression(subExpr.right, "-", expr.right, subExpr.position),
|
||||
"+",
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return expr
|
||||
}
|
||||
}
|
||||
|
@ -561,6 +561,14 @@ flt(x)
|
||||
Explicitly convert the number x to a floating point number.
|
||||
This is required if you want calculations to have floating point precision when the values aren't float already.
|
||||
|
||||
wrd(x)
|
||||
Explicitly convert the byte x to a word.
|
||||
This is required if you want calculations to have word precision when the values are bytes.
|
||||
|
||||
wrdhi(x)
|
||||
Explicitly convert the byte x to a word, where x will be the high byte (msb) in the word.
|
||||
This can be useful in calculations with word precision when the values are bytes.
|
||||
|
||||
any(x)
|
||||
1 ('true') if any of the values in the non-scalar (array or matrix) value x is 'true' (not zero), else 0 ('false')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user