diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/.merlin | 1 | ||||
l--------- | src/common.ml | 1 | ||||
-rw-r--r-- | src/common.mli | 47 | ||||
-rw-r--r-- | src/eurm.ml | 22 | ||||
-rw-r--r-- | src/eurml.mli | 25 | ||||
-rw-r--r-- | src/eurml_test.ml | 75 | ||||
-rw-r--r-- | src/instptr.ml | 43 | ||||
-rw-r--r-- | src/instptr.mli | 29 | ||||
-rw-r--r-- | src/main.ml | 30 | ||||
-rw-r--r-- | src/makefile | 18 | ||||
-rw-r--r-- | src/parser.ml | 32 | ||||
-rw-r--r-- | src/parser.mli | 22 | ||||
-rw-r--r-- | src/reg.ml | 16 | ||||
-rw-r--r-- | src/reg.mli | 29 | ||||
-rw-r--r-- | src/urm.ml | 41 | ||||
-rw-r--r-- | src/urm.mli | 17 | ||||
-rw-r--r-- | src/urm_test.ml | 151 |
17 files changed, 599 insertions, 0 deletions
diff --git a/src/.merlin b/src/.merlin new file mode 100644 index 0000000..22dd628 --- /dev/null +++ b/src/.merlin | |||
@@ -0,0 +1 @@ | |||
PKG kaputt | |||
diff --git a/src/common.ml b/src/common.ml new file mode 120000 index 0000000..ed50e6f --- /dev/null +++ b/src/common.ml | |||
@@ -0,0 +1 @@ | |||
common.mli \ No newline at end of file | |||
diff --git a/src/common.mli b/src/common.mli new file mode 100644 index 0000000..4fa838d --- /dev/null +++ b/src/common.mli | |||
@@ -0,0 +1,47 @@ | |||
1 | (* | ||
2 | * UPEM / L3 / Functional programming / Project: URM | ||
3 | * Pacien TRAN-GIRARD, Adam NAILI | ||
4 | *) | ||
5 | |||
6 | type line = int | ||
7 | type label = string | ||
8 | type regidx = int | ||
9 | type regval = int | ||
10 | type reg = Reg of regidx * regval | ||
11 | |||
12 | type urmcmd = | ||
13 | | URMCopy of regidx * regidx | ||
14 | | URMJump of regidx * regidx * line | ||
15 | | URMSucc of regidx | ||
16 | | URMZero of regidx | ||
17 | |||
18 | type eurmcmd = | ||
19 | | Add of regidx * regidx | ||
20 | | Comment of string | ||
21 | | Copy of regidx * regidx | ||
22 | | Dec of regidx | ||
23 | | EqPredicate of regidx * regidx * label | ||
24 | | GEqPredicate of regidx * regidx * label | ||
25 | | GTPredicate of regidx * regidx * label | ||
26 | | Goto of label | ||
27 | | Inc of regidx | ||
28 | | Label of label | ||
29 | | LEqPredicate of regidx * regidx * label | ||
30 | | LTPredicate of regidx * regidx * label | ||
31 | | Mult of regidx * regidx | ||
32 | | Quit | ||
33 | | Sub of regidx * regidx | ||
34 | | Zero of regidx | ||
35 | | ZeroPredicate of regidx * label | ||
36 | |||
37 | type instptr = InstPtr of (line * urmcmd) list * (line * urmcmd) list | ||
38 | |||
39 | type urm = { | ||
40 | instptr : instptr; | ||
41 | regs : reg list | ||
42 | } | ||
43 | |||
44 | type state = { todo : int } | ||
45 | |||
46 | exception Syntax_error | ||
47 | |||
diff --git a/src/eurm.ml b/src/eurm.ml new file mode 100644 index 0000000..c571384 --- /dev/null +++ b/src/eurm.ml | |||
@@ -0,0 +1,22 @@ | |||
1 | (* | ||
2 | * UPEM / L3 / Functional programming / Project: URM | ||
3 | * Pacien TRAN-GIRARD, Adam NAILI | ||
4 | *) | ||
5 | |||
6 | open Common | ||
7 | |||
8 | let compile_preprocess eurmcmds = eurmcmds | ||
9 | let compile_stage1 eurmcmds state = eurmcmds, state | ||
10 | let compile_stage2 eurmcmds state = eurmcmds, state | ||
11 | let compile_stage3 eurmcmds state = eurmcmds, state | ||
12 | let compile_stage4 eurmcmds state = [URMZero(0)], state | ||
13 | |||
14 | let urm_from_eurm = | ||
15 | let chain transform (eurmcmds, compile_state) = transform eurmcmds compile_state | ||
16 | and initial_state = 0 | ||
17 | in (compile_preprocess, initial_state) | ||
18 | |> chain compile_stage1 | ||
19 | |> chain compile_stage2 | ||
20 | |> chain compile_stage3 | ||
21 | |> chain compile_stage4 | ||
22 | |||
diff --git a/src/eurml.mli b/src/eurml.mli new file mode 100644 index 0000000..8fd8ef1 --- /dev/null +++ b/src/eurml.mli | |||
@@ -0,0 +1,25 @@ | |||
1 | (* | ||
2 | * UPEM / L3 / Functional programming / Project: URM | ||
3 | * Pacien TRAN-GIRARD, Adam NAILI | ||
4 | *) | ||
5 | |||
6 | open Common | ||
7 | |||
8 | (* Strips out comments and rewrite/enumerate labels *) | ||
9 | val compile_preprocess : eurmcmd list -> eurmcmd list | ||
10 | |||
11 | (* Rewrites Dec, GEqPredicate, LEqPredicate, LTPredicate, Mult and ZeroPredicate *) | ||
12 | val compile_stage1 : eurmcmd list -> state -> eurmcmd list * state | ||
13 | |||
14 | (* Rewrites Add, GTPredicate and Sub *) | ||
15 | val compile_stage2 : eurmcmd list -> state -> eurmcmd list * state | ||
16 | |||
17 | (* Rewrites Goto *) | ||
18 | val compile_stage3 : eurmcmd list -> state -> eurmcmd list * state | ||
19 | |||
20 | (* Rewrites Inc, EqPredicate, Label and Zero *) | ||
21 | val compile_stage4 : eurmcmd list -> state -> urmcmd list * state | ||
22 | |||
23 | (* Transcompiles an EURM instruction sequence into URM *) | ||
24 | val urm_from_eurm : eurmcmd list -> urmcmd list | ||
25 | |||
diff --git a/src/eurml_test.ml b/src/eurml_test.ml new file mode 100644 index 0000000..7dc6e5e --- /dev/null +++ b/src/eurml_test.ml | |||
@@ -0,0 +1,75 @@ | |||
1 | (* | ||
2 | * UPEM / L3 / Functional programming / Project: URM | ||
3 | * Pacien TRAN-GIRARD, Adam NAILI | ||
4 | *) | ||
5 | |||
6 | open Common | ||
7 | open Urm | ||
8 | open Eurm | ||
9 | open Kaputt.Abbreviations | ||
10 | |||
11 | let () = | ||
12 | Test.add_simple_test | ||
13 | ~title:"example_eurm_factorial_conversion" | ||
14 | (fun () -> | ||
15 | let input_eurm = [ | ||
16 | Comment "Compute r1! and place the result in r1"; | ||
17 | ZeroPredicate (1, "r1=0"); | ||
18 | Goto "r1>0"; | ||
19 | Comment "r1 holds 0"; | ||
20 | Label "r1=0"; | ||
21 | Inc 1; | ||
22 | Goto "done"; | ||
23 | Comment "r1 holds a positive integer"; | ||
24 | Label "r1>0"; | ||
25 | Copy (2, 1); | ||
26 | Zero 1; | ||
27 | Inc 1; | ||
28 | Zero 3; | ||
29 | Inc 3; | ||
30 | Comment "main loop"; | ||
31 | Label "loop"; | ||
32 | Mult (1, 3); | ||
33 | EqPredicate (2, 3, "done"); | ||
34 | Inc 3; | ||
35 | Goto "loop"; | ||
36 | Label "done"; | ||
37 | Quit] | ||
38 | and expected_urm = [ | ||
39 | URMZero 4; | ||
40 | URMJump (1, 4, 4); | ||
41 | URMZero 8; | ||
42 | URMJump (8, 8, 7); | ||
43 | URMSucc 1; | ||
44 | URMZero 9; | ||
45 | URMJump (9, 9, 29); | ||
46 | URMCopy (2, 1); | ||
47 | URMZero 1; | ||
48 | URMSucc 1; | ||
49 | URMZero 3; | ||
50 | URMSucc 3; | ||
51 | URMCopy (5, 1); | ||
52 | URMZero 1; | ||
53 | URMZero 6; | ||
54 | URMJump (3, 6, 25); | ||
55 | URMZero 7; | ||
56 | URMJump (5, 7, 22); | ||
57 | URMSucc 1; | ||
58 | URMSucc 7; | ||
59 | URMZero 10; | ||
60 | URMJump (10, 10, 17); | ||
61 | URMSucc 6; | ||
62 | URMZero 11; | ||
63 | URMJump (11, 11, 15); | ||
64 | URMJump (2, 3, 29); | ||
65 | URMSucc 3; | ||
66 | URMZero 12; | ||
67 | URMJump (12, 12, 12); | ||
68 | URMZero 13; | ||
69 | URMJump (13, 13, 38)] | ||
70 | in let output_urm = urm_from_eurm input_eurm | ||
71 | in | ||
72 | Assert.is_true (output_urm = expected_urm)) | ||
73 | |||
74 | let () = if Array.mem "run-tests" Sys.argv then Test.launch_tests () | ||
75 | |||
diff --git a/src/instptr.ml b/src/instptr.ml new file mode 100644 index 0000000..0311a00 --- /dev/null +++ b/src/instptr.ml | |||
@@ -0,0 +1,43 @@ | |||
1 | (* | ||
2 | * UPEM / L3 / Functional programming / Project: URM | ||
3 | * Pacien TRAN-GIRARD, Adam NAILI | ||
4 | *) | ||
5 | |||
6 | open Common | ||
7 | |||
8 | let instptr_mk urmcmd_list = | ||
9 | let rec aux urmcmd_list count acc = match urmcmd_list with | ||
10 | | [] -> acc | ||
11 | | instr :: tail -> aux tail (count + 1) ((count, instr) :: acc) | ||
12 | in InstPtr([], List.rev (aux urmcmd_list 0 [])) | ||
13 | |||
14 | let instptr_move_up = function | ||
15 | | InstPtr(instr :: list1, list2) -> InstPtr(list1, instr :: list2) | ||
16 | | x -> x | ||
17 | |||
18 | let instptr_move_down = function | ||
19 | | InstPtr(list1, instr :: list2) -> InstPtr(instr :: list1, list2) | ||
20 | | x -> x | ||
21 | |||
22 | let instptr_get = function | ||
23 | | InstPtr(_, x :: _) -> x | ||
24 | | InstPtr(_, []) -> failwith "No instruction left" | ||
25 | |||
26 | let instptr_string instptr = | ||
27 | let string_of_inst = function | ||
28 | | Zero(a) -> "Zero " ^ (string_of_int a) | ||
29 | | Succ(a) -> "Succ " ^ (string_of_int a) | ||
30 | | Copy(a, b) -> "Copy " ^ (string_of_int a) ^ " " ^ (string_of_int b) | ||
31 | | Jump(a, b, c) -> "Jump " ^ (string_of_int a) ^ " " ^ (string_of_int b) ^ " " ^ (string_of_int c) | ||
32 | in let string_of_instptr (l, inst) = (string_of_int l) ^ ": " ^ string_of_inst inst | ||
33 | in try string_of_instptr (instptr_get instptr) with _ -> "null" | ||
34 | |||
35 | let instptr_end = function | ||
36 | | InstPtr(_, []) -> true | ||
37 | | _ -> false | ||
38 | |||
39 | let rec instptr_jump ptr offset = match offset with | ||
40 | | 0 -> ptr | ||
41 | | _ when offset > 0 -> instptr_jump (instptr_move_up ptr) (offset - 1) | ||
42 | | _ -> instptr_jump (instptr_move_down ptr) (offset + 1) | ||
43 | |||
diff --git a/src/instptr.mli b/src/instptr.mli new file mode 100644 index 0000000..f1252b5 --- /dev/null +++ b/src/instptr.mli | |||
@@ -0,0 +1,29 @@ | |||
1 | (* | ||
2 | * UPEM / L3 / Functional programming / Project: URM | ||
3 | * Pacien TRAN-GIRARD, Adam NAILI | ||
4 | *) | ||
5 | |||
6 | open Common | ||
7 | |||
8 | (* Create an instruction pointer for an URM program. *) | ||
9 | val instptr_mk : urmcmd list -> instptr | ||
10 | |||
11 | (* Move the instruction pointer up. Do nothing if this is not possible. *) | ||
12 | val instptr_move_up : instptr -> instptr | ||
13 | |||
14 | (* Move the instruction pointer down. Do nothing if this is not possible. *) | ||
15 | val instptr_move_down : instptr -> instptr | ||
16 | |||
17 | (* Get the current command from the instruction pointer. | ||
18 | * Fail if the command pointer is not set on a valid command. *) | ||
19 |