mirror of
https://github.com/irmen/prog8.git
synced 2024-12-22 18:30:01 +00:00
added msw() and lsw() builtin functions (experimental)
This commit is contained in:
parent
cb86206698
commit
cc53d698bf
@ -92,7 +92,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
|
||||
is PtBinaryExpression -> false
|
||||
is PtBuiltinFunctionCall -> {
|
||||
when (name) {
|
||||
in arrayOf("msb", "lsb", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> this.args.all { it.isSimple() }
|
||||
in arrayOf("msb", "lsb", "msw", "lsw", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> this.args.all { it.isSimple() }
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,9 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
|
||||
"divmod__ubyte" to FSignature(false, listOf(FParam("dividend", arrayOf(DataType.UBYTE)), FParam("divisor", arrayOf(DataType.UBYTE)), FParam("quotient", arrayOf(DataType.UBYTE)), FParam("remainder", arrayOf(DataType.UBYTE))), null),
|
||||
"divmod__uword" to FSignature(false, listOf(FParam("dividend", arrayOf(DataType.UWORD)), FParam("divisor", arrayOf(DataType.UWORD)), FParam("quotient", arrayOf(DataType.UWORD)), FParam("remainder", arrayOf(DataType.UWORD))), null),
|
||||
"lsb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE),
|
||||
"lsw" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UWORD),
|
||||
"msb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE),
|
||||
"msw" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UWORD),
|
||||
"bankof" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE),
|
||||
"mkword" to FSignature(true, listOf(FParam("msb", arrayOf(DataType.UBYTE)), FParam("lsb", arrayOf(DataType.UBYTE))), DataType.UWORD),
|
||||
"clamp" to FSignature(true, listOf(FParam("value", arrayOf(DataType.BYTE)), FParam("minimum", arrayOf(DataType.BYTE)), FParam("maximum", arrayOf(DataType.BYTE))), null),
|
||||
|
@ -25,6 +25,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
|
||||
when (fcall.name) {
|
||||
"bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
|
||||
"lsw" -> throw AssemblyError("lsw() should have been removed or replaced by a const value")
|
||||
"msw" -> throw AssemblyError("msw() should have been removed or replaced by a const value")
|
||||
"msb" -> funcMsb(fcall, resultRegister)
|
||||
"lsb" -> funcLsb(fcall, resultRegister)
|
||||
"mkword" -> funcMkword(fcall, resultRegister)
|
||||
|
@ -161,7 +161,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
|
||||
private fun usesOtherRegistersWhileEvaluating(arg: PtExpression): Boolean {
|
||||
return when(arg) {
|
||||
is PtBuiltinFunctionCall -> {
|
||||
if (arg.name in arrayOf("lsb", "msb", "bankof"))
|
||||
if (arg.name in arrayOf("lsb", "msb", "lsw", "msw", "bankof"))
|
||||
return usesOtherRegistersWhileEvaluating(arg.args[0])
|
||||
if (arg.name == "mkword")
|
||||
return usesOtherRegistersWhileEvaluating(arg.args[0]) || usesOtherRegistersWhileEvaluating(arg.args[1])
|
||||
|
@ -928,7 +928,7 @@ internal class AssignmentAsmGen(
|
||||
is PtIdentifier -> true
|
||||
is PtIrRegister -> true
|
||||
is PtNumber -> true
|
||||
is PtBuiltinFunctionCall -> expr.name in arrayOf("lsb", "msb", "bankof")
|
||||
is PtBuiltinFunctionCall -> expr.name in arrayOf("lsb", "msb", "lsw", "msw", "bankof")
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
"callfar2" -> funcCallfar2(call)
|
||||
"call" -> funcCall(call)
|
||||
"bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
|
||||
"lsw" -> throw AssemblyError("lsw() should have been removed or replaced by a const value")
|
||||
"msw" -> throw AssemblyError("msw() should have been removed or replaced by a const value")
|
||||
"msb" -> funcMsb(call)
|
||||
"lsb" -> funcLsb(call)
|
||||
"memory" -> funcMemory(call)
|
||||
|
@ -20,7 +20,9 @@ internal val constEvaluatorsForBuiltinFuncs: Map<String, ConstExpressionCaller>
|
||||
"sqrt__uword" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, false) { sqrt(it.toDouble()) } },
|
||||
"sqrt__float" to { a, p, prg -> oneFloatArgOutputFloat(a, p, prg) { sqrt(it) } },
|
||||
"lsb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 255).toDouble() } },
|
||||
"lsw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 65535).toDouble() } },
|
||||
"msb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 8 and 255).toDouble()} },
|
||||
"msw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 65535).toDouble()} },
|
||||
"bankof" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 255).toDouble()} },
|
||||
"mkword" to ::builtinMkword,
|
||||
"clamp__ubyte" to ::builtinClampUByte,
|
||||
|
@ -1514,7 +1514,8 @@ internal class AstChecker(private val program: Program,
|
||||
ident = arg.value as IdentifierReference
|
||||
else if(arg.value is FunctionCallExpression) {
|
||||
val fcall = arg.value as FunctionCallExpression
|
||||
if(fcall.target.nameInSource == listOf("lsb") || fcall.target.nameInSource == listOf("msb") || fcall.target.nameInSource == listOf("bankof"))
|
||||
val name = fcall.target.nameInSource
|
||||
if(name==listOf("lsb") || name==listOf("msb") || name==listOf("bankof") || name==listOf("msw") || name==listOf("lsw"))
|
||||
ident = fcall.args[0] as? IdentifierReference
|
||||
}
|
||||
if(ident!=null && ident.nameInSource[0] == "cx16" && ident.nameInSource[1].startsWith("r")) {
|
||||
|
@ -118,7 +118,7 @@ private fun integrateDefers(subdefers: Map<PtSub, List<PtDefer>>, program: PtPro
|
||||
is PtAddressOf -> value.arrayIndexExpr == null || notComplex(value.arrayIndexExpr!!)
|
||||
is PtBuiltinFunctionCall -> {
|
||||
when (value.name) {
|
||||
in arrayOf("msb", "lsb", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> value.args.all { notComplex(it) }
|
||||
in arrayOf("msb", "lsb", "msw", "lsw", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> value.args.all { notComplex(it) }
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
@ -366,12 +366,27 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
||||
}
|
||||
|
||||
override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> {
|
||||
if(functionCallExpr.target.nameInSource==listOf("bankof")) {
|
||||
val name = functionCallExpr.target.nameInSource
|
||||
if(name==listOf("bankof")) {
|
||||
val valueDt = functionCallExpr.args[0].inferType(program)
|
||||
if(valueDt.isWords || valueDt.isBytes) {
|
||||
val zero = NumericLiteral.optimalInteger(0, functionCallExpr.position)
|
||||
val zero = NumericLiteral(DataType.UBYTE, 0.0, functionCallExpr.position)
|
||||
return listOf(IAstModification.ReplaceNode(functionCallExpr, zero, parent))
|
||||
}
|
||||
} else if(name==listOf("msw")) {
|
||||
val valueDt = functionCallExpr.args[0].inferType(program)
|
||||
if(valueDt.isWords || valueDt.isBytes) {
|
||||
val zero = NumericLiteral(DataType.UWORD, 0.0, functionCallExpr.position)
|
||||
return listOf(IAstModification.ReplaceNode(functionCallExpr, zero, parent))
|
||||
}
|
||||
} else if(name==listOf("lsw")) {
|
||||
val valueDt = functionCallExpr.args[0].inferType(program)
|
||||
if(valueDt.isWords)
|
||||
return listOf(IAstModification.ReplaceNode(functionCallExpr, functionCallExpr.args[0], parent))
|
||||
if(valueDt.isBytes) {
|
||||
val cast = TypecastExpression(functionCallExpr.args[0], DataType.UWORD, true, functionCallExpr.position)
|
||||
return listOf(IAstModification.ReplaceNode(functionCallExpr, cast, parent))
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import prog8.code.target.encodings.JapaneseCharacterConverter
|
||||
import java.io.CharConversionException
|
||||
import java.util.Objects
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.exp
|
||||
import kotlin.math.floor
|
||||
import kotlin.math.truncate
|
||||
|
||||
|
@ -5,7 +5,8 @@ what to do with bankof(): keep it? add another syntax like \`value or ^value t
|
||||
add a function like addr() or lsw() to complement bnk() in getting easy access to the lower 16 bits of a long integer?
|
||||
-> added unary ^ operator as alternative to bankof()
|
||||
-> added unary << operator as alternative to addr() / lsb(x>>16) / lsw()
|
||||
-> TODO document whatever remains of those!
|
||||
-> added msw() and lsw() . note: msw() on a 24 bits constant can ALSO be used to get the bank byte because the value, while a word type, will be <=255
|
||||
-> TODO document whatever remains of those! (and add to syntax files)
|
||||
|
||||
...
|
||||
|
||||
|
@ -21,6 +21,13 @@ main {
|
||||
txt.print_ubhex(bankof(foo2), true)
|
||||
txt.spc()
|
||||
txt.print_uwhex(foo2 &$ffff, false)
|
||||
txt.nl()
|
||||
|
||||
txt.print_ubhex(msw(foo2), true)
|
||||
txt.spc()
|
||||
txt.print_uwhex(lsw(foo2), false)
|
||||
txt.nl()
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user