The following code contains an infinite loop in it:
open System
type Ops = Add | Sub | Mul | Div | And | Or | Eor | Bic | Lsl | Lsr | Asr | Ror | Ldc of int
| Dup | Drop | Swap | Over | Ld8 | St8 | Ld16 | St16 | Ld32 | St32 | Se8 | Se16
| For of Exp | Next | If of Exp*Exp | Func of string*Exp | Ldl of string | Stl of string
and Exp = Ops list
type Sym = Var of int32 | Fun of Exp
let symbols = Map.empty
let isNumber (x:string) = fst (Int32.TryParse(x))
let getOps = function
| "+" -> Add
| "-" -> Sub
| "*" -> Mul
| "/" -> Div
| "and" -> And
| "or" -> Or
| "eor" -> Eor
| "bic" -> Bic
| "lsl" -> Lsl
| "lsr" -> Lsr
| "asr" -> Asr
| "ror" -> Ror
| "dup" -> Dup
| "drop" -> Drop
| "swap" -> Swap
| "over" -> Over
| "ld8" -> Ld8
| "st8" -> St8
| "ld16" -> Ld16
| "st16" -> St16
| "ld32" -> Ld32
| "st32" -> St32
| "for" -> For []
| "next" -> Next
| x when isNumber x -> Ldc (int x)
| x -> failwithf "Unknown word %A" x
let exec = function
| (Add,x::y::xs) -> (x+y)::xs
| (Sub,x::y::xs) -> (y-x)::xs
| (Mul,x::y::xs) -> (x*y)::xs
| (Div,x::y::xs) -> (y/x)::xs
| (Ldc x,xs) -> x::xs
| (_,[]) -> failwith "Empty stack"
| x -> failwithf "Unknown Op %A" x
let infix = function
| (Add,x::y::xs) -> ("("+x+" + "+y+")")::xs
| (Sub,x::y::xs) -> ("("+y+" - "+x+")")::xs
| (Mul,x::y::xs) -> ("("+x+" * "+y+")")::xs
| (Div,x::y::xs) -> ("("+y+" / "+x+")")::xs
| (Ldc x,xs) -> (string x)::xs
| (_,[]) -> failwith "Empty stack"
| x -> failwithf "Unknown Op %A" x
let run f = Array.fold (fun xs op -> f (op,xs)) []
//let source = "2 3 + 1 - 2 /"
let source = "1 4 for dup + next + -"
let code = source.Split() |> Array.filter ((<>)"") |> Array.map getOps
printfn "Source: %A" source
printfn "Code: %A" code
let rec combFor xs bb ys depth =
match xs with
| [] -> if bb <> [] then printfn "ERROR: bb not empty %A" bb
(xs,[],List.rev (bb@ys))
| Next::xs when depth = 0 -> printfn "ERROR: No For!"
failwith ""
| Next::xs when depth = 1 -> (xs,[],List.rev (bb@ys))//(xs,List.rev bb,ys)
//| Next::xs when depth > 0 -> combFor xs bb ys (depth - 1)
//| For [] :: xs -> combFor xs bb (For []::ys) (depth + 1)
| For [] :: xs -> let (xs,bb,ys) = combFor xs bb ys (depth + 1)
combFor xs [] (For bb :: ys) (depth + 1)
| x::xs when depth > 0 -> combFor xs (x::bb) ys depth
| x::xs -> combFor (x::xs) bb ys depth
let c = List.ofArray code
printfn "Code: %A" c
let d = combFor c [] [] 0
printfn "CFor: %A" d
//printfn "Infix: %A" (run infix code)
//let result = run exec code
//printfn "Result = %A" (List.rev result)
It's a lot, but this will run infinitely on a local machine as a console app.
In the browser, this will freeze the page until your browser eventually asks to quit. We should put a limit on execution time and stop executing code, then notify the user about that.
The following code contains an infinite loop in it:
It's a lot, but this will run infinitely on a local machine as a console app.
In the browser, this will freeze the page until your browser eventually asks to quit. We should put a limit on execution time and stop executing code, then notify the user about that.