Talk:Minks

How can any instructions be executed if all of them have to be preceded by a condition, and it is not possible to set a condition without executing an instruction? Are undefined conditions true by default? --Marinus 16:01, 21 Jul 2006 (UTC)


 * Apparently so. --Ihope127 21:59, 21 Jul 2006 (UTC)

Implementation
I have written an interpreter in Ocaml which I believe is working. I have tested it on the Minks programs  (exits without doing anything),   (cat program), and   (prints a newline, then exits.)

Features:
 * if  (or  ) is executed while input has reached end of file, the number 0 is stored in the REGISTER (or register)
 * each register can hold a value between 0 and Ocaml's
 * technically, they can hold negative values, but since /  never go below 0, the only way to do that is to overflow them with a lot of  /  instructions
 * trying to output a negative value will display an error like, because Ocaml's modulo function is such that   results in -1
 * whitespace (spaces, newlines, tabulations) are mostly ignored, except every condition must be separated from the next instruction or condition with at least one space/tab/newline
 * conditions can have any alphabetic names (except the empty string); whether a word is an instruction or a condition depends entirely on its position within the program

Here is the source: (* conditions are A-Za-z only, case insensitive *) type condition = int (* REGISTER is true, register is false *) type instruction = Inc of bool | Dec of bool * condition | Out of bool | Inp of bool type item = I of instruction | C of condition

exception Syntax_error

let string_of_list l = let length = List.length l in let s = String.create length and l = ref l in  for k = length - 1 downto 0 do    s.[k] <- List.hd !l; l := List.tl !l done; s

let l_pos = let l_of_conds = ref [] and n = ref 0 in let rec pos s k l = match l with | h :: t -> if h = s then !n - k else pos s (succ k) t   | [] -> (l_of_conds := s :: !l_of_conds;      incr n;       pred !n) in function s -> pos s 1 !l_of_conds

let rec take_cond l = match l with | ' ' :: t | '\n' :: t | '\t' :: t -> take_cond t | _ -> t_2 [] l and t_2 acc l = match l with | ' ' :: t | '\n' :: t | '\t' :: t -> let s = string_of_list acc in   (l_pos s, t)  | [] -> let s = string_of_list acc in   (l_pos s, []) | h :: t -> t_2 ((let x = int_of_char h in       if (x > 64 && x < 91) then h        else if x > 96 && x < 123 then Char.lowercase h        else raise Syntax_error ) :: acc) t

let rec parser acc prev p_list = match (prev, p_list) with | (C s, 'I' :: 'N' :: 'C' :: t) -> parser ((s, Inc true) :: acc) (I (Inc true)) t | (C s, 'i' :: 'n' :: 'c' :: t) -> parser ((s, Inc false) :: acc) (I (Inc false)) t | (C s, 'O' :: 'U' :: 'T' :: t) -> parser ((s, Out true) :: acc) (I (Out true)) t | (C s, 'o' :: 'u' :: 't' :: t) -> parser ((s, Out false) :: acc) (I (Out false)) t | (C s, 'I' :: 'N' :: 'P' :: t) -> parser ((s, Inp true) :: acc) (I (Inp true)) t | (C s, 'i' :: 'n' :: 'p' :: t) -> parser ((s, Inp false) :: acc) (I (Inp false)) t | (C s, 'D' :: 'E' :: 'C' :: t) -> parser acc (I (Dec (true, s))) t | (C s, 'd' :: 'e' :: 'c' :: t) -> parser acc (I (Dec (false, s))) t | (_, ' ' :: t) | (_, '\n' :: t) | (_, '\t' :: t) -> parser acc prev t | (I (Dec (b, s)), l) -> let (s2, t2) = take_cond l in   parser ((s, Dec (b, s2)) :: acc) (I (Inc b)) t2  | (C s, _) -> raise Syntax_error | (I _, []) -> (let n = l_pos "" in Array.make n true,   List.rev acc) | (I _, l) -> let (s, t) = take_cond l in   parser acc (C s) t;;

let list_of_string s = let l = ref [] in for k = String.length s - 1 downto 0 do    l := s.[k] :: !l done; !l

let (cond_tab, program) = parser [] (I (Inc true)) (list_of_string Sys.argv.(1))

let is_true c = cond_tab.(c) let set_cond c b = cond_tab.(c) <- b

let (register, rEGISTER) = (ref 0, ref 0)

let rec execution have_met p_list = match p_list with | (c, Inc b) :: t -> if is_true c then (incr (if b then rEGISTER else register);      execution true t)    else execution have_met t  | (c, Out b) :: t -> if is_true c then (print_char       (char_of_int (!(if b then rEGISTER else register) mod 256) );      execution true t)    else execution have_met t  | (c, Inp b) :: t -> if is_true c then ((if b then rEGISTER else register) :=         begin try int_of_char (input_char stdin) with          | End_of_file -> 0 end;       execution true t)    else execution have_met t  | (c, Dec (b, c2)) :: t -> (if is_true c then let reg = (if b then rEGISTER else register)     in      if !reg = 0        then set_cond c2 false        else (decr reg; set_cond c2 true)    ); execution (have_met || is_true c) t  | [] -> if have_met then execution false program;;

execution false program;; --Koen (talk) 16:21, 12 October 2012 (UTC)