blob: 04b678f96eb81360e08bda4a99df5936c4500a2b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
(*
* @LANG: ocaml
*)
let id x = x
let fail fmt = Printf.ksprintf failwith fmt
let pr fmt = Printf.ksprintf print_endline fmt
let failed fmt = Printf.ksprintf (fun s -> prerr_endline s; exit 1) fmt
let test' show f x y = if f x <> y then failed "FAILED: test %S" (show x)
let case = ref 0
let test f x y = incr case; if f x <> y then failed "FAILED: case %d" !case
let error f x = match try Some (f x) with _ -> None with Some _ -> failed "FAILED: fail %S" x | None -> ()
%%{
machine atoi;
write data;
}%%
let fail fmt = Printf.ksprintf failwith fmt
let atoi data =
let cs = ref 0 in
let p = ref 0 in
let pe = ref (String.length data) in
let neg = ref false in
let res = ref 0 in
%%{
action see_neg { neg := true; }
action add_digit { res := !res * 10 + (fc - Char.code '0'); }
main :=
( '-'@see_neg | '+' )? ( digit @add_digit )+
'\n'?
;
write init;
write exec;
}%%
if !neg then
res := (-1) * !res ;
print_int res.contents;
print_string "\n";
if !cs < atoi_first_final then
fail "atoi: cs %d < %d" !cs atoi_first_final;
!res
;;
let () =
let t = test atoi in
t "7" 7;
t "666" 666;
t "-666" (-666);
t "+666" 666;
t "123456789" 123456789;
t "+123456789\n" 123456789;
error atoi "+ 1234567890";
()
;;
##### OUTPUT #####
7
666
-666
666
123456789
123456789
0
|