2 people like it.

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

Abstract Syntax Tree

 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: 
type label = string
type name = string
type arithmetic = Add | Subtract | Multiply | Divide | Power
type value = 
   | String of string 
   | Integer of int
   | Pattern of pattern
and expression = 
   | Value of value
   | Variable of name
   | Arithmetic of expression * arithmetic * expression
and pattern =
   | Expression of expression
   | Or of pattern list
   | ConditionalAssignment of pattern * name
   | Len of int
   | Rem
type transferOn = Success | Failure | Any
type transfer = { On:transferOn; Goto:label }
type command =
   | Assign of name * expression list
   | Match of expression list * pattern list
   | Unit
type line = {
    Label : label option
    Command : command
    Transfer : transfer option
    }

Interpereter

  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: 
let toString = function 
   | String s -> s 
   | Integer n -> n.ToString()
   | Pattern _ -> invalidOp ""
let (|AsInteger|_|) s =
   match System.Int32.TryParse(s) with
   | true, n -> Some n
   | false, _ -> None
type environment = {     
   Subject:string;
   Cursor:int;
   Result:value;
   Success:bool }
let run input output (lines:line list) =
   let variables = System.Collections.Generic.Dictionary<name, value>()
   let assign name value =
      match name, value with
      | "OUTPUT", Pattern(_) -> name |> output
      | "OUTPUT", _ -> value |> toString |> output
      | _, _ -> variables.[name] <- value
   let get name =
      match name with
      | "INPUT" -> input () |> String
      | _ -> variables.[name]
   let rec concat expressions =      
      System.String.Concat [for e in expressions -> evaluate e |> toString] |> String
   and evaluate expression =      
      match expression with
      | Value(value) -> value
      | Variable(name) -> get name
      | Arithmetic(lhs,op,rhs) ->
         match evaluate lhs, evaluate rhs with
         | Integer l, Integer r -> Integer(arithmetic op l r)
         | Integer l, String (AsInteger r) -> Integer(arithmetic op l r)
         | _ -> invalidOp "Illegal data type"
   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 tryPattern (env:environment) pattern =
      match pattern with
      | Expression(expression) ->
         let subject = env.Subject.Substring(env.Cursor)
         let value = evaluate expression
         match value with
         | Pattern pattern -> tryPattern env pattern
         | value ->  
            let value = value|> toString
            if env.Cursor = 0 then
               let index = subject.IndexOf value
               if index <> -1 
               then
                  let cursor = env.Cursor+index+value.Length
                  let result = String value
                  { env with Cursor=cursor; Result=result; Success=true }
               else { env with Success=false }
            else
               if subject.Substring(env.Cursor).StartsWith(value)
               then
                  let cursor = env.Cursor+value.Length
                  let result = String value
                  { env with Cursor=cursor; Result=result;Success = true }
               else { env with Success = false }
      | Or(patterns) -> 
         let rec findPattern = function
            | [] -> { env with Success = false }
            | p::ps ->
               let newEnv = tryPattern env p
               if newEnv.Success 
               then newEnv
               else findPattern ps
         findPattern patterns
      | ConditionalAssignment(pattern,subject) ->
         let env = tryPattern env pattern
         if env.Success then assign subject env.Result
         env
      | Len(n) ->
         if n > env.Subject.Length + env.Cursor then 
            { env with Result=String ""; Success=false }
         else
            let result = env.Subject.Substring(env.Cursor,n)
            { env with Cursor=env.Cursor+n; Result=String result; Success=true }
      | Rem ->         
         let result = env.Subject.Substring(env.Cursor)
         { env with Result=String result; Cursor=env.Subject.Length-1 }
   let rec nextLine i =
      let line = lines.[i]      
      let env =
         match line.Command with           
         | Assign(subject, expressions) ->             
            let value = 
               match expressions with
               | expression::[] -> evaluate expression
               | _ -> concat expressions
            assign subject value
            { Subject=subject; Result=value; Cursor=0; Success=true}
         | Match(subject, patterns) ->                        
            let subject = concat subject |> toString
            let rec applyPattern env = function
               | [] -> env
               | p::ps ->
                  let newEnv = tryPattern env p
                  if newEnv.Success 
                  then applyPattern newEnv ps
                  else newEnv
            let env = { Subject=subject; Cursor=0; Result=String ""; Success=true}
            applyPattern env patterns
         | Unit -> { Subject=""; Cursor=0; Result=String ""; Success=true }
      match line.Transfer with
      | None -> 
         if i < lines.Length-1 then nextLine (i+1)
      | Some(transfer) ->
         let j = 
            lines 
            |> List.findIndex (fun line -> 
                  match line.Label with 
                  | Some label -> label = transfer.Goto 
                  | None -> false)                        
         match transfer.On, env.Success with
         | Success, true -> nextLine j
         | Failure, false -> nextLine j
         | Any, _ -> nextLine j
         | _ when i < lines.Length-1 -> nextLine (i+1)
         | _ -> ()         
   nextLine 0

