2 people like it.
Like the snippet!
Mini SNOBOL Interpreter
Minimal SNOBOL abstract syntax tree (AST), interpreter and internal DSL (but no parser), just enough to run some simple samples from Wikipedia's SNOBOL page: http://en.wikipedia.org/wiki/SNOBOL and most of the pattern matching examples from the SNOBOL 4 Tutorial http://www.snobol4.org/docs/burks/tutorial/ch4.htm
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:
|
type label = string
type name = string
type arithmetic = Add | Subtract | Multiply | Divide | Power
type value =
| String of string
| Integer of int
| Array of value[]
| Table of table
| Pattern of pattern
and table = System.Collections.Generic.Dictionary<string,value>
and expression =
| Value of value
| Variable of name
| GetItem of name * expression list
| Concat of expression list
| Arithmetic of expression * arithmetic * expression
| Convert of name * name
| NewArray of expression
| NewTable
and pattern =
| Expression of expression
| And of pattern list
| Or of pattern list
| ConditionalAssignment of pattern * name
| ImmediateAssignment of pattern * name
| Invoke of name * expression list
type transfer =
| Goto of label
| OnSuccessOrFailure of label * label
| OnSuccess of label
| OnFailure of label
type command =
| Assign of name * expression
| SetItem of name * expression list * expression
| Match of expression * pattern
| Replace of name * pattern * expression
| Unit
type line = {
Label : label option
Command : command
Transfer : transfer option
}
|
1:
2:
3:
4:
5:
6:
|
type environment = {
Subject:string;
Cursor:int;
Actions:(unit->unit) list
Result:value;
Success:bool }
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
|
let (|ToString|_|) = function
| String s -> Some s
| Integer n -> Some (n.ToString())
| Array _ | Table _ | Pattern _ -> None
let toString = function
| ToString s -> s
| _ -> invalidOp ""
let (|ParseInt|_|) s =
match System.Int32.TryParse(s) with
| true, n -> Some n
| false, _ -> None
let (|ToInt|_|) = function
| Integer n -> Some n
| String(ParseInt n) -> Some n
| _ -> None
let toInt = function
| ToInt n -> n
| _ -> invalidOp ""
|
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:
|
/// Match remainder of subject
let rem env =
let result = env.Subject.Substring(env.Cursor)
seq [{ env with Result=String result; Cursor=env.Subject.Length-1 }]
/// Match arbitrary characters
let arb env =
seq {
for n in 0..env.Subject.Length-env.Cursor ->
let result = env.Subject.Substring(env.Cursor,n)
{env with Cursor=env.Cursor+n; Result=String result }
}
/// Match fixed-length string
let len env n =
if n > env.Subject.Length + env.Cursor then
seq [{ env with Success=false }]
else
let result = env.Subject.Substring(env.Cursor,n)
seq [{ env with Cursor=env.Cursor+n; Result=String result }]
/// Verify cursor position
let pos env n =
if n = env.Cursor then seq [env]
else seq [{ env with Success=false }]
let rpos env n =
if n = env.Subject.Length - env.Cursor then seq [env]
else seq [{ env with Success=false }]
/// Match to fixed position
let tab env n =
if n >= env.Cursor && n < env.Subject.Length then
let result = env.Subject.Substring(env.Cursor, n - env.Cursor)
seq [{env with Result=String result; Cursor=n }]
else seq [{ env with Success=false }]
let rtab env n =
if (env.Subject.Length - env.Cursor) >= n then
let length = env.Subject.Length - env.Cursor - n
let result = env.Subject.Substring(env.Cursor, length)
seq [{env with Result=String result; Cursor=env.Subject.Length-n }]
else seq [{ env with Success=false }]
/// Match one character
let any env (s:string) =
let c = env.Subject.Chars(env.Cursor)
if s |> String.exists ((=)c) then
seq [{ env with Cursor=env.Cursor+1; Result=String(c.ToString()) }]
else
seq [{ env with Success=false }]
let notany env (s:string) =
let c = env.Subject.Chars(env.Cursor)
if not(s |> String.exists ((=)c)) then
seq [{ env with Cursor=env.Cursor+1; Result=String(c.ToString()) }]
else
seq [{ env with Success=false }]
/// Match a run of characters
let span env (s:string) =
let mutable n = 0
while env.Cursor+n < env.Subject.Length &&
let c = env.Subject.Chars(env.Cursor+n) in
(s |> String.exists ((=)(c))) do n <- n + 1
if n > 0
then
let result = env.Subject.Substring(env.Cursor,n)
seq [{ env with Cursor=env.Cursor+n; Result=String result }]
else seq [{ env with Success=false }]
let ``break`` env s =
let mutable n = 0
while env.Cursor+n < env.Subject.Length &&
let c = env.Subject.Chars(env.Cursor+n) in
(s |> String.exists ((=)(c)) |> not) do n <- n + 1
let result = env.Subject.Substring(env.Cursor,n)
seq [{ env with Cursor=env.Cursor+n; Result=String result }]
// Invoke a built-in function
let invoke env name args =
match name, args with
| "REM", [] -> rem env
| "ARB", [] -> arb env
| "LEN", [ToInt n] -> len env n
| "POS", [ToInt n] -> pos env n
| "RPOS", [ToInt n] -> rpos env n
| "TAB", [ToInt n] -> tab env n
| "RTAB", [ToInt n] -> rtab env n
| "ANY", [ToString s] -> any env s
| "NOTANY", [ToString s] -> notany env s
| "SPAN", [ToString s] -> span env s
| "BREAK", [ToString s] -> ``break`` env s
| _ -> failwith ("Function " + name + " not supported")
|
1:
2:
3:
4:
5:
|
type machine = {
Variables : System.Collections.Generic.IDictionary<name, value>
Input : unit -> string
Output : string -> unit
}
|
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:
|
let rec evaluate machine expression =
let get name =
match name with
| "INPUT" -> machine.Input () |> String
| _ -> machine.Variables.[name]
let getItem container index =
match container with
| Array(ar) ->
let index = toInt index
if index <= ar.Length then ar.[index-1]
else nil
| Table(table) ->
match table.TryGetValue(toString index) with
| true, value -> value
| false, _ -> nil
| _ -> invalidOp "Illegal data type"
match expression with
| Value(value) -> value
| Variable(name) -> get name
| GetItem(name, expressions) ->
let rec lookup item = function
| x::xs ->
let index = evaluate machine x
let item = getItem item index
lookup item xs
| [] -> item
let container = get name
lookup container expressions
| Concat(expressions) -> concat machine expressions
| Arithmetic(lhs,op,rhs) ->
match evaluate machine lhs, evaluate machine rhs with
| Integer l, Integer r -> Integer(arithmetic op l r)
| Integer l, String (ParseInt r) -> Integer(arithmetic op l r)
| String "", Integer r -> Integer(r)
| String (ParseInt l), Integer r -> Integer(arithmetic op l r)
| l, r -> invalidOp "Illegal data type"
| Convert(subject, target) ->
let value = get subject
match value, target with
| Table(table), "ARRAY" ->
Array
[|for kvp in table ->
Array [|String kvp.Key;String(toString kvp.Value)|] |]
| _ -> failwith "Not supported"
| NewArray(expression) ->
let length = evaluate machine expression |> toInt
Array(Array.create length nil)
| NewTable -> Table(table())
and arithmetic op l r =
match op with
| Add -> l + r
| Subtract -> l - r
| Multiply -> l * r
| Divide -> l / r
| Power -> pown l r
and concat machine expressions =
System.String.Concat
[for e in expressions -> evaluate machine e |> toString]
|> String
and nil = String ""
|
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:
|
let assign machine name value =
match name, value with
| "OUTPUT", Pattern(_) -> name |> machine.Output
| "OUTPUT", _ -> value |> toString |> machine.Output
| _, _ -> ()
machine.Variables.[name] <- value
let rec tryPattern machine env pattern : environment seq =
match pattern with
| Expression(expression) ->
let subject = env.Subject.Substring(env.Cursor)
let value = evaluate machine expression
match value with
| Pattern pattern -> tryPattern machine env pattern
| value ->
let value = value |> toString
if subject.StartsWith(value)
then
let cursor = env.Cursor+value.Length
let result = String value
seq [{ env with Cursor=cursor; Result=result }]
else
seq [{ env with Success = false }]
| And(patterns) ->
let rec applyPattern env = function
| [] -> env
| p::ps ->
let newEnvs = tryPattern machine env p
let found =
newEnvs |> Seq.tryPick (fun newEnv ->
if newEnv.Success then
let env = applyPattern newEnv ps
if env.Success
then Some env
else None
else None
)
match found with
| Some newEnv ->
let result = toString env.Result + toString newEnv.Result
{ newEnv with Result = String result }
| None -> {env with Success=false}
seq [applyPattern env patterns]
| Or(patterns) ->
let rec findPattern = function
| [] -> seq [{ env with Success = false }]
| p::ps ->
let newEnvs = tryPattern machine env p
match newEnvs |> Seq.tryFind (fun env -> env.Success) with
| Some env -> seq [env]
| None -> findPattern ps
findPattern patterns
| ConditionalAssignment(pattern,subject) ->
let envs = tryPattern machine env pattern
seq {
for env in envs ->
let onSuccess () = assign machine subject env.Result
{ env with Actions=onSuccess::env.Actions }
}
| ImmediateAssignment(pattern,subject) ->
let envs = tryPattern machine env pattern
seq {
for env in envs ->
assign machine subject env.Result
env
}
| Invoke(name, args) ->
invoke env name [for arg in args -> evaluate machine arg]
let patternMatch machine subject pattern =
let env = { Subject=subject; Cursor=0; Result=String ""; Actions=[]; Success=true }
let rec tryFromIndex n =
if n = subject.Length then { env with Success=false }
else
let env = { env with Cursor=n }
let found = tryPattern machine env pattern |> Seq.tryFind (fun env -> env.Success)
match found with
| None -> tryFromIndex (n+1)
| Some newEnv ->
for action in newEnv.Actions |> List.rev do action()
{ newEnv with Cursor = env.Cursor }
tryFromIndex 0
|
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:
|
let applyCommand machine command =
match command with
| Assign(subject, expression) ->
let value = evaluate machine expression
assign machine subject value
value <> nil
| SetItem(subject, [index], value) ->
let container = machine.Variables.[subject]
let index = evaluate machine index
let value = evaluate machine value
match container with
| Array(ar) -> (ar.[(toInt index)-1] <- value)
| Table(table) -> (table.[toString index] <- value)
| _ -> invalidOp "Illegal data type"
true
| SetItem _ -> failwith "Not supported"
| Match(subject, pattern) ->
let subject = evaluate machine subject |> toString
let env = patternMatch machine subject pattern
env.Success
| Replace(name, pattern, expression) ->
let subject = machine.Variables.[name] |> toString
let env = patternMatch machine subject pattern
if env.Success then
let s = subject.Remove(env.Cursor, (env.Result |> toString).Length)
.Insert(env.Cursor, evaluate machine expression |> toString)
assign machine name (String s)
env.Success
| Unit -> true
let tryFindTransfer success = function
| Goto label -> Some label
| (OnSuccessOrFailure(label,_) | OnSuccess(label)) when success ->
Some label
| (OnSuccessOrFailure(_,label) | OnFailure(label)) when not success ->
Some label
| _ -> None
let run (machine:machine) (lines:line list) =
let findLabel label =
lines
|> List.findIndex (fun line -> line.Label |> Option.exists ((=)label))
let rec gotoLine i =
let line = lines.[i]
let success =
try applyCommand machine line.Command
with e when line.Transfer.IsSome -> false
match line.Transfer with
| None ->
if i < lines.Length-1 then gotoLine (i+1)
| Some(transfer) ->
match tryFindTransfer success transfer with
| Some label -> findLabel label |> gotoLine
| None -> if i < lines.Length-1 then gotoLine (i+1)
gotoLine 0
|
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:
|
let S s = Value(String s)
let I s = Value(Integer s)
let V s = Variable(s)
let E e = Expression(e)
let P e = Value(Pattern(e))
let (+.) lhs rhs = Arithmetic(lhs,Add,rhs)
let (=.) name expression = Assign(name,expression)
let (.=) pattern name = ConditionalAssignment(pattern,name)
let ($) pattern name = ImmediateAssignment(pattern,name)
let (=?) subject pattern = Match(subject, pattern)
let (/=) pattern expressions = (pattern,expressions)
let (=/) (name) (pattern,expressions) = Replace(name,pattern,expressions)
let ARB = Invoke("ARB",[])
let REM = Invoke("REM",[])
let LEN(e) = Invoke("LEN",[e])
let POS(e) = Invoke("POS",[e])
let RPOS(e) = Invoke("RPOS",[e])
let TAB(e) = Invoke("TAB",[e])
let RTAB(e) = Invoke("RTAB",[e])
let ANY(e) = Invoke("ANY",[e])
let NOTANY(e) = Invoke("NOTANY",[e])
let SPAN(e) = Invoke("SPAN",[e])
let BREAK(e) = Invoke("BREAK",[e])
type Line =
static member Of(command,?label,?transfer) =
{Command=command; Label=label; Transfer=transfer}
let machine = {
Variables = System.Collections.Generic.Dictionary<_,_>()
Input = fun () -> ""
Output = printfn "%s"
}
|
1:
2:
3:
4:
5:
6:
|
(*
OUTPUT = "Hello world"
*)
[Line.Of( "OUTPUT" =. S"Hello World" )]
|> run machine
// > Hello World
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
|
(*
OUTPUT = "What is your name?"
Username = INPUT
OUTPUT = "Thank you, " Username
*)
[Line.Of( "OUTPUT" =. S"What is your name?")
Line.Of( "Username" =. V"INPUT")
Line.Of( "OUTPUT" =. Concat [S"Thank you, "; V"Username"])]
|> run {machine with Input = fun () -> "Doctor"}
// > What is your name?
// > Thank you, Doctor
|
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:
|
(*
OUTPUT = "What is your name?"
Username = INPUT
Username "Jay" :S(LOVE)
Username "Kay" :S(HATE)
MEH OUTPUT = "Hi, " Username :(END)
LOVE OUTPUT = "How nice to meet you, " Username :(END)
HATE OUTPUT = "Oh. It's you, " Username
END
*)
let program =
[
Line.Of("OUTPUT" =. S"What is your name?")
Line.Of("Username" =. V"INPUT")
Line.Of(V"Username" =? E(S"J"), transfer=OnSuccess "LOVE")
Line.Of(V"Username" =? E(S"K"), transfer=OnSuccess "HATE")
Line.Of("OUTPUT" =. Concat [S"Hi, ";V"Username"], label="MEH",
transfer=Goto "END")
Line.Of("OUTPUT" =. Concat [S"How nice to meet you, "; V"Username"], label="LOVE",
transfer=Goto "END")
Line.Of("OUTPUT" =. Concat [S"Oh. It's you, "; V"Username"], label="HATE")
Line.Of(Unit, label="END")
]
program |> run { machine with Input = fun () -> "Jay" }
// > What is your name?
// > How nice to meet you, Jay
program |> run { machine with Input = fun () -> "Kay" }
// > What is your name?
// > Oh. It's you, Kay
program |> run { machine with Input = fun () -> "Bob" }
// > What is your name?
// > Hi, Bob
|
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:
|
(*
OUTPUT = "This program will ask you for personal names"
OUTPUT = "until you press return without giving it one"
NameCount = 0 :(GETINPUT)
AGAIN NameCount = NameCount + 1
OUTPUT = "Name " NameCount ": " PersonalName
GETINPUT OUTPUT = "Please give me name " NameCount + 1
PersonalName = INPUT
PersonalName LEN(1) :S(AGAIN)
OUTPUT = "Finished. " NameCount " names requested."
END
*)
let loop =
[
Line.Of("OUTPUT" =. S"This program will ask you for personal names")
Line.Of("OUTPUT" =. S"until you press return without giving it one")
Line.Of("NameCount" =. I 0, transfer=Goto "GETINPUT")
Line.Of("NameCount" =. V"NameCount" +. I 1, label="AGAIN")
Line.Of("OUTPUT" =. Concat [S"Name ";V"NameCount";S": ";V"PersonalName"])
Line.Of("PersonalName" =. V"INPUT", label="GETINPUT")
Line.Of(V"PersonalName" =? LEN(I 1), transfer=OnSuccess "AGAIN")
Line.Of("OUTPUT" =. Concat [S"Finished. ";V"NameCount";S" names requested."] )
]
let names = seq ["Billy"; "Bob"; "Thornton"]
let successive (inputs:string seq) =
let e = inputs.GetEnumerator()
fun () -> if e.MoveNext() then e.Current else ""
loop |> run { machine with Input=successive names }
// > This program will ask you for personal names
// > until you press return without giving it one
// > Name 1: Billy
// > Name 2: Bob
// > Name 3: Thornton
// > Finished. 3 names requested.
|
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:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
|
(*
'BLUEBIRD' 'BIRD' . OUTPUT
END
*)
let bird = [Line.Of( S"BLUEBIRD" =? (E(S"BIRD") .= "OUTPUT") )]
bird |> run machine
// > BIRD
(*
B = 'BLUEBIRD'
B ('BLUE' | 'GOLD') . OUTPUT
G = 'GOLDFISH'
G ('BLUE' | 'GOLD') . OUTPUT
COLOR = 'BLUE' | 'GOLD'
B COLOR . OUTPUT
END
*)
let color =
[
// B = 'BLUEBIRD'
Line.Of("B" =. S"BLUEBIRD")
// B ('BLUE' | 'GOLD') . OUTPUT
Line.Of(V"B" =? (Or [E(S"BLUE");E(S"GOLD")] .= "OUTPUT"))
// G = 'GOLDFISH'
Line.Of("G" =. S"GOLDFISH")
// B ('BLUE' | 'GOLD') . OUTPUT
Line.Of(V"G" =? (Or [E(S"BLUE");E(S"GOLD")] .= "OUTPUT"))
// COLOR = 'BLUE' | 'GOLD'
Line.Of("COLOR" =. P(Or [E(S"GOLD");E(S"BLUE")]))
// B COLOR . OUTPUT
Line.Of(V"B" =? (E(V"COLOR") .= "OUTPUT"))
]
color |> run machine
// > BLUE
// > GOLD
// > BLUE
(*
'B2' ('A' | 'B') . OUTPUT (1 | 2 | 3) . OUTPUT
*)
let b2 =
[
Line.Of(S"B2" =? And [ Or [E(S"A");E(S"B")] .= "OUTPUT"
Or [E(S"1");E(S"2");E(S"3")] .= "OUTPUT"] )
]
b2 |> run machine
// > B
// > 2
(*
'THE WINTER WINDS' 'WIN' REM . OUTPUT
*)
let winter = [Line.Of(S"THE WINTER WINDS" =? And[E(S"WIN"); REM .= "OUTPUT"])]
winter |> run machine
// > TER WINDS
(*
'MOUNTAIN' 'O' ARB . OUTPUT 'A'
'MOUNTAIN' 'O' ARB . OUTPUT 'U'
*)
let mountain =
[Line.Of(S"MOUNTAIN" =? And[E(S"O");ARB .= "OUTPUT";E(S"A")])
Line.Of(S"MOUNTAIN" =? And[E(S"O");ARB .= "OUTPUT";E(S"U")])]
mountain |> run machine
// > UNT
// >
(*
S = 'ABCDA'
S LEN(3) . OUTPUT RPOS(0)
S POS(3) LEN(1) . OUTPUT
*)
let abcda =
[
Line.Of("S" =. S"ABCDA")
Line.Of(V"S" =? And[LEN(I 3) .= "OUTPUT";RPOS(I 0)])
Line.Of(V"S" =? And[POS(I 3);LEN(I 1) .= "OUTPUT"])
]
abcda |> run machine
// > CDA
// > D
(*
'ABCDE' TAB(2) . OUTPUT RTAB(1) . OUTPUT REM . OUTPUT
*)
let abcde =
[
Line.Of(S"ABCDE" =? And [TAB(I 2) .= "OUTPUT"
RTAB(I 1) .= "OUTPUT"
REM .= "OUTPUT" ])
]
abcde |> run machine
// > AB
// > CD
// > E
(*
VOWEL = ANY('AEIOU')
DVOWEL = VOWEL VOWEL
NOTVOWEL = NOTANY('AEIOU')
'VACUUM' VOWEL . OUTPUT
'VACUUM' DVOWEL . OUTPUT
'VACUUM' (VOWEL NOTVOWEL) . OUTPUT
*)
let vacuum =
[
Line.Of("VOWEL" =. P(ANY(S"AEIOU")))
Line.Of("DVOWEL" =. P(And[E(V"VOWEL");E(V"VOWEL")]))
Line.Of("NOTVOWEL" =. P(NOTANY(S"AEIOU")))
Line.Of(S"VACUUM" =? (E(V"VOWEL") .= "OUTPUT"))
Line.Of(S"VACUUM" =? (E(V"DVOWEL") .= "OUTPUT"))
Line.Of(S"VACUUM" =? (And [E(V"VOWEL");E(V"NOTVOWEL")] .= "OUTPUT"))
]
vacuum |> run machine
// > A
// > UU
// > AC
(*
LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ'-"
WORD = SPAN(LETTERS)
'SAMPLE LINE' WORD . OUTPUT
GAP = BREAK(LETTERS)
GAPO = GAP . OUTPUT
WORDO = WORD . OUTPUT
': ONE, TWO, THREE' GAPO WORDO GAPO WORDO
*)
let word =
[
Line.Of("LETTERS" =. S"ABCDEFGHIJKLMNOPQRSTUVWXYZ'-")
Line.Of(S"SAMPLE LINE" =? (SPAN(V"LETTERS") .= "OUTPUT"))
Line.Of("WORD" =. P(SPAN(V"LETTERS")))
Line.Of("GAP" =. P(BREAK(V"LETTERS")))
Line.Of("GAPO" =. P(E(V("GAP")) .= "OUTPUT"))
Line.Of("WORDO" =. P(E(V("WORD")) .= "OUTPUT"))
Line.Of(S": ONE, TWO, THREE" =? And [E(V"GAPO");E(V"WORDO");E(V"GAPO");E(V"WORDO")])
]
word |> run machine
// > SAMPLE
// > :
// > ONE
// > ,
// > TWO
(*
T = "MASH"
T 'M' = 'B'
OUTPUT = T
*)
let mash =
[
Line.Of("T" =. S"MASH")
Line.Of("T" =/ (E(S"M") /= S"B"))
Line.Of("OUTPUT" =. V"T")
]
mash |> run machine
// > BASH
(*
T = 'MUCH ADO ABOUT NOTHING'
T 'ADO' = 'FUSS'
OUTPUT = T
T 'NOTHING' =
OUTPUT = T
VOWEL = ANY('AEIOU')
VL T VOWEL = '*' :S(VL)
OUTPUT = T
*)
let much =
[
Line.Of("T" =. S"MUCH ADO ABOUT NOTHING")
Line.Of("T" =/ (E(S("ADO")) /= S"FUSS"))
Line.Of("OUTPUT" =. V("T"))
Line.Of("T" =/ (E(S("NOTHING")) /= S""))
Line.Of("OUTPUT" =. V("T"))
Line.Of("VOWEL" =. P(ANY(S"AIEOU")))
Line.Of("T" =/ (E(V"VOWEL") /= S"*"), label="VL",
transfer=OnSuccess "VL")
Line.Of("OUTPUT" =. V("T"))
]
much |> run machine
// > MUCH FUSS ABOUT NOTHING
// > MUCH FUSS ABOUT
// > M*CH F*SS *B**T
(*
* Define the characters which comprise a 'word'
WORD = "'-" '0123456789' &LCASE
* Pattern to isolate each word as assign it to ITEM:
WPAT = BREAK(WORD) SPAN(WORD) . ITEM
* Create a table to maintain the word counts
WCOUNT = TABLE()
* Read a line of input and obtain the next word
NEXTL LINE = REPLACE(INPUT, &UCASE, &LCASE) :F(DONE)
NEXTW LINE WPAT = :F(NEXTL)
* Use word as subscript, update its usage count
WCOUNT<ITEM> = WCOUNT<ITEM> + 1 :(NEXTW)
DONE A = CONVERT(WCOUNT, 'ARRAY') :F(EMPTY)
* Scan array, printing words and counts
I = 0
PRINT I = I + 1
OUTPUT = A<I,1> '--' A<I,2> :S(PRINT) F(END)
EMPTY OUTPUT = 'No words'
END
*)
let wordCount =
[
Line.Of("LCASE" =. S"abcdefghijklmnopqrstuvwxyz")
Line.Of("WORD" =. Concat [S"'-";S"0123456789";V"LCASE"])
Line.Of("WPAT" =. P(And [BREAK(V"WORD");SPAN(V"WORD") .= "ITEM"]))
Line.Of("WCOUNT" =. NewTable)
Line.Of("LINE" =. V"INPUT", label="NEXTL", transfer=OnFailure "DONE")
Line.Of("LINE" =/ (E(V"WPAT") /= S""), label="NEXTW",
transfer=OnFailure "NEXTL")
Line.Of(SetItem("WCOUNT",[V"ITEM"],GetItem("WCOUNT",[V"ITEM"]) +. I 1),
transfer=Goto "NEXTW")
Line.Of("A" =. Convert("WCOUNT", "ARRAY"), label="DONE")
Line.Of("I" =. I 0)
Line.Of("I" =. V"I" +. I 1, label="PRINT")
Line.Of("OUTPUT" =. Concat [GetItem("A",[V"I";I 1]);S"--";GetItem("A",[V"I";I 2])],
transfer=OnSuccessOrFailure("PRINT", "END"))
Line.Of("OUTPUT" =. S"No words", label="EMPTY")
Line.Of(Unit, label="END")
]
let lines = seq ["the wind in the willows"]
wordCount |> run { machine with Input = successive lines }
// > the--2
// > wind--1
// > in--1
// > willows--1
|
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
type name = string
Full name: Script.name
type arithmetic =
| Add
| Subtract
| Multiply
| Divide
| Power
Full name: Script.arithmetic
union case arithmetic.Add: arithmetic
union case arithmetic.Subtract: arithmetic
union case arithmetic.Multiply: arithmetic
union case arithmetic.Divide: arithmetic
union case arithmetic.Power: arithmetic
type value =
| String of string
| Integer of int
| Array of value []
| Table of table
| Pattern of pattern
Full name: Script.value
Multiple items
union case value.String: string -> value
--------------------
module String
from Microsoft.FSharp.Core
union case value.Integer: int -> value
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
Multiple items
union case value.Array: value [] -> value
--------------------
module Array
from Microsoft.FSharp.Collections
union case value.Table: table -> value
type table = System.Collections.Generic.Dictionary<string,value>
Full name: Script.table
union case value.Pattern: pattern -> value
type pattern =
| Expression of expression
| And of pattern list
| Or of pattern list
| ConditionalAssignment of pattern * name
| ImmediateAssignment of pattern * name
| Invoke of name * expression list
Full name: Script.pattern
namespace System
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type Dictionary<'TKey,'TValue> =
new : unit -> Dictionary<'TKey, 'TValue> + 5 overloads
member Add : key:'TKey * value:'TValue -> unit
member Clear : unit -> unit
member Comparer : IEqualityComparer<'TKey>
member ContainsKey : key:'TKey -> bool
member ContainsValue : value:'TValue -> bool
member Count : int
member GetEnumerator : unit -> Enumerator<'TKey, 'TValue>
member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
member Item : 'TKey -> 'TValue with get, set
...
nested type Enumerator
nested type KeyCollection
nested type ValueCollection
Full name: System.Collections.Generic.Dictionary<_,_>
--------------------
System.Collections.Generic.Dictionary() : unit
System.Collections.Generic.Dictionary(capacity: int) : unit
System.Collections.Generic.Dictionary(comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Generic.Dictionary(dictionary: System.Collections.Generic.IDictionary<'TKey,'TValue>) : unit
System.Collections.Generic.Dictionary(capacity: int, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Generic.Dictionary(dictionary: System.Collections.Generic.IDictionary<'TKey,'TValue>, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
type expression =
| Value of value
| Variable of name
| GetItem of name * expression list
| Concat of expression list
| Arithmetic of expression * arithmetic * expression
| Convert of name * name
| NewArray of expression
| NewTable
Full name: Script.expression
union case expression.Value: value -> expression
union case expression.Variable: name -> expression
union case expression.GetItem: name * expression list -> expression
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
union case expression.Concat: expression list -> expression
union case expression.Arithmetic: expression * arithmetic * expression -> expression
union case expression.Convert: name * name -> expression
union case expression.NewArray: expression -> expression
union case expression.NewTable: expression
union case pattern.Expression: expression -> pattern
union case pattern.And: pattern list -> pattern
union case pattern.Or: pattern list -> pattern
union case pattern.ConditionalAssignment: pattern * name -> pattern
union case pattern.ImmediateAssignment: pattern * name -> pattern
union case pattern.Invoke: name * expression list -> pattern
type transfer =
| Goto of label
| OnSuccessOrFailure of label * label
| OnSuccess of label
| OnFailure of label
Full name: Script.transfer
union case transfer.Goto: label -> transfer
type label = string
Full name: Script.label
union case transfer.OnSuccessOrFailure: label * label -> transfer
union case transfer.OnSuccess: label -> transfer
union case transfer.OnFailure: label -> transfer
type command =
| Assign of name * expression
| SetItem of name * expression list * expression
| Match of expression * pattern
| Replace of name * pattern * expression
| Unit
Full name: Script.command
union case command.Assign: name * expression -> command
union case command.SetItem: name * expression list * expression -> command
union case command.Match: expression * pattern -> command
union case command.Replace: name * pattern * expression -> command
union case command.Unit: command
type line =
{Label: label option;
Command: command;
Transfer: transfer option;}
Full name: Script.line
line.Label: label option
type 'T option = Option<'T>
Full name: Microsoft.FSharp.Core.option<_>
line.Command: command
line.Transfer: transfer option
type environment =
{Subject: string;
Cursor: int;
Actions: (unit -> unit) list;
Result: value;
Success: bool;}
Full name: Script.environment
environment.Subject: string
environment.Cursor: int
environment.Actions: (unit -> unit) list
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
environment.Result: value
environment.Success: bool
type bool = System.Boolean
Full name: Microsoft.FSharp.Core.bool
val s : string
union case Option.Some: Value: 'T -> Option<'T>
val n : int
System.Int32.ToString() : string
System.Int32.ToString(provider: System.IFormatProvider) : string
System.Int32.ToString(format: string) : string
System.Int32.ToString(format: string, provider: System.IFormatProvider) : string
union case Option.None: Option<'T>
val toString : _arg1:value -> string
Full name: Script.toString
active recognizer ToString: value -> string option
Full name: Script.( |ToString|_| )
val invalidOp : message:string -> 'T
Full name: Microsoft.FSharp.Core.Operators.invalidOp
type Int32 =
struct
member CompareTo : value:obj -> int + 1 overload
member Equals : obj:obj -> bool + 1 overload
member GetHashCode : unit -> int
member GetTypeCode : unit -> TypeCode
member ToString : unit -> string + 3 overloads
static val MaxValue : int
static val MinValue : int
static member Parse : s:string -> int + 3 overloads
static member TryParse : s:string * result:int -> bool + 1 overload
end
Full name: System.Int32
System.Int32.TryParse(s: string, result: byref<int>) : bool
System.Int32.TryParse(s: string, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<int>) : bool
active recognizer ParseInt: string -> int option
Full name: Script.( |ParseInt|_| )
val toInt : _arg1:value -> int
Full name: Script.toInt
active recognizer ToInt: value -> int option
Full name: Script.( |ToInt|_| )
val rem : env:environment -> seq<environment>
Full name: Script.rem
Match remainder of subject
val env : environment
val result : string
System.String.Substring(startIndex: int) : string
System.String.Substring(startIndex: int, length: int) : string
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
property System.String.Length: int
val arb : env:environment -> seq<environment>
Full name: Script.arb
Match arbitrary characters
val len : env:environment -> n:int -> seq<environment>
Full name: Script.len
Match fixed-length string
val pos : env:environment -> n:int -> seq<environment>
Full name: Script.pos
Verify cursor position
val rpos : env:environment -> n:int -> seq<environment>
Full name: Script.rpos
val tab : env:environment -> n:int -> seq<environment>
Full name: Script.tab
Match to fixed position
val rtab : env:environment -> n:int -> seq<environment>
Full name: Script.rtab
val length : int
val any : env:environment -> s:string -> seq<environment>
Full name: Script.any
Match one character
val c : char
property System.String.Chars: int -> char
val exists : predicate:(char -> bool) -> str:string -> bool
Full name: Microsoft.FSharp.Core.String.exists
System.Char.ToString() : string
System.Char.ToString(provider: System.IFormatProvider) : string
val notany : env:environment -> s:string -> seq<environment>
Full name: Script.notany
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
val span : env:environment -> s:string -> seq<environment>
Full name: Script.span
Match a run of characters
val mutable n : int
val invoke : env:environment -> name:string -> args:value list -> seq<environment>
Full name: Script.invoke
Multiple items
val name : string
--------------------
type name = string
Full name: Script.name
val args : value list
val failwith : message:string -> 'T
Full name: Microsoft.FSharp.Core.Operators.failwith
type machine =
{Variables: IDictionary<name,value>;
Input: unit -> string;
Output: string -> unit;}
Full name: Script.machine
machine.Variables: System.Collections.Generic.IDictionary<name,value>
type IDictionary<'TKey,'TValue> =
member Add : key:'TKey * value:'TValue -> unit
member ContainsKey : key:'TKey -> bool
member Item : 'TKey -> 'TValue with get, set
member Keys : ICollection<'TKey>
member Remove : key:'TKey -> bool
member TryGetValue : key:'TKey * value:'TValue -> bool
member Values : ICollection<'TValue>
Full name: System.Collections.Generic.IDictionary<_,_>
machine.Input: unit -> string
machine.Output: string -> unit
val evaluate : machine:machine -> expression:expression -> value
Full name: Script.evaluate
Multiple items
val machine : machine
--------------------
type machine =
{Variables: IDictionary<name,value>;
Input: unit -> string;
Output: string -> unit;}
Full name: Script.machine
Multiple items
val expression : expression
--------------------
type expression =
| Value of value
| Variable of name
| GetItem of name * expression list
| Concat of expression list
| Arithmetic of expression * arithmetic * expression
| Convert of name * name
| NewArray of expression
| NewTable
Full name: Script.expression
val get : (string -> value)
val getItem : (value -> value -> value)
val container : value
val index : value
val ar : value []
val index : int
property System.Array.Length: int
val nil : value
Full name: Script.nil
Multiple items
val table : table
--------------------
type table = System.Collections.Generic.Dictionary<string,value>
Full name: Script.table
System.Collections.Generic.Dictionary.TryGetValue(key: string, value: byref<value>) : bool
Multiple items
val value : value
--------------------
type value =
| String of string
| Integer of int
| Array of value []
| Table of table
| Pattern of pattern
Full name: Script.value
Multiple items
val name : name
--------------------
type name = string
Full name: Script.name
val expressions : expression list
val lookup : (value -> expression list -> value)
val item : value
val x : expression
val xs : expression list
val concat : machine:machine -> expressions:expression list -> value
Full name: Script.concat
val lhs : expression
val op : arithmetic
val rhs : expression
val l : int
val r : int
Multiple items
val arithmetic : op:arithmetic -> l:int -> r:int -> int
Full name: Script.arithmetic
--------------------
type arithmetic =
| Add
| Subtract
| Multiply
| Divide
| Power
Full name: Script.arithmetic
val l : value
val r : value
val subject : name
val target : name
val kvp : System.Collections.Generic.KeyValuePair<string,value>
property System.Collections.Generic.KeyValuePair.Key: string
property System.Collections.Generic.KeyValuePair.Value: value
val create : count:int -> value:'T -> 'T []
Full name: Microsoft.FSharp.Collections.Array.create
val pown : x:'T -> n:int -> 'T (requires member get_One and member ( * ) and member ( / ))
Full name: Microsoft.FSharp.Core.Operators.pown
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
System.String(value: nativeptr<char>) : unit
System.String(value: nativeptr<sbyte>) : unit
System.String(value: char []) : unit
System.String(c: char, count: int) : unit
System.String(value: nativeptr<char>, startIndex: int, length: int) : unit
System.String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
System.String(value: char [], startIndex: int, length: int) : unit
System.String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: System.Text.Encoding) : unit
System.String.Concat([<System.ParamArray>] values: string []) : string
(+0 other overloads)
System.String.Concat(values: System.Collections.Generic.IEnumerable<string>) : string
(+0 other overloads)
System.String.Concat<'T>(values: System.Collections.Generic.IEnumerable<'T>) : string
(+0 other overloads)
System.String.Concat([<System.ParamArray>] args: obj []) : string
(+0 other overloads)
System.String.Concat(arg0: obj) : string
(+0 other overloads)
System.String.Concat(str0: string, str1: string) : string
(+0 other overloads)
System.String.Concat(arg0: obj, arg1: obj) : string
(+0 other overloads)
System.String.Concat(str0: string, str1: string, str2: string) : string
(+0 other overloads)
System.String.Concat(arg0: obj, arg1: obj, arg2: obj) : string
(+0 other overloads)
System.String.Concat(str0: string, str1: string, str2: string, str3: string) : string
(+0 other overloads)
val e : expression
val assign : machine:machine -> name:string -> value:value -> unit
Full name: Script.assign
val tryPattern : machine:machine -> env:environment -> pattern:pattern -> seq<environment>
Full name: Script.tryPattern
Multiple items
val pattern : pattern
--------------------
type pattern =
| Expression of expression
| And of pattern list
| Or of pattern list
| ConditionalAssignment of pattern * name
| ImmediateAssignment of pattern * name
| Invoke of name * expression list
Full name: Script.pattern
val subject : string
Multiple items
val value : string
--------------------
type value =
| String of string
| Integer of int
| Array of value []
| Table of table
| Pattern of pattern
Full name: Script.value
System.String.StartsWith(value: string) : bool
System.String.StartsWith(value: string, comparisonType: System.StringComparison) : bool
System.String.StartsWith(value: string, ignoreCase: bool, culture: System.Globalization.CultureInfo) : bool
val cursor : int
val result : value
val patterns : pattern list
val applyPattern : (environment -> pattern list -> environment)
val p : pattern
val ps : pattern list
val newEnvs : seq<environment>
val found : environment option
module Seq
from Microsoft.FSharp.Collections
val tryPick : chooser:('T -> 'U option) -> source:seq<'T> -> 'U option
Full name: Microsoft.FSharp.Collections.Seq.tryPick
val newEnv : environment
val findPattern : (pattern list -> seq<environment>)
val tryFind : predicate:('T -> bool) -> source:seq<'T> -> 'T option
Full name: Microsoft.FSharp.Collections.Seq.tryFind
val envs : seq<environment>
val onSuccess : (unit -> unit)
val args : expression list
val arg : expression
val patternMatch : machine:machine -> subject:string -> pattern:pattern -> environment
Full name: Script.patternMatch
val tryFromIndex : (int -> environment)
val action : (unit -> unit)
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val rev : list:'T list -> 'T list
Full name: Microsoft.FSharp.Collections.List.rev
val applyCommand : machine:machine -> command:command -> bool
Full name: Script.applyCommand
Multiple items
val command : command
--------------------
type command =
| Assign of name * expression
| SetItem of name * expression list * expression
| Match of expression * pattern
| Replace of name * pattern * expression
| Unit
Full name: Script.command
val index : expression
Multiple items
val value : expression
--------------------
type value =
| String of string
| Integer of int
| Array of value []
| Table of table
| Pattern of pattern
Full name: Script.value
val subject : expression
System.String.Remove(startIndex: int) : string
System.String.Remove(startIndex: int, count: int) : string
val tryFindTransfer : success:bool -> _arg1:transfer -> label option
Full name: Script.tryFindTransfer
val success : bool
Multiple items
val label : label
--------------------
type label = string
Full name: Script.label
val run : machine:machine -> lines:line list -> unit
Full name: Script.run
val lines : line list
val findLabel : (label -> int)
val findIndex : predicate:('T -> bool) -> list:'T list -> int
Full name: Microsoft.FSharp.Collections.List.findIndex
Multiple items
val line : line
--------------------
type line =
{Label: label option;
Command: command;
Transfer: transfer option;}
Full name: Script.line
module Option
from Microsoft.FSharp.Core
val exists : predicate:('T -> bool) -> option:'T option -> bool
Full name: Microsoft.FSharp.Core.Option.exists
val gotoLine : (int -> unit)
val i : int
val e : exn
property Option.IsSome: bool
property List.Length: int
Multiple items
val transfer : transfer
--------------------
type transfer =
| Goto of label
| OnSuccessOrFailure of label * label
| OnSuccess of label
| OnFailure of label
Full name: Script.transfer
val S : s:string -> expression
Full name: Script.S
val I : s:int -> expression
Full name: Script.I
val s : int
val V : s:name -> expression
Full name: Script.V
val s : name
val E : e:expression -> pattern
Full name: Script.E
val P : e:pattern -> expression
Full name: Script.P
val e : pattern
Multiple items
val pattern : 'a
--------------------
type pattern =
| Expression of expression
| And of pattern list
| Or of pattern list
| ConditionalAssignment of pattern * name
| ImmediateAssignment of pattern * name
| Invoke of name * expression list
Full name: Script.pattern
val expressions : 'b
val expressions : expression
val ARB : pattern
Full name: Script.ARB
val REM : pattern
Full name: Script.REM
val LEN : e:expression -> pattern
Full name: Script.LEN
val POS : e:expression -> pattern
Full name: Script.POS
val RPOS : e:expression -> pattern
Full name: Script.RPOS
val TAB : e:expression -> pattern
Full name: Script.TAB
val RTAB : e:expression -> pattern
Full name: Script.RTAB
val ANY : e:expression -> pattern
Full name: Script.ANY
val NOTANY : e:expression -> pattern
Full name: Script.NOTANY
val SPAN : e:expression -> pattern
Full name: Script.SPAN
val BREAK : e:expression -> pattern
Full name: Script.BREAK
type Line =
static member Of : command:command * ?label:label * ?transfer:transfer -> line
Full name: Script.Line
static member Line.Of : command:command * ?label:label * ?transfer:transfer -> line
Full name: Script.Line.Of
Multiple items
val label : label option
--------------------
type label = string
Full name: Script.label
Multiple items
val transfer : transfer option
--------------------
type transfer =
| Goto of label
| OnSuccessOrFailure of label * label
| OnSuccess of label
| OnFailure of label
Full name: Script.transfer
Multiple items
val machine : machine
Full name: Script.machine
--------------------
type machine =
{Variables: IDictionary<name,value>;
Input: unit -> string;
Output: string -> unit;}
Full name: Script.machine
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
static member Line.Of : command:command * ?label:label * ?transfer:transfer -> line
val program : line list
Full name: Script.program
val loop : line list
Full name: Script.loop
val names : seq<string>
Full name: Script.names
val successive : inputs:seq<string> -> (unit -> string)
Full name: Script.successive
val inputs : seq<string>
val e : System.Collections.Generic.IEnumerator<string>
System.Collections.Generic.IEnumerable.GetEnumerator() : System.Collections.Generic.IEnumerator<string>
System.Collections.IEnumerator.MoveNext() : bool
property System.Collections.Generic.IEnumerator.Current: string
val bird : line list
Full name: Script.bird
val color : line list
Full name: Script.color
val b2 : line list
Full name: Script.b2
val winter : line list
Full name: Script.winter
val mountain : line list
Full name: Script.mountain
val abcda : line list
Full name: Script.abcda
val abcde : line list
Full name: Script.abcde
val vacuum : line list
Full name: Script.vacuum
val word : line list
Full name: Script.word
val mash : line list
Full name: Script.mash
val much : line list
Full name: Script.much
val wordCount : line list
Full name: Script.wordCount
val lines : seq<string>
Full name: Script.lines
More information