-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathconditional.go
124 lines (107 loc) · 3.13 KB
/
conditional.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package structs
import (
"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["if"] = proc.GoFunction{Func: cmdIf, TypeIn: types.Generic, TypeOut: types.Generic}
proc.GoFunctions["!if"] = proc.GoFunction{Func: cmdIf, TypeIn: types.Generic, TypeOut: types.Generic}
}
func cmdIf(p *proc.Process) (err error) {
var ifBlock, thenBlock, elseBlock []rune
switch {
case p.Parameters.Len() == 1 && p.IsMethod:
// "if" taken from stdin, "then" from 1st parameter.
thenBlock, err = p.Parameters.Block(0)
if err != nil {
return err
}
case p.Parameters.Len() == 2 && p.IsMethod:
// "if" taken from stdin, "then" and "else" from 1st and 2nd parameter.
thenBlock, err = p.Parameters.Block(0)
if err != nil {
return err
}
elseBlock, err = p.Parameters.Block(1)
if err != nil {
return err
}
case p.Parameters.Len() == 2 && !p.IsMethod:
// "if" taken from 1st parameter, "then" from 2nd parameter.
ifBlock, err = p.Parameters.Block(0)
if err != nil {
return err
}
thenBlock, err = p.Parameters.Block(1)
if err != nil {
return err
}
case p.Parameters.Len() == 3 && !p.IsMethod:
// "if" taken from 1st parameter, "then" from 2nd, "else" from 3rd.
ifBlock, err = p.Parameters.Block(0)
if err != nil {
return err
}
thenBlock, err = p.Parameters.Block(1)
if err != nil {
return err
}
elseBlock, err = p.Parameters.Block(2)
if err != nil {
return err
}
default:
if !p.IsNot {
return errors.New(`Not a valid if statement. Usage:
$conditional -> if: { $then } # conditional result read from stdin or previous process exit number
$conditional -> if: { $then } { $else } # conditional result read from stdin or previous process exit number
if: { $conditional } { $then } # if / then
if: { $conditional } { $then } { $else } # if / then / else
`)
} else {
return errors.New(`Not a valid if statement. Usage:
$conditional -> !if: { $else } # conditional result read from stdin or previous process exit number
$conditional -> !if: { $else } { $then } # conditional result read from stdin or previous process exit number
!if: { $conditional } { $else } # if / then
!if: { $conditional } { $else } { $then } # if / then / else
`)
}
}
var conditional bool
if len(ifBlock) != 0 {
// --- IF ---
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)
} else {
// --- IF ---
b := p.Stdin.ReadAll()
conditional = types.IsTrue(b, p.Previous.ExitNum)
}
if (conditional && !p.IsNot) || (!conditional && p.IsNot) {
// --- THEN ---
_, err = lang.ProcessNewBlock(thenBlock, nil, p.Stdout, p.Stderr, types.Null)
if err != nil {
return
}
} else {
// --- ELSE ---
if len(elseBlock) != 0 {
_, err = lang.ProcessNewBlock(elseBlock, nil, p.Stdout, p.Stderr, types.Null)
if err != nil {
return
}
} else {
p.ExitNum = 1
}
}
return
}