They look a lot like placeholders, but they exist before the typing system takes place. And there's a (much smaller) context to deal with. For now, removes Placeholders in user function definitions as they were not implemented. Adds signature to function to try to get them closer to type class methods. Already seeing some benefit in the constraint generator. Stricter zipping for safety.
344 lines
7.3 KiB
Markdown
344 lines
7.3 KiB
Markdown
# runtime_extract_value_literal
|
|
|
|
As a developer
|
|
I want to extract a $TYPE value
|
|
In order get the result I calculated with my phasm code
|
|
|
|
```py
|
|
@exported
|
|
def testEntry() -> $TYPE:
|
|
return $VAL0
|
|
```
|
|
|
|
```py
|
|
expect(VAL0)
|
|
```
|
|
|
|
# runtime_extract_value_round_trip
|
|
|
|
As a developer
|
|
I want to extract a $TYPE value that I've input
|
|
In order let the code select a value that I've predefined
|
|
|
|
```py
|
|
@exported
|
|
def testEntry(x: $TYPE) -> $TYPE:
|
|
return x
|
|
```
|
|
|
|
```py
|
|
expect(VAL0, given=[VAL0])
|
|
```
|
|
|
|
# module_constant_def_ok
|
|
|
|
As a developer
|
|
I want to define $TYPE module constants
|
|
In order to make hardcoded values more visible
|
|
and to make it easier to change hardcoded values
|
|
|
|
```py
|
|
CONSTANT: $TYPE = $VAL0
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return 9
|
|
```
|
|
|
|
```py
|
|
expect(9)
|
|
```
|
|
|
|
# module_constant_def_bad
|
|
|
|
As a developer
|
|
I want to receive a type error on an invalid assignment on a $TYPE module constant
|
|
In order to make debugging easier
|
|
|
|
```py
|
|
CONSTANT: (u32, ) = $VAL0
|
|
```
|
|
|
|
```py
|
|
if TYPE_NAME.startswith('tuple_') or TYPE_NAME.startswith('static_array_'):
|
|
expect_type_error(
|
|
'Tuple element count mismatch',
|
|
'The given literal must fit the expected type',
|
|
)
|
|
else:
|
|
expect_type_error(
|
|
'Must be tuple',
|
|
'The given literal must fit the expected type',
|
|
)
|
|
```
|
|
|
|
# function_result_is_literal_ok
|
|
|
|
As a developer
|
|
I want to use return a literal from a function
|
|
In order to define constants in a more dynamic way
|
|
|
|
```py
|
|
def drop_arg_return_9(x: $TYPE) -> i32:
|
|
return 9
|
|
|
|
def constant() -> $TYPE:
|
|
return $VAL0
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return drop_arg_return_9(constant())
|
|
```
|
|
|
|
```py
|
|
expect(9)
|
|
```
|
|
|
|
# function_result_is_literal_bad
|
|
|
|
As a developer
|
|
I want to receive a type error when returning a $TYPE literal for a function that doesn't return that type
|
|
In order to make debugging easier
|
|
|
|
```py
|
|
def drop_arg_return_9(x: (u32, )) -> i32:
|
|
return 9
|
|
|
|
def constant() -> (u32, ):
|
|
return $VAL0
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return drop_arg_return_9(constant())
|
|
```
|
|
|
|
```py
|
|
if TYPE_NAME.startswith('tuple_') or TYPE_NAME.startswith('static_array_'):
|
|
expect_type_error(
|
|
'Mismatch between applied types argument count',
|
|
'The type of a tuple is a combination of its members',
|
|
)
|
|
elif TYPE_NAME.startswith('struct_'):
|
|
expect_type_error(
|
|
TYPE + ' must be (u32, ) instead',
|
|
'The type of the value returned from function constant should match its return type',
|
|
)
|
|
else:
|
|
expect_type_error(
|
|
'Must be tuple',
|
|
'The given literal must fit the expected type',
|
|
)
|
|
```
|
|
|
|
# function_result_is_module_constant_ok
|
|
|
|
As a developer
|
|
I want to use return a $TYPE module constant from a function
|
|
In order to use my module constants in return statements
|
|
|
|
```py
|
|
CONSTANT: $TYPE = $VAL0
|
|
|
|
def helper(x: $TYPE) -> i32:
|
|
return 9
|
|
|
|
def constant() -> $TYPE:
|
|
return CONSTANT
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(constant())
|
|
```
|
|
|
|
```py
|
|
expect(9)
|
|
```
|
|
|
|
# function_result_is_module_constant_bad
|
|
|
|
As a developer
|
|
I want to receive a type error when returning a $TYPE module constant for a function that doesn't return that type
|
|
In order to make debugging easier
|
|
|
|
```py
|
|
CONSTANT: $TYPE = $VAL0
|
|
|
|
def drop_arg_return_9(x: (u32, )) -> i32:
|
|
return 9
|
|
|
|
def constant() -> (u32, ):
|
|
return CONSTANT
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return drop_arg_return_9(constant())
|
|
```
|
|
|
|
```py
|
|
if TYPE_NAME.startswith('tuple_') or TYPE_NAME.startswith('static_array_') or TYPE_NAME.startswith('struct_'):
|
|
expect_type_error(
|
|
TYPE + ' must be (u32, ) instead',
|
|
'The type of the value returned from function constant should match its return type',
|
|
)
|
|
else:
|
|
expect_type_error(
|
|
TYPE_NAME + ' must be (u32, ) instead',
|
|
'The type of the value returned from function constant should match its return type',
|
|
)
|
|
```
|
|
|
|
# function_result_is_arg_ok
|
|
|
|
As a developer
|
|
I want to use return a $TYPE function argument
|
|
In order to make it possible to select a value using a function
|
|
|
|
```py
|
|
CONSTANT: $TYPE = $VAL0
|
|
|
|
def drop_arg_return_9(x: $TYPE) -> i32:
|
|
return 9
|
|
|
|
def select(x: $TYPE) -> $TYPE:
|
|
return x
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return drop_arg_return_9(select(CONSTANT))
|
|
```
|
|
|
|
```py
|
|
expect(9)
|
|
```
|
|
|
|
# function_result_is_arg_bad
|
|
|
|
As a developer
|
|
I want to receive a type error when returning a $TYPE argument for a function that doesn't return that type
|
|
In order to make debugging easier
|
|
|
|
```py
|
|
def drop_arg_return_9(x: (u32, )) -> i32:
|
|
return 9
|
|
|
|
def select(x: $TYPE) -> (u32, ):
|
|
return x
|
|
```
|
|
|
|
```py
|
|
if TYPE_NAME.startswith('tuple_') or TYPE_NAME.startswith('static_array_') or TYPE_NAME.startswith('struct_'):
|
|
expect_type_error(
|
|
TYPE + ' must be (u32, ) instead',
|
|
'The type of the value returned from function select should match its return type',
|
|
)
|
|
else:
|
|
expect_type_error(
|
|
TYPE_NAME + ' must be (u32, ) instead',
|
|
'The type of the value returned from function select should match its return type',
|
|
)
|
|
```
|
|
|
|
# function_arg_literal_ok
|
|
|
|
As a developer
|
|
I want to use a $TYPE literal by passing it to a function
|
|
In order to use a pre-existing function with the values I specify
|
|
|
|
```py
|
|
def helper(x: $TYPE) -> i32:
|
|
return 9
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper($VAL0)
|
|
```
|
|
|
|
```py
|
|
expect(9)
|
|
```
|
|
|
|
# function_arg_literal_bad
|
|
|
|
As a developer
|
|
I want to receive a type error when passing a $TYPE literal to a function that does not accept it
|
|
In order to make debugging easier
|
|
|
|
```py
|
|
def helper(x: (u32, )) -> i32:
|
|
return 9
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper($VAL0)
|
|
```
|
|
|
|
```py
|
|
if TYPE_NAME.startswith('tuple_') or TYPE_NAME.startswith('static_array_'):
|
|
expect_type_error(
|
|
'Mismatch between applied types argument count',
|
|
# FIXME: Shouldn't this be the same as for the else statement?
|
|
'The type of a tuple is a combination of its members',
|
|
)
|
|
elif TYPE_NAME.startswith('struct_'):
|
|
expect_type_error(
|
|
TYPE + ' must be (u32, ) instead',
|
|
'The type of the value passed to argument x of function helper should match the type of that argument',
|
|
)
|
|
else:
|
|
expect_type_error(
|
|
'Must be tuple',
|
|
'The given literal must fit the expected type',
|
|
)
|
|
```
|
|
|
|
# function_arg_module_constant_def_ok
|
|
|
|
As a developer
|
|
I want to use a $TYPE module constant by passing it to a function
|
|
In order to use my defined value with a pre-existing function
|
|
|
|
```py
|
|
CONSTANT: $TYPE = $VAL0
|
|
|
|
def helper(x: $TYPE) -> i32:
|
|
return 9
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(CONSTANT)
|
|
```
|
|
|
|
```py
|
|
expect(9)
|
|
```
|
|
|
|
# function_arg_module_constant_def_bad
|
|
|
|
As a developer
|
|
I want to receive a type error when passing a $TYPE module constant to a function that does not accept it
|
|
In order to make debugging easier
|
|
|
|
```py
|
|
CONSTANT: $TYPE = $VAL0
|
|
|
|
def helper(x: (u32, )) -> i32:
|
|
return 9
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(CONSTANT)
|
|
```
|
|
|
|
```py
|
|
if TYPE_NAME.startswith('tuple_') or TYPE_NAME.startswith('static_array_') or TYPE_NAME.startswith('struct_'):
|
|
expect_type_error(
|
|
TYPE + ' must be (u32, ) instead',
|
|
'The type of the value passed to argument 0 of function helper should match the type of that argument',
|
|
)
|
|
else:
|
|
expect_type_error(
|
|
TYPE_NAME + ' must be (u32, ) instead',
|
|
'The type of the value passed to argument 0 of function helper should match the type of that argument',
|
|
)
|
|
```
|