removed some stdlib dependencies; license; bug fixes
This commit is contained in:
68
lib/array.ml
Normal file → Executable file
68
lib/array.ml
Normal file → Executable file
@ -1,27 +1,73 @@
|
||||
open General
|
||||
|
||||
external unsafe_get: 'a array -> int -> 'a = "%array_unsafe_get"
|
||||
external unsafe_set: 'a array -> int -> 'a -> unit = "%array_unsafe_set"
|
||||
external create: int -> 'a -> 'a array = "caml_make_vect"
|
||||
|
||||
let of_list = Stdlib.Array.of_list
|
||||
|
||||
let length = Stdlib.Array.length
|
||||
|
||||
let concat = Stdlib.Array.concat
|
||||
|
||||
let append = Stdlib.Array.append
|
||||
|
||||
let get = Stdlib.Array.get
|
||||
|
||||
let set = Stdlib.Array.set
|
||||
external length : 'a array -> int = "%array_length"
|
||||
|
||||
let map = Stdlib.Array.map
|
||||
external get : 'a array -> int -> 'a = "%array_safe_get"
|
||||
|
||||
let create = Stdlib.Array.init
|
||||
external set : 'a array -> int -> 'a -> unit = "%array_safe_set"
|
||||
|
||||
let heap_sort = Stdlib.Array.sort
|
||||
let of_list = function
|
||||
| [] -> [||]
|
||||
| x :: xs as l ->
|
||||
let a = create (List.length l) x in
|
||||
let rec fill i = function
|
||||
| [] ->
|
||||
a
|
||||
| x::xs ->
|
||||
unsafe_set a i x;
|
||||
fill Int.(i + 1) xs
|
||||
in
|
||||
fill 1 xs
|
||||
|
||||
let merge_sort = Stdlib.Array.stable_sort
|
||||
let create (length : int) (f : int -> 'a) : 'a array =
|
||||
if length = 0 then
|
||||
[||]
|
||||
else if length < 0 then
|
||||
Fatal.failwith "Cannot create an array with a size less than 0."
|
||||
else
|
||||
let result = create length (f 0) in
|
||||
for i = 1 to Int.(length - 1) do
|
||||
unsafe_set result i (f i)
|
||||
done;
|
||||
result
|
||||
|
||||
let copy = Stdlib.Array.copy
|
||||
let append (arr1 : 'a array) (arr2 : 'b array) =
|
||||
let open Int in
|
||||
let arr1_length = length arr1 in
|
||||
let arr2_length = length arr2 in
|
||||
|
||||
let init i =
|
||||
if i < arr1_length then
|
||||
get arr1 i
|
||||
else
|
||||
(get arr2 (i - arr1_length))
|
||||
in
|
||||
|
||||
create (arr1_length + arr2_length) init
|
||||
|
||||
let concat (arrays : 'a array list) : 'a array =
|
||||
arrays |> List.foldl append [||]
|
||||
|
||||
let map_mutate (f : 'a -> 'a) (arr : 'a array) : unit =
|
||||
let open Int in
|
||||
for i = 0 to length arr - 1 do
|
||||
set arr i ((get arr i) |> f);
|
||||
done;;
|
||||
|
||||
let copy (arr : 'a array) =
|
||||
create (length arr) (fun i -> get arr i)
|
||||
|
||||
let map (f : 'a -> 'b) (arr : 'a array) : 'b array =
|
||||
create (length arr) (fun i -> (get arr i) |> f)
|
||||
|
||||
let linear_search (arr : 'a array) (value : 'a) =
|
||||
let i = ref 0 in
|
||||
|
12
lib/array.mli
Normal file → Executable file
12
lib/array.mli
Normal file → Executable file
@ -3,24 +3,22 @@ open General
|
||||
|
||||
val of_list : 'a list -> 'a array
|
||||
|
||||
val length : 'a array -> int
|
||||
external length : 'a array -> int = "%array_length"
|
||||
|
||||
val concat : 'a array list -> 'a array
|
||||
|
||||
val append : 'a array -> 'a array -> 'a array
|
||||
|
||||
val get : 'a array -> int -> 'a
|
||||
external get: 'a array -> int -> 'a = "%array_safe_get"
|
||||
|
||||
val set : 'a array -> int -> 'a -> unit
|
||||
external set: 'a array -> int -> 'a -> unit = "%array_safe_set"
|
||||
|
||||
val map_mutate : ('a -> 'a) -> 'a array -> unit
|
||||
|
||||
val map : ('a -> 'b) -> 'a array -> 'b array
|
||||
|
||||
val create : int -> (int -> 'a) -> 'a array
|
||||
|
||||
val heap_sort : ('a -> 'a -> int) -> 'a array -> unit
|
||||
|
||||
val merge_sort : ('a -> 'a -> int) -> 'a array -> unit
|
||||
|
||||
val copy : 'a array -> 'a array
|
||||
|
||||
val linear_search : 'a array -> 'a -> 'a
|
||||
|
0
lib/bool.ml
Normal file → Executable file
0
lib/bool.ml
Normal file → Executable file
0
lib/bool.mli
Normal file → Executable file
0
lib/bool.mli
Normal file → Executable file
0
lib/char.ml
Normal file → Executable file
0
lib/char.ml
Normal file → Executable file
0
lib/char.mli
Normal file → Executable file
0
lib/char.mli
Normal file → Executable file
8
lib/console.ml
Executable file
8
lib/console.ml
Executable file
@ -0,0 +1,8 @@
|
||||
open General
|
||||
|
||||
external print : string -> unit = "print"
|
||||
|
||||
external read_line : int -> string = "read_line"
|
||||
|
||||
let print_all (contents : string list) : unit =
|
||||
print (String.concat contents)
|
10
lib/console.mli
Executable file
10
lib/console.mli
Executable file
@ -0,0 +1,10 @@
|
||||
open General
|
||||
|
||||
(** Prints the provided string to the console. *)
|
||||
external print : string -> unit = "print"
|
||||
|
||||
(** Reads a line from the console until a new line or EOF, using the specified buffer size. *)
|
||||
external read_line : int -> string = "read_line"
|
||||
|
||||
(** Displays all provided strings to the console in order. *)
|
||||
val print_all : string list -> unit
|
36
lib/console_external.c
Executable file
36
lib/console_external.c
Executable file
@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include <caml/mlvalues.h>
|
||||
#include <caml/memory.h>
|
||||
#include <caml/alloc.h>
|
||||
|
||||
CAMLprim value print(value data)
|
||||
{
|
||||
CAMLparam1(data);
|
||||
const char *data_string = String_val(data);
|
||||
|
||||
printf("%s", data_string);
|
||||
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
CAMLprim value read_line(value input_length)
|
||||
{
|
||||
CAMLparam1(input_length);
|
||||
const int input_length_int = Int_val(input_length);
|
||||
|
||||
char *input_line = malloc(sizeof (char) * input_length_int + 1);
|
||||
char *result = fgets(input_line, input_length_int + 1, stdin);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
printf("Failed to read input line from stdin.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
CAMLlocal1(return_string);
|
||||
|
||||
return_string = caml_copy_string(input_line);
|
||||
|
||||
free(input_line);
|
||||
CAMLreturn(return_string);
|
||||
}
|
0
lib/fatal.ml
Normal file → Executable file
0
lib/fatal.ml
Normal file → Executable file
0
lib/fatal.mli
Normal file → Executable file
0
lib/fatal.mli
Normal file → Executable file
0
lib/file.ml
Normal file → Executable file
0
lib/file.ml
Normal file → Executable file
0
lib/file.mli
Normal file → Executable file
0
lib/file.mli
Normal file → Executable file
90
lib/file_external.c
Executable file
90
lib/file_external.c
Executable file
@ -0,0 +1,90 @@
|
||||
#include <stdio.h>
|
||||
#include <caml/mlvalues.h>
|
||||
#include <caml/memory.h>
|
||||
#include <caml/alloc.h>
|
||||
|
||||
CAMLprim value write_all_lines(value file_path, value contents)
|
||||
{
|
||||
CAMLparam2(contents, file_path);
|
||||
|
||||
const char *contents_string = String_val(contents);
|
||||
const char *file_path_string = String_val(file_path);
|
||||
|
||||
FILE *fp = fopen(file_path_string, "w");
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("File %s was not opened correctly.\n", file_path_string);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fprintf(fp, "%s", contents_string);
|
||||
fclose(fp);
|
||||
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
long file_length_from_pointer(FILE *fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
long file_length(value file_path)
|
||||
{
|
||||
CAMLparam1(file_path);
|
||||
const char *file_path_string = String_val(file_path);
|
||||
|
||||
FILE *fp = fopen(file_path_string, "r");
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("File %s was not opened correctly.\n", file_path_string);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
long length = file_length_from_pointer(fp);
|
||||
fclose(fp);
|
||||
|
||||
return Val_long(length);
|
||||
}
|
||||
|
||||
|
||||
CAMLprim value read_all_lines(value file_path)
|
||||
{
|
||||
// Copy input from value to c string.
|
||||
CAMLparam1(file_path);
|
||||
const char *file_path_string = String_val(file_path);
|
||||
|
||||
// Open the file.
|
||||
FILE *fp = fopen(file_path_string, "r");
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("File %s was not opened correctly.\n", file_path_string);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Calculate the file length.
|
||||
long length = file_length_from_pointer(fp);
|
||||
|
||||
// Allocate the buffer
|
||||
char *buffer = malloc(sizeof (char) * length + 1);
|
||||
buffer[length] = '\0';
|
||||
|
||||
// Read the file.
|
||||
size_t read_size = fread(buffer, sizeof (char), length, fp);
|
||||
fclose(fp);
|
||||
|
||||
// Create the OCaml return value and copy over.
|
||||
CAMLlocal1(file_contents);
|
||||
file_contents = caml_copy_string(buffer);
|
||||
|
||||
// Free the buffer.
|
||||
free(buffer);
|
||||
|
||||
return file_contents;
|
||||
}
|
0
lib/float.ml
Normal file → Executable file
0
lib/float.ml
Normal file → Executable file
0
lib/float.mli
Normal file → Executable file
0
lib/float.mli
Normal file → Executable file
0
lib/general.ml
Normal file → Executable file
0
lib/general.ml
Normal file → Executable file
0
lib/general.mli
Normal file → Executable file
0
lib/general.mli
Normal file → Executable file
0
lib/int.ml
Normal file → Executable file
0
lib/int.ml
Normal file → Executable file
0
lib/int.mli
Normal file → Executable file
0
lib/int.mli
Normal file → Executable file
21
lib/list.ml
Normal file → Executable file
21
lib/list.ml
Normal file → Executable file
@ -152,5 +152,22 @@ let rec initialize_helper (f : int -> 'a) (length : int) (index : int) (acc : 'a
|
||||
let initialize (f : int -> 'a) (length : int) : 'a list =
|
||||
initialize_helper f length 0 []
|
||||
|
||||
let of_array =
|
||||
Stdlib.Array.to_list
|
||||
|
||||
|
||||
|
||||
|
||||
external unsafe_get: 'a array -> int -> 'a = "%array_unsafe_get"
|
||||
external array_length : 'a array -> int = "%array_length"
|
||||
|
||||
let rec of_array_helper arr i res =
|
||||
let open Int in
|
||||
if i < 0 then
|
||||
res
|
||||
else
|
||||
of_array_helper arr (i - 1) (unsafe_get arr i :: res)
|
||||
|
||||
|
||||
let of_array arr =
|
||||
let open Int in
|
||||
of_array_helper arr (array_length arr - 1) []
|
||||
|
0
lib/list.mli
Normal file → Executable file
0
lib/list.mli
Normal file → Executable file
28
lib/makefile
Normal file → Executable file
28
lib/makefile
Normal file → Executable file
@ -1,11 +1,19 @@
|
||||
STANDARD_FLAGS = -O3
|
||||
STANDARD_COMPILE = ocamlopt $(STANDARD_FLAGS) -nopervasives -c
|
||||
COMPILER = ocamlopt
|
||||
EXT = .cmx
|
||||
AEXT = .cmxa
|
||||
|
||||
STANDARD_FLAGS = -nopervasives -O3
|
||||
STANDARD_COMPILE = $(COMPILER) $(STANDARD_FLAGS) -c
|
||||
STANDARD_COMPILE_WITH_C = $(COMPILER) -ccopt -fPIC -c
|
||||
LIB_NAME = library
|
||||
|
||||
COMPILED_FILES = general$(EXT) fatal$(EXT) int$(EXT) float$(EXT) option$(EXT) stack$(EXT) list$(EXT) map$(EXT) queue$(EXT) set$(EXT) tree$(EXT) string$(EXT) char$(EXT) bool$(EXT) console$(EXT) file$(EXT)
|
||||
C_LIBS_FOR_LINKING = -cclib -lconsole_external -cclib -lfile_external
|
||||
|
||||
build:
|
||||
make clean
|
||||
|
||||
ocamlopt $(STANDARD_FLAGS) -nopervasives -c general.mli general.ml
|
||||
$(COMPILER) $(STANDARD_FLAGS) -c general.mli general.ml
|
||||
|
||||
$(STANDARD_COMPILE) fatal.mli fatal.ml
|
||||
$(STANDARD_COMPILE) int.mli int.ml
|
||||
@ -20,12 +28,14 @@ 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
|
||||
$(STANDARD_COMPILE) file.mli file.ml
|
||||
$(STANDARD_COMPILE) array.mli array.ml
|
||||
$(STANDARD_COMPILE) random.mli random.ml
|
||||
$(STANDARD_COMPILE_WITH_C) console_external.c console.mli console.ml
|
||||
ocamlmklib console_external.o -o console_external
|
||||
$(STANDARD_COMPILE_WITH_C) file_external.c file.mli file.ml
|
||||
ocamlmklib file_external.o -o file_external
|
||||
|
||||
ocamlopt -a 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 file.cmx array.cmx random.cmx -o $(LIB_NAME).cmxa
|
||||
$(STANDARD_COMPILE) array.mli array.ml
|
||||
|
||||
$(COMPILER) -a $(C_LIBS_FOR_LINKING) $(COMPILED_FILES) -o library.cmxa
|
||||
|
||||
clean:
|
||||
rm -f *.o *.a *.s *.cmi *.cmx *.cmxa *.cmo *.cma
|
||||
rm -f *.o *.a *.s *.so *.cmi *.cmx *.cmxa *.cmo *.cma
|
||||
|
0
lib/map.ml
Normal file → Executable file
0
lib/map.ml
Normal file → Executable file
0
lib/map.mli
Normal file → Executable file
0
lib/map.mli
Normal file → Executable file
0
lib/option.ml
Normal file → Executable file
0
lib/option.ml
Normal file → Executable file
0
lib/option.mli
Normal file → Executable file
0
lib/option.mli
Normal file → Executable file
5
lib/queue.ml
Normal file → Executable file
5
lib/queue.ml
Normal file → Executable file
@ -2,9 +2,10 @@ open General
|
||||
|
||||
open List
|
||||
|
||||
|
||||
let enqueue (a : 'a) (qu : 'a queue) : 'a queue =
|
||||
{ qu with front = a :: qu.back }
|
||||
match qu.front with
|
||||
| [] -> { front = [a]; back = [] }
|
||||
| _ -> { qu with back = a :: qu.back }
|
||||
|
||||
let dequeue (qu : 'a queue) : ('a option * 'a queue) =
|
||||
match qu.front with
|
||||
|
0
lib/queue.mli
Normal file → Executable file
0
lib/queue.mli
Normal file → Executable file
@ -1,17 +0,0 @@
|
||||
open General
|
||||
|
||||
|
||||
let init = Stdlib.Random.self_init
|
||||
|
||||
|
||||
let integer low high =
|
||||
init ();
|
||||
Int.((Stdlib.Random.int (high - low)) + low)
|
||||
|
||||
let float low high =
|
||||
init ();
|
||||
Float.((Stdlib.Random.float (high - low)) + low)
|
||||
|
||||
let boolean =
|
||||
init ();
|
||||
Stdlib.Random.bool
|
@ -1,11 +0,0 @@
|
||||
open General
|
||||
|
||||
|
||||
(** Generates a random integer between low (inclusive) and high (exclusive). *)
|
||||
val integer : int -> int -> int
|
||||
|
||||
(** Generates a random float between low (inclusive) and high (exclusive). *)
|
||||
val float : float -> float -> float
|
||||
|
||||
(** Generates a random boolean at even odds. *)
|
||||
val boolean : unit -> bool
|
0
lib/set.ml
Normal file → Executable file
0
lib/set.ml
Normal file → Executable file
0
lib/set.mli
Normal file → Executable file
0
lib/set.mli
Normal file → Executable file
0
lib/stack.ml
Normal file → Executable file
0
lib/stack.ml
Normal file → Executable file
0
lib/stack.mli
Normal file → Executable file
0
lib/stack.mli
Normal file → Executable file
5
lib/string.ml
Normal file → Executable file
5
lib/string.ml
Normal file → Executable file
@ -11,6 +11,8 @@ external format_float : string -> float -> string = "caml_format_float"
|
||||
|
||||
external length : string -> int = "%string_length"
|
||||
|
||||
external get : string -> int -> char = "%string_safe_get"
|
||||
|
||||
let of_int n =
|
||||
format_int "%d" n
|
||||
|
||||
@ -31,6 +33,8 @@ let ( + ) s1 s2 =
|
||||
|
||||
bytes_unsafe_to_string s
|
||||
|
||||
let concat : string list -> string =
|
||||
List.foldl (fun s m -> s + m) ""
|
||||
|
||||
external string_get : string -> int -> char = "%string_safe_get"
|
||||
let valid_float_lexem s =
|
||||
@ -44,6 +48,5 @@ let valid_float_lexem s =
|
||||
|
||||
loop 0
|
||||
|
||||
|
||||
let of_float f =
|
||||
valid_float_lexem (format_float "%.12g" f)
|
||||
|
8
lib/string.mli
Normal file → Executable file
8
lib/string.mli
Normal file → Executable file
@ -4,6 +4,9 @@ open General
|
||||
(** Calculates the length of the provided string. *)
|
||||
external length : string -> int = "%string_length"
|
||||
|
||||
(** Gets the character at the specified index. *)
|
||||
external get : string -> int -> char = "%string_safe_get"
|
||||
|
||||
(** Converts an int to a string. *)
|
||||
val of_int : int -> string
|
||||
|
||||
@ -14,4 +17,7 @@ val of_float : float -> string
|
||||
val of_bool : bool -> string
|
||||
|
||||
(** Concatenates two strings together in the provided order. *)
|
||||
val ( + ) : string -> string -> string
|
||||
val ( + ) : string -> string -> string
|
||||
|
||||
(** Concatenates a list of strings into a single string in sequence. *)
|
||||
val concat : string list -> string
|
@ -1,8 +0,0 @@
|
||||
open General
|
||||
|
||||
|
||||
let printf = Stdlib.Printf.printf
|
||||
|
||||
let print s = printf "%s" s
|
||||
|
||||
let read_line = Stdlib.read_line
|
@ -1,11 +0,0 @@
|
||||
open General
|
||||
|
||||
|
||||
(** Formatted print to terminal. *)
|
||||
val printf : ('a, Stdlib.out_channel, unit) Stdlib.format -> 'a
|
||||
|
||||
(** Prints the provided string to the terminal. *)
|
||||
val print : string -> unit
|
||||
|
||||
(** Reads an input line from the terminal. *)
|
||||
val read_line : unit -> string
|
0
lib/tree.ml
Normal file → Executable file
0
lib/tree.ml
Normal file → Executable file
0
lib/tree.mli
Normal file → Executable file
0
lib/tree.mli
Normal file → Executable file
Reference in New Issue
Block a user