mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
builtin funcs with multiple param types
This commit is contained in:
parent
02075f2cf2
commit
d1589bef26
@ -9,12 +9,81 @@ sub start() {
|
||||
str_p spvar = "spvar"
|
||||
str_s ssvar = "ssvar"
|
||||
str_ps spsvar = "spsvar"
|
||||
byte[2,3] matrixvar1
|
||||
byte[2,3] matrixvar2 = 2
|
||||
byte[2,3] matrixvar
|
||||
byte[5] barrayvar
|
||||
byte[5] barrayvar1 = 44
|
||||
word[5] warrayvar
|
||||
word[5] warrayvar1 = 22
|
||||
|
||||
|
||||
set_carry()
|
||||
clear_carry()
|
||||
set_irqd()
|
||||
clear_irqd()
|
||||
|
||||
rol(bvar)
|
||||
rol(wvar)
|
||||
rol(fvar)
|
||||
rol(svar)
|
||||
rol(spvar)
|
||||
rol(ssvar)
|
||||
rol(spsvar)
|
||||
rol(matrixvar)
|
||||
rol(barrayvar)
|
||||
rol(warrayvar)
|
||||
|
||||
rol2(bvar)
|
||||
rol2(wvar)
|
||||
rol2(fvar)
|
||||
rol2(svar)
|
||||
rol2(spvar)
|
||||
rol2(ssvar)
|
||||
rol2(spsvar)
|
||||
rol2(matrixvar)
|
||||
rol2(barrayvar)
|
||||
rol2(warrayvar)
|
||||
|
||||
ror(bvar)
|
||||
ror(wvar)
|
||||
ror(fvar)
|
||||
ror(svar)
|
||||
ror(spvar)
|
||||
ror(ssvar)
|
||||
ror(spsvar)
|
||||
ror(matrixvar)
|
||||
ror(barrayvar)
|
||||
ror(warrayvar)
|
||||
|
||||
ror2(bvar)
|
||||
ror2(wvar)
|
||||
ror2(fvar)
|
||||
ror2(svar)
|
||||
ror2(spvar)
|
||||
ror2(ssvar)
|
||||
ror2(spsvar)
|
||||
ror2(matrixvar)
|
||||
ror2(barrayvar)
|
||||
ror2(warrayvar)
|
||||
|
||||
lsl(bvar)
|
||||
lsl(wvar)
|
||||
lsl(fvar)
|
||||
lsl(svar)
|
||||
lsl(spvar)
|
||||
lsl(ssvar)
|
||||
lsl(spsvar)
|
||||
lsl(matrixvar)
|
||||
lsl(barrayvar)
|
||||
lsl(warrayvar)
|
||||
|
||||
lsr(bvar)
|
||||
lsr(wvar)
|
||||
lsr(fvar)
|
||||
lsr(svar)
|
||||
lsr(spvar)
|
||||
lsr(ssvar)
|
||||
lsr(spsvar)
|
||||
lsr(matrixvar)
|
||||
lsr(barrayvar)
|
||||
lsr(warrayvar)
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1152,11 +1152,11 @@ class FunctionCall(override var target: IdentifierReference,
|
||||
var resultValue: LiteralValue? = null
|
||||
val func = BuiltinFunctions[target.nameInSource[0]]
|
||||
if(func!=null) {
|
||||
val exprfunc = func.expressionFunc
|
||||
val exprfunc = func.constExpressionFunc
|
||||
if(exprfunc!=null)
|
||||
resultValue = exprfunc(arglist, position, namespace, heap)
|
||||
else if(func.returnvalues.isEmpty())
|
||||
throw ExpressionError("builtin function ${target.nameInSource[0]} can't be used in expressions because it doesn't return a value", position)
|
||||
else if(func.returntype==null)
|
||||
throw ExpressionError("builtin function ${target.nameInSource[0]} can't be used here because it doesn't return a value", position)
|
||||
}
|
||||
|
||||
if(withDatatypeCheck) {
|
||||
|
@ -5,87 +5,64 @@ import prog8.compiler.HeapValues
|
||||
import kotlin.math.log2
|
||||
|
||||
|
||||
class FunctionSignature(val pure: Boolean, // does it have side effects?
|
||||
val parameters: List<SubroutineParameter>,
|
||||
val paramTypesVariable: Boolean,
|
||||
val returnvalues: List<DataType>,
|
||||
val type: DataType?,
|
||||
val expressionFunc: ((args: List<IExpression>, position: Position, namespace: INameScope, heap: HeapValues) -> LiteralValue)?) {
|
||||
companion object {
|
||||
private val dummyPos = Position("dummy", 0, 0, 0)
|
||||
|
||||
fun sig(pure: Boolean,
|
||||
args: List<Pair<String, DataType?>>,
|
||||
hasReturnValue: Boolean,
|
||||
type: DataType?,
|
||||
expressionFunc: ((args: List<IExpression>, position: Position, namespace: INameScope, heap: HeapValues) -> LiteralValue)? = null
|
||||
) : FunctionSignature {
|
||||
if(!hasReturnValue && expressionFunc!=null)
|
||||
throw IllegalArgumentException("can't have expression func when hasReturnValue is false")
|
||||
return FunctionSignature(pure,
|
||||
args.map { SubroutineParameter(it.first, it.second ?: DataType.BYTE, dummyPos) },
|
||||
args.any { it.second==null },
|
||||
if(hasReturnValue && type!=null)
|
||||
listOf(type)
|
||||
else
|
||||
emptyList(),
|
||||
type,
|
||||
expressionFunc
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
class BuiltinFunctionParam(val name: String, possibleDatatypes: List<DataType>)
|
||||
|
||||
class FunctionSignature(val pure: Boolean, // does it have side effects?
|
||||
val parameters: List<BuiltinFunctionParam>,
|
||||
val returntype: DataType?,
|
||||
val constExpressionFunc: ((args: List<IExpression>, position: Position, namespace: INameScope, heap: HeapValues) -> LiteralValue)? = null)
|
||||
|
||||
|
||||
val BuiltinFunctions = mapOf(
|
||||
"set_carry" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"clear_carry" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"set_irqd" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"clear_irqd" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"rol" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
|
||||
"ror" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
|
||||
"rol2" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
|
||||
"ror2" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
|
||||
"lsl" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
|
||||
"lsr" to FunctionSignature.sig(false, listOf(Pair("item", null)), false, null),
|
||||
"sin" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) },
|
||||
"cos" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) },
|
||||
"acos" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::acos) },
|
||||
"asin" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::asin) },
|
||||
"tan" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::tan) },
|
||||
"atan" to FunctionSignature.sig(true, listOf(Pair("rads", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) },
|
||||
"rnd" to FunctionSignature.sig(true, emptyList(), true, DataType.BYTE),
|
||||
"rndw" to FunctionSignature.sig(true, emptyList(), true, DataType.WORD),
|
||||
"rndf" to FunctionSignature.sig(true, emptyList(), true, DataType.FLOAT),
|
||||
"ln" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log) },
|
||||
"log2" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) },
|
||||
"log10" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log10) },
|
||||
"sqrt" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) },
|
||||
"rad" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) },
|
||||
"deg" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },
|
||||
"avg" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, DataType.FLOAT, ::builtinAvg),
|
||||
"abs" to FunctionSignature.sig(true, listOf(Pair("value", null)), true, null, ::builtinAbs), // type depends on arg
|
||||
"round" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::round) }, // type depends on arg
|
||||
"floor" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::floor) }, // type depends on arg
|
||||
"ceil" to FunctionSignature.sig(true, listOf(Pair("value", DataType.FLOAT)), true, null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::ceil) }, // type depends on arg
|
||||
"max" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args
|
||||
"min" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args
|
||||
"sum" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // type depends on args
|
||||
"len" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, null, ::builtinLen), // type depends on args
|
||||
"any" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
|
||||
"all" to FunctionSignature.sig(true, listOf(Pair("values", null)), true, DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
|
||||
"lsb" to FunctionSignature.sig(true, listOf(Pair("value", DataType.WORD)), true, DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x and 255 }},
|
||||
"msb" to FunctionSignature.sig(true, listOf(Pair("value", DataType.WORD)), true, DataType.BYTE) { a, p, n, h -> oneIntArgOutputInt(a, p, n, h) { x: Int -> x ushr 8 and 255}},
|
||||
"flt" to FunctionSignature.sig(true, listOf(Pair("value", null)), true, DataType.FLOAT, ::builtinFlt),
|
||||
"_vm_write_memchr" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"_vm_write_memstr" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"_vm_write_num" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"_vm_write_char" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"_vm_write_str" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"_vm_input_str" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"_vm_gfx_clearscr" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"_vm_gfx_pixel" to FunctionSignature.sig(false, emptyList(), false, null),
|
||||
"_vm_gfx_text" to FunctionSignature.sig(false, emptyList(), false, null)
|
||||
"rol" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"ror" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"rol2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"ror2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", listOf(DataType.BYTE, DataType.WORD))), null),
|
||||
"sin" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) },
|
||||
"cos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) },
|
||||
"acos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::acos) },
|
||||
"asin" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::asin) },
|
||||
"tan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::tan) },
|
||||
"atan" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::atan) },
|
||||
"ln" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log) },
|
||||
"log2" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, ::log2) },
|
||||
"log10" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::log10) },
|
||||
"sqrt" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sqrt) },
|
||||
"rad" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) },
|
||||
"deg" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) },
|
||||
"avg" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX))), DataType.FLOAT, ::builtinAvg),
|
||||
"abs" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), DataType.FLOAT, ::builtinAbs),
|
||||
"round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::round) }, // type depends on arg
|
||||
"floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::floor) }, // type depends on arg
|
||||
"ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", listOf(DataType.FLOAT))), null) { a, p, n, h -> oneDoubleArgOutputInt(a, p, n, h, Math::ceil) }, // type depends on arg
|
||||
"max" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX))), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args
|
||||
"min" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX))), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args
|
||||
"sum" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX))), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // type depends on args
|
||||
"len" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS, DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX))), null, ::builtinLen), // type depends on args
|
||||
"any" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX))), DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.any { v -> v != 0.0} }},
|
||||
"all" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", listOf(DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX))), DataType.BYTE) { a, p, n, h -> collectionArgOutputBoolean(a, p, n, h) { it.all { v -> v != 0.0} }},
|
||||
"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),
|
||||
"rnd" to FunctionSignature(true, emptyList(), DataType.BYTE),
|
||||
"rndw" to FunctionSignature(true, emptyList(), DataType.WORD),
|
||||
"rndf" to FunctionSignature(true, emptyList(), DataType.FLOAT),
|
||||
"set_carry" to FunctionSignature(false, emptyList(), null),
|
||||
"clear_carry" to FunctionSignature(false, emptyList(), null),
|
||||
"set_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"clear_irqd" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_write_memchr" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_write_memstr" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_write_num" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_write_char" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_write_str" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_input_str" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_gfx_clearscr" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_gfx_pixel" to FunctionSignature(false, emptyList(), null),
|
||||
"_vm_gfx_text" to FunctionSignature(false, emptyList(), null)
|
||||
)
|
||||
|
||||
|
||||
@ -127,14 +104,11 @@ fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespa
|
||||
}
|
||||
|
||||
val func = BuiltinFunctions[function]!!
|
||||
if(func.returnvalues.isEmpty())
|
||||
return null
|
||||
if(func.type!=null)
|
||||
return func.type
|
||||
if(func.returntype!=null)
|
||||
return func.returntype
|
||||
// function has return values, but the return type depends on the arguments
|
||||
|
||||
return when (function) {
|
||||
"abs" -> args.single().resultingDatatype(namespace, heap)
|
||||
"max", "min" -> {
|
||||
val dt = datatypeFromListArg(args.single())
|
||||
when(dt) {
|
||||
|
Loading…
Reference in New Issue
Block a user