diff --git a/src/core/CompileReturn.go b/src/core/CompileReturn.go index ab901f2..8fa72c8 100644 --- a/src/core/CompileReturn.go +++ b/src/core/CompileReturn.go @@ -14,6 +14,10 @@ func (f *Function) CompileReturn(node *ast.Return) error { return nil } + if len(node.Values) != len(f.ReturnTypes) { + return errors.New(&errors.ReturnCountMismatch{Count: len(node.Values), ExpectedCount: len(f.ReturnTypes)}, f.File, node.Values[0].Token.Position) + } + for i := len(node.Values) - 1; i >= 0; i-- { typ, err := f.ExpressionToRegister(node.Values[i], f.CPU.Output[i]) diff --git a/src/errors/ReturnCountMismatch.go b/src/errors/ReturnCountMismatch.go new file mode 100644 index 0000000..726f63d --- /dev/null +++ b/src/errors/ReturnCountMismatch.go @@ -0,0 +1,26 @@ +package errors + +import "fmt" + +// ReturnCountMismatch error is created when the number of returned values doesn't match the return type. +type ReturnCountMismatch struct { + Count int + ExpectedCount int +} + +// Error generates the string representation. +func (err *ReturnCountMismatch) Error() string { + values := "values" + + if err.Count == 1 { + values = "value" + } + + types := "types" + + if err.ExpectedCount == 1 { + types = "type" + } + + return fmt.Sprintf("Returns %d %s in a function with %d return %s", err.Count, values, err.ExpectedCount, types) +} diff --git a/tests/errors/ReturnCountMismatch.q b/tests/errors/ReturnCountMismatch.q new file mode 100644 index 0000000..eea1ba5 --- /dev/null +++ b/tests/errors/ReturnCountMismatch.q @@ -0,0 +1,3 @@ +main() { + return 42 +} \ No newline at end of file diff --git a/tests/errors_test.go b/tests/errors_test.go index 7ecdddc..9de4094 100644 --- a/tests/errors_test.go +++ b/tests/errors_test.go @@ -37,7 +37,7 @@ var errs = []struct { {"MissingMainFunction.q", errors.MissingMainFunction}, {"MissingOperand.q", errors.MissingOperand}, {"MissingOperand2.q", errors.MissingOperand}, - {"VariableAlreadyExists.q", &errors.VariableAlreadyExists{Name: "x"}}, + {"ReturnCountMismatch.q", &errors.ReturnCountMismatch{Count: 1, ExpectedCount: 0}}, {"TypeMismatch.q", &errors.TypeMismatch{Expected: "Pointer", Encountered: "Int64", ParameterName: "p"}}, {"UnknownFunction.q", &errors.UnknownFunction{Name: "unknown"}}, {"UnknownFunction2.q", &errors.UnknownFunction{Name: "f"}}, @@ -47,6 +47,7 @@ var errs = []struct { {"UnknownPackage.q", &errors.UnknownPackage{Name: "sys"}}, {"UnusedImport.q", &errors.UnusedImport{Package: "sys"}}, {"UnusedVariable.q", &errors.UnusedVariable{Name: "x"}}, + {"VariableAlreadyExists.q", &errors.VariableAlreadyExists{Name: "x"}}, } func TestErrors(t *testing.T) {