lang: ast: The res and edge names should not use exclusives
This removes the exclusive from the res names and edge names. We now require that the names should be lists of strings, however they can still be single strings if that can be determined statically. Programmers should explicitly wrap their variables in a string by interpolation to force this, or in square brackets to force a list. The former is generally preferable because it generates a small function graph since it doesn't need to build a list.
This commit is contained in:
@@ -283,6 +283,14 @@ one of many ways you can perform iterative tasks that you might have
|
|||||||
traditionally used a `for` loop for instead. This is preferred, because flow
|
traditionally used a `for` loop for instead. This is preferred, because flow
|
||||||
control is error-prone and can make for less readable code.
|
control is error-prone and can make for less readable code.
|
||||||
|
|
||||||
|
The single `str` variation, may only be used when it is possible for the
|
||||||
|
compiler to determine statically that the value is of that type. Otherwise, it
|
||||||
|
will assume it to be a list of strings. Programmers should explicitly wrap their
|
||||||
|
variables in a string by interpolation to force this static `str` determination,
|
||||||
|
or in square brackets to force a list. The former is generally preferable
|
||||||
|
because it generates a smaller function graph since it doesn't need to build a
|
||||||
|
list.
|
||||||
|
|
||||||
##### Internal edges
|
##### Internal edges
|
||||||
|
|
||||||
Resources may also declare edges internally. The edges may point to or from
|
Resources may also declare edges internally. The edges may point to or from
|
||||||
@@ -337,6 +345,28 @@ to express a relationship between three resources. The first character in the
|
|||||||
resource kind must be capitalized so that the parser can't ascertain
|
resource kind must be capitalized so that the parser can't ascertain
|
||||||
unambiguously that we are referring to a dependency relationship.
|
unambiguously that we are referring to a dependency relationship.
|
||||||
|
|
||||||
|
##### Edge naming
|
||||||
|
|
||||||
|
Each edge must have a unique name of type `str` that is used to uniquely
|
||||||
|
identify that edge, and can be used in the functioning of the edge at its
|
||||||
|
discretion.
|
||||||
|
|
||||||
|
Alternatively, the name value may be a list of strings `[]str` to build a list
|
||||||
|
of edges, each with a name from that list.
|
||||||
|
|
||||||
|
Using this construct is a veiled form of looping (iteration). This technique is
|
||||||
|
one of many ways you can perform iterative tasks that you might have
|
||||||
|
traditionally used a `for` loop for instead. This is preferred, because flow
|
||||||
|
control is error-prone and can make for less readable code.
|
||||||
|
|
||||||
|
The single `str` variation, may only be used when it is possible for the
|
||||||
|
compiler to determine statically that the value is of that type. Otherwise, it
|
||||||
|
will assume it to be a list of strings. Programmers should explicitly wrap their
|
||||||
|
variables in a string by interpolation to force this static `str` determination,
|
||||||
|
or in square brackets to force a list. The former is generally preferable
|
||||||
|
because it generates a smaller function graph since it doesn't need to build a
|
||||||
|
list.
|
||||||
|
|
||||||
#### Class
|
#### Class
|
||||||
|
|
||||||
A class is a grouping structure that bind's a list of statements to a name in
|
A class is a grouping structure that bind's a list of statements to a name in
|
||||||
|
|||||||
@@ -326,6 +326,10 @@ func (obj *StmtBind) Output(map[interfaces.Func]types.Value) (*interfaces.Output
|
|||||||
// value can be a single string or a list of strings. The former will produce a
|
// value can be a single string or a list of strings. The former will produce a
|
||||||
// single resource, the latter produces a list of resources. Using this list
|
// single resource, the latter produces a list of resources. Using this list
|
||||||
// mechanism is a safe alternative to traditional flow control like `for` loops.
|
// mechanism is a safe alternative to traditional flow control like `for` loops.
|
||||||
|
// The `Name` value can only be a single string when it can be detected
|
||||||
|
// statically. Otherwise, it is assumed that a list of strings should be
|
||||||
|
// expected. More mechanisms to determine if the value is static may be added
|
||||||
|
// over time.
|
||||||
// TODO: Consider expanding Name to have this return a list of Res's in the
|
// TODO: Consider expanding Name to have this return a list of Res's in the
|
||||||
// Output function if it is a map[name]struct{}, or even a map[[]name]struct{}.
|
// Output function if it is a map[name]struct{}, or even a map[[]name]struct{}.
|
||||||
type StmtRes struct {
|
type StmtRes struct {
|
||||||
@@ -576,39 +580,35 @@ func (obj *StmtRes) Unify() ([]interfaces.Invariant, error) {
|
|||||||
}
|
}
|
||||||
invariants = append(invariants, invars...)
|
invariants = append(invariants, invars...)
|
||||||
|
|
||||||
invarStr := &interfaces.EqualsInvariant{
|
|
||||||
Expr: obj.Name,
|
|
||||||
Type: types.TypeStr,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimization: If we know it's an str, no need for exclusives!
|
// Optimization: If we know it's an str, no need for exclusives!
|
||||||
|
// TODO: Check other cases, like if it's a function call, and we know it
|
||||||
|
// can only return a single string. (Eg: fmt.printf for example.)
|
||||||
|
isString := false
|
||||||
if _, ok := obj.Name.(*ExprStr); ok {
|
if _, ok := obj.Name.(*ExprStr); ok {
|
||||||
invariants = append(invariants, invarStr)
|
// It's a string! (A plain string was specified.)
|
||||||
|
isString = true
|
||||||
|
}
|
||||||
|
if typ, err := obj.Name.Type(); err == nil {
|
||||||
|
// It has type of string! (Might be an interpolation specified.)
|
||||||
|
if typ.Cmp(types.TypeStr) == nil {
|
||||||
|
isString = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isString {
|
||||||
|
invar := &interfaces.EqualsInvariant{
|
||||||
|
Expr: obj.Name,
|
||||||
|
Type: types.TypeStr,
|
||||||
|
}
|
||||||
|
invariants = append(invariants, invar)
|
||||||
|
|
||||||
return invariants, nil
|
return invariants, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
invarListStr := &interfaces.EqualsInvariant{
|
// Down here, we only allow []str, no need for exclusives!
|
||||||
|
invar := &interfaces.EqualsInvariant{
|
||||||
Expr: obj.Name,
|
Expr: obj.Name,
|
||||||
Type: types.TypeListStr,
|
Type: types.TypeListStr,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimization: If we know it's a []str, no need for exclusives!
|
|
||||||
if expr, ok := obj.Name.(*ExprList); ok {
|
|
||||||
typ, err := expr.Type()
|
|
||||||
if err == nil && typ.Cmp(types.TypeListStr) == nil {
|
|
||||||
invariants = append(invariants, invarListStr)
|
|
||||||
return invariants, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// name must be a string or a list
|
|
||||||
ors := []interfaces.Invariant{}
|
|
||||||
ors = append(ors, invarStr)
|
|
||||||
ors = append(ors, invarListStr)
|
|
||||||
|
|
||||||
invar := &interfaces.ExclusiveInvariant{
|
|
||||||
Invariants: ors, // one and only one of these should be true
|
|
||||||
}
|
|
||||||
invariants = append(invariants, invar)
|
invariants = append(invariants, invar)
|
||||||
|
|
||||||
return invariants, nil
|
return invariants, nil
|
||||||
@@ -2379,7 +2379,13 @@ func (obj *StmtEdge) Output(table map[interfaces.Func]types.Value) (*interfaces.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StmtEdgeHalf represents half of an edge in the parsed edge representation.
|
// StmtEdgeHalf represents half of an edge in the parsed edge representation.
|
||||||
// This does not satisfy the Stmt interface.
|
// This does not satisfy the Stmt interface. The `Name` value can be a single
|
||||||
|
// string or a list of strings. The former will produce a single edge half, the
|
||||||
|
// latter produces a list of resources. Using this list mechanism is a safe
|
||||||
|
// alternative to traditional flow control like `for` loops. The `Name` value
|
||||||
|
// can only be a single string when it can be detected statically. Otherwise, it
|
||||||
|
// is assumed that a list of strings should be expected. More mechanisms to
|
||||||
|
// determine if the value is static may be added over time.
|
||||||
type StmtEdgeHalf struct {
|
type StmtEdgeHalf struct {
|
||||||
Kind string // kind of resource, eg: pkg, file, svc, etc...
|
Kind string // kind of resource, eg: pkg, file, svc, etc...
|
||||||
Name interfaces.Expr // unique name for the res of this kind
|
Name interfaces.Expr // unique name for the res of this kind
|
||||||
@@ -2488,39 +2494,35 @@ func (obj *StmtEdgeHalf) Unify() ([]interfaces.Invariant, error) {
|
|||||||
}
|
}
|
||||||
invariants = append(invariants, invars...)
|
invariants = append(invariants, invars...)
|
||||||
|
|
||||||
invarStr := &interfaces.EqualsInvariant{
|
|
||||||
Expr: obj.Name,
|
|
||||||
Type: types.TypeStr,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimization: If we know it's an str, no need for exclusives!
|
// Optimization: If we know it's an str, no need for exclusives!
|
||||||
|
// TODO: Check other cases, like if it's a function call, and we know it
|
||||||
|
// can only return a single string. (Eg: fmt.printf for example.)
|
||||||
|
isString := false
|
||||||
if _, ok := obj.Name.(*ExprStr); ok {
|
if _, ok := obj.Name.(*ExprStr); ok {
|
||||||
invariants = append(invariants, invarStr)
|
// It's a string! (A plain string was specified.)
|
||||||
|
isString = true
|
||||||
|
}
|
||||||
|
if typ, err := obj.Name.Type(); err == nil {
|
||||||
|
// It has type of string! (Might be an interpolation specified.)
|
||||||
|
if typ.Cmp(types.TypeStr) == nil {
|
||||||
|
isString = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isString {
|
||||||
|
invar := &interfaces.EqualsInvariant{
|
||||||
|
Expr: obj.Name,
|
||||||
|
Type: types.TypeStr,
|
||||||
|
}
|
||||||
|
invariants = append(invariants, invar)
|
||||||
|
|
||||||
return invariants, nil
|
return invariants, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
invarListStr := &interfaces.EqualsInvariant{
|
// Down here, we only allow []str, no need for exclusives!
|
||||||
|
invar := &interfaces.EqualsInvariant{
|
||||||
Expr: obj.Name,
|
Expr: obj.Name,
|
||||||
Type: types.TypeListStr,
|
Type: types.TypeListStr,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimization: If we know it's a []str, no need for exclusives!
|
|
||||||
if expr, ok := obj.Name.(*ExprList); ok {
|
|
||||||
typ, err := expr.Type()
|
|
||||||
if err == nil && typ.Cmp(types.TypeListStr) == nil {
|
|
||||||
invariants = append(invariants, invarListStr)
|
|
||||||
return invariants, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// name must be a string or a list
|
|
||||||
ors := []interfaces.Invariant{}
|
|
||||||
ors = append(ors, invarStr)
|
|
||||||
ors = append(ors, invarListStr)
|
|
||||||
|
|
||||||
invar := &interfaces.ExclusiveInvariant{
|
|
||||||
Invariants: ors, // one and only one of these should be true
|
|
||||||
}
|
|
||||||
invariants = append(invariants, invar)
|
invariants = append(invariants, invar)
|
||||||
|
|
||||||
return invariants, nil
|
return invariants, nil
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class base($config) {
|
|||||||
panic($prefix == "") # panic if prefix is empty
|
panic($prefix == "") # panic if prefix is empty
|
||||||
panic(not strings.has_suffix($prefix, "/"))
|
panic(not strings.has_suffix($prefix, "/"))
|
||||||
|
|
||||||
file $prefix { # dir
|
file "${prefix}" { # dir
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
}
|
}
|
||||||
$tftp_prefix = "${prefix}${tftp_suffix}"
|
$tftp_prefix = "${prefix}${tftp_suffix}"
|
||||||
@@ -85,7 +85,7 @@ class base($config) {
|
|||||||
#
|
#
|
||||||
# network
|
# network
|
||||||
#
|
#
|
||||||
net $interface {
|
net "${interface}" {
|
||||||
state => $const.res.net.state.up,
|
state => $const.res.net.state.up,
|
||||||
addrs => [$router,], # has cidr suffix
|
addrs => [$router,], # has cidr suffix
|
||||||
#gateway => "192.168.42.1", # TODO: get upstream public gateway with new function
|
#gateway => "192.168.42.1", # TODO: get upstream public gateway with new function
|
||||||
@@ -130,10 +130,10 @@ class base($config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file $tftp_prefix { # dir
|
file "${tftp_prefix}" { # dir
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
}
|
}
|
||||||
file $uefi_prefix { # dir
|
file "${uefi_prefix}" { # dir
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ class base($config) {
|
|||||||
|
|
||||||
# XXX: should this also be part of repo too?
|
# XXX: should this also be part of repo too?
|
||||||
class tftp_root_file($f) {
|
class tftp_root_file($f) {
|
||||||
#tftp:file $f { # without root slash
|
#tftp:file "${f}" { # without root slash
|
||||||
tftp:file "/${f}" { # with root slash
|
tftp:file "/${f}" { # with root slash
|
||||||
path => $syslinux_root + $f, # TODO: add autoedges
|
path => $syslinux_root + $f, # TODO: add autoedges
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ class base($config) {
|
|||||||
#
|
#
|
||||||
# http
|
# http
|
||||||
#
|
#
|
||||||
file $http_prefix { # dir
|
file "${http_prefix}" { # dir
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ class base($config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$kickstart_http_prefix = "${http_prefix}${kickstart_suffix}"
|
$kickstart_http_prefix = "${http_prefix}${kickstart_suffix}"
|
||||||
file $kickstart_http_prefix {
|
file "${kickstart_http_prefix}" {
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
#source => "", # this default means empty directory
|
#source => "", # this default means empty directory
|
||||||
recurse => true,
|
recurse => true,
|
||||||
@@ -237,21 +237,21 @@ class base:repo($config) {
|
|||||||
$distroarch_release_http_prefix = "${distroarch_http_prefix}release/"
|
$distroarch_release_http_prefix = "${distroarch_http_prefix}release/"
|
||||||
$distroarch_updates_http_prefix = "${distroarch_http_prefix}updates/"
|
$distroarch_updates_http_prefix = "${distroarch_http_prefix}updates/"
|
||||||
|
|
||||||
file $distroarch_tftp_prefix { # dir
|
file "${distroarch_tftp_prefix}" { # dir
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
|
|
||||||
#Meta:quiet => true, # TODO
|
#Meta:quiet => true, # TODO
|
||||||
}
|
}
|
||||||
file $distroarch_uefi_prefix { # dir
|
file "${distroarch_uefi_prefix}" { # dir
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
}
|
}
|
||||||
file $distroarch_http_prefix { # root http dir
|
file "${distroarch_http_prefix}" { # root http dir
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
}
|
}
|
||||||
file $distroarch_release_http_prefix {
|
file "${distroarch_release_http_prefix}" {
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
}
|
}
|
||||||
file $distroarch_updates_http_prefix {
|
file "${distroarch_updates_http_prefix}" {
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ class base:repo($config) {
|
|||||||
$uefi_download_dir = "${distroarch_uefi_prefix}download/"
|
$uefi_download_dir = "${distroarch_uefi_prefix}download/"
|
||||||
$uefi_extract_dir = "${distroarch_uefi_prefix}extract/"
|
$uefi_extract_dir = "${distroarch_uefi_prefix}extract/"
|
||||||
|
|
||||||
file $uefi_extract_dir { # mkdir
|
file "${uefi_extract_dir}" { # mkdir
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
|
|
||||||
Depend => Exec["uefi-download-${uid}"],
|
Depend => Exec["uefi-download-${uid}"],
|
||||||
@@ -609,7 +609,7 @@ class base:host($name, $config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$kickstart_file = "${kickstart_http_prefix}${hkey}.ks"
|
$kickstart_file = "${kickstart_http_prefix}${hkey}.ks"
|
||||||
file $kickstart_file {
|
file "${kickstart_file}" {
|
||||||
state => $const.res.file.state.exists,
|
state => $const.res.file.state.exists,
|
||||||
content => template(deploy.readfile("/files/kickstart.ks.tmpl"), $http_kickstart_template),
|
content => template(deploy.readfile("/files/kickstart.ks.tmpl"), $http_kickstart_template),
|
||||||
}
|
}
|
||||||
@@ -631,11 +631,11 @@ class base:host($name, $config) {
|
|||||||
#kv "${name}" {
|
#kv "${name}" {
|
||||||
# key => $provision_key,
|
# key => $provision_key,
|
||||||
#}
|
#}
|
||||||
#value $provision_key {
|
#value "${provision_key}" {
|
||||||
# #any => true, # bool
|
# #any => true, # bool
|
||||||
#}
|
#}
|
||||||
#Http:Flag["${name}"].value -> Kv["${name}"].value
|
#Http:Flag["${name}"].value -> Kv["${name}"].value
|
||||||
#Http:Flag["${name}"].value -> Value[$provision_key].any
|
#Http:Flag["${name}"].value -> Value["${provision_key}"].any
|
||||||
##$st_provisioned = value.get_bool($provision_key)
|
##$st_provisioned = value.get_bool($provision_key)
|
||||||
#$st_provisioned = value.get_str($provision_key)
|
#$st_provisioned = value.get_str($provision_key)
|
||||||
#$provisioned = $st_provisioned->ready and $st_provisioned->value == "true" # export this value to parent scope
|
#$provisioned = $st_provisioned->ready and $st_provisioned->value == "true" # export this value to parent scope
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ $fn2 = funcgen(false)
|
|||||||
$out1 = $fn1()
|
$out1 = $fn1()
|
||||||
$out2 = $fn2()
|
$out2 = $fn2()
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
test $out2 {}
|
test "${out2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ import "fmt"
|
|||||||
|
|
||||||
include c1([13, 42, 0, -37,])
|
include c1([13, 42, 0, -37,])
|
||||||
class c1($b) {
|
class c1($b) {
|
||||||
test fmt.printf("len is: %d", len($b)) {} # len is 4
|
test [fmt.printf("len is: %d", len($b)),] {} # len is 4
|
||||||
}
|
}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
|
Edge: call -> composite # 0
|
||||||
Edge: const -> composite # 0
|
Edge: const -> composite # 0
|
||||||
Edge: const -> composite # 1
|
Edge: const -> composite # 1
|
||||||
Edge: const -> composite # 2
|
Edge: const -> composite # 2
|
||||||
@@ -17,6 +18,7 @@ Vertex: FuncValue
|
|||||||
Vertex: call
|
Vertex: call
|
||||||
Vertex: call
|
Vertex: call
|
||||||
Vertex: composite
|
Vertex: composite
|
||||||
|
Vertex: composite
|
||||||
Vertex: const
|
Vertex: const
|
||||||
Vertex: const
|
Vertex: const
|
||||||
Vertex: const
|
Vertex: const
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ $some_value1 = 42 # or something more complex like the output of a slow function
|
|||||||
class foo($num) {
|
class foo($num) {
|
||||||
# we should have a different `$inside` value for each use of this class
|
# we should have a different `$inside` value for each use of this class
|
||||||
$inside = $some_value1 + $some_value2 + 4
|
$inside = $some_value1 + $some_value2 + 4
|
||||||
test fmt.printf("test-%d-%d", $num, $inside) {} # some resource
|
test [fmt.printf("test-%d-%d", $num, $inside),] {} # some resource
|
||||||
}
|
}
|
||||||
$some_value2 = 13 # check that non-ordering works too!
|
$some_value2 = 13 # check that non-ordering works too!
|
||||||
|
|
||||||
@@ -24,6 +24,9 @@ Edge: FuncValue -> call # fn
|
|||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
|
Edge: call -> composite # 0
|
||||||
|
Edge: call -> composite # 0
|
||||||
|
Edge: call -> composite # 0
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
@@ -42,6 +45,9 @@ Vertex: call
|
|||||||
Vertex: call
|
Vertex: call
|
||||||
Vertex: call
|
Vertex: call
|
||||||
Vertex: call
|
Vertex: call
|
||||||
|
Vertex: composite
|
||||||
|
Vertex: composite
|
||||||
|
Vertex: composite
|
||||||
Vertex: const
|
Vertex: const
|
||||||
Vertex: const
|
Vertex: const
|
||||||
Vertex: const
|
Vertex: const
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
include c1("t1")
|
include c1("t1")
|
||||||
include c1("t2")
|
include c1("t2")
|
||||||
class c1($a) {
|
class c1($a) {
|
||||||
test $a {
|
test "${a}" {
|
||||||
stringptr => $foo,
|
stringptr => $foo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ $prefixer = func($x) {
|
|||||||
$out1 = $prefixer("a")
|
$out1 = $prefixer("a")
|
||||||
$out2 = $prefixer("b")
|
$out2 = $prefixer("b")
|
||||||
|
|
||||||
test $out1 {} # helloa
|
test "${out1}" {} # helloa
|
||||||
test $out2 {} # hellob
|
test "${out2}" {} # hellob
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
# this is an empty list of test resources, iow test resources
|
# This is an empty list of test resources, iow test resources. This must pass
|
||||||
# this must pass type unification
|
# type unification. This previously only passed if we allowed recursive
|
||||||
# this can only currently pass if we allow recursive unification solving
|
# unification solving, but now we can support it without that.
|
||||||
# if we do, then the function graph is: `Vertex: list()` otherwise it's an error
|
|
||||||
test [] {}
|
test [] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errUnify: only recursive solutions left
|
Vertex: composite
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ $prefixer = func($x) {
|
|||||||
$out1 = $prefixer("world")
|
$out1 = $prefixer("world")
|
||||||
$out2 = $prefixer($out1)
|
$out2 = $prefixer($out1)
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
test $out2 {}
|
test "${out2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import "fmt"
|
|||||||
include c1("t1", "hello") # len is 5
|
include c1("t1", "hello") # len is 5
|
||||||
include c1("t2", [13, 42, 0, -37,]) # len is 4
|
include c1("t2", [13, 42, 0, -37,]) # len is 4
|
||||||
class c1($a, $b) {
|
class c1($a, $b) {
|
||||||
test $a {
|
test "${a}" {
|
||||||
anotherstr => fmt.printf("len is: %d", len($b)),
|
anotherstr => fmt.printf("len is: %d", len($b)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ include c1("t2", [13, 42, 0, -37,]) # len is 4
|
|||||||
|
|
||||||
# specifying a fixed type for $b is a compile error, because it's sometimes str!
|
# specifying a fixed type for $b is a compile error, because it's sometimes str!
|
||||||
class c1($a, $b []str) {
|
class c1($a, $b []str) {
|
||||||
test $a {
|
test "${a}" {
|
||||||
anotherstr => fmt.printf("len is: %d", len($b)),
|
anotherstr => fmt.printf("len is: %d", len($b)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ func funcgen() {
|
|||||||
$fn = funcgen()
|
$fn = funcgen()
|
||||||
$out = $fn()
|
$out = $fn()
|
||||||
|
|
||||||
test $out {}
|
test "${out}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: call -> call # fn
|
Edge: call -> call # fn
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ $funcgen = func() {
|
|||||||
$fn = $funcgen()
|
$fn = $funcgen()
|
||||||
$out = $fn()
|
$out = $fn()
|
||||||
|
|
||||||
test $out {}
|
test "${out}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: call -> call # fn
|
Edge: call -> call # fn
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ $x = "hello"
|
|||||||
if true {
|
if true {
|
||||||
$x = "world" # shadowed
|
$x = "world" # shadowed
|
||||||
}
|
}
|
||||||
test $x {}
|
test "${x}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: const
|
Vertex: const
|
||||||
Vertex: const
|
Vertex: const
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
$x = "hello"
|
$x = "hello"
|
||||||
if true {
|
if true {
|
||||||
$x = "world" # shadowed
|
$x = "world" # shadowed
|
||||||
test $x {}
|
test "${x}" {}
|
||||||
}
|
}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: const
|
Vertex: const
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ func answer() {
|
|||||||
|
|
||||||
$out1 = answer()
|
$out1 = answer()
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
|
|||||||
@@ -6,15 +6,17 @@ func answer() {
|
|||||||
$out1 = answer()
|
$out1 = answer()
|
||||||
$out2 = answer()
|
$out2 = answer()
|
||||||
|
|
||||||
test $out1 + $out2 {}
|
test [$out1 + $out2,] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
|
Edge: call -> composite # 0
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
Vertex: call
|
Vertex: call
|
||||||
Vertex: call
|
Vertex: call
|
||||||
Vertex: call
|
Vertex: call
|
||||||
|
Vertex: composite
|
||||||
Vertex: const
|
Vertex: const
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ $answer = func() {
|
|||||||
|
|
||||||
$out = $answer()
|
$out = $answer()
|
||||||
|
|
||||||
test $out {}
|
test "${out}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
|
|||||||
@@ -9,14 +9,16 @@ $answer = func() {
|
|||||||
$out1 = $answer()
|
$out1 = $answer()
|
||||||
$out2 = $answer()
|
$out2 = $answer()
|
||||||
|
|
||||||
test $out1 + $out2 {}
|
test [$out1 + $out2,] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
Edge: FuncValue -> call # fn
|
Edge: FuncValue -> call # fn
|
||||||
|
Edge: call -> composite # 0
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
Vertex: FuncValue
|
Vertex: FuncValue
|
||||||
Vertex: call
|
Vertex: call
|
||||||
Vertex: call
|
Vertex: call
|
||||||
Vertex: call
|
Vertex: call
|
||||||
|
Vertex: composite
|
||||||
Vertex: const
|
Vertex: const
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ $fn = if $some_bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$out = $fn("wide")
|
$out = $fn("wide")
|
||||||
test $out {}
|
test "${out}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[worldwide]
|
Vertex: test[worldwide]
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ $fn = if $some_bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$out = $fn(false)
|
$out = $fn(false)
|
||||||
test $out {}
|
test "${out}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[world]
|
Vertex: test[world]
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ $fn1 = funcgen()
|
|||||||
$fn2 = $fn1()
|
$fn2 = $fn1()
|
||||||
$out = $fn2()
|
$out = $fn2()
|
||||||
|
|
||||||
test $out {}
|
test "${out}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
|
|||||||
@@ -15,6 +15,6 @@ $fn2 = $fn1()
|
|||||||
$fn3 = $fn2()
|
$fn3 = $fn2()
|
||||||
$out = $fn3()
|
$out = $fn3()
|
||||||
|
|
||||||
test $out {}
|
test "${out}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
|
|||||||
@@ -33,10 +33,15 @@ $out2 = $fn1("there")
|
|||||||
$out3 = $fn2("hello")
|
$out3 = $fn2("hello")
|
||||||
$out4 = $fn2("world")
|
$out4 = $fn2("world")
|
||||||
|
|
||||||
test $out1() {} # hey
|
$name1 = $out1()
|
||||||
test $out2() {} # there
|
$name2 = $out2()
|
||||||
test $out3() {} # wow: hello
|
$name3 = $out3()
|
||||||
test $out4() {} # wow: world
|
$name4 = $out4()
|
||||||
|
|
||||||
|
test [$name1,] {} # hey
|
||||||
|
test [$name2,] {} # there
|
||||||
|
test [$name3,] {} # wow: hello
|
||||||
|
test [$name4,] {} # wow: world
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hey]
|
Vertex: test[hey]
|
||||||
Vertex: test[there]
|
Vertex: test[there]
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ $zero = 0
|
|||||||
$one = $zero + 1
|
$one = $zero + 1
|
||||||
$two = $one + 1 # needs a chain to panic
|
$two = $one + 1 # needs a chain to panic
|
||||||
|
|
||||||
test fmt.printf("%d%d%d", $zero, $one, $two) {}
|
test [fmt.printf("%d%d%d", $zero, $one, $two),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[012]
|
Vertex: test[012]
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ $fn2 = funcgen(false)
|
|||||||
$out1 = $fn1()
|
$out1 = $fn1()
|
||||||
$out2 = $fn2()
|
$out2 = $fn2()
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
test $out2 {}
|
test "${out2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[world]
|
Vertex: test[world]
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ $fn2 = $funcgen(false)
|
|||||||
$out1 = $fn1()
|
$out1 = $fn1()
|
||||||
$out2 = $fn2()
|
$out2 = $fn2()
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
test $out2 {}
|
test "${out2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[world]
|
Vertex: test[world]
|
||||||
|
|||||||
@@ -36,10 +36,15 @@ $out2 = $fn1("world")
|
|||||||
$out3 = $fn2("hello")
|
$out3 = $fn2("hello")
|
||||||
$out4 = $fn2("world")
|
$out4 = $fn2("world")
|
||||||
|
|
||||||
test $out1() {}
|
$name1 = $out1()
|
||||||
test $out2() {}
|
$name2 = $out2()
|
||||||
test $out3() {}
|
$name3 = $out3()
|
||||||
test $out4() {}
|
$name4 = $out4()
|
||||||
|
|
||||||
|
test "${name1}" {}
|
||||||
|
test "${name2}" {}
|
||||||
|
test "${name3}" {}
|
||||||
|
test "${name4}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[true-true]
|
Vertex: test[true-true]
|
||||||
Vertex: test[true-false]
|
Vertex: test[true-false]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
$x1 = "t1"
|
$x1 = "t1"
|
||||||
class foo {
|
class foo {
|
||||||
test $x1 {}
|
test "${x1}" {}
|
||||||
}
|
}
|
||||||
include foo
|
include foo
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
include foo
|
include foo
|
||||||
class foo {
|
class foo {
|
||||||
test $x1 {}
|
test "${x1}" {}
|
||||||
}
|
}
|
||||||
$x1 = "t1"
|
$x1 = "t1"
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
$x1 = "bad1"
|
$x1 = "bad1"
|
||||||
class foo($x1) {
|
class foo($x1) {
|
||||||
test $x1 {}
|
test "${x1}" {}
|
||||||
}
|
}
|
||||||
include foo("t1")
|
include foo("t1")
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
$x1 = "t1"
|
$x1 = "t1"
|
||||||
class foo {
|
class foo {
|
||||||
test $x1 {}
|
test "${x1}" {}
|
||||||
test $x2 {}
|
test "${x2}" {}
|
||||||
}
|
}
|
||||||
include foo
|
include foo
|
||||||
$x2 = "t2"
|
$x2 = "t2"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
$x1 = "bad1"
|
$x1 = "bad1"
|
||||||
class foo($x1, $x2) {
|
class foo($x1, $x2) {
|
||||||
test "t1: " + $x2 {} # swapped
|
test ["t1: " + $x2,] {} # swapped
|
||||||
test "t2: " + $x1 {}
|
test ["t2: " + $x1,] {}
|
||||||
}
|
}
|
||||||
include foo($x2, "t1")
|
include foo($x2, "t1")
|
||||||
$x2 = "t2"
|
$x2 = "t2"
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
$x1 = "bad1"
|
$x1 = "bad1"
|
||||||
class foo($x1, $x2) {
|
class foo($x1, $x2) {
|
||||||
include bar
|
include bar
|
||||||
test "t1: " + $x1 {}
|
test ["t1: " + $x1,] {}
|
||||||
test "t2: " + $x2 {}
|
test ["t2: " + $x2,] {}
|
||||||
class bar {
|
class bar {
|
||||||
test "t0: " + $x0 {}
|
test ["t0: " + $x0,] {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
include foo("t1", $x2)
|
include foo("t1", $x2)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ include defs.foo
|
|||||||
import "defs.mcl" # out of order for fun
|
import "defs.mcl" # out of order for fun
|
||||||
-- defs.mcl --
|
-- defs.mcl --
|
||||||
class foo {
|
class foo {
|
||||||
test $x1 {} # capture the var
|
test "${x1}" {} # capture the var
|
||||||
}
|
}
|
||||||
$x1 = "t1"
|
$x1 = "t1"
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ class c1 {
|
|||||||
include c1 as i1 # has $y
|
include c1 as i1 # has $y
|
||||||
include i1.c0 as i0 # has $x ...and $y
|
include i1.c0 as i0 # has $x ...and $y
|
||||||
|
|
||||||
test $i0.x {} # ok
|
test "${i0.x}" {} # ok
|
||||||
test $i1.y {} # ok
|
test "${i1.y}" {} # ok
|
||||||
panic($i0.x != "goodbye")
|
panic($i0.x != "goodbye")
|
||||||
panic($i1.y != "hello")
|
panic($i1.y != "hello")
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ panic($i1.y != "hello")
|
|||||||
# current child scope, which makes this variable visible. Unfortunately, it does
|
# current child scope, which makes this variable visible. Unfortunately, it does
|
||||||
# not have the correct dependency (edge) present in the Ordering system, so it
|
# not have the correct dependency (edge) present in the Ordering system, so it
|
||||||
# is flaky depending on luck of the toposort.
|
# is flaky depending on luck of the toposort.
|
||||||
#test $i0.y {}
|
#test "${i0.y}" {}
|
||||||
|
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
|
|||||||
@@ -26,8 +26,11 @@ include i1.c0 as i01
|
|||||||
include c1(false) as i2
|
include c1(false) as i2
|
||||||
include i2.c0 as i02
|
include i2.c0 as i02
|
||||||
|
|
||||||
test $i01.x {}
|
$name1 = $i01.x
|
||||||
test $i02.x {}
|
$name2 = $i02.x
|
||||||
|
|
||||||
|
test "${name1}" {}
|
||||||
|
test "${name2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ class c1() {
|
|||||||
# TODO: can this be allowed?
|
# TODO: can this be allowed?
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
test $i1.x {}
|
test "${i1.x}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:i1`, have: include(c1)
|
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:i1`, have: include(c1)
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ class c1($s) {
|
|||||||
# TODO: can this be allowed?
|
# TODO: can this be allowed?
|
||||||
include c1("hey") as i1
|
include c1("hey") as i1
|
||||||
include c1("hey") as i1
|
include c1("hey") as i1
|
||||||
test $i1.x {}
|
test "${i1.x}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:i1`, have: include(c1)
|
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:i1`, have: include(c1)
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ class c1($s) {
|
|||||||
|
|
||||||
include c1("hey") as i1
|
include c1("hey") as i1
|
||||||
include c1("there") as i1
|
include c1("there") as i1
|
||||||
test $i1.x {}
|
test "${i1.x}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:i1`, have: include(c1)
|
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:i1`, have: include(c1)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class c1 {
|
|||||||
}
|
}
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
|
|
||||||
test i1.f1("world") {}
|
test [i1.f1("world"),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[helloworld]
|
Vertex: test[helloworld]
|
||||||
Vertex: test[t1]
|
Vertex: test[t1]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class c1 {
|
|||||||
}
|
}
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
|
|
||||||
test i1.f1("whatever") {}
|
test [i1.f1("whatever"),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[helloworld]
|
Vertex: test[helloworld]
|
||||||
Vertex: test[t1]
|
Vertex: test[t1]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class c1 {
|
|||||||
}
|
}
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
|
|
||||||
test i1.f1() {}
|
test [i1.f1(),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[t1]
|
Vertex: test[t1]
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ class c1($b) {
|
|||||||
include c1(true) as i1
|
include c1(true) as i1
|
||||||
include c1(false) as i2
|
include c1(false) as i2
|
||||||
|
|
||||||
test i1.f1() {}
|
test [i1.f1(),] {}
|
||||||
test i2.f1() {}
|
test [i2.f1(),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ class c1($b) {
|
|||||||
include c1(true) as i1
|
include c1(true) as i1
|
||||||
include c1(false) as i2
|
include c1(false) as i2
|
||||||
|
|
||||||
test i1.f1() {}
|
test [i1.f1(),] {}
|
||||||
test i2.f1() {}
|
test [i2.f1(),] {}
|
||||||
test i1.i0.f0() {} # I think these might work directly too. Do we want them to?
|
test [i1.i0.f0(),] {} # I think these might work directly too. Do we want them to?
|
||||||
test i2.i0.f0() {}
|
test [i2.i0.f0(),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ class c1($s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
include c1("hey") as i1
|
include c1("hey") as i1
|
||||||
test $i1.x {}
|
test "${i1.x}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:i1`, have: import(fmt)
|
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:i1`, have: import(fmt)
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ class c1($s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
include c1("hey") as fmt
|
include c1("hey") as fmt
|
||||||
test $fmt.x {}
|
test "${fmt.x}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:fmt`, have: import(fmt)
|
# err: errSetScope: could not generate ordering: duplicate assignment to `scoped:fmt`, have: import(fmt)
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ class c1 {
|
|||||||
}
|
}
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
|
|
||||||
test $i1.f1("world") {}
|
$name = $i1.f1("world")
|
||||||
|
|
||||||
|
test "${name}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[helloworld]
|
Vertex: test[helloworld]
|
||||||
Vertex: test[t1]
|
Vertex: test[t1]
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ class c1 {
|
|||||||
}
|
}
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
|
|
||||||
test $i1.f1("whatever") {}
|
$name = $i1.f1("whatever")
|
||||||
|
|
||||||
|
test "${name}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[helloworld]
|
Vertex: test[helloworld]
|
||||||
Vertex: test[t1]
|
Vertex: test[t1]
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ class c1 {
|
|||||||
}
|
}
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
|
|
||||||
test $i1.f1() {}
|
$name = $i1.f1()
|
||||||
|
|
||||||
|
test "${name}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[t1]
|
Vertex: test[t1]
|
||||||
|
|||||||
@@ -17,8 +17,11 @@ class c1($b) {
|
|||||||
include c1(true) as i1
|
include c1(true) as i1
|
||||||
include c1(false) as i2
|
include c1(false) as i2
|
||||||
|
|
||||||
test $i1.f1() {}
|
$name1 = $i1.f1()
|
||||||
test $i2.f1() {}
|
$name2 = $i2.f1()
|
||||||
|
|
||||||
|
test "${name1}" {}
|
||||||
|
test "${name2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
|
|||||||
@@ -28,11 +28,17 @@ class c1($b) {
|
|||||||
include c1(true) as i1
|
include c1(true) as i1
|
||||||
include c1(false) as i2
|
include c1(false) as i2
|
||||||
|
|
||||||
test $i1.x() {}
|
$name1 = $i1.x()
|
||||||
test $i1.i0.f0() {}
|
$name2 = $i1.i0.f0()
|
||||||
test $i2.x() {}
|
$name3 = $i2.x()
|
||||||
test $i1.i0.f0() {} # I think these should work directly too. Do we want them to?
|
$name4 = $i1.i0.f0() # I think these should work directly too. Do we want them to?
|
||||||
test $i2.i0.f0() {}
|
$name5 = $i2.i0.f0()
|
||||||
|
|
||||||
|
test "${name1}" {}
|
||||||
|
test "${name2}" {}
|
||||||
|
test "${name3}" {}
|
||||||
|
test "${name4}" {}
|
||||||
|
test "${name5}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
$top = "top-level"
|
$top = "top-level"
|
||||||
class base($s) {
|
class base($s) {
|
||||||
test "middle " + $s {}
|
test ["middle " + $s,] {}
|
||||||
$middle = "inside base"
|
$middle = "inside base"
|
||||||
}
|
}
|
||||||
|
|
||||||
# syntactic sugar for the equivalent of defining a class `inner` inside of base.
|
# syntactic sugar for the equivalent of defining a class `inner` inside of base.
|
||||||
class base:inner($s) {
|
class base:inner($s) {
|
||||||
test "inner " + $s {}
|
test ["inner " + $s,] {}
|
||||||
|
|
||||||
$last = "i am inner and i can see " + $middle
|
$last = "i am inner and i can see " + $middle
|
||||||
}
|
}
|
||||||
@@ -15,9 +15,9 @@ class base:inner($s) {
|
|||||||
include base("world") as b1
|
include base("world") as b1
|
||||||
include b1.inner("hello") as b2 # inner comes out of `base`
|
include b1.inner("hello") as b2 # inner comes out of `base`
|
||||||
|
|
||||||
test $top {}
|
test "${top}" {}
|
||||||
test $b1.middle {}
|
test "${b1.middle}" {}
|
||||||
test $b2.last {}
|
test "${b2.last}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[inner hello]
|
Vertex: test[inner hello]
|
||||||
Vertex: test[middle world]
|
Vertex: test[middle world]
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
$top = "top-level"
|
$top = "top-level"
|
||||||
class base($s) {
|
class base($s) {
|
||||||
test "middle " + $s {}
|
test ["middle " + $s,] {}
|
||||||
$middle = "inside base"
|
$middle = "inside base"
|
||||||
}
|
}
|
||||||
|
|
||||||
# syntactic sugar for the equivalent of defining a class `inner` inside of base.
|
# syntactic sugar for the equivalent of defining a class `inner` inside of base.
|
||||||
class base:inner1($s) {
|
class base:inner1($s) {
|
||||||
test "inner1 " + $s {}
|
test ["inner1 " + $s,] {}
|
||||||
|
|
||||||
$last = "i am inner1 and i can see " + $middle
|
$last = "i am inner1 and i can see " + $middle
|
||||||
}
|
}
|
||||||
|
|
||||||
class base:inner2($s) {
|
class base:inner2($s) {
|
||||||
test "inner2 " + $s {}
|
test ["inner2 " + $s,] {}
|
||||||
|
|
||||||
$last = "i am inner2 and i can see " + $middle
|
$last = "i am inner2 and i can see " + $middle
|
||||||
}
|
}
|
||||||
|
|
||||||
# three deep!
|
# three deep!
|
||||||
class base:inner1:deep($s, $b) {
|
class base:inner1:deep($s, $b) {
|
||||||
test "deep is " + $s {}
|
test ["deep is " + $s,] {}
|
||||||
|
|
||||||
$end = "i am deep and i can see " + $middle + " and last says " + $last
|
$end = "i am deep and i can see " + $middle + " and last says " + $last
|
||||||
}
|
}
|
||||||
@@ -30,11 +30,11 @@ include b0.inner1("hello") as b1 # inner comes out of `base`
|
|||||||
include b0.inner2("hello") as b2 # inner comes out of `base`
|
include b0.inner2("hello") as b2 # inner comes out of `base`
|
||||||
include b1.deep("deep", true) as d # deep comes out of `inner1`
|
include b1.deep("deep", true) as d # deep comes out of `inner1`
|
||||||
|
|
||||||
test $top {}
|
test "${top}" {}
|
||||||
test $b0.middle {}
|
test "${b0.middle}" {}
|
||||||
test $b1.last {}
|
test "${b1.last}" {}
|
||||||
test $b2.last {}
|
test "${b2.last}" {}
|
||||||
test $d.end {}
|
test "${d.end}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[deep is deep]
|
Vertex: test[deep is deep]
|
||||||
Vertex: test[i am deep and i can see inside base and last says i am inner1 and i can see inside base]
|
Vertex: test[i am deep and i can see inside base and last says i am inner1 and i can see inside base]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class c1 {
|
|||||||
}
|
}
|
||||||
include c1 as i1
|
include c1 as i1
|
||||||
|
|
||||||
test $i1.x {}
|
test "${i1.x}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[t1]
|
Vertex: test[t1]
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ class c1($b) {
|
|||||||
include c1(true) as i1
|
include c1(true) as i1
|
||||||
include c1(false) as i2
|
include c1(false) as i2
|
||||||
|
|
||||||
test $i1.x {}
|
test "${i1.x}" {}
|
||||||
test $i2.x {}
|
test "${i2.x}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ class c1($b) {
|
|||||||
include c1(true) as i1
|
include c1(true) as i1
|
||||||
include c1(false) as i2
|
include c1(false) as i2
|
||||||
|
|
||||||
test $i1.x {}
|
test "${i1.x}" {}
|
||||||
test $i2.x {}
|
test "${i2.x}" {}
|
||||||
test $i1.i0.y {} # I think these should work directly too. Do we want them to?
|
test "${i1.i0.y}" {} # I think these should work directly too. Do we want them to?
|
||||||
test $i2.i0.y {}
|
test "${i2.i0.y}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
$wat = "bad1"
|
$wat = "bad1"
|
||||||
class c1($wat) {
|
class c1($wat) {
|
||||||
test $wat {}
|
test "${wat}" {}
|
||||||
}
|
}
|
||||||
include c1("hello")
|
include c1("hello")
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ class shadowme($msg) {
|
|||||||
$msg = "c"
|
$msg = "c"
|
||||||
if true {
|
if true {
|
||||||
$msg = "d" # this is used!
|
$msg = "d" # this is used!
|
||||||
test $msg {}
|
test "${msg}" {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class shadowme($msg) {
|
|||||||
if true {
|
if true {
|
||||||
$msg = "d"
|
$msg = "d"
|
||||||
}
|
}
|
||||||
test $msg {}
|
test "${msg}" {}
|
||||||
}
|
}
|
||||||
|
|
||||||
include shadowme("b")
|
include shadowme("b")
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ include c1(true)
|
|||||||
# error prone, and also require a higher-order FRP, which would add complexity
|
# error prone, and also require a higher-order FRP, which would add complexity
|
||||||
# but little value.
|
# but little value.
|
||||||
|
|
||||||
test $foo {}
|
test "${foo}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[a]
|
Vertex: test[a]
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ $f = func($x) {
|
|||||||
$wat
|
$wat
|
||||||
}
|
}
|
||||||
|
|
||||||
test $f("foo") {}
|
$name = $f("foo")
|
||||||
|
test "${name}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: variable x not in scope
|
# err: errSetScope: variable x not in scope
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ $out1 = $fn("user")
|
|||||||
$out2 = $fn("james")
|
$out2 = $fn("james")
|
||||||
$out3 = $fn("")
|
$out3 = $fn("")
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
test $out2 {}
|
test "${out2}" {}
|
||||||
test $out3 {}
|
test "${out3}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello purpleidea]
|
Vertex: test[hello purpleidea]
|
||||||
Vertex: test[hello user]
|
Vertex: test[hello user]
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ $generate = func($idn) {
|
|||||||
|
|
||||||
$foo = iter.map([$id1, $id2,], $generate)
|
$foo = iter.map([$id1, $id2,], $generate)
|
||||||
|
|
||||||
test $foo[0] || "fail" {}
|
$name0 = $foo[0] || "fail"
|
||||||
test $foo[1] || "fail" {}
|
$name1 = $foo[1] || "fail"
|
||||||
|
test "${name0}" {}
|
||||||
|
test "${name1}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[foo]
|
Vertex: test[foo]
|
||||||
Vertex: test[foofoo]
|
Vertex: test[foofoo]
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ $funcgen = func() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
test $out2 {}
|
test "${out2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[so true]
|
Vertex: test[so true]
|
||||||
Vertex: test[so false]
|
Vertex: test[so false]
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ $fn = if $some_bool {
|
|||||||
$out1 = $fn(true)
|
$out1 = $fn(true)
|
||||||
$out2 = $fn(false)
|
$out2 = $fn(false)
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
test $out2 {}
|
test "${out2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[so true]
|
Vertex: test[so true]
|
||||||
Vertex: test[so false]
|
Vertex: test[so false]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
# this magic string variable should exist and be "exists"
|
# this magic string variable should exist and be "exists"
|
||||||
test $const.res.file.state.exists {}
|
test "${const.res.file.state.exists}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[exists]
|
Vertex: test[exists]
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ $id = func($y) { $y }
|
|||||||
# since $apply changes over time, this call needs a dynamic sub-graph. In
|
# since $apply changes over time, this call needs a dynamic sub-graph. In
|
||||||
# theory, the $f calls above do not need a sub-graph, but does our optimization
|
# theory, the $f calls above do not need a sub-graph, but does our optimization
|
||||||
# support this corner case yet?
|
# support this corner case yet?
|
||||||
test $apply($id, "foo") {}
|
$name = $apply($id, "foo")
|
||||||
|
test "${name}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[foo]
|
Vertex: test[foo]
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ $s4 = if contains([42, 13, 0,], $intlists) {
|
|||||||
"passed4"
|
"passed4"
|
||||||
}
|
}
|
||||||
|
|
||||||
test $s1 {} # passed
|
test "${s1}" {} # passed
|
||||||
test $s2 {} # passed
|
test "${s2}" {} # passed
|
||||||
test $s3 {} # passed
|
test "${s3}" {} # passed
|
||||||
test $s4 {} # passed
|
test "${s4}" {} # passed
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[passed1]
|
Vertex: test[passed1]
|
||||||
Vertex: test[passed2]
|
Vertex: test[passed2]
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ $call_f1 = func($x) {
|
|||||||
$call_f2 = func($x) {
|
$call_f2 = func($x) {
|
||||||
$f2() + $x
|
$f2() + $x
|
||||||
}
|
}
|
||||||
test $call_f1("!") {}
|
$name1 = $call_f1("!")
|
||||||
test $call_f2("?") {}
|
$name2 = $call_f2("?")
|
||||||
|
test "${name1}" {}
|
||||||
|
test "${name2}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[top-level1!]
|
Vertex: test[top-level1!]
|
||||||
Vertex: test[top-level2?]
|
Vertex: test[top-level2?]
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ if $x3 != $mod1.x3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# hide the newlines from our output
|
# hide the newlines from our output
|
||||||
test strings.trim_space($x1) {}
|
test [strings.trim_space($x1),] {}
|
||||||
test strings.trim_space($x2) {}
|
test [strings.trim_space($x2),] {}
|
||||||
test strings.trim_space($x3) {}
|
test [strings.trim_space($x3),] {}
|
||||||
# debugging:
|
# debugging:
|
||||||
#test "f1" {
|
#test "f1" {
|
||||||
# anotherstr => $x1,
|
# anotherstr => $x1,
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ if $x3 != $mod1.x3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# hide the newlines from our output
|
# hide the newlines from our output
|
||||||
test strings.trim_space($x1) {}
|
test [strings.trim_space($x1),] {}
|
||||||
test strings.trim_space($x2) {}
|
test [strings.trim_space($x2),] {}
|
||||||
test strings.trim_space($x3) {}
|
test [strings.trim_space($x3),] {}
|
||||||
# debugging:
|
# debugging:
|
||||||
#test "f1" {
|
#test "f1" {
|
||||||
# anotherstr => $x1,
|
# anotherstr => $x1,
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ if $x2 != $second.x2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# hide the newlines from our output
|
# hide the newlines from our output
|
||||||
test strings.trim_space($x1) {}
|
test [strings.trim_space($x1),] {}
|
||||||
test strings.trim_space($x2) {}
|
test [strings.trim_space($x2),] {}
|
||||||
-- second.mcl --
|
-- second.mcl --
|
||||||
import "deploy"
|
import "deploy"
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ if $x1 != deploy.readfile($f1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# hide the newlines from our output
|
# hide the newlines from our output
|
||||||
test strings.trim_space($x1) {}
|
test [strings.trim_space($x1),] {}
|
||||||
-- files/file1 --
|
-- files/file1 --
|
||||||
This is file1 in the files/ folder.
|
This is file1 in the files/ folder.
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ $f1 = "/files/file1"
|
|||||||
$x1 = deploy.readfileabs($f1)
|
$x1 = deploy.readfileabs($f1)
|
||||||
|
|
||||||
# hide the newlines from our output
|
# hide the newlines from our output
|
||||||
test $x1 {}
|
test "${x1}" {}
|
||||||
-- files/file1 --
|
-- files/file1 --
|
||||||
This is file1 in the files/ folder.
|
This is file1 in the files/ folder.
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ func prefixer($x) {
|
|||||||
$out1 = prefixer("a")
|
$out1 = prefixer("a")
|
||||||
$out2 = prefixer("b")
|
$out2 = prefixer("b")
|
||||||
|
|
||||||
test $out1 {} # hello:a
|
test "${out1}" {} # hello:a
|
||||||
test $out2 {} # hello:b
|
test "${out2}" {} # hello:b
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello:a]
|
Vertex: test[hello:a]
|
||||||
Vertex: test[hello:b]
|
Vertex: test[hello:b]
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ $prefixer = func($x) {
|
|||||||
$out1 = $prefixer("a")
|
$out1 = $prefixer("a")
|
||||||
$out2 = $prefixer("b")
|
$out2 = $prefixer("b")
|
||||||
|
|
||||||
test $out1 {} # helloa
|
test "${out1}" {} # helloa
|
||||||
test $out2 {} # hellob
|
test "${out2}" {} # hellob
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[helloa]
|
Vertex: test[helloa]
|
||||||
Vertex: test[hellob]
|
Vertex: test[hellob]
|
||||||
|
|||||||
6
lang/interpret_test/TestAstFunc2/empty-res-list-0.txtar
Normal file
6
lang/interpret_test/TestAstFunc2/empty-res-list-0.txtar
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
# This is an empty list of test resources, iow test resources. This must pass
|
||||||
|
# type unification. This previously only passed if we allowed recursive
|
||||||
|
# unification solving, but now we can support it without that.
|
||||||
|
test [] {}
|
||||||
|
-- OUTPUT --
|
||||||
@@ -3,7 +3,7 @@ some comment can go here!
|
|||||||
-- main.mcl --
|
-- main.mcl --
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
test fmt.printf("answer: %d", 42) {}
|
test [fmt.printf("answer: %d", 42),] {}
|
||||||
-- files/file1 --
|
-- files/file1 --
|
||||||
this is file1
|
this is file1
|
||||||
-- files/file2 --
|
-- files/file2 --
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import "fmt"
|
|||||||
import "math"
|
import "math"
|
||||||
# FIXME: floats don't print nicely: https://github.com/golang/go/issues/46118
|
# FIXME: floats don't print nicely: https://github.com/golang/go/issues/46118
|
||||||
# FIXME: This means that we see "42" for both, instead of 42.0 ...
|
# FIXME: This means that we see "42" for both, instead of 42.0 ...
|
||||||
test fmt.printf("int: %d", math.fortytwo()) {}
|
test [fmt.printf("int: %d", math.fortytwo()),] {}
|
||||||
test fmt.printf("float: %f", math.fortytwo()) {}
|
test [fmt.printf("float: %f", math.fortytwo()),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[float: 42]
|
Vertex: test[float: 42]
|
||||||
Vertex: test[int: 42]
|
Vertex: test[int: 42]
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ func stradd($x) {
|
|||||||
|
|
||||||
$x1 = stradd("hey")
|
$x1 = stradd("hey")
|
||||||
|
|
||||||
test $x1 {}
|
test "${x1}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[heyhey]
|
Vertex: test[heyhey]
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ class funcgen1 {
|
|||||||
}
|
}
|
||||||
include funcgen1
|
include funcgen1
|
||||||
$x1 = fun1() # not funcgen1.fun1 since it's *not* an import!
|
$x1 = fun1() # not funcgen1.fun1 since it's *not* an import!
|
||||||
test $x1 {} # hi
|
test "${x1}" {} # hi
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: func `fun1` does not exist in this scope
|
# err: errSetScope: func `fun1` does not exist in this scope
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ $const2 = "world" # added here to confirm any-order rules
|
|||||||
|
|
||||||
include funcgen2
|
include funcgen2
|
||||||
$x2 = fun2() # not funcgen2.fun2 since it's *not* an import!
|
$x2 = fun2() # not funcgen2.fun2 since it's *not* an import!
|
||||||
test $x2 {} # hello world
|
test "${x2}" {} # hello world
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: func `fun2` does not exist in this scope
|
# err: errSetScope: func `fun2` does not exist in this scope
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ func sq1($x) {
|
|||||||
|
|
||||||
$x1 = sq1(3) # 3^2 + 4 = 13
|
$x1 = sq1(3) # 3^2 + 4 = 13
|
||||||
|
|
||||||
test fmt.printf("sq1: %d", $x1) {}
|
test [fmt.printf("sq1: %d", $x1),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[sq1: 6]
|
Vertex: test[sq1: 6]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ func sq1($x) {
|
|||||||
|
|
||||||
$x1 = sq1(math.fortytwo())
|
$x1 = sq1(math.fortytwo())
|
||||||
|
|
||||||
test fmt.printf("sq1: %d", $x1) {}
|
test [fmt.printf("sq1: %d", $x1),] {}
|
||||||
|
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[sq1: 45]
|
Vertex: test[sq1: 45]
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ func stradd($x) {
|
|||||||
|
|
||||||
$x1 = stradd("hey")
|
$x1 = stradd("hey")
|
||||||
|
|
||||||
test $x1 {}
|
test "${x1}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[heythere]
|
Vertex: test[heythere]
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ $foo = "bad1"
|
|||||||
func bar($foo) {
|
func bar($foo) {
|
||||||
"hello " + $foo # shadows parent var
|
"hello " + $foo # shadows parent var
|
||||||
}
|
}
|
||||||
test bar("world") {}
|
test [bar("world"),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello world]
|
Vertex: test[hello world]
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ $foo = "bad1"
|
|||||||
$bar = func($foo) {
|
$bar = func($foo) {
|
||||||
"hello " + $foo # shadows parent var
|
"hello " + $foo # shadows parent var
|
||||||
}
|
}
|
||||||
test $bar("world") {}
|
$name = $bar("world")
|
||||||
|
test "${name}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello world]
|
Vertex: test[hello world]
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ func stradd($x) {
|
|||||||
|
|
||||||
$x1 = stradd("hey")
|
$x1 = stradd("hey")
|
||||||
|
|
||||||
test $x1 {}
|
test "${x1}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[nothing]
|
Vertex: test[nothing]
|
||||||
|
|||||||
@@ -31,15 +31,16 @@ $funcgen3 = func() {
|
|||||||
|
|
||||||
$fn1 = $funcgen1()
|
$fn1 = $funcgen1()
|
||||||
$out1 = $fn1("hello")
|
$out1 = $fn1("hello")
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
|
|
||||||
$fn2 = $funcgen2()
|
$fn2 = $funcgen2()
|
||||||
$out2 = $fn2("hello")
|
$out2 = $fn2("hello")
|
||||||
test $out2 {}
|
test "${out2}" {}
|
||||||
|
|
||||||
$fn3 = $funcgen3()
|
$fn3 = $funcgen3()
|
||||||
$out3 = $fn3("goodbye")
|
$out3 = $fn3("goodbye")
|
||||||
test $out3() {}
|
$name3 = $out3()
|
||||||
|
test "${name3}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[goodbye]
|
Vertex: test[goodbye]
|
||||||
Vertex: test[hello world]
|
Vertex: test[hello world]
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ func identity($x) {
|
|||||||
$x
|
$x
|
||||||
}
|
}
|
||||||
|
|
||||||
test identity("hey") {}
|
test [identity("hey"),] {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hey]
|
Vertex: test[hey]
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ $out1 = if true {
|
|||||||
"world"
|
"world"
|
||||||
}
|
}
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ $fn = func($b) {
|
|||||||
|
|
||||||
$out1 = $fn(true)
|
$out1 = $fn(true)
|
||||||
|
|
||||||
test $out1 {}
|
test "${out1}" {}
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hello]
|
Vertex: test[hello]
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ class c2() {
|
|||||||
|
|
||||||
include c2 as f1
|
include c2 as f1
|
||||||
|
|
||||||
test $f1.z {} # yep
|
test "${f1.z}" {} # yep
|
||||||
#test $f1.x {} # no
|
#test "${f1.x}" {} # no
|
||||||
test $f1.g1.x {} # yep
|
test "${f1.g1.x}" {} # yep
|
||||||
|
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[i am y and i am x]
|
Vertex: test[i am y and i am x]
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ class c2() {
|
|||||||
|
|
||||||
include c2 as f1
|
include c2 as f1
|
||||||
|
|
||||||
test $f1.z {}
|
test "${f1.z}" {}
|
||||||
test $f1.x {} # tricky
|
test "${f1.x}" {} # tricky
|
||||||
test $f1.newx {}
|
test "${f1.newx}" {}
|
||||||
|
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[i am x]
|
Vertex: test[i am x]
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ class c2() {
|
|||||||
|
|
||||||
include c2 as f1
|
include c2 as f1
|
||||||
|
|
||||||
test $f1.z {}
|
test "${f1.z}" {}
|
||||||
test $f1.x {} # tricky
|
test "${f1.x}" {} # tricky
|
||||||
test $f1.newx {}
|
test "${f1.newx}" {}
|
||||||
|
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: recursive reference while setting scope: not a dag
|
# err: errSetScope: recursive reference while setting scope: not a dag
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ class c2() {
|
|||||||
|
|
||||||
include c2 as f1
|
include c2 as f1
|
||||||
|
|
||||||
test $f1.z {}
|
test "${f1.z}" {}
|
||||||
test $f1.x1 {}
|
test "${f1.x1}" {}
|
||||||
|
|
||||||
# the really tricky case
|
# the really tricky case
|
||||||
# XXX: works atm, but not supported for now: could not set scope: variable f1.x2 not in scope
|
# XXX: works atm, but not supported for now: could not set scope: variable f1.x2 not in scope
|
||||||
@@ -19,7 +19,7 @@ test $f1.x1 {}
|
|||||||
# current child scope, which makes this variable visible. Unfortunately, it does
|
# current child scope, which makes this variable visible. Unfortunately, it does
|
||||||
# not have the correct dependency (edge) present in the Ordering system, so it
|
# not have the correct dependency (edge) present in the Ordering system, so it
|
||||||
# is flaky depending on luck of the toposort.
|
# is flaky depending on luck of the toposort.
|
||||||
#test $f1.x2 {}
|
#test "${f1.x2}" {}
|
||||||
|
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[hey]
|
Vertex: test[hey]
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ class c2() {
|
|||||||
|
|
||||||
include c2 as f1
|
include c2 as f1
|
||||||
|
|
||||||
test $x {}
|
test "${x}" {}
|
||||||
test $f1.y {}
|
test "${f1.y}" {}
|
||||||
|
|
||||||
# the really tricky case
|
# the really tricky case
|
||||||
# XXX: not supported for now: could not set scope: not a dag
|
# XXX: not supported for now: could not set scope: not a dag
|
||||||
#test $f1.x {}
|
#test "${f1.x}" {}
|
||||||
|
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
Vertex: test[i am x]
|
Vertex: test[i am x]
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ class c2() {
|
|||||||
|
|
||||||
include c2 as f1
|
include c2 as f1
|
||||||
|
|
||||||
test $f1.z {}
|
test "${f1.z}" {}
|
||||||
test $f1.x {} # tricky
|
test "${f1.x}" {} # tricky
|
||||||
test $f1.newx {}
|
test "${f1.newx}" {}
|
||||||
|
|
||||||
-- OUTPUT --
|
-- OUTPUT --
|
||||||
# err: errSetScope: recursive reference while setting scope: not a dag
|
# err: errSetScope: recursive reference while setting scope: not a dag
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user