adjust return value literal type to subroutine return type

This commit is contained in:
Irmen de Jong 2018-11-21 00:02:02 +01:00
parent 034973a9e6
commit e89788eeab
6 changed files with 70 additions and 10 deletions

1
.gitignore vendored
View File

@ -6,6 +6,7 @@
*.directory
*.prg
*.asm
*.bin
*.labels.txt
*.vice-mon-list
docs/build

View File

@ -16,8 +16,8 @@
; greeting
c64scr.print_string("Enter your name: ")
Y = c64scr.input_chars(name)
c64.CHROUT("\n")
Y = c64scr.input_chars(name) ; @todo fix argument type check
c64.CHROUT("\n") ; @todo fix argument type check
c64.CHROUT("\n")
c64scr.print_string("Hello, ")
c64scr.print_string(name)
@ -30,7 +30,7 @@
c64.MUL10() ; .. and now *100
c64.FADDH() ; add 0.5..
c64.FADDH() ; and again, so +1 total
AY = c64flt.GETADRAY()
A, Y = c64flt.GETADRAY()
secretnumber = A
;A=math.randbyte()
;A+=c64.RASTER
@ -50,7 +50,7 @@ ask_guess:
c64.CHROUT("\n")
freadstr_arg = guess
c64.FREADSTR(A)
AY = c64flt.GETADRAY()
A, Y = c64flt.GETADRAY()
if(A==secretnumber) {
c64scr.print_string("\nThat's my number, impressive!\n")
goto goodbye

View File

@ -533,6 +533,19 @@ class Return(var values: List<IExpression>, override val position: Position) : I
override fun toString(): String {
return "Return(values: $values, pos=$position)"
}
fun definingSubroutine(): Subroutine? {
var scope = definingScope()
while(scope !is GlobalNamespace) {
if(scope is Subroutine)
return scope
val parent = scope.parent
if(parent is Subroutine)
return parent
scope = parent.definingScope()
}
return null
}
}
class Continue(override val position: Position) : IStatement {

View File

@ -86,7 +86,7 @@ class AstChecker(private val namespace: INameScope,
}
override fun process(returnStmt: Return): IStatement {
val expectedReturnValues = (returnStmt.definingScope() as? Subroutine)?.returntypes ?: emptyList()
val expectedReturnValues = returnStmt.definingSubroutine()?.returntypes ?: emptyList()
if(expectedReturnValues.size != returnStmt.values.size) {
// if the return value is a function call, check the result of that call instead
if(returnStmt.values.size==1 && returnStmt.values[0] is FunctionCall) {

View File

@ -154,8 +154,22 @@ class AstIdentifiersChecker : IAstProcessor {
override fun process(returnStmt: Return): IStatement {
if(returnStmt.values.isNotEmpty()) {
println("CHECK $returnStmt") // TODO adjust return value literalvalue datatype to subroutine's definition
returnStmt.definingScope()
// possibly adjust any literal values returned, into the desired returning data type
val subroutine = returnStmt.definingSubroutine()!!
val newValues = mutableListOf<IExpression>()
for(returnvalue in returnStmt.values.zip(subroutine.returntypes)) {
val lval = returnvalue.first as? LiteralValue
if(lval!=null) {
val adjusted = lval.intoDatatype(returnvalue.second)
if(adjusted!=null && adjusted !== lval)
newValues.add(adjusted)
else
newValues.add(lval)
}
else
newValues.add(returnvalue.first)
}
returnStmt.values = newValues
}
return super.process(returnStmt)
}

View File

@ -49,6 +49,9 @@ push_float
pop_var_float
rts
pop_mem_float
rts
copy_float
rts
@ -73,16 +76,45 @@ mul_f
neg_f
rts
sub_uw
rts
less_ub
rts
less_b
rts
less_f
rts
add_w
rts ; @todo inline?
add_uw
rts ; @todo inline?
sub_w
rts ; @todo inline?
sub_uw
rts ; @todo inline?
mul_b
rts
mul_ub
rts
mul_w
rts
mul_uw
rts
div_b
rts
div_ub
rts
div_w
rts
div_uw
rts
func_sin
rts
func_cos