Интерпретатор BF в выпуске F#

Итак, я работаю над небольшим проектом, как вы можете сказать в заголовке, я делаю интерпретатор BrainFuck в f#, и я новичок в этом языке, но это весело, за исключением того, что вы боретесь с большим количеством компилятора, но я привык к этому, потому что Раньше я использовал ржавчину, но, кроме того, мне кажется, что символы выполняются только один раз. Я знаю, что это неэффективно и не полностью функционально, но сейчас я просто работаю. Вот мой код
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

В чем именно заключается ваш вопрос? Вы имеете в виду, что вы просто определяете значения вместо функций? Функциям нужны входные данные, и они могут принимать void, если это необходимо. Определите это так let exec() = и вызовите его с помощью exec(), и это относится ко всему остальному, что является функцией в вашем коде.

s952163 17.12.2020 15:10

Я думаю, что @ s952163 правильный. Но технически не void, а unit. См. learn.microsoft.com/en-us/dotnet/fsharp/language-reference/…

Scott Hutchinson 17.12.2020 17:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Добро пожаловать в сообщество 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 ()

Другие вопросы по теме