-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathiteration.go
97 lines (79 loc) · 2.03 KB
/
iteration.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package structs
import (
"bytes"
"errors"
"github.com/lmorg/murex/lang"
"github.com/lmorg/murex/lang/proc"
"github.com/lmorg/murex/lang/proc/streams"
"github.com/lmorg/murex/lang/types"
)
func init() {
proc.GoFunctions["foreach"] = proc.GoFunction{Func: cmdForEach, TypeIn: types.Generic, TypeOut: types.Generic}
proc.GoFunctions["while"] = proc.GoFunction{Func: cmdWhile, TypeIn: types.Null, TypeOut: types.Generic}
}
func cmdForEach(p *proc.Process) (err error) {
block, err := p.Parameters.Block(1)
if err != nil {
return err
}
varName, err := p.Parameters.String(0)
if err != nil {
return err
}
p.Stdin.ReadLineFunc(func(b []byte) {
b = bytes.TrimSpace(b)
if len(b) == 0 {
return
}
proc.GlobalVars.Set(varName, string(b), p.Previous.ReturnType)
stdin := streams.NewStdin()
stdin.Writeln(b)
stdin.Close()
lang.ProcessNewBlock(block, stdin, p.Stdout, p.Stderr, p.Previous.Name)
})
return nil
}
func cmdWhile(p *proc.Process) error {
switch p.Parameters.Len() {
case 1:
// Condition is taken from the while loop.
block, err := p.Parameters.Block(0)
if err != nil {
return err
}
for {
i, err := lang.ProcessNewBlock(block, nil, p.Stdout, p.Stderr, types.Null)
if err != nil || !types.IsTrue([]byte{}, i) {
return nil
}
}
case 2:
// Condition is first parameter, while loop is second.
ifBlock, err := p.Parameters.Block(0)
if err != nil {
return err
}
whileBlock, err := p.Parameters.Block(1)
if err != nil {
return err
}
for {
stdout := streams.NewStdin()
i, err := lang.ProcessNewBlock(ifBlock, nil, stdout, nil, types.Null)
if err != nil {
return err
}
stdout.Close()
b := stdout.ReadAll()
conditional := types.IsTrue(b, i)
if !conditional {
return nil
}
lang.ProcessNewBlock(whileBlock, nil, p.Stdout, p.Stderr, types.Null)
}
default:
// Error
return errors.New("Invalid number of parameters. Please read usage notes.")
}
return errors.New("cmdWhile(p *proc.Process) unexpected escaped a switch with default case.")
}