Created
July 29, 2011 05:04
-
-
Save ytomino/1113165 to your computer and use it in GitHub Desktop.
Revisions
-
aghia05 revised this gist
Nov 18, 2008 . 1 changed file with 17 additions and 17 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,19 +26,18 @@ let rec scan s i = ( | _ -> scan s (i + 1) );; type value = Value of char option * (value -> value);; let interpret stack source = ( let rec interpret stack source ((index, token) as position) = ( let rec apply stack f a = ( match stack with | s :: sr -> if a = 1 then ( let Value (_, func) = List.nth stack (f - 1) in func s ) else if f = 1 then ( let Value (_, func) = s in let arg = List.nth stack (a - 1) in func arg ) else ( @@ -73,13 +72,14 @@ let interpret stack source = ( let rec loop stack body = ( match body with | [] -> List.hd stack | (f, a) :: [] -> apply stack f a | (f, a) :: br -> loop ((apply stack f a) :: stack) br ) in loop stack body ) else ( Value (None, bind (n - 1) stack) ) ) in let r = Value (None, bind argc stack) in interpret (r :: stack) source position | T_W -> (* 関数適用 *) @@ -101,23 +101,23 @@ let interpret stack source = ( interpret stack source (find_first source) );; let true_f = Value (None, fun x -> Value (None, fun _ -> x));; let false_f = Value (None, fun _ -> Value (None, fun y -> y));; let char_f x = Value (Some x, fun y -> match y with | Value (Some y, _) -> if x = y then true_f else false_f | _ -> raise (Failure "In equal, argument is not char!\n"));; let init_stack = [ Value (None, function | Value (Some c, _) as a -> print_char c; if c = '\n' then flush stdout; a | _ -> raise (Failure "In primitive out, argument is not char!\n")); Value (None, function | Value (Some c, _) -> char_f (char_of_int ((int_of_char c + 1) mod 256)) | _ -> raise (Failure "In primitive succ, argument is not char!\n")); char_f 'w'; Value (None, fun x -> try char_f (input_char stdin) with End_of_file -> x)];; let read_all filename = ( let f = open_in_bin filename in -
aghia05 revised this gist
Nov 18, 2008 . 1 changed file with 77 additions and 75 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,102 +1,104 @@ type token = T_w | T_W | T_v | EOF;; let rec scan s i = ( let length = String.length s in if i >= length then length, EOF else match s.[i] with | 'W' -> i + 1, T_W | 'w' -> i + 1, T_w | 'v' -> i + 1, T_v | '\xef' -> (* W : EF BC B7, v : EF BD 96, w : EF BD 97 *) if i + 2 >= length then length, EOF else begin match s.[i + 1] with | '\xbc' -> begin match s.[i + 2] with | '\xb7' -> i + 3, T_W | _ -> scan s (i + 3) end | '\xbd' -> begin match s.[i + 2] with | '\x96' -> i + 3, T_v | '\x97' -> i + 3, T_w | _ -> scan s (i + 3) end | _ -> scan s (i + 3) end | _ -> scan s (i + 1) );; type value = char option * func and func = Func of (value -> value);; let interpret stack source = ( let rec interpret stack source ((index, token) as position) = ( let rec apply stack f a = ( match stack with | s :: sr -> if a = 1 then ( let _, Func func = List.nth stack (f - 1) in func s ) else if f = 1 then ( let _, Func func = s in let arg = List.nth stack (a - 1) in func arg ) else ( apply sr (f - 1) (a - 1) ) | [] -> raise (Failure "Stack underflow!\n") ) in let rec read target source ((index, token) as position) n = ( if token = target then ( read target source (scan source index) (n + 1) ) else ( position, n ) ) in let rec read_body source position body = ( let position, f = read T_W source position 0 in if f = 0 then (position, List.rev body) else let position, a = read T_w source position 0 in read_body source position ((f, a) :: body) ) in match token with | EOF -> (* 最後に来たらApply(1,1)して終了 *) let _ = apply stack 1 1 in () | T_w -> (* 関数定義 *) let position, argc = read T_w source position 0 in let position, body = read_body source position [] in let rec bind n stack arg = ( let stack = arg :: stack in if n = 1 then ( let rec loop stack body = ( match body with | [] -> List.hd stack | (f, a) :: br -> loop ((apply stack f a) :: stack) br ) in loop stack body ) else ( None, Func (bind (n - 1) stack) ) ) in let r = None, Func (bind argc stack) in interpret (r :: stack) source position | T_W -> (* 関数適用 *) let position, f = read T_W source position 0 in let position, a = read T_w source position 0 in let r = apply stack f a in interpret (r :: stack) source position | T_v -> interpret stack source (scan source index) (* skip *) ) in let find_first s = ( let rec loop s i = ( let (j, t) as r = scan s i in match t with | T_w | EOF -> r | _ -> loop s j ) in loop s 0 ) in interpret stack source (find_first source) );; let true_f = None, Func (fun x -> None, Func (fun _ -> x));; -
aghia05 created this gist
Nov 18, 2008 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,130 @@ type value = char option * func and func = Func of (value -> value);; let sub_eq sub s i = ( let rec loop sub j s i c = ( if c <= 0 then true else if sub.[j] <> s.[i] then false else loop sub (j + 1) s (i + 1) (c - 1) ) in let sub_length = String.length sub in if i + sub_length > String.length s then false else loop sub 0 s i sub_length );; let peek half full s i = ( let length = String.length s in if i >= length then i else if s.[i] = half then i + 1 else let full_length = String.length full in if i + full_length > length then i else if sub_eq full s i then i + full_length else i );; let peek_w = peek 'w' "w";; let peek_W = peek 'W' "W";; let peek_v = peek 'v' "v";; let find_first peek s = ( let rec loop peek s i = ( if i >= String.length s then i else let r = peek s i in if r > i then i else loop peek s (i + 1) ) in loop peek s 0 );; let interpret stack source = ( let rec interpret stack source index = ( let rec read peek source index n = ( let r = peek source index in if r > index then ( read peek source r (n + 1) ) else if peek_w source index > index || peek_W source index > index || peek_v source index > index then ( index, n ) else if index < String.length source then ( read peek source (index + 1) n (* skip *) ) else ( index, n ) ) in let rec read_body source index body = ( let (index, f) = read peek_W source index 0 in if f = 0 then (index, List.rev body) else let (index, a) = read peek_w source index 0 in read_body source index ((f, a) :: body) ) in let apply stack f a = ( let (_, Func func) = List.nth stack (f - 1) in let arg = List.nth stack (a - 1) in func arg ) in if index >= String.length source then ( (* 最後に来たらApply(1,1)して終了 *) let _ = apply stack 1 1 in () ) else if peek_w source index > index then ( (* 関数定義 *) let (index, argc) = read peek_w source index 0 in (* Printf.printf "%d:\n" argc; flush stdout; *) let (index, body) = read_body source index [] in let rec make stack n = ( if n = 0 then ( let rec loop stack body = ( match body with | [] -> List.hd stack | (f, a) :: br -> loop ((apply stack f a) :: stack) br ) in loop stack body ) else ( None, Func (fun a -> make (a :: stack) (n - 1)) ) ) in let r = make stack argc in interpret (r :: stack) source index ) else if peek_W source index > index then ( (* 関数適用 *) let (index, f) = read peek_W source index 0 in let (index, a) = read peek_w source index 0 in (* Printf.printf " %d %d\n" f a; flush stdout; *) let r = apply stack f a in interpret (r :: stack) source index ) else ( (* 無視 *) interpret stack source (index + 1) ) ) in interpret stack source (find_first peek_w source); );; let true_f = None, Func (fun x -> None, Func (fun _ -> x));; let false_f = None, Func (fun _ -> None, Func (fun y -> y));; let char_f x = Some x, Func (fun y -> match y with | Some y, _ -> if x = y then true_f else false_f | _ -> raise (Failure "In equal, argument is not char!\n"));; let init_stack = [ None, Func (function | (Some c, _) as a -> print_char c; if c = '\n' then flush stdout; a | None, _ -> raise (Failure "In primitive out, argument is not char!\n")); None, Func (function | Some c, _ -> char_f (char_of_int ((int_of_char c + 1) mod 256)) | None, _ -> raise (Failure "In primitive succ, argument is not char!\n")); char_f 'w'; None, Func (fun x -> try char_f (input_char stdin) with End_of_file -> x)];; let read_all filename = ( let f = open_in_bin filename in let size = in_channel_length f in let result = String.make size '\x00' in really_input f result 0 size; close_in f; result );; let filename = Sys.argv.(1) in interpret init_stack (read_all filename);;