2 people like it.

Befunge

Minimal Befunge-93 interpreter.

 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: 
let run (program:string) =
    let rand = System.Random()
    let stack = System.Collections.Generic.Stack()
    let grid = Array2D.create 80 25 ' '
    let lines = program.Split('\n')
    lines 
    |> Seq.truncate 25
    |> Seq.iteri (fun y line ->
        let length = min 80 line.Length
        for x = 0 to length-1 do grid.[x,y] <- line.[x]
    )
    let push c = stack.Push c
    let pop () = stack.Pop()
    let running = ref true
    let string_mode = ref false
    let v = ref (1,0)
    let pc = ref (0,0)
    let (+.) (a,b) (c,d) = a+c, b+d
    let instruction c =
        match c with
        | c  when System.Char.IsDigit(c) -> 
            let digit = c |> byte 
            digit - byte '0' |> push
        | '+' -> pop () + pop () |> push
        | '-' -> let a, b = pop (), pop () in b - a |> push
        | '*' -> pop () * pop () |> push
        | '/' -> let a, b = pop (), pop () in b / a |> push
        | '%' -> let a, b = pop (), pop () in b % a |> push
        | '!' -> (if pop() = 0uy then 1uy else 0uy) |> push
        | ''' -> let a, b = pop (), pop() in (if b > a then 1uy else 0uy) |> push
        | '>' -> v := (1,0)
        | '<' -> v := (-1,0)
        | '^' -> v := (0,-1)
        | 'v' -> v := (0,1)
        | '?' -> v := [-1,0;1,0;0,-1;0,1].[rand.Next(4)]
        | '_' -> v := if pop() = 0uy then (1,0) else (-1,0) 
        | '|' -> v := if pop() = 0uy then (0,1) else (0,-1)
        | '"' -> string_mode := true
        | ':' -> let top = pop() in push top; push top
        | '\\' -> let a,b = pop(),pop() in push b; push a
        | '$' -> pop () |> ignore
        | '.' -> pop () |> int |> printf "%d"
        | ',' -> pop () |> char |> printf "%O"
        | '#' -> pc := !pc +. !v
        | 'p' -> let y,x,v = pop(), pop(), pop() in grid.[int y,int x] <- char v
        | 'g' -> let y,x = pop(), pop() in grid.[int y, int x] |> byte |> push
        | '&' -> System.Console.Read() |> byte |> push
        | '~' -> System.Console.Read() |> byte |> push
        | '@' -> running := false
        |  _  -> ()
    let execute c =
        if !string_mode then
            if c = '"' then string_mode := false
            else c |> byte |> push
        else
            instruction c
    push 0uy    
    while !running do
        let x,y = !pc
        let x,y = (x+80)%80, (y+25)%25
        let c = grid.[x,y]
        execute c
        pc := !pc +. !v

let program=">              v
v  ,,,,,\"Hello\"<
>48*,          v
v,,,,,,\"World!\"<
>25*,@"

run program
val run : program:string -> unit

Full name: Script.run
val program : 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 rand : System.Random
namespace System
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
System.Random() : unit
System.Random(Seed: int) : unit
val stack : System.Collections.Generic.Stack<byte>
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type Stack<'T> =
  new : unit -> Stack<'T> + 2 overloads
  member Clear : unit -> unit
  member Contains : item:'T -> bool
  member CopyTo : array:'T[] * arrayIndex:int -> unit
  member Count : int
  member GetEnumerator : unit -> Enumerator<'T>
  member Peek : unit -> 'T
  member Pop : unit -> 'T
  member Push : item:'T -> unit
  member ToArray : unit -> 'T[]
  ...
  nested type Enumerator

Full name: System.Collections.Generic.Stack<_>

--------------------
System.Collections.Generic.Stack() : unit
System.Collections.Generic.Stack(capacity: int) : unit
System.Collections.Generic.Stack(collection: System.Collections.Generic.IEnumerable<'T>) : unit
val grid : char [,]
module Array2D

from Microsoft.FSharp.Collections
val create : length1:int -> length2:int -> value:'T -> 'T [,]

Full name: Microsoft.FSharp.Collections.Array2D.create
val lines : string []
System.String.Split([<System.ParamArray>] separator: char []) : string []
System.String.Split(separator: string [], options: System.StringSplitOptions) : string []
System.String.Split(separator: char [], options: System.StringSplitOptions) : string []
System.String.Split(separator: char [], count: int) : string []
System.String.Split(separator: string [], count: int, options: System.StringSplitOptions) : string []
System.String.Split(separator: char [], count: int, options: System.StringSplitOptions) : string []
module Seq

from Microsoft.FSharp.Collections
val truncate : count:int -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.truncate
val iteri : action:(int -> 'T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iteri
val y : int
val line : string
val length : int
val min : e1:'T -> e2:'T -> 'T (requires comparison)

Full name: Microsoft.FSharp.Core.Operators.min
property System.String.Length: int
val x : int
val push : (byte -> unit)
val c : byte
System.Collections.Generic.Stack.Push(item: byte) : unit
val pop : (unit -> byte)
System.Collections.Generic.Stack.Pop() : byte
val running : bool 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 string_mode : bool ref
val v : (int * int) ref
val pc : (int * int) ref
val a : int
val b : int
val c : int
val d : int
val instruction : (char -> unit)
val c : char
type Char =
  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 + 1 overload
    static val MaxValue : char
    static val MinValue : char
    static member ConvertFromUtf32 : utf32:int -> string
    static member ConvertToUtf32 : highSurrogate:char * lowSurrogate:char -> int + 1 overload
    static member GetNumericValue : c:char -> float + 1 overload
    ...
  end

Full name: System.Char
System.Char.IsDigit(c: char) : bool
System.Char.IsDigit(s: string, index: int) : bool
val digit : byte
Multiple items
val byte : value:'T -> byte (requires member op_Explicit)

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

--------------------
type byte = System.Byte

Full name: Microsoft.FSharp.Core.byte
val a : byte
val b : byte
System.Random.Next() : int
System.Random.Next(maxValue: int) : int
System.Random.Next(minValue: int, maxValue: int) : int
val top : byte
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
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<_>
val printf : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printf
Multiple items
val char : value:'T -> char (requires member op_Explicit)

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

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

Full name: Microsoft.FSharp.Core.char
val y : byte
val x : byte
val v : byte
type Console =
  static member BackgroundColor : ConsoleColor with get, set
  static member Beep : unit -> unit + 1 overload
  static member BufferHeight : int with get, set
  static member BufferWidth : int with get, set
  static member CapsLock : bool
  static member Clear : unit -> unit
  static member CursorLeft : int with get, set
  static member CursorSize : int with get, set
  static member CursorTop : int with get, set
  static member CursorVisible : bool with get, set
  ...

Full name: System.Console
System.Console.Read() : int
val execute : (char -> unit)
val program : string

Full name: Script.program
Raw view Test code New version

More information

Link:http://fssnip.net/cl
Posted:12 years ago
Author:Phillip Trelford
Tags: interpreter