File: main.v

package info (click to toggle)
coq-simple-io 1.11.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 380 kB
  • sloc: ml: 273; makefile: 66
file content (133 lines) | stat: -rw-r--r-- 3,277 bytes parent folder | download
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
From Coq.Strings Require Import
     Ascii String.
From Coq Require Import List.
Import ListNotations.

From Coq.extraction Require Import
     ExtrOcamlIntConv.

From SimpleIO Require Import SimpleIO IO_UnsafeNat IO_Bytes.
Import IO.Notations.

Local Open Scope string_scope.

Parameter int_constant : int.
Extract Constant int_constant => "3".

Class Eq (a : Type) :=
  eqb : a -> a -> bool.

Class Print (a : Type) :=
  print : a -> IO unit.

#[local]
Instance Eq_nat : Eq nat := Nat.eqb.
#[local]
Instance Print_nat : Print nat := print_nat.

#[local]
Instance Eq_option {a : Type} `{Eq a} : Eq (option a) :=
  fun x y =>
    match x, y with
    | None, None => true
    | Some x, Some y => eqb x y
    | _, _ => false
    end.
#[local]
Instance Print_option {a : Type} `{Print a} : Print (option a) :=
  fun x =>
    match x with
    | None => print_string "None"
    | Some x => print_string "Some (";; print x;; print_string ")"
    end.

(* Using coercions. [String.eqb] also exists since Coq 8.9 but this
   test needs to be compatible with 8.8. *)
#[local]
Instance Eq_string : Eq string := ostring_eqb.
#[local]
Instance Print_string : Print string := print_string.

#[local]
Instance Eq_ostring : Eq ocaml_string := ostring_eqb.
#[local]
Instance Print_ostring : Print ocaml_string :=
  fun s => print_string (OString.escaped s).

#[local]
Instance Eq_char : Eq char := char_eqb.
#[local]
Instance Print_char : Print char :=
  fun c => print (OString.of_list [c]).

Definition assert_eq {a} `{Eq a} `{Print a} (expect actual : a) : IO unit :=
  if eqb expect actual then
    IO.ret tt
  else
    (print_string "Expected: ";; print expect;; print_newline;;
     print_string "Actual  : ";; print actual;; print_newline;;
     exit_nat 1).

Coercion int_of_nat : nat >-> int.

Definition main (_ : unit) : IO unit :=
  (* Pervasives *)

  print_char (char_of_ascii "a");; print_newline;;
  print_int int_constant;; print_newline;;
  print_string "Hello";;
  print_endline " world!";;
  h <- open_out "test_file.txt";;
  output_byte_nat h 65;;
  close_out h;;
  h <- open_in "test_file.txt";;
  n <- input_byte_nat h;;
  close_in h;;
  assert_eq 65 n;;
  r <- new_ref 13;;
  incr_ref_nat r;;
  i <- read_ref r;;
  assert_eq 14 i;;
  write_ref r 1;;
  decr_ref_nat r;;
  j <- read_ref r;;
  assert_eq 0 j;;

  (* String *)

  let s : ocaml_string := "test" in
  assert_eq 4 (nat_of_int (OString.length s));;
  assert_eq (Some ("t"%char : char)) (OString.get_opt s 3);;
  assert_eq None (OString.get_opt s 4);;
  assert_eq ("test,test" : ocaml_string) (OString.concat "," [s;s]);;

  let nl := String "010" "" in
  let s' := OString.escaped (nl ++ nl)%string in
  assert_eq ("\n\n" : ocaml_string) s';;

  (* Bytes *)

  b <- OBytes.of_string "test";;
  s <- OBytes.to_string b;;
  assert_eq "test" (from_ostring s);;

  let n := nat_of_int (OBytes.length b) in
  assert_eq 4 n;;

  OBytes.set b 0 "r"%char;;
  r <- OBytes.get b 0;;
  assert_eq ("r"%char : char) r;;

  b <- OBytes.create (int_of_nat 1);;
  assert_eq 1 (nat_of_int (OBytes.length b));;

  exit_nat 0.

Definition run_main : io_unit := IO.unsafe_run (main tt).

Set Extraction Output Directory ".".

(* We extract the whole library to typecheck it. *)
Separate Extraction
  SimpleIO.SimpleIO
  run_main.