mirror of
https://github.com/irmen/prog8.git
synced 2024-08-18 23:29:32 +00:00
fix abs() and also try to convert const arguments to the desired datatype of subroutine params
This commit is contained in:
parent
b911a95fc2
commit
86ff08e854
@ -1 +1 @@
|
||||
1.1 (beta)
|
||||
1.2 (beta)
|
||||
|
@ -37,10 +37,10 @@ enum class DataType {
|
||||
fun assignableTo(targetType: DataType) =
|
||||
// what types are assignable to others without loss of precision?
|
||||
when(this) {
|
||||
UBYTE -> targetType == BYTE || targetType == UBYTE || targetType == UWORD || targetType==WORD || targetType == FLOAT
|
||||
BYTE -> targetType == BYTE || targetType == UBYTE || targetType == WORD || targetType == FLOAT
|
||||
UBYTE -> targetType == UBYTE || targetType == UWORD || targetType==WORD || targetType == FLOAT
|
||||
BYTE -> targetType == BYTE || targetType == UBYTE || targetType == UWORD || targetType==WORD || targetType == FLOAT
|
||||
UWORD -> targetType == UWORD || targetType == FLOAT
|
||||
WORD -> targetType == WORD || targetType == FLOAT
|
||||
WORD -> targetType == WORD || targetType==UWORD || targetType == FLOAT
|
||||
FLOAT -> targetType == FLOAT
|
||||
STR -> targetType == STR || targetType==STR_S || targetType == UWORD
|
||||
STR_P -> targetType == STR_P || targetType==STR_PS || targetType == UWORD
|
||||
|
@ -111,7 +111,7 @@ val BuiltinFunctions = mapOf(
|
||||
|
||||
fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespace: INameScope, heap: HeapValues): DataType? {
|
||||
|
||||
fun datatypeFromListArg(arglist: IExpression): DataType {
|
||||
fun datatypeFromIterableArg(arglist: IExpression): DataType {
|
||||
if(arglist is LiteralValue) {
|
||||
if(arglist.type==DataType.ARRAY_UB || arglist.type==DataType.ARRAY_UW || arglist.type==DataType.ARRAY_F) {
|
||||
val dt = arglist.arrayvalue!!.map {it.resultingDatatype(namespace, heap)}
|
||||
@ -133,10 +133,10 @@ fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespa
|
||||
DataType.ARRAY_UW -> DataType.UWORD
|
||||
DataType.ARRAY_W -> DataType.WORD
|
||||
DataType.ARRAY_F -> DataType.FLOAT
|
||||
null -> throw FatalAstException("function requires one argument which is an arrayspec $function")
|
||||
null -> throw FatalAstException("function '$function' requires one argument which is an iterable")
|
||||
}
|
||||
}
|
||||
throw FatalAstException("function requires one argument which is an arrayspec $function")
|
||||
throw FatalAstException("function '$function' requires one argument which is an iterable")
|
||||
}
|
||||
|
||||
val func = BuiltinFunctions.getValue(function)
|
||||
@ -145,8 +145,17 @@ fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespa
|
||||
// function has return values, but the return type depends on the arguments
|
||||
|
||||
return when (function) {
|
||||
"max", "min", "abs" -> {
|
||||
val dt = datatypeFromListArg(args.single())
|
||||
"abs" -> {
|
||||
val dt = args.single().resultingDatatype(namespace, heap)
|
||||
when(dt) {
|
||||
DataType.UBYTE, DataType.BYTE -> DataType.UBYTE
|
||||
DataType.UWORD, DataType.WORD -> DataType.UWORD
|
||||
DataType.FLOAT -> DataType.FLOAT
|
||||
else -> throw FatalAstException("weird datatype passed to abs $dt")
|
||||
}
|
||||
}
|
||||
"max", "min" -> {
|
||||
val dt = datatypeFromIterableArg(args.single())
|
||||
when(dt) {
|
||||
DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT -> dt
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> DataType.UBYTE
|
||||
@ -158,7 +167,7 @@ fun builtinFunctionReturnType(function: String, args: List<IExpression>, namespa
|
||||
}
|
||||
}
|
||||
"sum" -> {
|
||||
val dt=datatypeFromListArg(args.single())
|
||||
val dt=datatypeFromIterableArg(args.single())
|
||||
when(dt) {
|
||||
DataType.UBYTE, DataType.UWORD -> DataType.UWORD
|
||||
DataType.BYTE, DataType.WORD -> DataType.WORD
|
||||
|
@ -142,6 +142,7 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
override fun process(functionCall: FunctionCall): IExpression {
|
||||
return try {
|
||||
super.process(functionCall)
|
||||
typeCastConstArguments(functionCall)
|
||||
functionCall.constValue(namespace, heap) ?: functionCall
|
||||
} catch (ax: AstException) {
|
||||
addError(ax)
|
||||
@ -149,6 +150,29 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
}
|
||||
}
|
||||
|
||||
override fun process(functionCallStatement: FunctionCallStatement): IStatement {
|
||||
super.process(functionCallStatement)
|
||||
typeCastConstArguments(functionCallStatement)
|
||||
return functionCallStatement
|
||||
}
|
||||
|
||||
private fun typeCastConstArguments(functionCall: IFunctionCall) {
|
||||
val subroutine = functionCall.target.targetStatement(namespace) as? Subroutine
|
||||
if(subroutine!=null) {
|
||||
// if types differ, try to typecast constant arguments to the function call to the desired data type of the parameter
|
||||
for(arg in functionCall.arglist.withIndex().zip(subroutine.parameters)) {
|
||||
val expectedDt = arg.second.type
|
||||
val argConst = arg.first.value.constValue(namespace, heap)
|
||||
if(argConst!=null && argConst.type!=expectedDt) {
|
||||
val convertedValue = argConst.intoDatatype(expectedDt)
|
||||
if(convertedValue!=null)
|
||||
functionCall.arglist[arg.first.index] = convertedValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to process a unary prefix expression.
|
||||
* Compile-time constant sub expressions will be evaluated on the spot.
|
||||
|
@ -1,32 +1,30 @@
|
||||
%import c64utils
|
||||
%import c64flt
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
byte[10] ba = [1,2,3,4,5,6,7,8,9,-88]
|
||||
ubyte[10] uba = [1,2,3,4,5,6,7,8,9,10]
|
||||
foo(1)
|
||||
foo2(20)
|
||||
bar(2,3)
|
||||
baz(3333)
|
||||
baz(-3333)
|
||||
|
||||
c64scr.print_w(sum(ba))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_uw(sum(uba))
|
||||
c64.CHROUT('\n')
|
||||
|
||||
c64scr.print_ub(X)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
|
||||
; c64scr.print_w(w2)
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_w(w3)
|
||||
; c64.CHROUT('\n')
|
||||
; c64scr.print_uw(uw2)
|
||||
; c64.CHROUT('\n')
|
||||
}
|
||||
|
||||
sub foo(ubyte arg) {
|
||||
A=arg
|
||||
}
|
||||
|
||||
; @todo float & float -> nice error instead of crash
|
||||
sub foo2(byte arg) {
|
||||
A=33
|
||||
}
|
||||
|
||||
sub bar(ubyte arg1, ubyte arg2) {
|
||||
A=arg1
|
||||
}
|
||||
|
||||
sub baz(word arg) {
|
||||
A=lsb(arg)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user