/* ----------------------------------------------------------------------------- Copyright 2020 Kevin P. Barry Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ----------------------------------------------------------------------------- */ // Author: Kevin P. Barry [ta0kira@gmail.com] testcase "missing assign" { error require "value" } @value interface Value {} concrete Test {} define Test { @value process () -> (Value) process () (value) {} } testcase "assign before logical" { compiles } concrete Test {} define Test { @value process () -> (Bool) process () (value) { \ (value <- true) || false } } testcase "assign after logical" { error require "value.+initialized" } concrete Test {} define Test { @value process () -> (Bool) process () (value) { \ false || (value <- true) } } testcase "assign before arithmetic" { compiles } concrete Test {} define Test { @value process () -> (Int) process () (value) { \ (value <- 1) + 2 } } testcase "assign after arithmetic" { compiles } concrete Test {} define Test { @value process () -> (Int) process () (value) { \ 2 + (value <- 1) } } testcase "return used before assigned" { error require "value.+initialized" } concrete Test {} define Test { @category process () -> (Int) process () (value) { value <- value+1 } } testcase "return used after assigned" { success } unittest test { Int value <- Test:process() if (value != 2) { fail("Failed") } } concrete Test { @category process () -> (Int) } define Test { process () (value) { value <- 1 value <- value+1 } } testcase "return used as return before assigned" { error require "value.+initialized" } concrete Test {} define Test { @category process () -> (Int) process () (value) { return value } } testcase "explicit return with named" { compiles } concrete Test {} define Test { @category process () -> (Int) process () (value) { return 1 } } testcase "empty return with named" { error require "value.+initialized" } concrete Test {} define Test { @category process () -> (Int) process () (value) { return _ } } testcase "returns in correct order" { success } unittest test { scoped { Int x, Int y <- Test.get() } in if (x != 1) { fail("Failed") } elif (y != 2) { fail("Failed") } } concrete Test { @type get () -> (Int,Int) } define Test { get () { return 1, 2 } } testcase "assigns in correct order" { success } unittest test { scoped { _, Int x, Int y <- Test.get() } in if (x != 1) { fail("Failed") } elif (y != 2) { fail("Failed") } } concrete Value { @type create () -> (Value) } define Value { create () { return Value{ } } } concrete Test { @type get () -> (Value,Int,Int) } define Test { get () (v,x,y) { // This makes sure that x and y (primitive) are offset. v <- Value.create() x <- 1 y <- 2 } } testcase "assigns in correct order with explicit return" { success } unittest test { scoped { Int x, Int y <- Test.get() } in if (x != 1) { fail("Failed") } elif (y != 2) { fail("Failed") } } concrete Test { @type get () -> (Int,Int) } define Test { get () (x,y) { x <- 1 y <- 2 return _ } } testcase "positional return sets named return" { crash require "message" } unittest test { \ Test.get() } concrete Test { @type get () -> (String) } define Test { get () (value) { cleanup { fail(value) } in return "message" } }