Execute SNUSP/OCaml: Difference between revisions
Content added Content deleted
(added ocaml) |
m (Fixed syntax highlighting.) |
||
(4 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{implementation|SNUSP}}{{collection|RCSNUSP}} |
{{implementation|SNUSP}}{{collection|RCSNUSP}} |
||
This is an implementation of '''Modular SNUSP'''. |
|||
⚫ | |||
Usage: ocaml rcsnusp.ml srccode.snusp |
|||
⚫ | |||
try Some(input_line ic) |
try Some(input_line ic) |
||
with End_of_file -> None |
with End_of_file -> None |
||
Line 27: | Line 31: | ||
let ruld (x,y) = (y,x) |
let ruld (x,y) = (y,x) |
||
let lurd (x,y) = (-y,-x) |
let lurd (x,y) = (-y,-x) |
||
⚫ | |||
(* Printf.printf " (%d,%d)%!" (x+1) (y+1); *) |
|||
(x+dx, y+dy) |
|||
let incr (l,v,r) = (l,v+1,r) |
let incr (l,v,r) = (l,v+1,r) |
||
Line 47: | Line 47: | ||
let zero = function (_,0,_) -> true | _ -> false |
let zero = function (_,0,_) -> true | _ -> false |
||
⚫ | |||
⚫ | |||
let max_x = Array.fold_left (fun v line -> max v (String.length line)) 0 code |
|||
let max_y = Array.length code |
|||
let get_char code (x,y) = |
let get_char code (x,y) = |
||
if x < 0 || y < 0 || x > max_x || y > max_y then raise Exit; |
|||
try code.(y).[x] |
try code.(y).[x] |
||
with _ -> '\000' |
with _ -> '\000' |
||
let () = |
let () = |
||
⚫ | |||
let rec loop pos dir cells stk = |
let rec loop pos dir cells stk = |
||
match (get_char code pos) with |
match (get_char code pos) with |
||
Line 73: | Line 79: | ||
| _ -> loop (next_pos pos dir) dir cells stk |
| _ -> loop (next_pos pos dir) dir cells stk |
||
in |
in |
||
loop (dolar_pos code) (1,0) ([],0,[]) []</ |
loop (dolar_pos code) (1,0) ([],0,[]) []</syntaxhighlight> |
Latest revision as of 09:08, 1 September 2022
Execute SNUSP/OCaml is an implementation of SNUSP.
Other implementations of SNUSP.
Execute SNUSP/OCaml is part of RCSNUSP. You may find other members of RCSNUSP at Category:RCSNUSP.
This is an implementation of Modular SNUSP.
Usage: ocaml rcsnusp.ml srccode.snusp
let input_line ic =
try Some(input_line ic)
with End_of_file -> None
let read filename =
let ic = open_in filename in
let rec aux acc =
match input_line ic with
| Some line -> aux (line::acc)
| None -> close_in ic; Array.of_list(List.rev acc)
in
aux []
let dolar_pos code =
let x = ref 0 and y = ref 0 in
try
Array.iter (fun line ->
x := 0;
String.iter (function '$' -> raise Exit | _ -> incr x) line;
incr y) code;
(0, 0)
with Exit ->
(!x, !y)
let ruld (x,y) = (y,x)
let lurd (x,y) = (-y,-x)
let incr (l,v,r) = (l,v+1,r)
let decr (l,v,r) = (l,v-1,r)
let slide_left = function
| (p::l, v, r) -> (l, p, v::r)
| ([], v, r) -> ([], 0, v::r)
let slide_right = function
| (l, v, p::r) -> (v::l, p, r)
| (l, v, []) -> (v::l, 0, [])
let put (_,v,_) = print_char(char_of_int v)
let get (l,_,r) = (l, int_of_char(input_char stdin), r)
let zero = function (_,0,_) -> true | _ -> false
let next_pos ~pos:(x,y) ~dir:(dx,dy) = (x+dx, y+dy)
let code = read Sys.argv.(1)
let max_x = Array.fold_left (fun v line -> max v (String.length line)) 0 code
let max_y = Array.length code
let get_char code (x,y) =
if x < 0 || y < 0 || x > max_x || y > max_y then raise Exit;
try code.(y).[x]
with _ -> '\000'
let () =
let rec loop pos dir cells stk =
match (get_char code pos) with
| '\\' -> let dir = ruld dir in loop (next_pos pos dir) dir cells stk
| '/' -> let dir = lurd dir in loop (next_pos pos dir) dir cells stk
| '+' -> loop (next_pos pos dir) dir (incr cells) stk
| '-' -> loop (next_pos pos dir) dir (decr cells) stk
| '>' -> loop (next_pos pos dir) dir (slide_right cells) stk
| '<' -> loop (next_pos pos dir) dir (slide_left cells) stk
| '.' -> put cells; loop (next_pos pos dir) dir cells stk
| ',' -> loop (next_pos pos dir) dir (get cells) stk
| '?' when zero cells
-> loop (next_pos (next_pos pos dir) dir) dir cells stk
| '!' -> loop (next_pos (next_pos pos dir) dir) dir cells stk
| '@' -> let pos = next_pos pos dir in
loop pos dir cells ((next_pos pos dir, dir)::stk)
| '#' -> (match stk with [] -> ()
| (pos,dir)::stk -> loop pos dir cells stk)
| _ -> loop (next_pos pos dir) dir cells stk
in
loop (dolar_pos code) (1,0) ([],0,[]) []