summaryrefslogtreecommitdiff
path: root/test/ragel.d/atoi4.rl
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