scratch/brainfuck/src/gbf.gleam (view raw)
| 1 | import gbf/internal/ascii |
| 2 | import gbf/internal/eval |
| 3 | import gbf/internal/lexer |
| 4 | import gbf/internal/parser |
| 5 | import gbf/internal/vm.{type VirtualMachine} |
| 6 | import gleam/list |
| 7 | import gleam/result |
| 8 | import gleam/string |
| 9 | |
| 10 | pub type Error { |
| 11 | Parser(reason: parser.Error) |
| 12 | Eval(reason: eval.Error) |
| 13 | } |
| 14 | |
| 15 | pub fn run(source: String) -> Result(VirtualMachine, Error) { |
| 16 | let bvm = |
| 17 | source |
| 18 | |> string.split(on: "") |
| 19 | |> list.map(ascii.to_code) |
| 20 | |> vm.new |
| 21 | |
| 22 | use ast <- result.try(parse_ast(source)) |
| 23 | use bvm <- result.try(eval_ast(bvm, ast)) |
| 24 | |
| 25 | Ok(bvm) |
| 26 | } |
| 27 | |
| 28 | pub fn output(virtual_machine: VirtualMachine) -> String { |
| 29 | vm.output(virtual_machine) |
| 30 | } |
| 31 | |
| 32 | fn parse_ast(source: String) { |
| 33 | source |
| 34 | |> lexer.new |
| 35 | |> lexer.lex |
| 36 | |> parser.parse |
| 37 | |> result.map_error(fn(e) { Parser(e) }) |
| 38 | } |
| 39 | |
| 40 | fn eval_ast(vm, ast) { |
| 41 | eval.eval(vm, ast) |
| 42 | |> result.map_error(fn(e) { Eval(e) }) |
| 43 | } |