5 people like it.

Unlambda

A minimal interpreter for David Madore's crazy-esoteric programming language.

 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: 
// http://www.madore.org/~david/programs/unlambda/

type C = F -> unit
and F = F of ((F * C) -> unit)

let getReader (source : string) = 
    let pos = ref 0
    (fun () -> let result = source.[!pos] in pos := !pos + 1; result)

let eval (source : string) =
    let apply (first : C -> unit) (second : C -> unit) : C -> unit = 
        fun c -> first (fun (F f) -> second (fun g -> f(g, c)))
    let rec eval' reader : C -> unit =
        let c = reader() 
        match c with
        | '`' -> 
            let first, second = eval' reader, eval' reader
            apply first second
        | 's' -> 
            fun c -> c <| F (fun (x, c') ->  c' <| F (fun (y, c'') -> c'' <| F (fun (z, c''') ->  
                apply (apply (fun c -> c x) (fun c -> c z)) (apply (fun c -> c y) (fun c -> c z)) <| c'''))) 
        | 'k' -> fun c -> c <| F (fun (x, c') -> c' <| F (fun (_, c'') -> c'' x))
        | 'i' -> fun c -> c <| F (fun (x, c') -> c' x)
        | 'c' -> fun c -> c <| F (fun (F f, c') -> f (F (fun (x, _) -> c' x), c') )
        | '.' -> 
            let char = reader()
            fun c -> c <| F (fun (x, c') -> printf "%c" char; c' x)
        | 'r' -> fun c -> c <| F (fun (x, c') -> printf "\n"; c' x)
        | _ -> failwithf "Invalid symbol %c" c 
    let c = eval' <| getReader source
    c (fun _ -> ())

// Examples
eval "```si`k``s.H``s.e``s.l``s.l``s.o``s. ``s.w``s.o``s.r``s.l``s.d``s.!``sri``si``si``si``si``si``si``si``si`ki" // Hello World! * 8
eval "```s``s``sii`ki`k.*``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`kr``s`k`sikk`k``s`ksk" // factorial
eval "``cir" // call/cc
type C = F -> unit

Full name: Script.C
type F = | F of (F * C -> unit)

Full name: Script.F
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
union case F.F: (F * C -> unit) -> F
val getReader : source:string -> (unit -> char)

Full name: Script.getReader
val source : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val pos : int ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val result : char
val eval : source:string -> unit

Full name: Script.eval
val apply : ((C -> unit) -> (C -> unit) -> C -> unit)
val first : (C -> unit)
val second : (C -> unit)
val c : C
val f : (F * C -> unit)
val g : F
val eval' : ((unit -> char) -> C -> unit)
val reader : (unit -> char)
val c : char
val x : F
val c' : C
val y : F
val c'' : C
val z : F
val c''' : C
Multiple items
val char : char

--------------------
type char = System.Char

Full name: Microsoft.FSharp.Core.char
val printf : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printf
val failwithf : format:Printf.StringFormat<'T,'Result> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.failwithf
val c : (C -> unit)
Raw view Test code New version

More information

Link:http://fssnip.net/dr
Posted:11 years ago
Author:Nick Palladinos
Tags: interpreter