diff options
Diffstat (limited to 'src/parser.ml')
-rw-r--r-- | src/parser.ml | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/src/parser.ml b/src/parser.ml index 0bc1be6..0a0c3a8 100644 --- a/src/parser.ml +++ b/src/parser.ml | |||
@@ -8,24 +8,51 @@ open Common | |||
8 | let rec string_of_file f = | 8 | let rec string_of_file f = |
9 | try | 9 | try |
10 | let str = input_line f | 10 | let str = input_line f |
11 | in str ^ " " ^ (string_of_file f) | 11 | in str ^ "\n" ^ (string_of_file f) |
12 | with End_of_file -> "" | 12 | with End_of_file -> "" |
13 | 13 | ||
14 | let rec program_of_lex = function | 14 | let rec eurm_program_of_lex = function |
15 | | [] -> [] | 15 | | [] -> [] |
16 | | instr :: tail -> match (String.lowercase_ascii instr) :: tail with | 16 | | l -> match l with |
17 | | "zero" :: arg_1 :: tail -> (URMZero (int_of_string arg_1)) :: (program_of_lex tail) | 17 | | "comment" :: comment :: tail -> Comment(comment) :: eurm_program_of_lex tail |
18 | | "succ" :: arg_1 :: tail -> (URMSucc (int_of_string arg_1)) :: (program_of_lex tail) | 18 | | "label" :: lbl :: tail -> Label(lbl) :: eurm_program_of_lex tail |
19 | | "copy" :: arg_1 :: arg_2 :: tail -> (URMCopy ((int_of_string arg_1), (int_of_string arg_2))) :: (program_of_lex tail) | 19 | | "goto" :: lbl :: tail -> Goto(lbl) :: eurm_program_of_lex tail |
20 | | "jump" :: arg_1 :: arg_2 :: arg_3 :: tail -> (URMJump ((int_of_string arg_1), (int_of_string arg_2), (int_of_string arg_3))) :: (program_of_lex tail) | 20 | | "zero" :: r :: tail -> Zero(int_of_string r) :: eurm_program_of_lex tail |
21 | | "inc" :: r :: tail -> Inc(int_of_string r) :: eurm_program_of_lex tail | ||
22 | | "dec" :: r :: tail -> Dec(int_of_string r) :: eurm_program_of_lex tail | ||
23 | | "copy" :: r1 :: r2 :: tail -> Copy(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail | ||
24 | | "add" :: r1 :: r2 :: tail -> Add(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail | ||
25 | | "sub" :: r1 :: r2 :: tail -> Sub(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail | ||
26 | | "mult" :: r1 :: r2 :: tail -> Mult(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail | ||
27 | | "eq?" :: r1 :: r2 :: lbl :: tail -> EqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail | ||
28 | | "geq?" :: r1 :: r2 :: lbl :: tail -> GEqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail | ||
29 | | "gt?" :: r1 :: r2 :: lbl :: tail -> GTPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail | ||
30 | | "leq?" :: r1 :: r2 :: lbl :: tail -> LEqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail | ||
31 | | "lt?" :: r1 :: r2 :: lbl :: tail -> LTPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail | ||
32 | | "zero?" :: r :: lbl :: tail -> ZeroPredicate(int_of_string r, lbl) :: eurm_program_of_lex tail | ||
33 | | "quit" :: tail -> Quit :: eurm_program_of_lex tail | ||
34 | | x -> String.concat " " x |> print_endline; raise Syntax_error | ||
35 | |||
36 | let rec urm_program_of_lex = function | ||
37 | | [] -> [] | ||
38 | | l -> match l with | ||
39 | | "zero" :: r :: tail -> URMZero(int_of_string r) :: urm_program_of_lex tail | ||
40 | | "succ" :: r :: tail -> URMSucc(int_of_string r) :: urm_program_of_lex tail | ||
41 | | "copy" :: r1 :: r2 :: tail -> URMCopy(int_of_string r1, int_of_string r2) :: urm_program_of_lex tail | ||
42 | | "jump" :: r1 :: r2 :: l :: tail -> URMJump (int_of_string r1, int_of_string r2, int_of_string l) :: urm_program_of_lex tail | ||
21 | | _ -> raise Syntax_error | 43 | | _ -> raise Syntax_error |
22 | 44 | ||
23 | (* FIXME: reject multiple definition of a single register *) | 45 | (* TODO: reject multiple definition of a single register *) |
24 | let rec regs_of_lex = function | 46 | let rec regs_of_lex = function |
25 | | [] -> [] | 47 | | [] -> [] |
26 | | regnum :: regvalue :: tail -> Reg (int_of_string regnum, int_of_string regvalue) :: (regs_of_lex tail) | 48 | | regnum :: regvalue :: tail -> Reg (int_of_string regnum, int_of_string regvalue) :: (regs_of_lex tail) |
27 | | _ -> raise Syntax_error | 49 | | _ -> raise Syntax_error |
28 | 50 | ||
29 | let seq_from_string lexer_func str = Str.split (Str.regexp "[\t\n(), ]+") str |> lexer_func | 51 | let seq_from_string lexer_func str = |
30 | let program_of_string = seq_from_string program_of_lex | 52 | String.lowercase_ascii str |
53 | |> Str.global_replace (Str.regexp "comment.*\n") "" | ||
54 | |> Str.split (Str.regexp "[\t\n(), ]+") | ||
55 | |> lexer_func | ||
56 | |||
57 | let program_of_string lexer = seq_from_string lexer | ||
31 | let regs_of_string = seq_from_string regs_of_lex | 58 | let regs_of_string = seq_from_string regs_of_lex |