Hello World Example

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
(*
          OUTPUT = "Hello world"
*)
let input () = ""
let output = printfn "%s"
[{Label=None; Command=Assign("OUTPUT",[Value(String("Hello World"))]);Transfer=None}]
|> run input output
// > Hello World

Input Example

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
(*
          OUTPUT = "What is your name?"
          Username = INPUT
          OUTPUT = "Thank you, " Username
*)
[{Label=None; Command=Assign("OUTPUT",[Value(String("What is your name?"))]);Transfer=None}
 {Label=None; Command=Assign("Username",[Variable("INPUT")]);Transfer=None}
 {Label=None; Command=Assign("OUTPUT",[Value(String("Thank you, "));Variable("Username")]);
                                      Transfer=None}]
|> run (fun () -> "Doctor") output
// > What is your name?
// > Thank you, Doctor

Control Flow Example

 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: 
(*
          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 =
   [
   {Label=None; Command=Assign("OUTPUT",[Value(String("What is your name?"))]);Transfer=None}
   {Label=None; Command=Assign("Username",[Variable("INPUT")]);Transfer=None}
   {Label=None; Command=Match([Variable("Username")],[Expression(Value(String "J"))]);
                Transfer=Some {On=Success;Goto="LOVE"}}
   {Label=None; Command=Match([Variable("Username")],[Expression(Value(String "K"))]);
                Transfer=Some {On=Success;Goto="HATE"}}
   {Label=Some "MEH"; 
    Command=Assign("OUTPUT",[Value(String "Hi, ");Variable("Username")]);
    Transfer=Some {On=Success;Goto="END"}}
   {Label=Some "LOVE"; 
    Command=Assign("OUTPUT",[Value(String "How nice to meet you, ");Variable("Username")]);
    Transfer=Some {On=Success;Goto="END"}}
   {Label=Some "HATE"; 
    Command=Assign("OUTPUT",[Value(String "Oh. It's you, ");Variable("Username")]);
    Transfer=Some {On=Success;Goto="END"}}
   {Label=Some "END"; Command=Unit;Transfer=None}
   ]

program |> run (fun () -> "Jay") output
// > What is your name?
// > How nice to meet you, Jay
program |> run (fun () -> "Kay") output
// > What is your name?
// > Oh. It's you, Kay
program |> run (fun () -> "Bob") output
// > What is your name?
// > Hi, Bob

Input Loop Example

 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: 
(*
          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 =
   [
   {Label=None; 
    Command=Assign("OUTPUT",[Value(String("This program will ask you for personal names"))]);
    Transfer=None}
   {Label=None; 
    Command=Assign("OUTPUT",[Value(String("until you press return without giving it one"))]);
    Transfer=None}
   {Label=None; 
    Command=Assign("NameCount",[Value(Integer(0))]);
    Transfer=Some {On=Any;Goto="GETINPUT"}}
   {Label=Some "AGAIN"; 
    Command=Assign("NameCount",[Arithmetic(Variable("NameCount"),Add,Value(Integer(1)))]);
    Transfer=None}
   {Label=None; 
    Command=Assign("OUTPUT",[Value(String("Name ")); Variable("NameCount");
                             Value(String(": "));Variable("PersonalName")]);
    Transfer=None}      
   {Label=Some "GETINPUT"; Command=Assign("PersonalName",[Variable("INPUT")]); Transfer=None}
   {Label=None; 
    Command=Match([Variable("PersonalName")],[Len(1)]); 
    Transfer=Some {On=Success;Goto="AGAIN"}}
   {Label=None; 
    Command=Assign("OUTPUT", [Value(String("Finished. ")); Variable("NameCount");
                              Value(String(" names requested."))])
    Transfer=None}
   ]

let names () =
   let names = seq ["Billy"; "Bob"; "Thornton"]
   let e = names.GetEnumerator()
   fun () -> if e.MoveNext() then e.Current else ""
loop |> run (names ()) output
// > 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.

Simple Pattern Matching Examples

 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: 
(*
          'BLUEBIRD' 'BIRD' . OUTPUT
END
*)
let bird =
   [
   {Label=None; 
    Command=Match([Value(String("BLUEBIRD"))],
                  [ConditionalAssignment(Expression(Value(String("BIRD"))),"OUTPUT")]); 
    Transfer=None}
   ]

bird |> run input output
// > BIRD

(*
          B = 'BLUEBIRD'
          B ('BLUE' | 'GOLD') . OUTPUT
          G = 'GOLDFISH'
          B ('BLUE' | 'GOLD') . OUTPUT
          COLOR = 'BLUE' | 'GOLD'
          B COLOR . OUTPUT
END
*)
let color =
   [
   // B = 'BLUEBIRD'
   {Label=None; Command=Assign("B", [Value(String("BLUEBIRD"))]); Transfer=None}
   // B ('BLUE' | 'GOLD') . OUTPUT
   {Label=None; 
    Command=Match([Variable("B")],
                  [ConditionalAssignment(
                     Or [Expression(Value(String("GOLD")));Expression(Value(String("BLUE")))],
                     "OUTPUT")]); 
    Transfer=None}
   // G = 'GOLDFISH'
   {Label=None; Command=Assign("G", [Value(String("GOLDFISH"))]); Transfer=None}
   // B ('BLUE' | 'GOLD') . OUTPUT
   {Label=None; 
    Command=Match([Variable("G")],
                  [ConditionalAssignment(
                     Or [Expression(Value(String("GOLD")));Expression(Value(String("BLUE")))],
                     "OUTPUT")]); 
    Transfer=None}  
   // COLOR = 'BLUE' | 'GOLD'
   {Label=None; 
    Command=Assign("COLOR",
                   [Value(Pattern(Or [Expression(Value(String("GOLD")));
                                      Expression(Value(String("BLUE")))]))]); 
    Transfer=None}
   // B COLOR . OUTPUT
   {Label=None; 
    Command=Match([Variable("B")],
                  [ConditionalAssignment(Expression(Variable("COLOR")), "OUTPUT")]); 
    Transfer=None}  
   ]

color |> run input output
// > BLUE
// > GOLD
// > BLUE

(*
          'THE WINTER WINDS' 'WIN' REM . OUTPUT
*)

let winter = 
   [
   {Label=None; 
    Command=Match([Value(String("'THE WINTER WINDS"))],
                  [Expression(Value(String("WIN")));
                   ConditionalAssignment(Rem,"OUTPUT")]); 
    Transfer=None}
   ]

winter |> run input output
// > TER WINDS
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
  | 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<_>
union case value.Pattern: pattern -> value
type pattern =
  | Expression of expression
  | Or of pattern list
  | ConditionalAssignment of pattern * name
  | Len of int
  | Rem

Full name: Script.pattern
type expression =
  | Value of value
  | Variable of name
  | Arithmetic of expression * arithmetic * expression

Full name: Script.expression
union case expression.Value: value -> expression
union case expression.Variable: name -> expression
union case expression.Arithmetic: expression * arithmetic * expression -> expression
union case pattern.Expression: expression -> pattern
union case pattern.Or: pattern list -> pattern
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
union case pattern.ConditionalAssignment: pattern * name -> pattern
union case pattern.Len: int -> pattern
union case pattern.Rem: pattern
type transferOn =
  | Success
  | Failure
  | Any

Full name: Script.transferOn
union case transferOn.Success: transferOn
Multiple items
union case transferOn.Failure: transferOn

--------------------
active recognizer Failure: exn -> string option

Full name: Microsoft.FSharp.Core.Operators.( |Failure|_| )
union case transferOn.Any: transferOn
type transfer =
  {On: transferOn;
   Goto: label;}

Full name: Script.transfer
transfer.On: transferOn
transfer.Goto: label
type label = string

Full name: Script.label
type command =
  | Assign of name * expression list
  | Match of expression list * pattern list
  | Unit

Full name: Script.command
union case command.Assign: name * expression list -> command
union case command.Match: expression list * pattern list -> 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
val toString : _arg1:value -> string

Full name: Script.toString
val s : string
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
val invalidOp : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.invalidOp
namespace System
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
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
type environment =
  {Subject: string;
   Cursor: int;
   Result: value;
   Success: bool;}

Full name: Script.environment
environment.Subject: string
environment.Cursor: int
environment.Result: value
environment.Success: bool
type bool = System.Boolean

Full name: Microsoft.FSharp.Core.bool
val run : input:(unit -> string) -> output:(string -> unit) -> lines:line list -> unit

Full name: Script.run
val input : (unit -> string)
val output : (string -> unit)
val lines : line list
val variables : System.Collections.Generic.Dictionary<name,value>
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
val assign : (string -> value -> unit)
Multiple items
val name : string

--------------------
type name = string

Full name: Script.name
Multiple items
val value : value

--------------------
type value =
  | String of string
  | Integer of int
  | Pattern of pattern

Full name: Script.value
val get : (string -> value)
val concat : (seq<expression> -> value)
val expressions : seq<expression>
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 evaluate : (expression -> value)
Multiple items
val expression : expression

--------------------
type expression =
  | Value of value
  | Variable of name
  | Arithmetic of expression * arithmetic * expression

Full name: Script.expression
Multiple items
val name : name

--------------------
type name = string

Full name: Script.name
val lhs : expression
val op : arithmetic
val rhs : expression
val l : int
val r : int
Multiple items
val arithmetic : (arithmetic -> int -> int -> int)

--------------------
type arithmetic =
  | Add
  | Subtract
  | Multiply
  | Divide
  | Power

Full name: Script.arithmetic
active recognizer AsInteger: string -> int option

Full name: Script.( |AsInteger|_| )
val pown : x:'T -> n:int -> 'T (requires member get_One and member ( * ) and member ( / ))

Full name: Microsoft.FSharp.Core.Operators.pown
val tryPattern : (environment -> pattern -> environment)
val env : environment
Multiple items
val pattern : pattern

--------------------
type pattern =
  | Expression of expression
  | Or of pattern list
  | ConditionalAssignment of pattern * name
  | Len of int
  | Rem

Full name: Script.pattern
val subject : string
System.String.Substring(startIndex: int) : string
System.String.Substring(startIndex: int, length: int) : string
Multiple items
val value : string

--------------------
type value =
  | String of string
  | Integer of int
  | Pattern of pattern

Full name: Script.value
val index : int
System.String.IndexOf(value: string) : int
System.String.IndexOf(value: char) : int
System.String.IndexOf(value: string, comparisonType: System.StringComparison) : int
System.String.IndexOf(value: string, startIndex: int) : int
System.String.IndexOf(value: char, startIndex: int) : int
System.String.IndexOf(value: string, startIndex: int, comparisonType: System.StringComparison) : int
System.String.IndexOf(value: string, startIndex: int, count: int) : int
System.String.IndexOf(value: char, startIndex: int, count: int) : int
System.String.IndexOf(value: string, startIndex: int, count: int, comparisonType: System.StringComparison) : int
val cursor : int
property System.String.Length: int
val result : value
val patterns : pattern list
val findPattern : (pattern list -> environment)
val p : pattern
val ps : pattern list
val newEnv : environment
val subject : name
val result : string
val nextLine : (int -> unit)
val i : int
Multiple items
val line : line

--------------------
type line =
  {Label: label option;
   Command: command;
   Transfer: transfer option;}

Full name: Script.line
val expressions : expression list
val subject : expression list
val applyPattern : (environment -> pattern list -> environment)
property List.Length: int
Multiple items
val transfer : transfer

--------------------
type transfer =
  {On: transferOn;
   Goto: label;}

Full name: Script.transfer
val j : int
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 findIndex : predicate:('T -> bool) -> list:'T list -> int

Full name: Microsoft.FSharp.Collections.List.findIndex
Multiple items
val label : label

--------------------
type label = string

Full name: Script.label
union case transferOn.Failure: transferOn
val input : unit -> string

Full name: Script.input
val output : (string -> unit)

Full name: Script.output
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val program : line list

Full name: Script.program
val loop : line list

Full name: Script.loop
val names : unit -> (unit -> string)

Full name: Script.names
val names : seq<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<_>
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 winter : line list

Full name: Script.winter

More information

Link:http://fssnip.net/oV
Posted:10 years ago
Author:Phillip Trelford
Tags: snobol , language , ast , interpreter