lang: Port TestAstFunc1 to txtar format
This commit is contained in:
@@ -587,31 +587,11 @@ func TestAstFunc1(t *testing.T) {
|
|||||||
Functions: ast.FuncPrefixToFunctionsScope(""), // runs funcs.LookupPrefix
|
Functions: ast.FuncPrefixToFunctionsScope(""), // runs funcs.LookupPrefix
|
||||||
}
|
}
|
||||||
|
|
||||||
type errs struct {
|
|
||||||
failLexParse bool
|
|
||||||
failInit bool
|
|
||||||
failSetScope bool
|
|
||||||
failUnify bool
|
|
||||||
failGraph bool
|
|
||||||
}
|
|
||||||
type test struct { // an individual test
|
type test struct { // an individual test
|
||||||
name string
|
name string
|
||||||
path string // relative sub directory path inside tests dir
|
path string // relative txtar path inside tests dir
|
||||||
fail bool
|
|
||||||
//graph *pgraph.Graph
|
|
||||||
expstr string // expected graph in string format
|
|
||||||
errs errs
|
|
||||||
}
|
}
|
||||||
testCases := []test{}
|
testCases := []test{}
|
||||||
//{
|
|
||||||
// graph, _ := pgraph.NewGraph("g")
|
|
||||||
// testCases = append(testCases, test{
|
|
||||||
// name: "simple hello world",
|
|
||||||
// path: "hello0/",
|
|
||||||
// fail: false,
|
|
||||||
// expstr: graph.Sprint(),
|
|
||||||
// })
|
|
||||||
//}
|
|
||||||
|
|
||||||
// build test array automatically from reading the dir
|
// build test array automatically from reading the dir
|
||||||
files, err := ioutil.ReadDir(dir)
|
files, err := ioutil.ReadDir(dir)
|
||||||
@@ -621,87 +601,19 @@ func TestAstFunc1(t *testing.T) {
|
|||||||
}
|
}
|
||||||
sorted := []string{}
|
sorted := []string{}
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if !f.IsDir() {
|
if !strings.HasSuffix(f.Name(), ".txtar") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
sorted = append(sorted, f.Name())
|
sorted = append(sorted, f.Name())
|
||||||
}
|
}
|
||||||
sort.Strings(sorted)
|
sort.Strings(sorted)
|
||||||
for _, f := range sorted {
|
for _, f := range sorted {
|
||||||
graphFile := f + ".graph" // expected graph file
|
|
||||||
graphFileFull := dir + graphFile
|
|
||||||
info, err := os.Stat(graphFileFull)
|
|
||||||
if err != nil || info.IsDir() {
|
|
||||||
p := dir + f + "." + "T" + "O" + "D" + "O"
|
|
||||||
if _, err := os.Stat(p); err == nil {
|
|
||||||
// if it's a WIP, then don't error things
|
|
||||||
t.Logf("missing: %s", p)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Errorf("missing: %s", graphFile)
|
|
||||||
t.Errorf("(err: %+v)", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
content, err := ioutil.ReadFile(graphFileFull)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("could not read graph file: %+v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
str := string(content) // expected graph
|
|
||||||
|
|
||||||
// if the graph file has a magic error string, it's a failure
|
|
||||||
errStr := ""
|
|
||||||
failLexParse := false
|
|
||||||
failInit := false
|
|
||||||
failSetScope := false
|
|
||||||
failUnify := false
|
|
||||||
failGraph := false
|
|
||||||
if strings.HasPrefix(str, magicError) {
|
|
||||||
errStr = strings.TrimPrefix(str, magicError)
|
|
||||||
str = errStr
|
|
||||||
|
|
||||||
if strings.HasPrefix(str, magicErrorLexParse) {
|
|
||||||
errStr = strings.TrimPrefix(str, magicErrorLexParse)
|
|
||||||
str = errStr
|
|
||||||
failLexParse = true
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(str, magicErrorInit) {
|
|
||||||
errStr = strings.TrimPrefix(str, magicErrorInit)
|
|
||||||
str = errStr
|
|
||||||
failInit = true
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(str, magicErrorSetScope) {
|
|
||||||
errStr = strings.TrimPrefix(str, magicErrorSetScope)
|
|
||||||
str = errStr
|
|
||||||
failSetScope = true
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(str, magicErrorUnify) {
|
|
||||||
errStr = strings.TrimPrefix(str, magicErrorUnify)
|
|
||||||
str = errStr
|
|
||||||
failUnify = true
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(str, magicErrorGraph) {
|
|
||||||
errStr = strings.TrimPrefix(str, magicErrorGraph)
|
|
||||||
str = errStr
|
|
||||||
failGraph = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add automatic test case
|
// add automatic test case
|
||||||
testCases = append(testCases, test{
|
testCases = append(testCases, test{
|
||||||
name: fmt.Sprintf("dir: %s", f),
|
name: fmt.Sprintf("%s", f),
|
||||||
path: f + "/",
|
path: f, // <something>.txtar
|
||||||
fail: errStr != "",
|
|
||||||
expstr: str,
|
|
||||||
errs: errs{
|
|
||||||
failLexParse: failLexParse,
|
|
||||||
failInit: failInit,
|
|
||||||
failSetScope: failSetScope,
|
|
||||||
failUnify: failUnify,
|
|
||||||
failGraph: failGraph,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
//t.Logf("adding: %s", f + "/")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
@@ -730,13 +642,87 @@ func TestAstFunc1(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
name, path, fail, expstr, errs := tc.name, tc.path, tc.fail, strings.Trim(tc.expstr, "\n"), tc.errs
|
name, path := tc.name, tc.path
|
||||||
src := dir + path // location of the test
|
tmpdir := t.TempDir() // gets cleaned up at end, new dir for each call
|
||||||
failLexParse := errs.failLexParse
|
src := tmpdir // location of the test
|
||||||
failInit := errs.failInit
|
txtarFile := dir + path
|
||||||
failSetScope := errs.failSetScope
|
|
||||||
failUnify := errs.failUnify
|
archive, err := txtar.ParseFile(txtarFile)
|
||||||
failGraph := errs.failGraph
|
if err != nil {
|
||||||
|
t.Errorf("err parsing txtar(%s): %+v", txtarFile, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
comment := strings.TrimSpace(string(archive.Comment))
|
||||||
|
t.Logf("comment: %s\n", comment)
|
||||||
|
|
||||||
|
// copy files out into the test temp directory
|
||||||
|
var testOutput []byte
|
||||||
|
found := false
|
||||||
|
for _, file := range archive.Files {
|
||||||
|
if file.Name == "OUTPUT" {
|
||||||
|
testOutput = file.Data
|
||||||
|
found = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
name := filepath.Join(tmpdir, file.Name)
|
||||||
|
dir := filepath.Dir(name)
|
||||||
|
if err := os.MkdirAll(dir, 0770); err != nil {
|
||||||
|
t.Errorf("err making dir(%s): %+v", dir, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := ioutil.WriteFile(name, file.Data, 0660); err != nil {
|
||||||
|
t.Errorf("err writing file(%s): %+v", name, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found { // skip missing tests
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
expstr := string(testOutput) // expected graph
|
||||||
|
|
||||||
|
// if the graph file has a magic error string, it's a failure
|
||||||
|
errStr := ""
|
||||||
|
failLexParse := false
|
||||||
|
failInit := false
|
||||||
|
failSetScope := false
|
||||||
|
failUnify := false
|
||||||
|
failGraph := false
|
||||||
|
if strings.HasPrefix(expstr, magicError) {
|
||||||
|
errStr = strings.TrimPrefix(expstr, magicError)
|
||||||
|
expstr = errStr
|
||||||
|
|
||||||
|
if strings.HasPrefix(expstr, magicErrorLexParse) {
|
||||||
|
errStr = strings.TrimPrefix(expstr, magicErrorLexParse)
|
||||||
|
expstr = errStr
|
||||||
|
failLexParse = true
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(expstr, magicErrorInit) {
|
||||||
|
errStr = strings.TrimPrefix(expstr, magicErrorInit)
|
||||||
|
expstr = errStr
|
||||||
|
failInit = true
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(expstr, magicErrorSetScope) {
|
||||||
|
errStr = strings.TrimPrefix(expstr, magicErrorSetScope)
|
||||||
|
expstr = errStr
|
||||||
|
failSetScope = true
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(expstr, magicErrorUnify) {
|
||||||
|
errStr = strings.TrimPrefix(expstr, magicErrorUnify)
|
||||||
|
expstr = errStr
|
||||||
|
failUnify = true
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(expstr, magicErrorGraph) {
|
||||||
|
errStr = strings.TrimPrefix(expstr, magicErrorGraph)
|
||||||
|
expstr = errStr
|
||||||
|
failGraph = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fail := errStr != ""
|
||||||
|
expstr = strings.Trim(expstr, "\n")
|
||||||
|
|
||||||
t.Logf("\n\ntest #%d (%s) ----------------\npath: %s\n\n", index, name, src)
|
t.Logf("\n\ntest #%d (%s) ----------------\npath: %s\n\n", index, name, src)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,26 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
# this can return changing functions, and could be optimized, too
|
||||||
|
func funcgen($b) {
|
||||||
|
if $b {
|
||||||
|
func() {
|
||||||
|
"hello"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
func() {
|
||||||
|
"world"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fn1 = funcgen(true)
|
||||||
|
$fn2 = funcgen(false)
|
||||||
|
|
||||||
|
$out1 = $fn1()
|
||||||
|
$out2 = $fn2()
|
||||||
|
|
||||||
|
test $out1 {}
|
||||||
|
test $out2 {}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: bool(false) -> call:funcgen(bool(false)) # b
|
Edge: bool(false) -> call:funcgen(bool(false)) # b
|
||||||
Edge: bool(false) -> var(b) # var:b
|
Edge: bool(false) -> var(b) # var:b
|
||||||
Edge: bool(true) -> call:funcgen(bool(true)) # b
|
Edge: bool(true) -> call:funcgen(bool(true)) # b
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
# this can return changing functions, and could be optimized, too
|
|
||||||
func funcgen($b) {
|
|
||||||
if $b {
|
|
||||||
func() {
|
|
||||||
"hello"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
func() {
|
|
||||||
"world"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$fn1 = funcgen(true)
|
|
||||||
$fn2 = funcgen(false)
|
|
||||||
|
|
||||||
$out1 = $fn1()
|
|
||||||
$out2 = $fn2()
|
|
||||||
|
|
||||||
test $out1 {}
|
|
||||||
test $out2 {}
|
|
||||||
@@ -1,3 +1,11 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
include c1([13, 42, 0, -37,])
|
||||||
|
class c1($b) {
|
||||||
|
test fmt.printf("len is: %d", len($b)) {} # len is 4
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:len(var(b)) -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # a
|
Edge: call:len(var(b)) -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # a
|
||||||
Edge: int(-37) -> list(int(13), int(42), int(0), int(-37)) # 3
|
Edge: int(-37) -> list(int(13), int(42), int(0), int(-37)) # 3
|
||||||
Edge: int(0) -> list(int(13), int(42), int(0), int(-37)) # 2
|
Edge: int(0) -> list(int(13), int(42), int(0), int(-37)) # 2
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import "fmt"
|
|
||||||
|
|
||||||
include c1([13, 42, 0, -37,])
|
|
||||||
class c1($b) {
|
|
||||||
test fmt.printf("len is: %d", len($b)) {} # len is 4
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# empty!
|
|
||||||
4
lang/interpret_test/TestAstFunc1/comment1.txtar
Normal file
4
lang/interpret_test/TestAstFunc1/comment1.txtar
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
# this is a comment
|
||||||
|
-- OUTPUT --
|
||||||
|
# empty!
|
||||||
@@ -1 +0,0 @@
|
|||||||
# this is a comment
|
|
||||||
@@ -1,3 +1,20 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
# this value should only be built once
|
||||||
|
$some_value1 = 42 # or something more complex like the output of a slow function...
|
||||||
|
class foo($num) {
|
||||||
|
# we should have a different `$inside` value for each use of this class
|
||||||
|
$inside = $some_value1 + $some_value2 + 4
|
||||||
|
test fmt.printf("test-%d-%d", $num, $inside) {} # some resource
|
||||||
|
}
|
||||||
|
$some_value2 = 13 # check that non-ordering works too!
|
||||||
|
|
||||||
|
# We *don't* unnecessarily copy `4` on each include, because it's static!
|
||||||
|
include foo(1)
|
||||||
|
include foo(2)
|
||||||
|
include foo(3)
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:_operator(str("+"), call:_operator(str("+"), var(some_value1), var(some_value2)), int(4)) -> var(inside) # var:inside
|
Edge: call:_operator(str("+"), call:_operator(str("+"), var(some_value1), var(some_value2)), int(4)) -> var(inside) # var:inside
|
||||||
Edge: call:_operator(str("+"), call:_operator(str("+"), var(some_value1), var(some_value2)), int(4)) -> var(inside) # var:inside
|
Edge: call:_operator(str("+"), call:_operator(str("+"), var(some_value1), var(some_value2)), int(4)) -> var(inside) # var:inside
|
||||||
Edge: call:_operator(str("+"), call:_operator(str("+"), var(some_value1), var(some_value2)), int(4)) -> var(inside) # var:inside
|
Edge: call:_operator(str("+"), call:_operator(str("+"), var(some_value1), var(some_value2)), int(4)) -> var(inside) # var:inside
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import "fmt"
|
|
||||||
|
|
||||||
# this value should only be built once
|
|
||||||
$some_value1 = 42 # or something more complex like the output of a slow function...
|
|
||||||
class foo($num) {
|
|
||||||
# we should have a different `$inside` value for each use of this class
|
|
||||||
$inside = $some_value1 + $some_value2 + 4
|
|
||||||
test fmt.printf("test-%d-%d", $num, $inside) {} # some resource
|
|
||||||
}
|
|
||||||
$some_value2 = 13 # check that non-ordering works too!
|
|
||||||
|
|
||||||
# We *don't* unnecessarily copy `4` on each include, because it's static!
|
|
||||||
include foo(1)
|
|
||||||
include foo(2)
|
|
||||||
include foo(3)
|
|
||||||
@@ -1,3 +1,13 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
include c1("t1")
|
||||||
|
include c1("t2")
|
||||||
|
class c1($a) {
|
||||||
|
test $a {
|
||||||
|
stringptr => $foo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$foo = "hey"
|
||||||
|
-- OUTPUT --
|
||||||
Edge: str("hey") -> var(foo) # var:foo
|
Edge: str("hey") -> var(foo) # var:foo
|
||||||
Edge: str("hey") -> var(foo) # var:foo
|
Edge: str("hey") -> var(foo) # var:foo
|
||||||
Edge: str("t1") -> var(a) # var:a
|
Edge: str("t1") -> var(a) # var:a
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
include c1("t1")
|
|
||||||
include c1("t2")
|
|
||||||
class c1($a) {
|
|
||||||
test $a {
|
|
||||||
stringptr => $foo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$foo = "hey"
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
Edge: str("hello world") -> call:fmt.printf(str("hello world")) # format
|
|
||||||
Vertex: call:fmt.printf(str("hello world"))
|
|
||||||
Vertex: str("/tmp/foo")
|
|
||||||
Vertex: str("/tmp/foo")
|
|
||||||
Vertex: str("cowsay")
|
|
||||||
Vertex: str("cowsay")
|
|
||||||
Vertex: str("hello world")
|
|
||||||
Vertex: str("hello world")
|
|
||||||
Vertex: str("installed")
|
|
||||||
Vertex: str("newest")
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
# these two resources are identical to each other, so we should allow it
|
# these two resources are identical to each other, so we should allow it
|
||||||
@@ -15,3 +16,14 @@ pkg "cowsay" {
|
|||||||
pkg "cowsay" {
|
pkg "cowsay" {
|
||||||
state => "newest",
|
state => "newest",
|
||||||
}
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
Edge: str("hello world") -> call:fmt.printf(str("hello world")) # format
|
||||||
|
Vertex: call:fmt.printf(str("hello world"))
|
||||||
|
Vertex: str("/tmp/foo")
|
||||||
|
Vertex: str("/tmp/foo")
|
||||||
|
Vertex: str("cowsay")
|
||||||
|
Vertex: str("cowsay")
|
||||||
|
Vertex: str("hello world")
|
||||||
|
Vertex: str("hello world")
|
||||||
|
Vertex: str("installed")
|
||||||
|
Vertex: str("newest")
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
# this should be a function as a value, iow a lambda
|
||||||
|
$prefixer = func($x) {
|
||||||
|
"hello" + $x # i'd only ever expect one "hello" string in the graph
|
||||||
|
}
|
||||||
|
|
||||||
|
$out1 = $prefixer("a")
|
||||||
|
$out2 = $prefixer("b")
|
||||||
|
|
||||||
|
test $out1 {} # helloa
|
||||||
|
test $out2 {} # hellob
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:_operator(str("+"), str("hello"), var(x)) -> func(x) { call:_operator(str("+"), str("hello"), var(x)) } # body
|
Edge: call:_operator(str("+"), str("hello"), var(x)) -> func(x) { call:_operator(str("+"), str("hello"), var(x)) } # body
|
||||||
Edge: call:_operator(str("+"), str("hello"), var(x)) -> func(x) { call:_operator(str("+"), str("hello"), var(x)) } # body
|
Edge: call:_operator(str("+"), str("hello"), var(x)) -> func(x) { call:_operator(str("+"), str("hello"), var(x)) } # body
|
||||||
Edge: call:prefixer(str("a")) -> var(out1) # var:out1
|
Edge: call:prefixer(str("a")) -> var(out1) # var:out1
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# this should be a function as a value, iow a lambda
|
|
||||||
$prefixer = func($x) {
|
|
||||||
"hello" + $x # i'd only ever expect one "hello" string in the graph
|
|
||||||
}
|
|
||||||
|
|
||||||
$out1 = $prefixer("a")
|
|
||||||
$out2 = $prefixer("b")
|
|
||||||
|
|
||||||
test $out1 {} # helloa
|
|
||||||
test $out2 {} # hellob
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errUnify: only recursive solutions left
|
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
|
-- 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 type unification
|
# this must pass type unification
|
||||||
# this can only currently pass if we allow recursive unification solving
|
# this can only currently pass if we allow recursive unification solving
|
||||||
# if we do, then the function graph is: `Vertex: list()` otherwise it's an error
|
# if we do, then the function graph is: `Vertex: list()` otherwise it's an error
|
||||||
test [] {}
|
test [] {}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errUnify: only recursive solutions left
|
||||||
@@ -1,3 +1,14 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
# single resource
|
||||||
|
test "name" {}
|
||||||
|
|
||||||
|
# single resource, defined by list variable
|
||||||
|
$names = ["hey",]
|
||||||
|
test $names {}
|
||||||
|
|
||||||
|
# multiples resources, defined by list
|
||||||
|
test ["hello", "world",] {}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: list(str("hey")) -> var(names) # var:names
|
Edge: list(str("hey")) -> var(names) # var:names
|
||||||
Edge: str("hello") -> list(str("hello"), str("world")) # 0
|
Edge: str("hello") -> list(str("hello"), str("world")) # 0
|
||||||
Edge: str("hey") -> list(str("hey")) # 0
|
Edge: str("hey") -> list(str("hey")) # 0
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# single resource
|
|
||||||
test "name" {}
|
|
||||||
|
|
||||||
# single resource, defined by list variable
|
|
||||||
$names = ["hey",]
|
|
||||||
test $names {}
|
|
||||||
|
|
||||||
# multiples resources, defined by list
|
|
||||||
test ["hello", "world",] {}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errLexParse: parser: `syntax error: unexpected COLON` @2:8
|
|
||||||
7
lang/interpret_test/TestAstFunc1/fail1.txtar
Normal file
7
lang/interpret_test/TestAstFunc1/fail1.txtar
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
# this is not valid mcl code, this is puppet!
|
||||||
|
file { "/tmp/foo":
|
||||||
|
ensure => present,
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errLexParse: parser: `syntax error: unexpected COLON` @2:8
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# this is not valid mcl code, this is puppet!
|
|
||||||
file { "/tmp/foo":
|
|
||||||
ensure => present,
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errUnify: can't unify, invariant illogicality with equality: base kind does not match (Str != Int)
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
import "fmt"
|
import "fmt"
|
||||||
$x str = if true { # should fail unification
|
$x str = if true { # should fail unification
|
||||||
42
|
42
|
||||||
@@ -7,3 +8,5 @@ $x str = if true { # should fail unification
|
|||||||
test "t1" {
|
test "t1" {
|
||||||
anotherstr => fmt.printf("hello %s", $x),
|
anotherstr => fmt.printf("hello %s", $x),
|
||||||
}
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errUnify: can't unify, invariant illogicality with equality: base kind does not match (Str != Int)
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
$s = "world"
|
||||||
|
|
||||||
|
test "greeting" {
|
||||||
|
anotherstr => fmt.printf("hello: %s", $s),
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: str("hello: %s") -> call:fmt.printf(str("hello: %s"), var(s)) # format
|
Edge: str("hello: %s") -> call:fmt.printf(str("hello: %s"), var(s)) # format
|
||||||
Edge: str("world") -> var(s) # var:s
|
Edge: str("world") -> var(s) # var:s
|
||||||
Edge: var(s) -> call:fmt.printf(str("hello: %s"), var(s)) # a
|
Edge: var(s) -> call:fmt.printf(str("hello: %s"), var(s)) # a
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import "fmt"
|
|
||||||
|
|
||||||
$s = "world"
|
|
||||||
|
|
||||||
test "greeting" {
|
|
||||||
anotherstr => fmt.printf("hello: %s", $s),
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,21 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
import "second.mcl"
|
||||||
|
|
||||||
|
include second.xclass
|
||||||
|
-- second.mcl --
|
||||||
|
import "os"
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
class xclass {
|
||||||
|
#import "os" # this should not be required, top-level should be enough
|
||||||
|
|
||||||
|
$aaa = if os.is_debian() { "bbb" } else { "ccc" }
|
||||||
|
|
||||||
|
print "${aaa}" {
|
||||||
|
msg => "hello",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:os.is_debian() -> if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } # c
|
Edge: call:os.is_debian() -> if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } # c
|
||||||
Edge: if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } -> var(aaa) # var:aaa
|
Edge: if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } -> var(aaa) # var:aaa
|
||||||
Edge: str("bbb") -> if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } # a
|
Edge: str("bbb") -> if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } # a
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import "second.mcl"
|
|
||||||
|
|
||||||
include second.xclass
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import "os"
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
class xclass {
|
|
||||||
#import "os" # this should not be required, top-level should be enough
|
|
||||||
|
|
||||||
$aaa = if os.is_debian() { "bbb" } else { "ccc" }
|
|
||||||
|
|
||||||
print "${aaa}" {
|
|
||||||
msg => "hello",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errSetScope: import scope `second.mcl` failed: local import of `second.mcl` failed: could not set scope from import: func `os.is_debian` does not exist in this scope
|
|
||||||
19
lang/interpret_test/TestAstFunc1/importscope1.txtar
Normal file
19
lang/interpret_test/TestAstFunc1/importscope1.txtar
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
import "second.mcl"
|
||||||
|
|
||||||
|
import "os" # this fixes it but the wrong way
|
||||||
|
|
||||||
|
include second.xclass
|
||||||
|
-- second.mcl --
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
class xclass {
|
||||||
|
# note that `os` is not imported here
|
||||||
|
$aaa = if os.is_debian() { "bbb" } else { "ccc" }
|
||||||
|
|
||||||
|
print "${aaa}" {
|
||||||
|
msg => "hello",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errSetScope: import scope `second.mcl` failed: local import of `second.mcl` failed: could not set scope from import: func `os.is_debian` does not exist in this scope
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import "second.mcl"
|
|
||||||
|
|
||||||
import "os" # this fixes it but the wrong way
|
|
||||||
|
|
||||||
include second.xclass
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import "fmt"
|
|
||||||
|
|
||||||
class xclass {
|
|
||||||
# note that `os` is not imported here
|
|
||||||
$aaa = if os.is_debian() { "bbb" } else { "ccc" }
|
|
||||||
|
|
||||||
print "${aaa}" {
|
|
||||||
msg => "hello",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,20 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
import "second.mcl"
|
||||||
|
|
||||||
|
include second.xclass
|
||||||
|
-- second.mcl --
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
class xclass {
|
||||||
|
import "os" # we can also use a scoped local import
|
||||||
|
|
||||||
|
$aaa = if os.is_debian() { "bbb" } else { "ccc" }
|
||||||
|
|
||||||
|
print "${aaa}" {
|
||||||
|
msg => "hello",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:os.is_debian() -> if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } # c
|
Edge: call:os.is_debian() -> if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } # c
|
||||||
Edge: if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } -> var(aaa) # var:aaa
|
Edge: if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } -> var(aaa) # var:aaa
|
||||||
Edge: str("bbb") -> if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } # a
|
Edge: str("bbb") -> if( call:os.is_debian() ) { str("bbb") } else { str("ccc") } # a
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import "second.mcl"
|
|
||||||
|
|
||||||
include second.xclass
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import "fmt"
|
|
||||||
|
|
||||||
class xclass {
|
|
||||||
import "os" # we can also use a scoped local import
|
|
||||||
|
|
||||||
$aaa = if os.is_debian() { "bbb" } else { "ccc" }
|
|
||||||
|
|
||||||
print "${aaa}" {
|
|
||||||
msg => "hello",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,17 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
$prefix = "hello"
|
||||||
|
|
||||||
|
# this should be a function as a value, iow a lambda
|
||||||
|
$prefixer = func($x) {
|
||||||
|
$prefix + ":" + $x # i'd only ever expect one ":" in the graph
|
||||||
|
}
|
||||||
|
|
||||||
|
$out1 = $prefixer("world")
|
||||||
|
$out2 = $prefixer($out1)
|
||||||
|
|
||||||
|
test $out1 {}
|
||||||
|
test $out2 {}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) -> func(x) { call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) } # body
|
Edge: call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) -> func(x) { call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) } # body
|
||||||
Edge: call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) -> func(x) { call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) } # body
|
Edge: call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) -> func(x) { call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) } # body
|
||||||
Edge: call:_operator(str("+"), var(prefix), str(":")) -> call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) # a
|
Edge: call:_operator(str("+"), var(prefix), str(":")) -> call:_operator(str("+"), call:_operator(str("+"), var(prefix), str(":")), var(x)) # a
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
$prefix = "hello"
|
|
||||||
|
|
||||||
# this should be a function as a value, iow a lambda
|
|
||||||
$prefixer = func($x) {
|
|
||||||
$prefix + ":" + $x # i'd only ever expect one ":" in the graph
|
|
||||||
}
|
|
||||||
|
|
||||||
$out1 = $prefixer("world")
|
|
||||||
$out2 = $prefixer($out1)
|
|
||||||
|
|
||||||
test $out1 {}
|
|
||||||
test $out2 {}
|
|
||||||
@@ -1,3 +1,67 @@
|
|||||||
|
-- metadata.yaml --
|
||||||
|
main: "main/hello.mcl" # this is not the default, the default is "main.mcl"
|
||||||
|
files: "files/" # these are some extra files we can use (is the default)
|
||||||
|
path: "path/" # where to look for modules, defaults to using a global
|
||||||
|
-- main/h2g2.mcl --
|
||||||
|
import "third.mcl"
|
||||||
|
|
||||||
|
$answer = 42 + $third.three
|
||||||
|
-- main/hello.mcl --
|
||||||
|
import "fmt"
|
||||||
|
import "h2g2.mcl"
|
||||||
|
import "mod1/"
|
||||||
|
|
||||||
|
# imports as example1
|
||||||
|
import "git://github.com/purpleidea/mgmt-example1/"
|
||||||
|
import "git://github.com/purpleidea/mgmt-example2/"
|
||||||
|
|
||||||
|
$answer = $h2g2.answer
|
||||||
|
|
||||||
|
test "hello" {
|
||||||
|
anotherstr => fmt.printf("the answer is: %d", $answer),
|
||||||
|
}
|
||||||
|
test "hello2" {
|
||||||
|
anotherstr => fmt.printf("i imported local: %s", $mod1.name),
|
||||||
|
}
|
||||||
|
test "hello3" {
|
||||||
|
anotherstr => fmt.printf("i imported remote: %s and %s", $example1.name, $example2.ex1),
|
||||||
|
}
|
||||||
|
-- main/third.mcl --
|
||||||
|
$three = 3
|
||||||
|
-- main/mod1/metadata.yaml --
|
||||||
|
# empty metadata file (use defaults)
|
||||||
|
-- main/mod1/main.mcl --
|
||||||
|
import "mod1/" # the nested version, not us
|
||||||
|
|
||||||
|
$name = "this is module mod1 which contains: " + $mod1.name
|
||||||
|
-- main/mod1/mod1/metadata.yaml --
|
||||||
|
# empty metadata file (use defaults)
|
||||||
|
-- main/mod1/mod1/main.mcl --
|
||||||
|
$name = "this is the nested local module mod1"
|
||||||
|
-- path/github.com/purpleidea/mgmt-example1/metadata.yaml --
|
||||||
|
main: "main.mcl"
|
||||||
|
files: "files/" # these are some extra files we can use (is the default)
|
||||||
|
-- path/github.com/purpleidea/mgmt-example1/main.mcl --
|
||||||
|
# this is a pretty lame module!
|
||||||
|
import "mod1/" # yet another similarly named "mod1" import
|
||||||
|
|
||||||
|
$name = "i am github.com/purpleidea/mgmt-example1/ and i contain: " + $mod1.name
|
||||||
|
-- path/github.com/purpleidea/mgmt-example1/mod1/metadata.yaml --
|
||||||
|
# empty metadata file (use defaults)
|
||||||
|
-- path/github.com/purpleidea/mgmt-example1/mod1/main.mcl --
|
||||||
|
$name = "this is the nested git module mod1"
|
||||||
|
-- path/github.com/purpleidea/mgmt-example2/metadata.yaml --
|
||||||
|
main: "main.mcl"
|
||||||
|
files: "files/" # these are some extra files we can use (is the default)
|
||||||
|
path: "path/" # specify this, even though we already imported in parent
|
||||||
|
parentpathblock: false
|
||||||
|
-- path/github.com/purpleidea/mgmt-example2/main.mcl --
|
||||||
|
# this is a pretty lame module!
|
||||||
|
import "git://github.com/purpleidea/mgmt-example1/" # import another module
|
||||||
|
$ex1 = $example1.name
|
||||||
|
|
||||||
|
$name = "i am github.com/purpleidea/mgmt-example2/ and i contain: " + $ex1
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:_operator(str("+"), int(42), var(third.three)) -> var(h2g2.answer) # var:h2g2.answer
|
Edge: call:_operator(str("+"), int(42), var(third.three)) -> var(h2g2.answer) # var:h2g2.answer
|
||||||
Edge: call:_operator(str("+"), str("i am github.com/purpleidea/mgmt-example1/ and i contain: "), var(mod1.name)) -> var(example1.name) # var:example1.name
|
Edge: call:_operator(str("+"), str("i am github.com/purpleidea/mgmt-example1/ and i contain: "), var(mod1.name)) -> var(example1.name) # var:example1.name
|
||||||
Edge: call:_operator(str("+"), str("i am github.com/purpleidea/mgmt-example1/ and i contain: "), var(mod1.name)) -> var(example1.name) # var:example1.name
|
Edge: call:_operator(str("+"), str("i am github.com/purpleidea/mgmt-example1/ and i contain: "), var(mod1.name)) -> var(example1.name) # var:example1.name
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import "third.mcl"
|
|
||||||
|
|
||||||
$answer = 42 + $third.three
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import "fmt"
|
|
||||||
import "h2g2.mcl"
|
|
||||||
import "mod1/"
|
|
||||||
|
|
||||||
# imports as example1
|
|
||||||
import "git://github.com/purpleidea/mgmt-example1/"
|
|
||||||
import "git://github.com/purpleidea/mgmt-example2/"
|
|
||||||
|
|
||||||
$answer = $h2g2.answer
|
|
||||||
|
|
||||||
test "hello" {
|
|
||||||
anotherstr => fmt.printf("the answer is: %d", $answer),
|
|
||||||
}
|
|
||||||
test "hello2" {
|
|
||||||
anotherstr => fmt.printf("i imported local: %s", $mod1.name),
|
|
||||||
}
|
|
||||||
test "hello3" {
|
|
||||||
anotherstr => fmt.printf("i imported remote: %s and %s", $example1.name, $example2.ex1),
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import "mod1/" # the nested version, not us
|
|
||||||
|
|
||||||
$name = "this is module mod1 which contains: " + $mod1.name
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# empty metadata file (use defaults)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
$name = "this is the nested local module mod1"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# empty metadata file (use defaults)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
$three = 3
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
main: "main/hello.mcl" # this is not the default, the default is "main.mcl"
|
|
||||||
files: "files/" # these are some extra files we can use (is the default)
|
|
||||||
path: "path/" # where to look for modules, defaults to using a global
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# this is a pretty lame module!
|
|
||||||
import "mod1/" # yet another similarly named "mod1" import
|
|
||||||
|
|
||||||
$name = "i am github.com/purpleidea/mgmt-example1/ and i contain: " + $mod1.name
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
main: "main.mcl"
|
|
||||||
files: "files/" # these are some extra files we can use (is the default)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
$name = "this is the nested git module mod1"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# empty metadata file (use defaults)
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# this is a pretty lame module!
|
|
||||||
import "git://github.com/purpleidea/mgmt-example1/" # import another module
|
|
||||||
$ex1 = $example1.name
|
|
||||||
|
|
||||||
$name = "i am github.com/purpleidea/mgmt-example2/ and i contain: " + $ex1
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
main: "main.mcl"
|
|
||||||
files: "files/" # these are some extra files we can use (is the default)
|
|
||||||
path: "path/" # specify this, even though we already imported in parent
|
|
||||||
parentpathblock: false
|
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
# note that the class can have two separate types for $b
|
||||||
|
include c1("t1", "hello") # len is 5
|
||||||
|
include c1("t2", [13, 42, 0, -37,]) # len is 4
|
||||||
|
class c1($a, $b) {
|
||||||
|
test $a {
|
||||||
|
anotherstr => fmt.printf("len is: %d", len($b)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:len(var(b)) -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # a
|
Edge: call:len(var(b)) -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # a
|
||||||
Edge: call:len(var(b)) -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # a
|
Edge: call:len(var(b)) -> call:fmt.printf(str("len is: %d"), call:len(var(b))) # a
|
||||||
Edge: int(-37) -> list(int(13), int(42), int(0), int(-37)) # 3
|
Edge: int(-37) -> list(int(13), int(42), int(0), int(-37)) # 3
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import "fmt"
|
|
||||||
|
|
||||||
# note that the class can have two separate types for $b
|
|
||||||
include c1("t1", "hello") # len is 5
|
|
||||||
include c1("t2", [13, 42, 0, -37,]) # len is 4
|
|
||||||
class c1($a, $b) {
|
|
||||||
test $a {
|
|
||||||
anotherstr => fmt.printf("len is: %d", len($b)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errUnify: can't unify, invariant illogicality with equals: base kind does not match (Str != List)
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
# note that the class can have two separate types for $b
|
# note that the class can have two separate types for $b
|
||||||
@@ -10,3 +11,5 @@ class c1($a, $b []str) {
|
|||||||
anotherstr => fmt.printf("len is: %d", len($b)),
|
anotherstr => fmt.printf("len is: %d", len($b)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errUnify: can't unify, invariant illogicality with equals: base kind does not match (Str != List)
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errSetScope: recursive reference while setting scope: not a dag
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
import "fmt"
|
import "fmt"
|
||||||
$max = 3
|
$max = 3
|
||||||
include c1(0) # start at zero
|
include c1(0) # start at zero
|
||||||
@@ -10,3 +11,5 @@ class c1($count) {
|
|||||||
include c1($count + 1) # recursion not supported atm
|
include c1($count + 1) # recursion not supported atm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errSetScope: recursive reference while setting scope: not a dag
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errSetScope: recursive reference while setting scope: not a dag
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
# this currently fails with: "class `c1` does not exist in this scope"
|
# this currently fails with: "class `c1` does not exist in this scope"
|
||||||
# instead of: "recursive class `c1` found" or "recursive class `c2` found"
|
# instead of: "recursive class `c1` found" or "recursive class `c2` found"
|
||||||
# ideally, we'd consider allowing finite (static) recursion such as this...
|
# ideally, we'd consider allowing finite (static) recursion such as this...
|
||||||
@@ -22,3 +23,5 @@ class c2($count) {
|
|||||||
include c1($count + 1) # recursion not supported atm
|
include c1($count + 1) # recursion not supported atm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errSetScope: recursive reference while setting scope: not a dag
|
||||||
@@ -1,3 +1,65 @@
|
|||||||
|
-- metadata.yaml --
|
||||||
|
main: "main/hello.mcl" # this is not the default, the default is "main.mcl"
|
||||||
|
files: "files/" # these are some extra files we can use (is the default)
|
||||||
|
path: "path/" # where to look for modules, defaults to using a global
|
||||||
|
-- main/h2g2.mcl --
|
||||||
|
import "third.mcl"
|
||||||
|
|
||||||
|
$answer = 42 + $third.three
|
||||||
|
-- main/hello.mcl --
|
||||||
|
import "fmt"
|
||||||
|
import "h2g2.mcl"
|
||||||
|
import "mod1/"
|
||||||
|
|
||||||
|
# imports as example1
|
||||||
|
import "git://github.com/purpleidea/mgmt-example1/"
|
||||||
|
import "git://github.com/purpleidea/mgmt-example2/"
|
||||||
|
|
||||||
|
$answer = $h2g2.answer
|
||||||
|
|
||||||
|
test "hello" {
|
||||||
|
anotherstr => fmt.printf("the answer is: %d", $answer),
|
||||||
|
}
|
||||||
|
test "hello2" {
|
||||||
|
anotherstr => fmt.printf("i imported local: %s", $mod1.name),
|
||||||
|
}
|
||||||
|
test "hello3" {
|
||||||
|
anotherstr => fmt.printf("i imported remote: %s and %s", $example1.name, $example2.ex1),
|
||||||
|
}
|
||||||
|
-- main/third.mcl --
|
||||||
|
$three = 3
|
||||||
|
-- main/mod1/metadata.yaml --
|
||||||
|
# empty metadata file (use defaults)
|
||||||
|
-- main/mod1/main.mcl --
|
||||||
|
import "mod1/" # the nested version, not us
|
||||||
|
|
||||||
|
$name = "this is module mod1 which contains: " + $mod1.name
|
||||||
|
-- main/mod1/mod1/metadata.yaml --
|
||||||
|
# empty metadata file (use defaults)
|
||||||
|
-- main/mod1/mod1/main.mcl --
|
||||||
|
$name = "this is the nested local module mod1"
|
||||||
|
-- path/github.com/purpleidea/mgmt-example1/metadata.yaml --
|
||||||
|
main: "main.mcl"
|
||||||
|
files: "files/" # these are some extra files we can use (is the default)
|
||||||
|
-- path/github.com/purpleidea/mgmt-example1/main.mcl --
|
||||||
|
# this is a pretty lame module!
|
||||||
|
import "mod1/" # yet another similarly named "mod1" import
|
||||||
|
|
||||||
|
$name = "i am github.com/purpleidea/mgmt-example1/ and i contain: " + $mod1.name
|
||||||
|
-- path/github.com/purpleidea/mgmt-example1/mod1/metadata.yaml --
|
||||||
|
# empty metadata file (use defaults)
|
||||||
|
-- path/github.com/purpleidea/mgmt-example1/mod1/main.mcl --
|
||||||
|
$name = "this is the nested git module mod1"
|
||||||
|
-- path/github.com/purpleidea/mgmt-example2/metadata.yaml --
|
||||||
|
main: "main.mcl"
|
||||||
|
files: "files/" # these are some extra files we can use (is the default)
|
||||||
|
-- path/github.com/purpleidea/mgmt-example2/main.mcl --
|
||||||
|
# this is a pretty lame module!
|
||||||
|
import "git://github.com/purpleidea/mgmt-example1/" # import another module
|
||||||
|
$ex1 = $example1.name
|
||||||
|
|
||||||
|
$name = "i am github.com/purpleidea/mgmt-example2/ and i contain: " + $ex1
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:_operator(str("+"), int(42), var(third.three)) -> var(h2g2.answer) # var:h2g2.answer
|
Edge: call:_operator(str("+"), int(42), var(third.three)) -> var(h2g2.answer) # var:h2g2.answer
|
||||||
Edge: call:_operator(str("+"), str("i am github.com/purpleidea/mgmt-example1/ and i contain: "), var(mod1.name)) -> var(example1.name) # var:example1.name
|
Edge: call:_operator(str("+"), str("i am github.com/purpleidea/mgmt-example1/ and i contain: "), var(mod1.name)) -> var(example1.name) # var:example1.name
|
||||||
Edge: call:_operator(str("+"), str("i am github.com/purpleidea/mgmt-example1/ and i contain: "), var(mod1.name)) -> var(example1.name) # var:example1.name
|
Edge: call:_operator(str("+"), str("i am github.com/purpleidea/mgmt-example1/ and i contain: "), var(mod1.name)) -> var(example1.name) # var:example1.name
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import "third.mcl"
|
|
||||||
|
|
||||||
$answer = 42 + $third.three
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import "fmt"
|
|
||||||
import "h2g2.mcl"
|
|
||||||
import "mod1/"
|
|
||||||
|
|
||||||
# imports as example1
|
|
||||||
import "git://github.com/purpleidea/mgmt-example1/"
|
|
||||||
import "git://github.com/purpleidea/mgmt-example2/"
|
|
||||||
|
|
||||||
$answer = $h2g2.answer
|
|
||||||
|
|
||||||
test "hello" {
|
|
||||||
anotherstr => fmt.printf("the answer is: %d", $answer),
|
|
||||||
}
|
|
||||||
test "hello2" {
|
|
||||||
anotherstr => fmt.printf("i imported local: %s", $mod1.name),
|
|
||||||
}
|
|
||||||
test "hello3" {
|
|
||||||
anotherstr => fmt.printf("i imported remote: %s and %s", $example1.name, $example2.ex1),
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import "mod1/" # the nested version, not us
|
|
||||||
|
|
||||||
$name = "this is module mod1 which contains: " + $mod1.name
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# empty metadata file (use defaults)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
$name = "this is the nested local module mod1"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# empty metadata file (use defaults)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
$three = 3
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
main: "main/hello.mcl" # this is not the default, the default is "main.mcl"
|
|
||||||
files: "files/" # these are some extra files we can use (is the default)
|
|
||||||
path: "path/" # where to look for modules, defaults to using a global
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# this is a pretty lame module!
|
|
||||||
import "mod1/" # yet another similarly named "mod1" import
|
|
||||||
|
|
||||||
$name = "i am github.com/purpleidea/mgmt-example1/ and i contain: " + $mod1.name
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
main: "main.mcl"
|
|
||||||
files: "files/" # these are some extra files we can use (is the default)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
$name = "this is the nested git module mod1"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# empty metadata file (use defaults)
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# this is a pretty lame module!
|
|
||||||
import "git://github.com/purpleidea/mgmt-example1/" # import another module
|
|
||||||
$ex1 = $example1.name
|
|
||||||
|
|
||||||
$name = "i am github.com/purpleidea/mgmt-example2/ and i contain: " + $ex1
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
main: "main.mcl"
|
|
||||||
files: "files/" # these are some extra files we can use (is the default)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errGraph: resource has duplicate meta entry of: noop
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
test "test" {
|
test "test" {
|
||||||
anotherstr => "test",
|
anotherstr => "test",
|
||||||
|
|
||||||
@@ -20,3 +21,5 @@ test "test" {
|
|||||||
#Meta:autoedge => true,
|
#Meta:autoedge => true,
|
||||||
#Meta:autogroup => false,
|
#Meta:autogroup => false,
|
||||||
}
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errGraph: resource has duplicate meta entry of: noop
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errInit: resource has duplicate field of: anotherstr
|
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
|
-- main.mcl --
|
||||||
test "test" {
|
test "test" {
|
||||||
anotherstr => "hello",
|
anotherstr => "hello",
|
||||||
anotherstr => "hello", # values aren't checked in dupe checks
|
anotherstr => "hello", # values aren't checked in dupe checks
|
||||||
}
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errInit: resource has duplicate field of: anotherstr
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errInit: resource has duplicate field of: anotherstr
|
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
|
-- main.mcl --
|
||||||
test "test" {
|
test "test" {
|
||||||
anotherstr => "hello",
|
anotherstr => "hello",
|
||||||
anotherstr => "hello world", # values aren't checked in dupe checks
|
anotherstr => "hello world", # values aren't checked in dupe checks
|
||||||
}
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errInit: resource has duplicate field of: anotherstr
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errInit: resource has duplicate meta entry of: noop
|
|
||||||
8
lang/interpret_test/TestAstFunc1/resdupefields3.txtar
Normal file
8
lang/interpret_test/TestAstFunc1/resdupefields3.txtar
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
test "test" {
|
||||||
|
anotherstr => "test",
|
||||||
|
Meta:noop => false,
|
||||||
|
Meta:noop => false,
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errInit: resource has duplicate meta entry of: noop
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
test "test" {
|
|
||||||
anotherstr => "test",
|
|
||||||
Meta:noop => false,
|
|
||||||
Meta:noop => false,
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# err: errInit: resource has duplicate meta entry of: noop
|
|
||||||
8
lang/interpret_test/TestAstFunc1/resdupefields4.txtar
Normal file
8
lang/interpret_test/TestAstFunc1/resdupefields4.txtar
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
test "test" {
|
||||||
|
anotherstr => "test",
|
||||||
|
Meta:noop => false,
|
||||||
|
Meta:noop => true,
|
||||||
|
}
|
||||||
|
-- OUTPUT --
|
||||||
|
# err: errInit: resource has duplicate meta entry of: noop
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
test "test" {
|
|
||||||
anotherstr => "test",
|
|
||||||
Meta:noop => false,
|
|
||||||
Meta:noop => true,
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
# XXX: should error at graph unification, but we have a type unification bug
|
# XXX: should error at graph unification, but we have a type unification bug
|
||||||
#test "test" {
|
#test "test" {
|
||||||
# anotherstr => "test",
|
# anotherstr => "test",
|
||||||
@@ -20,3 +21,4 @@
|
|||||||
# noop => false,
|
# noop => false,
|
||||||
# },
|
# },
|
||||||
#}
|
#}
|
||||||
|
-- OUTPUT --
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-- main.mcl --
|
||||||
# XXX: should work, but we have a type unification bug
|
# XXX: should work, but we have a type unification bug
|
||||||
#test "test" {
|
#test "test" {
|
||||||
# anotherstr => "test",
|
# anotherstr => "test",
|
||||||
@@ -19,3 +20,4 @@
|
|||||||
# Meta:noop => true,
|
# Meta:noop => true,
|
||||||
# Meta:autoedge => true,
|
# Meta:autoedge => true,
|
||||||
#}
|
#}
|
||||||
|
-- OUTPUT --
|
||||||
@@ -1,3 +1,16 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
# simple function definition containing function to be returned
|
||||||
|
func funcgen() {
|
||||||
|
func() {
|
||||||
|
"hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fn = funcgen()
|
||||||
|
$out = $fn()
|
||||||
|
|
||||||
|
test $out {}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:fn() -> var(out) # var:out
|
Edge: call:fn() -> var(out) # var:out
|
||||||
Edge: call:funcgen() -> call:fn() # call:fn
|
Edge: call:funcgen() -> call:fn() # call:fn
|
||||||
Edge: func() { func() { str("hello") } } -> call:funcgen() # call:funcgen
|
Edge: func() { func() { str("hello") } } -> call:funcgen() # call:funcgen
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# simple function definition containing function to be returned
|
|
||||||
func funcgen() {
|
|
||||||
func() {
|
|
||||||
"hello"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$fn = funcgen()
|
|
||||||
$out = $fn()
|
|
||||||
|
|
||||||
test $out {}
|
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
$funcgen = func() {
|
||||||
|
func() {
|
||||||
|
"hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fn = $funcgen()
|
||||||
|
$out = $fn()
|
||||||
|
|
||||||
|
test $out {}
|
||||||
|
-- OUTPUT --
|
||||||
Edge: call:fn() -> var(out) # var:out
|
Edge: call:fn() -> var(out) # var:out
|
||||||
Edge: call:funcgen() -> call:fn() # call:fn
|
Edge: call:funcgen() -> call:fn() # call:fn
|
||||||
Edge: func() { func() { str("hello") } } -> call:funcgen() # call:funcgen
|
Edge: func() { func() { str("hello") } } -> call:funcgen() # call:funcgen
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
$funcgen = func() {
|
|
||||||
func() {
|
|
||||||
"hello"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$fn = $funcgen()
|
|
||||||
$out = $fn()
|
|
||||||
|
|
||||||
test $out {}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Edge: str("hello") -> var(x) # var:x
|
|
||||||
Vertex: bool(true)
|
|
||||||
Vertex: str("hello")
|
|
||||||
Vertex: var(x)
|
|
||||||
12
lang/interpret_test/TestAstFunc1/shadowing1.txtar
Normal file
12
lang/interpret_test/TestAstFunc1/shadowing1.txtar
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
-- main.mcl --
|
||||||
|
# this should be okay, because var is shadowed
|
||||||
|
$x = "hello"
|
||||||
|
if true {
|
||||||
|
$x = "world" # shadowed
|
||||||
|
}
|
||||||
|
test $x {}
|
||||||
|
-- OUTPUT --
|
||||||
|
Edge: str("hello") -> var(x) # var:x
|
||||||
|
Vertex: bool(true)
|
||||||
|
Vertex: str("hello")
|
||||||
|
Vertex: var(x)
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# this should be okay, because var is shadowed
|
|
||||||
$x = "hello"
|
|
||||||
if true {
|
|
||||||
$x = "world" # shadowed
|
|
||||||
}
|
|
||||||
test $x {}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user