Fixed so functions can do type conversion between in/out params and arguments. Lossy conversions give a warning now.
This commit is contained in:
parent
b830a41b5f
commit
5f01282df5
2 changed files with 38 additions and 18 deletions
|
|
@ -386,42 +386,60 @@ func (fh *FunctionHandler) processStringArg(arg string, param *FuncParam, funcNa
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// processVarArg handles variable arguments
|
|
||||||
func (fh *FunctionHandler) processVarArg(sym *Symbol, param *FuncParam, funcName string, line preproc.Line, inAssigns, outAssigns *[]string) error {
|
func (fh *FunctionHandler) processVarArg(sym *Symbol, param *FuncParam, funcName string, line preproc.Line, inAssigns, outAssigns *[]string) error {
|
||||||
// Check type compatibility
|
|
||||||
if (sym.IsByte() && param.Symbol.IsWord()) || (sym.IsWord() && param.Symbol.IsByte()) {
|
|
||||||
return fmt.Errorf("%s:%d: CALL %s: type mismatch for parameter %s", line.Filename, line.LineNo, funcName, param.Symbol.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if sym.IsConst() {
|
if sym.IsConst() {
|
||||||
return fmt.Errorf("%s:%d: CALL %s: cannot pass constant to function", line.Filename, line.LineNo, funcName)
|
return fmt.Errorf("%s:%d: CALL %s: cannot pass constant to function", line.Filename, line.LineNo, funcName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate IN assignments
|
// Generate IN assignments (sym -> param)
|
||||||
if param.Direction.Has(DirIn) {
|
if param.Direction.Has(DirIn) {
|
||||||
*inAssigns = append(*inAssigns,
|
*inAssigns = append(*inAssigns,
|
||||||
fmt.Sprintf(" lda %s", sym.FullName()),
|
fmt.Sprintf(" lda %s", sym.FullName()),
|
||||||
fmt.Sprintf(" sta %s", param.Symbol.FullName()),
|
fmt.Sprintf(" sta %s", param.Symbol.FullName()),
|
||||||
)
|
)
|
||||||
|
if param.Symbol.IsWord() {
|
||||||
if sym.IsWord() {
|
if sym.IsWord() {
|
||||||
*inAssigns = append(*inAssigns,
|
*inAssigns = append(*inAssigns,
|
||||||
fmt.Sprintf(" lda %s+1", sym.FullName()),
|
fmt.Sprintf(" lda %s+1", sym.FullName()),
|
||||||
fmt.Sprintf(" sta %s+1", param.Symbol.FullName()),
|
fmt.Sprintf(" sta %s+1", param.Symbol.FullName()),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
// byte -> word: zero extend
|
||||||
|
*inAssigns = append(*inAssigns,
|
||||||
|
" lda #0",
|
||||||
|
fmt.Sprintf(" sta %s+1", param.Symbol.FullName()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if sym.IsWord() {
|
||||||
|
// word -> byte: lossy
|
||||||
|
fmt.Printf("%s:%d: warning: CALL %s: truncating word '%s' to byte parameter '%s'\n",
|
||||||
|
line.Filename, line.LineNo, funcName, sym.Name, param.Symbol.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate OUT assignments
|
// Generate OUT assignments (param -> sym)
|
||||||
if param.Direction.Has(DirOut) {
|
if param.Direction.Has(DirOut) {
|
||||||
*outAssigns = append(*outAssigns,
|
*outAssigns = append(*outAssigns,
|
||||||
fmt.Sprintf(" lda %s", param.Symbol.FullName()),
|
fmt.Sprintf(" lda %s", param.Symbol.FullName()),
|
||||||
fmt.Sprintf(" sta %s", sym.FullName()),
|
fmt.Sprintf(" sta %s", sym.FullName()),
|
||||||
)
|
)
|
||||||
if sym.IsWord() {
|
if sym.IsWord() {
|
||||||
|
if param.Symbol.IsWord() {
|
||||||
*outAssigns = append(*outAssigns,
|
*outAssigns = append(*outAssigns,
|
||||||
fmt.Sprintf(" lda %s+1", param.Symbol.FullName()),
|
fmt.Sprintf(" lda %s+1", param.Symbol.FullName()),
|
||||||
fmt.Sprintf(" sta %s+1", sym.FullName()),
|
fmt.Sprintf(" sta %s+1", sym.FullName()),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
// byte -> word: zero extend
|
||||||
|
*outAssigns = append(*outAssigns,
|
||||||
|
" lda #0",
|
||||||
|
fmt.Sprintf(" sta %s+1", sym.FullName()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if param.Symbol.IsWord() {
|
||||||
|
// word -> byte: lossy
|
||||||
|
fmt.Printf("%s:%d: warning: CALL %s: truncating word parameter '%s' to byte '%s'\n",
|
||||||
|
line.Filename, line.LineNo, funcName, param.Symbol.Name, sym.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -587,6 +587,8 @@ func TestHandleFuncCall_Errors(t *testing.T) {
|
||||||
line: "CALL test ( 1 2 )",
|
line: "CALL test ( 1 2 )",
|
||||||
wantErr: "expected 1 arguments, got 2",
|
wantErr: "expected 1 arguments, got 2",
|
||||||
},
|
},
|
||||||
|
//
|
||||||
|
/* This is no error anymore, just a warning.
|
||||||
{
|
{
|
||||||
name: "type mismatch",
|
name: "type mismatch",
|
||||||
setup: func(fh *FunctionHandler, st *SymbolTable) {
|
setup: func(fh *FunctionHandler, st *SymbolTable) {
|
||||||
|
|
@ -596,7 +598,7 @@ func TestHandleFuncCall_Errors(t *testing.T) {
|
||||||
},
|
},
|
||||||
line: "CALL test ( wvar )",
|
line: "CALL test ( wvar )",
|
||||||
wantErr: "type mismatch",
|
wantErr: "type mismatch",
|
||||||
},
|
}, */
|
||||||
{
|
{
|
||||||
name: "const to out param",
|
name: "const to out param",
|
||||||
setup: func(fh *FunctionHandler, st *SymbolTable) {
|
setup: func(fh *FunctionHandler, st *SymbolTable) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue