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 PtBinaryExpression -> false
|
||||||
is PtBuiltinFunctionCall -> {
|
is PtBuiltinFunctionCall -> {
|
||||||
when (name) {
|
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
|
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__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),
|
"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),
|
"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),
|
"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),
|
"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),
|
"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),
|
"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) {
|
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)")
|
"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)
|
"msb" -> funcMsb(fcall, resultRegister)
|
||||||
"lsb" -> funcLsb(fcall, resultRegister)
|
"lsb" -> funcLsb(fcall, resultRegister)
|
||||||
"mkword" -> funcMkword(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 {
|
private fun usesOtherRegistersWhileEvaluating(arg: PtExpression): Boolean {
|
||||||
return when(arg) {
|
return when(arg) {
|
||||||
is PtBuiltinFunctionCall -> {
|
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])
|
return usesOtherRegistersWhileEvaluating(arg.args[0])
|
||||||
if (arg.name == "mkword")
|
if (arg.name == "mkword")
|
||||||
return usesOtherRegistersWhileEvaluating(arg.args[0]) || usesOtherRegistersWhileEvaluating(arg.args[1])
|
return usesOtherRegistersWhileEvaluating(arg.args[0]) || usesOtherRegistersWhileEvaluating(arg.args[1])
|
||||||
|
@ -928,7 +928,7 @@ internal class AssignmentAsmGen(
|
|||||||
is PtIdentifier -> true
|
is PtIdentifier -> true
|
||||||
is PtIrRegister -> true
|
is PtIrRegister -> true
|
||||||
is PtNumber -> 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
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
"callfar2" -> funcCallfar2(call)
|
"callfar2" -> funcCallfar2(call)
|
||||||
"call" -> funcCall(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)")
|
"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)
|
"msb" -> funcMsb(call)
|
||||||
"lsb" -> funcLsb(call)
|
"lsb" -> funcLsb(call)
|
||||||
"memory" -> funcMemory(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__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) } },
|
"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() } },
|
"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()} },
|
"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()} },
|
"bankof" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 255).toDouble()} },
|
||||||
"mkword" to ::builtinMkword,
|
"mkword" to ::builtinMkword,
|
||||||
"clamp__ubyte" to ::builtinClampUByte,
|
"clamp__ubyte" to ::builtinClampUByte,
|
||||||
|
@ -1514,7 +1514,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
ident = arg.value as IdentifierReference
|
ident = arg.value as IdentifierReference
|
||||||
else if(arg.value is FunctionCallExpression) {
|
else if(arg.value is FunctionCallExpression) {
|
||||||
val fcall = arg.value as 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
|
ident = fcall.args[0] as? IdentifierReference
|
||||||
}
|
}
|
||||||
if(ident!=null && ident.nameInSource[0] == "cx16" && ident.nameInSource[1].startsWith("r")) {
|
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 PtAddressOf -> value.arrayIndexExpr == null || notComplex(value.arrayIndexExpr!!)
|
||||||
is PtBuiltinFunctionCall -> {
|
is PtBuiltinFunctionCall -> {
|
||||||
when (value.name) {
|
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
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,12 +366,27 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> {
|
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)
|
val valueDt = functionCallExpr.args[0].inferType(program)
|
||||||
if(valueDt.isWords || valueDt.isBytes) {
|
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))
|
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
|
return noModifications
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import prog8.code.target.encodings.JapaneseCharacterConverter
|
|||||||
import java.io.CharConversionException
|
import java.io.CharConversionException
|
||||||
import java.util.Objects
|
import java.util.Objects
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.exp
|
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
import kotlin.math.truncate
|
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?
|
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 bankof()
|
||||||
-> added unary << operator as alternative to addr() / lsb(x>>16) / lsw()
|
-> 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.print_ubhex(bankof(foo2), true)
|
||||||
txt.spc()
|
txt.spc()
|
||||||
txt.print_uwhex(foo2 &$ffff, false)
|
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