Execute Brain****/F Sharp: Difference between revisions
Content added Content deleted
m (add horizontal scrolling) |
m (moved RCBF/F Sharp to Execute Brain****/F Sharp) |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{implementation|Brainf***}}{{collection|RCBF}} |
{{implementation|Brainf***}}{{collection|RCBF}} |
||
An implementation of [[Brainf***]] in [[F Sharp|F#]]. |
|||
<br clear=all/> |
<br clear=all/> |
||
<div style='width: full; overflow: scroll'><lang fsharp>open System |
<div style='width: full; overflow: scroll'><lang fsharp>open System |
||
open System.Collections.Generic |
|||
let |
let RCBF (pgmStr : string) = |
||
let pgm = Seq.toArray pgmStr // Turn program into an array |
let pgm = Seq.toArray pgmStr // Turn program into an array |
||
let ptr = ref 0 // Pointer into input |
let ptr = ref 0 // Pointer into input |
||
let ip = ref 0 // Instruction Pointer |
let ip = ref 0 // Instruction Pointer |
||
let input = ref (Array.create 100 0) |
|||
let InputNumber() = |
let InputNumber() = |
||
Line 13: | Line 15: | ||
let mutable num = 0 |
let mutable num = 0 |
||
printfn "Enter a valid number" |
printfn "Enter a valid number" |
||
fValid <- |
fValid <- Int32.TryParse(Console.ReadLine(), &num); |
||
while not fValid do |
while not fValid do |
||
printfn "Invalid input. Please enter a valid number" |
printfn "Invalid input. Please enter a valid number" |
||
fValid <- |
fValid <- Int32.TryParse(Console.ReadLine(), &num); |
||
num |
num |
||
let InputAscii() = |
|||
printfn "Enter an ascii character" |
|||
let chOut = (Console.ReadKey().KeyChar) |
|||
printfn "" |
|||
int chOut |
|||
let AdvanceIp() = ip := !ip + 1 // Advance IP |
let AdvanceIp() = ip := !ip + 1 // Advance IP |
||
Line 23: | Line 31: | ||
let SkipBrackets fForward = |
let SkipBrackets fForward = |
||
if input.[!ptr] <> 0 then // If we have a 0 input |
if (!input).[!ptr] <> 0 then // If we have a 0 input |
||
AdvanceIp() // Then just advance to next instruction |
AdvanceIp() // Then just advance to next instruction |
||
else // otherwise |
else // otherwise |
||
Line 36: | Line 44: | ||
| _ -> ignore(0) // Ignore anything else |
| _ -> ignore(0) // Ignore anything else |
||
AdvanceIp() // When we're on the matching bracket, skip to the next instruction |
AdvanceIp() // When we're on the matching bracket, skip to the next instruction |
||
let MovePtr fRight = |
|||
if fRight then |
|||
ptr := !ptr + 1 |
|||
if !ptr >= (!input).Length then |
|||
Array.Resize(input, (!input).Length + 20) |
|||
else |
|||
ptr := !ptr - 1 |
|||
if !ptr < 0 then |
|||
let newInput = Array.create ((!input).Length + 20) 0 |
|||
Array.ConstrainedCopy(!input, 0, newInput, 20, (!input).Length) |
|||
ptr := 19 |
|||
let interpretCmd() = |
let interpretCmd() = |
||
match pgm.[!ip] with |
match pgm.[!ip] with |
||
| '>' -> |
| '>' -> MovePtr true; AdvanceIp() |
||
| '<' -> |
| '<' -> MovePtr false; AdvanceIp() |
||
| '+' -> input.[!ptr] <- input.[!ptr] + 1; AdvanceIp() |
| '+' -> (!input).[!ptr] <- (!input).[!ptr] + 1; AdvanceIp() |
||
| '-' -> input.[!ptr] <- input.[!ptr] - 1; AdvanceIp() |
| '-' -> (!input).[!ptr] <- (!input).[!ptr] - 1; AdvanceIp() |
||
| '.' -> printf "%c" (char input.[!ptr]); AdvanceIp() |
| '.' -> printf "%c" (char (!input).[!ptr]); AdvanceIp() |
||
| ',' -> input.[!ptr] <- InputNumber(); AdvanceIp() |
| ',' -> (!input).[!ptr] <- InputNumber(); AdvanceIp() |
||
| '~' -> (!input).[!ptr] <- InputAscii(); AdvanceIp() |
|||
| '[' -> SkipBrackets true |
| '[' -> SkipBrackets true |
||
| ']' -> SkipBrackets false |
| ']' -> SkipBrackets false |
||
| _ -> |
| _ -> AdvanceIp() |
||
while !ip >= 0 && !ip < pgm.Length do |
while !ip >= 0 && !ip < pgm.Length do |
Latest revision as of 14:20, 6 February 2010
Execute Brain****/F Sharp is an implementation of Brainf***.
Other implementations of Brainf***.
Execute Brain****/F Sharp is part of RCBF. You may find other members of RCBF at Category:RCBF.
An implementation of Brainf*** in F#.
<lang fsharp>open System
let RCBF (pgmStr : string) =
let pgm = Seq.toArray pgmStr // Turn program into an array let ptr = ref 0 // Pointer into input let ip = ref 0 // Instruction Pointer let input = ref (Array.create 100 0)
let InputNumber() = let mutable fValid = false let mutable num = 0 printfn "Enter a valid number" fValid <- Int32.TryParse(Console.ReadLine(), &num); while not fValid do printfn "Invalid input. Please enter a valid number" fValid <- Int32.TryParse(Console.ReadLine(), &num); num
let InputAscii() = printfn "Enter an ascii character" let chOut = (Console.ReadKey().KeyChar) printfn "" int chOut
let AdvanceIp() = ip := !ip + 1 // Advance IP let RetreatIp() = ip := !ip - 1 // Decrement IP
let SkipBrackets fForward = if (!input).[!ptr] <> 0 then // If we have a 0 input AdvanceIp() // Then just advance to next instruction else // otherwise let fnMove = if fForward then AdvanceIp else RetreatIp // get the appropriate function to move forward or backward let mutable cBrackets = 1 // Count of brackets we've seen while cBrackets > 0 do // While we have unmatched brackets fnMove() // move to the next character if !ip >= 0 && !ip < pgm.Length then // and if we're still within range match pgm.[!ip] with // look at the character | '[' -> cBrackets <- cBrackets + 1 // If it's a '[' then count up brackets | ']' -> cBrackets <- cBrackets - 1 // If it's a ']' then count down brackets | _ -> ignore(0) // Ignore anything else AdvanceIp() // When we're on the matching bracket, skip to the next instruction
let MovePtr fRight = if fRight then ptr := !ptr + 1 if !ptr >= (!input).Length then Array.Resize(input, (!input).Length + 20) else ptr := !ptr - 1 if !ptr < 0 then let newInput = Array.create ((!input).Length + 20) 0 Array.ConstrainedCopy(!input, 0, newInput, 20, (!input).Length) ptr := 19
let interpretCmd() = match pgm.[!ip] with | '>' -> MovePtr true; AdvanceIp() | '<' -> MovePtr false; AdvanceIp() | '+' -> (!input).[!ptr] <- (!input).[!ptr] + 1; AdvanceIp() | '-' -> (!input).[!ptr] <- (!input).[!ptr] - 1; AdvanceIp() | '.' -> printf "%c" (char (!input).[!ptr]); AdvanceIp() | ',' -> (!input).[!ptr] <- InputNumber(); AdvanceIp() | '~' -> (!input).[!ptr] <- InputAscii(); AdvanceIp() | '[' -> SkipBrackets true | ']' -> SkipBrackets false | _ -> AdvanceIp()
while !ip >= 0 && !ip < pgm.Length dointerpretCmd()</lang>
Hello world in RCBF (stolen from the Wiki site):
<lang fsharp>let pgmHelloWorld = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
let tape = Array.create 5 0
Rcbf pgmHelloWorld tape</lang>