terminal and fatal modules, cleaner hiding of FromStdlib functions and renamed exposed module to general
This commit is contained in:
parent
a8cdd2411f
commit
e9368e17c1
19
README.md
19
README.md
@ -14,6 +14,7 @@ This library includes the following custom modules:
|
||||
|
||||
- Bool (for basic operations on booleans)
|
||||
- Char (for basic operations on characters)
|
||||
- Fatal (for throwing exceptions, and making assertions)
|
||||
- Float (for basic operations on floating point numbers)
|
||||
- Int (for basic operations on integers)
|
||||
- List (functional list data structure)
|
||||
@ -23,19 +24,16 @@ This library includes the following custom modules:
|
||||
- Set (functional set implemented as a red-black tree)
|
||||
- Stack (functional stack data structure)
|
||||
- String (for basic operations on strings)
|
||||
- Terminal (for terminal IO)
|
||||
- Tree (functional generic tree type with some general functions to manipulate it)
|
||||
|
||||
## Exposure of Functions from Standard Library
|
||||
|
||||
With respect to the exposed parts of the standard library, these are all handled in the `FromStdlib` module, which redefines some definitions directly from the standard library so that this file can be safely included separately, exposing only the desired functions. As such, it is recommended that this file is opened in the code that uses this library, while others are not, and referenced from the module level instead (with one additional exception of `Exposed`, mentioned in the following section).
|
||||
|
||||
All files are compiled with `-nopervasives` except `FromStdlib` (to avoid the headaches in exposing functions like `printf` which have many dependencies). Linking is also done without `-nopervasives` so that `fromStdlib.cmx` can find the corresponding functions.
|
||||
|
||||
Some functions exist in the `FromStdlib` module which have names starting with `stdlib`. These functions can be called directly, but it is generally recommended they are called from the corresponding module in the custom standard library. They exist in `FromStdlib` to be exposed more neatly elsewhere.
|
||||
Some functions from the OCaml standard library are exposed through this library. They are handled by the `FromStdlib` module which SHOULD NOT be accessed directly in projects using this library. All functions and types from this module that are exposed to be used in projects are redefined in another module and should be accessed there. The reason for this module is to allow the rest of the modules to be compile with the `-nopervasives` flag yet still access a few of the official OCaml standard module functions.
|
||||
|
||||
## Type Declarations and General Functions
|
||||
|
||||
In order to prevent duplicate definitions of common types like collections, but still allow things like list literals to work, and to prevent the need of a type annotation at the module level, a `Exposed` module is provided to be opened in code files which exposes types like `'a queue` and other collections. `Exposed` also includes generic operators that should be opened file wide, such as function composition (`>>`). This should always be opened at the top of project files.
|
||||
In order to prevent duplicate definitions of common types like collections, but still allow things like list literals to work, and to prevent the need of a type annotation at the module level, the `General` module is provided to be opened in code files which exposes types like `'a queue` and other collections. `General` also includes generic operators that should be opened file wide, such as function composition (`>>`). This should always be opened at the top of project files.
|
||||
|
||||
## Compiler Options
|
||||
|
||||
@ -51,7 +49,7 @@ In the root folder of this repository, a makefile is provided to be used for pro
|
||||
|
||||
To create a new project, simply create the file you wish to add in the top level. For example, let's say we are creating a file called `main.ml`.
|
||||
|
||||
We first create the file in the root directory, and then change the build section of makefile from this:
|
||||
We first create the file in the root directory, add the line `open General` to the top of the file, and then change the build section of makefile from this:
|
||||
|
||||
```
|
||||
build:
|
||||
@ -98,7 +96,7 @@ Just as with the project in the top level, file order should be consistent acros
|
||||
|
||||
## The Core Library
|
||||
|
||||
One of the unfortunate consequences of the way OCaml's compilation works, is that there is a library called the core library (not to be confused with Jane Street's Core), documented [here](https://ocaml.org/manual/core.html), which contains some definitions for types and exceptions, yet does not include the code from the stdlib that uses them. When compiling with the `-nopervasives` flag, this is still included but without the standard library. While this makes sense from the perspective of having some fundamental exceptions always available, having types like `list` included makes it very annoying when implemented a custom standard library. This quirk is why my library has no type definition for `list`, `bool`, `option`, etc. but still uses these types.
|
||||
One of the unfortunate consequences of the way OCaml's compilation works, is that there is a library called the core library (not to be confused with Jane Street's Core), documented [here](https://ocaml.org/manual/core.html), which contains some definitions for types and exceptions, yet does not include the code from the stdlib that uses them. When compiling with the `-nopervasives` flag, this is still included but without the standard library. While this makes sense from the perspective of having some fundamental exceptions always available, having types like `list` included makes it very annoying when implemented a custom standard library (with the benefit of list literals still functioning properly). This quirk is why my library has no type definition for `list`, `bool`, `option`, etc. but still uses these types.
|
||||
|
||||
## Planned Changes
|
||||
|
||||
@ -107,7 +105,10 @@ The following modules are some that I plan on introducing in future iterations o
|
||||
- Array: for operations with mutable arrays.
|
||||
- Random: for random number generation.
|
||||
- File: for file IO.
|
||||
- Input: for command line inputs and arguments.
|
||||
|
||||
I also intend on modifying the following modules:
|
||||
|
||||
- Terminal: this module still needs input functions.
|
||||
|
||||
## Tests
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
open FromStdlib open Exposed
|
||||
open General
|
||||
|
||||
let of_string = stdlib_bool_of_string_opt
|
||||
let of_string = FromStdlib.bool_of_string_opt
|
||||
|
@ -1,2 +1,4 @@
|
||||
open General
|
||||
|
||||
(** Converts the string to a bool, returning option type to account for invalid strings. *)
|
||||
val of_string : string -> bool option
|
@ -1,3 +1,3 @@
|
||||
open FromStdlib open Exposed
|
||||
open General
|
||||
|
||||
let of_int = stdlib_char_of_int
|
||||
let of_int = FromStdlib.char_of_int
|
@ -1,2 +1,4 @@
|
||||
open General
|
||||
|
||||
(** Converts an int to a char. *)
|
||||
val of_int : int -> char
|
@ -1,20 +0,0 @@
|
||||
type 'a queue = { front : 'a list; back : 'a list }
|
||||
|
||||
type 'a result =
|
||||
| Error of string
|
||||
| Success of 'a
|
||||
|
||||
type 'a stack =
|
||||
| Empty
|
||||
| Stacked of 'a * 'a stack
|
||||
|
||||
type 'a tree =
|
||||
| Leaf
|
||||
| Branch of 'a * 'a tree list
|
||||
|
||||
|
||||
let id (x : 'a) = x
|
||||
|
||||
let ( >> ) f g x = g (f x)
|
||||
|
||||
let ( << ) g f x = g (f x)
|
@ -1,25 +0,0 @@
|
||||
(** Purely functional queue, implemented as a pair of lists. *)
|
||||
type 'a queue = { front : 'a list; back : 'a list }
|
||||
|
||||
type 'a result =
|
||||
| Error of string
|
||||
| Success of 'a
|
||||
|
||||
(** Purely functional stack. *)
|
||||
type 'a stack =
|
||||
| Empty
|
||||
| Stacked of 'a * 'a stack
|
||||
|
||||
(* A purely functional tree with arbitrarily many branches at each node. *)
|
||||
type 'a tree =
|
||||
| Leaf
|
||||
| Branch of 'a * 'a tree list
|
||||
|
||||
(** Identity function. *)
|
||||
val id : 'a -> 'a
|
||||
|
||||
(** Function composition. (f >> g) x represents g (f x). *)
|
||||
val ( >> ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c
|
||||
|
||||
(** Function composition. (f << g) x represents f (g x). *)
|
||||
val ( << ) : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
|
11
lib/fatal.ml
Normal file
11
lib/fatal.ml
Normal file
@ -0,0 +1,11 @@
|
||||
open General
|
||||
|
||||
let failwith = FromStdlib.failwith
|
||||
|
||||
let guarantee b =
|
||||
if not b then
|
||||
failwith "guarantee failed.\n"
|
||||
|
||||
let guarantee_equal a b =
|
||||
if a <> b then
|
||||
failwith "guarantee_equal failed."
|
10
lib/fatal.mli
Normal file
10
lib/fatal.mli
Normal file
@ -0,0 +1,10 @@
|
||||
open General
|
||||
|
||||
(** Throws an exception with a message. *)
|
||||
val failwith : string -> 'a
|
||||
|
||||
(** Throws an exception if the provided bool is not true. *)
|
||||
val guarantee : bool -> unit
|
||||
|
||||
(** Throws an exception if the provided arguments are not equal. *)
|
||||
val guarantee_equal : 'a -> 'a -> unit
|
12
lib/float.ml
12
lib/float.ml
@ -1,11 +1,11 @@
|
||||
open FromStdlib open Exposed
|
||||
open General
|
||||
|
||||
let ( + ) a b = stdlib_plus_float a b
|
||||
let ( + ) a b = FromStdlib.plus_float a b
|
||||
|
||||
let ( - ) a b = stdlib_minus_float a b
|
||||
let ( - ) a b = FromStdlib.minus_float a b
|
||||
|
||||
let ( * ) a b = stdlib_multiply_float a b
|
||||
let ( * ) a b = FromStdlib.multiply_float a b
|
||||
|
||||
let ( / ) a b = stdlib_divide_float a b
|
||||
let ( / ) a b = FromStdlib.divide_float a b
|
||||
|
||||
let of_string = stdlib_float_of_string_opt
|
||||
let of_string = FromStdlib.float_of_string_opt
|
||||
|
@ -1,3 +1,5 @@
|
||||
open General
|
||||
|
||||
val ( + ) : float -> float -> float
|
||||
|
||||
val ( - ) : float -> float -> float
|
||||
|
@ -1,37 +1,46 @@
|
||||
(* https://github.com/ocaml/ocaml/blob/cce52acc7c7903e92078e9fe40745e11a1b944f0/stdlib/pervasives.ml *)
|
||||
|
||||
(* For fatal.ml *)
|
||||
let failwith = Stdlib.failwith
|
||||
|
||||
|
||||
(* For terminal.ml *)
|
||||
let printf = Printf.printf
|
||||
|
||||
external ( |> ) : 'a -> ('a -> 'b) -> 'b = "%revapply"
|
||||
external ignore : 'a -> unit = "%ignore"
|
||||
type 'a printf_format = ('a, out_channel, unit) format
|
||||
|
||||
|
||||
external stdlib_int_of_char : char -> int = "%identity"
|
||||
let stdlib_char_of_int = char_of_int
|
||||
let stdlib_string_of_bool = string_of_bool
|
||||
let stdlib_bool_of_string = bool_of_string
|
||||
let stdlib_bool_of_string_opt = bool_of_string_opt
|
||||
let stdlib_string_of_int = string_of_int
|
||||
external stdlib_int_of_string : string -> int = "caml_int_of_string"
|
||||
let stdlib_int_of_string_opt = int_of_string_opt
|
||||
let stdlib_string_of_float = string_of_float
|
||||
external stdlib_float_of_string : string -> float = "caml_float_of_string"
|
||||
let stdlib_float_of_string_opt = float_of_string_opt
|
||||
(* For int.ml *)
|
||||
external int_of_char : char -> int = "%identity"
|
||||
let int_of_string_opt = int_of_string_opt
|
||||
|
||||
external stdlib_plus_int : int -> int -> int = "%addint"
|
||||
external stdlib_minus_int : int -> int -> int = "%subint"
|
||||
external stdlib_multiply_int : int -> int -> int = "%mulint"
|
||||
external stdlib_divide_int : int -> int -> int = "%divint"
|
||||
external stdlib_mod_int : int -> int -> int = "%modint"
|
||||
external plus_int : int -> int -> int = "%addint"
|
||||
external minus_int : int -> int -> int = "%subint"
|
||||
external multiply_int : int -> int -> int = "%mulint"
|
||||
external divide_int : int -> int -> int = "%divint"
|
||||
external mod_int : int -> int -> int = "%modint"
|
||||
|
||||
external stdlib_plus_float : float -> float -> float = "%addfloat"
|
||||
external stdlib_minus_float : float -> float -> float = "%subfloat"
|
||||
external stdlib_multiply_float : float -> float -> float = "%mulfloat"
|
||||
external stdlib_divide_float : float -> float -> float = "%divfloat"
|
||||
|
||||
external stdlib_string_length : string -> int = "%string_length"
|
||||
(* For float.ml *)
|
||||
let float_of_string_opt = float_of_string_opt
|
||||
|
||||
external plus_float : float -> float -> float = "%addfloat"
|
||||
external minus_float : float -> float -> float = "%subfloat"
|
||||
external multiply_float : float -> float -> float = "%mulfloat"
|
||||
external divide_float : float -> float -> float = "%divfloat"
|
||||
|
||||
|
||||
(* For char.ml *)
|
||||
let char_of_int = char_of_int
|
||||
|
||||
|
||||
(* For string.ml *)
|
||||
let string_of_bool = string_of_bool
|
||||
let string_of_int = string_of_int
|
||||
let string_of_float = string_of_float
|
||||
|
||||
external string_length : string -> int = "%string_length"
|
||||
|
||||
(* This block are not exposed *)
|
||||
external bytes_create : int -> bytes = "caml_create_bytes"
|
||||
external string_blit : string -> int -> bytes -> int -> int -> unit
|
||||
= "caml_blit_string" [@@noalloc]
|
||||
@ -39,24 +48,32 @@ external bytes_blit : bytes -> int -> bytes -> int -> int -> unit
|
||||
= "caml_blit_bytes" [@@noalloc]
|
||||
external bytes_unsafe_to_string : bytes -> string = "%bytes_to_string"
|
||||
|
||||
let stdlib_string_concat s1 s2 =
|
||||
let l1 = stdlib_string_length s1 and l2 = stdlib_string_length s2 in
|
||||
let string_concat s1 s2 =
|
||||
let l1 = string_length s1 and l2 = string_length s2 in
|
||||
let s = bytes_create (l1 + l2) in
|
||||
string_blit s1 0 s 0 l1;
|
||||
string_blit s2 0 s l1 l2;
|
||||
bytes_unsafe_to_string s
|
||||
|
||||
external ( = ) : 'a -> 'a -> bool = "%equal"
|
||||
external ( <> ) : 'a -> 'a -> bool = "%notequal"
|
||||
|
||||
external ( < ) : 'a -> 'a -> bool = "%lessthan"
|
||||
external ( > ) : 'a -> 'a -> bool = "%greaterthan"
|
||||
external ( <= ) : 'a -> 'a -> bool = "%lessequal"
|
||||
external ( >= ) : 'a -> 'a -> bool = "%greaterequal"
|
||||
(* For bool.ml *)
|
||||
let bool_of_string_opt = bool_of_string_opt
|
||||
|
||||
|
||||
(* For general.ml *)
|
||||
external equal : 'a -> 'a -> bool = "%equal"
|
||||
external not_equal : 'a -> 'a -> bool = "%notequal"
|
||||
|
||||
external less_than : 'a -> 'a -> bool = "%lessthan"
|
||||
external greater_than : 'a -> 'a -> bool = "%greaterthan"
|
||||
external less_than_or_equal : 'a -> 'a -> bool = "%lessequal"
|
||||
external greater_than_or_equal : 'a -> 'a -> bool = "%greaterequal"
|
||||
|
||||
external not : bool -> bool = "%boolnot"
|
||||
external ( or ) : bool -> bool -> bool = "%sequor"
|
||||
external ( & ) : bool -> bool -> bool = "%sequand"
|
||||
|
||||
external or_ : bool -> bool -> bool = "%sequor"
|
||||
external and_ : bool -> bool -> bool = "%sequand"
|
||||
|
||||
external pipeline : 'a -> ('a -> 'b) -> 'b = "%revapply"
|
||||
external ignore : 'a -> unit = "%ignore"
|
||||
|
||||
|
||||
|
@ -1,43 +1,61 @@
|
||||
(* For fatal.ml *)
|
||||
val failwith : string -> 'a
|
||||
|
||||
|
||||
(* For terminal.ml *)
|
||||
val printf : ('a, out_channel, unit) format -> 'a
|
||||
type 'a printf_format = ('a, out_channel, unit) format
|
||||
|
||||
external ( |> ) : 'a -> ('a -> 'b) -> 'b = "%revapply"
|
||||
external ignore : 'a -> unit = "%ignore"
|
||||
|
||||
external stdlib_int_of_char : char -> int = "%identity"
|
||||
val stdlib_char_of_int : int -> char
|
||||
val stdlib_string_of_bool : bool -> string
|
||||
val stdlib_bool_of_string : string -> bool
|
||||
val stdlib_bool_of_string_opt : string -> bool option
|
||||
val stdlib_string_of_int : int -> string
|
||||
external stdlib_int_of_string : string -> int = "caml_int_of_string"
|
||||
val stdlib_int_of_string_opt : string -> int option
|
||||
val stdlib_string_of_float : float -> string
|
||||
external stdlib_float_of_string : string -> float = "caml_float_of_string"
|
||||
val stdlib_float_of_string_opt : string -> float option
|
||||
(* For int.ml *)
|
||||
external int_of_char : char -> int = "%identity"
|
||||
val int_of_string_opt : string -> int option
|
||||
|
||||
external stdlib_plus_int : int -> int -> int = "%addint"
|
||||
external stdlib_minus_int : int -> int -> int = "%subint"
|
||||
external stdlib_multiply_int : int -> int -> int = "%mulint"
|
||||
external stdlib_divide_int : int -> int -> int = "%divint"
|
||||
external stdlib_mod_int : int -> int -> int = "%modint"
|
||||
external plus_int : int -> int -> int = "%addint"
|
||||
external minus_int : int -> int -> int = "%subint"
|
||||
external multiply_int : int -> int -> int = "%mulint"
|
||||
external divide_int : int -> int -> int = "%divint"
|
||||
external mod_int : int -> int -> int = "%modint"
|
||||
|
||||
external stdlib_plus_float : float -> float -> float = "%addfloat"
|
||||
external stdlib_minus_float : float -> float -> float = "%subfloat"
|
||||
external stdlib_multiply_float : float -> float -> float = "%mulfloat"
|
||||
external stdlib_divide_float : float -> float -> float = "%divfloat"
|
||||
|
||||
external stdlib_string_length : string -> int = "%string_length"
|
||||
val stdlib_string_concat : string -> string -> string
|
||||
(* For float.ml *)
|
||||
val float_of_string_opt : string -> float option
|
||||
|
||||
external ( = ) : 'a -> 'a -> bool = "%equal"
|
||||
external ( <> ) : 'a -> 'a -> bool = "%notequal"
|
||||
external plus_float : float -> float -> float = "%addfloat"
|
||||
external minus_float : float -> float -> float = "%subfloat"
|
||||
external multiply_float : float -> float -> float = "%mulfloat"
|
||||
external divide_float : float -> float -> float = "%divfloat"
|
||||
|
||||
external ( < ) : 'a -> 'a -> bool = "%lessthan"
|
||||
external ( > ) : 'a -> 'a -> bool = "%greaterthan"
|
||||
external ( <= ) : 'a -> 'a -> bool = "%lessequal"
|
||||
external ( >= ) : 'a -> 'a -> bool = "%greaterequal"
|
||||
|
||||
(* For char.ml *)
|
||||
val char_of_int : int -> char
|
||||
|
||||
|
||||
(* For string.ml *)
|
||||
val string_of_bool : bool -> string
|
||||
val string_of_int : int -> string
|
||||
val string_of_float : float -> string
|
||||
|
||||
external string_length : string -> int = "%string_length"
|
||||
val string_concat : string -> string -> string
|
||||
|
||||
|
||||
(* For bool.ml *)
|
||||
val bool_of_string_opt : string -> bool option
|
||||
|
||||
|
||||
(* For general.ml *)
|
||||
external equal : 'a -> 'a -> bool = "%equal"
|
||||
external not_equal : 'a -> 'a -> bool = "%notequal"
|
||||
|
||||
external less_than : 'a -> 'a -> bool = "%lessthan"
|
||||
external greater_than : 'a -> 'a -> bool = "%greaterthan"
|
||||
external less_than_or_equal : 'a -> 'a -> bool = "%lessequal"
|
||||
external greater_than_or_equal : 'a -> 'a -> bool = "%greaterequal"
|
||||
|
||||
external not : bool -> bool = "%boolnot"
|
||||
external ( or ) : bool -> bool -> bool = "%sequor"
|
||||
external ( & ) : bool -> bool -> bool = "%sequand"
|
||||
external or_ : bool -> bool -> bool = "%sequor"
|
||||
external and_ : bool -> bool -> bool = "%sequand"
|
||||
|
||||
external pipeline : 'a -> ('a -> 'b) -> 'b = "%revapply"
|
||||
external ignore : 'a -> unit = "%ignore"
|
42
lib/general.ml
Normal file
42
lib/general.ml
Normal file
@ -0,0 +1,42 @@
|
||||
type 'a queue = { front : 'a list; back : 'a list }
|
||||
|
||||
type 'a result =
|
||||
| Error of string
|
||||
| Success of 'a
|
||||
|
||||
type 'a stack =
|
||||
| Empty
|
||||
| Stacked of 'a * 'a stack
|
||||
|
||||
type 'a tree =
|
||||
| Leaf
|
||||
| Branch of 'a * 'a tree list
|
||||
|
||||
let ignore = FromStdlib.ignore
|
||||
|
||||
let id (x : 'a) = x
|
||||
|
||||
let ( >> ) f g x = g (f x)
|
||||
|
||||
let ( << ) g f x = g (f x)
|
||||
|
||||
let ( |> ) = FromStdlib.pipeline
|
||||
|
||||
let ( = ) = FromStdlib.equal
|
||||
|
||||
let ( <> ) = FromStdlib.not_equal
|
||||
|
||||
let ( < ) = FromStdlib.less_than
|
||||
|
||||
let ( > ) = FromStdlib.greater_than
|
||||
|
||||
let ( <= ) = FromStdlib.less_than_or_equal
|
||||
|
||||
let ( >= ) = FromStdlib.greater_than_or_equal
|
||||
|
||||
let not = FromStdlib.not
|
||||
|
||||
let ( or ) = FromStdlib.or_
|
||||
|
||||
let ( & ) = FromStdlib.and_
|
||||
|
58
lib/general.mli
Normal file
58
lib/general.mli
Normal file
@ -0,0 +1,58 @@
|
||||
(** Purely functional queue, implemented as a pair of lists. *)
|
||||
type 'a queue = { front : 'a list; back : 'a list }
|
||||
|
||||
type 'a result =
|
||||
| Error of string
|
||||
| Success of 'a
|
||||
|
||||
(** Purely functional stack. *)
|
||||
type 'a stack =
|
||||
| Empty
|
||||
| Stacked of 'a * 'a stack
|
||||
|
||||
(* A purely functional tree with arbitrarily many branches at each node. *)
|
||||
type 'a tree =
|
||||
| Leaf
|
||||
| Branch of 'a * 'a tree list
|
||||
|
||||
(** Identity function. *)
|
||||
val id : 'a -> 'a
|
||||
|
||||
(** Suppresses compiler warnings for unassigned return value from function. *)
|
||||
val ignore : 'a -> unit
|
||||
|
||||
(** Function composition. (f >> g) x represents g (f x). *)
|
||||
val ( >> ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c
|
||||
|
||||
(** Function composition. (f << g) x represents f (g x). *)
|
||||
val ( << ) : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
|
||||
|
||||
(** Pipeline operator, to reverse function application order. *)
|
||||
val ( |> ) : 'a -> ('a -> 'b) -> 'b
|
||||
|
||||
(** Checks for structural equality. *)
|
||||
val ( = ) : 'a -> 'a -> bool
|
||||
|
||||
(** Checks for structural inequality. *)
|
||||
val ( <> ) : 'a -> 'a -> bool
|
||||
|
||||
(** Polymorphic less than. *)
|
||||
val ( < ) : 'a -> 'a -> bool
|
||||
|
||||
(** Polymorphic greater than. *)
|
||||
val ( > ) : 'a -> 'a -> bool
|
||||
|
||||
(** Polymorphic less than or equal to. *)
|
||||
val ( <= ) : 'a -> 'a -> bool
|
||||
|
||||
(** Polymorphic greater than or equal to. *)
|
||||
val ( >= ) : 'a -> 'a -> bool
|
||||
|
||||
(** Logical negation. *)
|
||||
val not : bool -> bool
|
||||
|
||||
(** Logical or (infix). *)
|
||||
val ( or ) : bool -> bool -> bool
|
||||
|
||||
(** Logical and. *)
|
||||
val ( & ) : bool -> bool -> bool
|
16
lib/int.ml
16
lib/int.ml
@ -1,16 +1,16 @@
|
||||
open FromStdlib
|
||||
open General
|
||||
|
||||
let ( + ) a b = stdlib_plus_int a b
|
||||
let ( + ) a b = FromStdlib.plus_int a b
|
||||
|
||||
let ( - ) a b = stdlib_minus_int a b
|
||||
let ( - ) a b = FromStdlib.minus_int a b
|
||||
|
||||
let ( * ) a b = stdlib_multiply_int a b
|
||||
let ( * ) a b = FromStdlib.multiply_int a b
|
||||
|
||||
let ( / ) a b = stdlib_divide_int a b
|
||||
let ( / ) a b = FromStdlib.divide_int a b
|
||||
|
||||
let ( mod ) a b = stdlib_mod_int a b
|
||||
let ( mod ) a b = FromStdlib.mod_int a b
|
||||
|
||||
let of_char = stdlib_int_of_char
|
||||
let of_char = FromStdlib.int_of_char
|
||||
|
||||
let of_string = stdlib_int_of_string_opt
|
||||
let of_string = FromStdlib.int_of_string_opt
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
open General
|
||||
|
||||
val ( + ) : int -> int -> int
|
||||
|
||||
val ( - ) : int -> int -> int
|
||||
|
@ -1,5 +1,4 @@
|
||||
open FromStdlib
|
||||
open Exposed
|
||||
open General
|
||||
|
||||
let empty : 'a list = []
|
||||
|
||||
@ -71,8 +70,8 @@ let rec zip2_rev_tr_helper (ls1 : 'a list) (ls2 : 'b list) (acc : ('a * 'b) list
|
||||
else if (first_head = None & second_head <> None) or (first_head <> None & second_head = None) then
|
||||
Error "The two lists must be of the same length."
|
||||
else
|
||||
let a = match first_head with | Some x -> x | None -> failwith "if this exception is raised there is an error in the implementation of the function that called it" in
|
||||
let b = match second_head with | Some x -> x | None -> failwith "if this exception is raised there is an error in the implementation of the function that called it" in
|
||||
let a = match first_head with | Some x -> x | None -> Fatal.failwith "if this exception is raised there is an error in the implementation of the function that called it" in
|
||||
let b = match second_head with | Some x -> x | None -> Fatal.failwith "if this exception is raised there is an error in the implementation of the function that called it" in
|
||||
|
||||
zip2_rev_tr_helper (tail ls1) (tail ls2) ((a, b) :: acc)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
open Exposed
|
||||
open General
|
||||
|
||||
(** The empty list *)
|
||||
val empty : 'a list
|
||||
|
@ -6,10 +6,11 @@ build:
|
||||
# fromStdlib manages things that need to be exposed from the standard library
|
||||
ocamlopt $(STANDARD_FLAGS) -c fromStdlib.mli fromStdlib.ml
|
||||
|
||||
# exposed types and functions, that can be opened module wide
|
||||
ocamlopt $(STANDARD_FLAGS) -nopervasives -c exposed.mli exposed.ml
|
||||
# types and functions that should be opened module wide
|
||||
ocamlopt $(STANDARD_FLAGS) -nopervasives -c general.mli general.ml
|
||||
|
||||
# the following files make up the core custom standard library code
|
||||
$(STANDARD_COMPILE) fatal.mli fatal.ml
|
||||
$(STANDARD_COMPILE) int.mli int.ml
|
||||
$(STANDARD_COMPILE) float.mli float.ml
|
||||
$(STANDARD_COMPILE) option.mli option.ml
|
||||
@ -22,8 +23,9 @@ build:
|
||||
$(STANDARD_COMPILE) string.mli string.ml
|
||||
$(STANDARD_COMPILE) char.mli char.ml
|
||||
$(STANDARD_COMPILE) bool.mli bool.ml
|
||||
$(STANDARD_COMPILE) terminal.mli terminal.ml
|
||||
|
||||
ocamlopt -a fromStdlib.cmx exposed.cmx int.cmx float.cmx option.cmx stack.cmx list.cmx map.cmx queue.cmx set.cmx tree.cmx string.cmx -o $(LIB_NAME).cmxa
|
||||
ocamlopt -a fromStdlib.cmx general.cmx fatal.cmx int.cmx float.cmx option.cmx stack.cmx list.cmx map.cmx queue.cmx set.cmx tree.cmx string.cmx char.cmx bool.cmx terminal.cmx -o $(LIB_NAME).cmxa
|
||||
|
||||
clean:
|
||||
rm -f *.o *.a *.s *.cmi *.cmx *.cmxa *.cmo *.cma
|
||||
|
@ -1,4 +1,4 @@
|
||||
open FromStdlib
|
||||
open General
|
||||
|
||||
module type Map = sig
|
||||
type key
|
||||
@ -63,6 +63,6 @@ module RBTreeMap (M : MapSpecification) : Map with type key = M.key = struct
|
||||
let insert ((k, v) : (key * 'v)) map =
|
||||
match insert_helper (k, v) map with
|
||||
| Branch (_, (key, value), left, right) -> Branch (Black, (key, value), left, right)
|
||||
| Leaf -> failwith "if this exception is raised there is an error in the implementation of the function that called it"
|
||||
| Leaf -> Fatal.failwith "if this exception is raised there is an error in the implementation of the function that called it"
|
||||
|
||||
end
|
@ -1,3 +1,5 @@
|
||||
open General
|
||||
|
||||
module type Map = sig
|
||||
(** The type of keys in the map. *)
|
||||
type key
|
||||
|
@ -1,4 +1,4 @@
|
||||
open Exposed
|
||||
open General
|
||||
|
||||
let return (x : 'a) : 'a option = Some x
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
open General
|
||||
|
||||
(* Monadic return for option type. Trivially boxes the variable of type 'a into a 'a option by applying the Some constructor. *)
|
||||
val return : 'a -> 'a option
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
open General
|
||||
open List
|
||||
open Exposed
|
||||
|
||||
let enqueue (a : 'a) (qu : 'a queue) : 'a queue =
|
||||
{ qu with front = a :: qu.back }
|
||||
|
@ -1,4 +1,4 @@
|
||||
open Exposed
|
||||
open General
|
||||
|
||||
(** Adds an element to the back of the queue, returning the new queue. Runs in O(1). *)
|
||||
val enqueue : 'a -> 'a queue -> 'a queue
|
||||
|
@ -1,4 +1,4 @@
|
||||
open FromStdlib
|
||||
open General
|
||||
|
||||
module type RBTreeSet = sig
|
||||
type member
|
||||
@ -73,7 +73,7 @@ module RBTreeSet (M : SetSpecification) : RBTreeSet with type member = M.member
|
||||
let insert (v : member) (set : set) : set =
|
||||
match insert_helper v set with
|
||||
| Branch (_, value, left, right) -> Branch (Black, value, left, right)
|
||||
| Leaf -> failwith "if this exception is raised there is an error in the implementation of the function that called it"
|
||||
| Leaf -> Fatal.failwith "if this exception is raised there is an error in the implementation of the function that called it"
|
||||
|
||||
let rec union set1 set2 =
|
||||
match set1 with
|
||||
|
@ -1,3 +1,5 @@
|
||||
open General
|
||||
|
||||
module type RBTreeSet = sig
|
||||
(** Type of members in the set. *)
|
||||
type member
|
||||
|
@ -1,4 +1,4 @@
|
||||
open FromStdlib open Exposed
|
||||
open General
|
||||
|
||||
let pop (st : 'a stack) : 'a option * 'a stack =
|
||||
match st with
|
||||
|
@ -1,4 +1,4 @@
|
||||
open Exposed
|
||||
open General
|
||||
|
||||
(** Removes the top element from the stack, returning a tuple of the new stack, and None if the stack was empty, or Some [x] if [x] was on top of the stack. Popping an empty stack will result in the returned stack also being empty. Runs in O(1). *)
|
||||
val pop : 'a stack -> 'a option * 'a stack
|
||||
|
@ -1,11 +1,11 @@
|
||||
open FromStdlib open Exposed
|
||||
open General
|
||||
|
||||
let ( + ) = stdlib_string_concat
|
||||
let ( + ) = FromStdlib.string_concat
|
||||
|
||||
let length = stdlib_string_length
|
||||
let length = FromStdlib.string_length
|
||||
|
||||
let of_int = stdlib_string_of_int
|
||||
let of_int = FromStdlib.string_of_int
|
||||
|
||||
let of_float = stdlib_string_of_float
|
||||
let of_float = FromStdlib.string_of_float
|
||||
|
||||
let of_bool = stdlib_string_of_bool
|
||||
let of_bool = FromStdlib.string_of_bool
|
@ -1,3 +1,5 @@
|
||||
open General
|
||||
|
||||
(** Concatenates two strings together in the provided order. *)
|
||||
val ( + ) : string -> string -> string
|
||||
|
||||
|
6
lib/terminal.ml
Normal file
6
lib/terminal.ml
Normal file
@ -0,0 +1,6 @@
|
||||
open General
|
||||
|
||||
let printf = FromStdlib.printf
|
||||
|
||||
|
||||
let print s = printf "%s" s
|
7
lib/terminal.mli
Normal file
7
lib/terminal.mli
Normal file
@ -0,0 +1,7 @@
|
||||
open General
|
||||
|
||||
(** Formatted print to terminal. *)
|
||||
val printf : 'a FromStdlib.printf_format -> 'a
|
||||
|
||||
(** Prints the provided string to the terminal. *)
|
||||
val print : string -> unit
|
@ -1,5 +1,4 @@
|
||||
open FromStdlib
|
||||
open Exposed
|
||||
open General
|
||||
|
||||
let combine (tr1 : 'a tree) (tr2 : 'a tree) (topBranch : 'a) : 'a tree =
|
||||
Branch (topBranch, tr1 :: tr2 :: [])
|
||||
|
@ -1,4 +1,4 @@
|
||||
open Exposed
|
||||
open General
|
||||
|
||||
(* Combines two trees of the same type, with the specified value at the new top node. Runs in O(1). *)
|
||||
val combine : 'a tree -> 'a tree -> 'a -> 'a tree
|
||||
|
Loading…
Reference in New Issue
Block a user