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 ()
好的,所以我正在做一个小项目,正如你在标题中所说的那样,我正在用 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 ()