F# Issue 中的 BF 解释器

BF Interpreter in F# Issue

好的,所以我正在做一个小项目,正如你在标题中所说的那样,我正在用 f# 制作一个 BrainFuck interpeter,我是这门语言的新手,但它很有趣,除了你与编译器打架,但我我已经习惯了,因为我曾经使用过 rust,但撇开它在我看来它只执行一次符号这一点不谈。我知道这效率不高或功能不全,但现在我只是在努力工作。这是我的代码
main.fs

open System
open System.IO
let mutable reg : int array = Array.zeroCreate 50
let mutable ptr = 0
let mutable larr : int array = Array.zeroCreate 50
let mutable lptr = 0
let mutable pc = 0
let result = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."
let prog = result.ToCharArray()
let startLoop = 
    larr.[lptr] <- pc
    printfn "STARTING LOOP AT %d" larr.[lptr]
    lptr <- lptr + 1
let doEnd = 
    pc <- larr.[lptr]
    while larr.[lptr - 1] > 0 do
        ptr <- larr.[lptr - 1]
        larr.[lptr - 1] <- larr.[lptr - 1] - 1
let endLoop =
    lptr <- lptr - 1
    if reg.[ptr] = 0 then pc <- pc  
    else doEnd
let doPlus =
    reg.[ptr] <- (reg.[ptr] + 1) % 265
    printfn "ADDING"
let doMinus = 
    reg.[ptr] <- (reg.[ptr] - 1) % 265
    printfn "SUB"
let doInc = 
    ptr <- (ptr + 1) % 265
    printfn "INC"
let doDec = 
    ptr <- (ptr - 1) % 265
    printfn "MINUS"
let doPrt = 
    printfn "%c" (reg.[ptr] |> char)
let doSloop =
    startLoop
    printfn "START LOOP"
let doEloop = 
    endLoop
    printfn "END LOOP"
let exec = 
    while pc < prog.Length do
        let i = prog.[pc]
        if i = '+' then doPlus
        elif i = '-' then doMinus
        elif i = '>' then doInc
        elif i = '<' then doDec
        elif i = '.' then doPrt
        elif i = '[' then doSloop
        elif i = ']' then doEloop
        else 1 |> ignore
        pc <- pc + 1
exec

欢迎来到 F# 社区。

这是一种更实用的程序编写方式。这只是一个开始,但我希望它能给你一些关于如何进行的想法。最终,您将希望尽可能避免使用可变值,而这样做的第一步可能是编写具有 unit 以外参数的函数。

let result = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."

let doPlus () =
    // reg.[ptr] <- (reg.[ptr] + 1) % 265
    printfn "ADDING"

let doMinus () = 
    // reg.[ptr] <- (reg.[ptr] - 1) % 265
    printfn "SUB"

let doDefault () = printfn ""

let funcs = 
    [|
        '+', doPlus
        '-', doMinus
    |] |> Map.ofArray

let exec () =
    result
    |> Seq.iteri (fun i c -> 
        printf "%03d: " i
        match funcs.TryFind(c) with
        | Some func -> func ()
        | None -> doDefault ()
    )
exec ()