diff options
Diffstat (limited to 'asm')
-rw-r--r-- | asm/Makefile | 10 | ||||
-rw-r--r-- | asm/_tags | 2 | ||||
-rw-r--r-- | asm/asm.ml | 2 | ||||
-rw-r--r-- | asm/asmlex.mll | 11 | ||||
-rw-r--r-- | asm/asmpars.mly | 18 | ||||
-rw-r--r-- | asm/assembler.ml | 8 |
6 files changed, 36 insertions, 15 deletions
diff --git a/asm/Makefile b/asm/Makefile new file mode 100644 index 0000000..8ac2004 --- /dev/null +++ b/asm/Makefile @@ -0,0 +1,10 @@ + +all: asm + +asm: assembler.ml asm.ml asmlex.mll asmpars.mly + ocamlbuild assembler.native + mv assembler.native asm + +clean: + rm asm + rm -r _build @@ -1,2 +1,4 @@ true: use_menhir +<*.ml>: debug +<*.byte>: use_unix, debug @@ -1,3 +1,5 @@ +exception Asm_error of string + type reg = int type imm = diff --git a/asm/asmlex.mll b/asm/asmlex.mll index fc77c93..b2c7718 100644 --- a/asm/asmlex.mll +++ b/asm/asmlex.mll @@ -54,8 +54,8 @@ let valh d = let c = Char.code d in if c >= Char.code '0' && c <= Char.code '9' then c - (Char.code '0') - else if c >= Char.code 'a' && c <= Char.code 'f' then c - (Char.code 'a') - else c - (Char.code 'A') + else if c >= Char.code 'a' && c <= Char.code 'f' then c - (Char.code 'a') + 10 + else c - (Char.code 'A') + 10 let read_16 n = let res = ref 0 in @@ -94,9 +94,13 @@ rule token = parse with Not_found -> ID id } | "0x" (((hexdigit)+) as n) { INT (read_16 n) } + | "'\\n'" { INT (Char.code '\n') } + | "'\\t'" { INT (Char.code '\t') } + | "'\\r'" { INT (Char.code '\r') } + | "'" (_ as c) "'" { INT (Char.code c) } | (digit)+ as n { INT (int_of_string n) } | "0b" (['0' '1']+ as n) { INT (read_2 n) } - | ['A'-'Z']+ as name { REG (List.assoc name regs) } + | ['A'-'Z']+ as name { try REG (List.assoc name regs) with Not_found -> raise (Asm_error ("no reg " ^ name))} | '$' (['0'-'7'] as n) { REG (Char.code n - (Char.code '0')) } | ".text" { TEXT } | ".data" { DATA } @@ -127,3 +131,4 @@ and comment = parse | eof { EOF } | '\n' { Lexing.new_line lexbuf; token lexbuf } | _ { comment lexbuf } + diff --git a/asm/asmpars.mly b/asm/asmpars.mly index e568127..c48c9ce 100644 --- a/asm/asmpars.mly +++ b/asm/asmpars.mly @@ -53,7 +53,7 @@ %% program: - TEXT NLB* is=instr* data? EOF + NLB* TEXT NLB* is=instr* data? EOF { { text = List.flatten is; lbls = !lbls2 } } @@ -66,10 +66,10 @@ datas: | WORD n=INT NLB+ { add ram (2*n) } labeli: - id=ID COLON { lbls2 := Imap.add id (!pc,true) !lbls2 } + id=ID COLON { lbls2 := Imap.add id (!pc,true) !lbls2 } labeld: - id=ID COLON { lbls2 := Imap.add id (!ram,false) !lbls2 } + id=ID COLON { lbls2 := Imap.add id (!ram,false) !lbls2 } instr: | labeli NLB* i=instr { i } @@ -129,9 +129,9 @@ _instr: | MOVE r1=REG r2=REG { add pc 2; [R (Add,r1,r2,0)] } | NOT r1=REG r2=REG { add pc 2; [R (Nor,r1,r2,0)] } | JZ r=REG l=ID { let l = li false 5 (Lab l) in - add pc 2; l @ [R (Jer,r,5,0)] } + add pc 2; l @ [R (Jer,5,r,0)] } | JNZ r=REG l=ID { let l = li false 5 (Lab l) in - add pc 2; l @ [R (Jner,r,5,0)] } + add pc 2; l @ [R (Jner,5,r,0)] } | POP r=REG { add pc 4; [Lw (r,7,0); Incri (7,2)] } | PUSH r=REG { add pc 4; [Incri (7,-2); Sw (r,7,0)] } | BYTE bs=int+ { List.map (fun b -> add pc 1; Byte b) bs } @@ -140,9 +140,9 @@ _instr: | ASCII s=STR { List.map (fun c -> add pc 1; Byte (Char.code c)) s } imm: - | id=ID { Lab id } - | n=int { Imm n } + | id=ID { Lab id } + | n=int { Imm n } int: - | n=INT { n } - | MINUS n=INT { - n } + | n=INT { n } + | MINUS n=INT { - n } diff --git a/asm/assembler.ml b/asm/assembler.ml index c794c98..35395e0 100644 --- a/asm/assembler.ml +++ b/asm/assembler.ml @@ -2,6 +2,8 @@ open Asm open Printf open Lexing +exception No_such_label of string + let init_string n f = let res = String.make n 'a' in for i = 0 to n - 1 do res.[i] <- f i done; res @@ -83,13 +85,13 @@ let print_program p = let pc = ref 0 in let value = function | Imm i -> i - | Lab l -> fst (Imap.find l p.lbls) in + | Lab l -> try fst (Imap.find l p.lbls) with Not_found -> raise (No_such_label l) in let value2 = function | Imm i -> i - | Lab l -> fst (Imap.find l p.lbls) - !pc in + | Lab l -> try fst (Imap.find l p.lbls) - !pc with Not_found -> raise (No_such_label l) in let value3 = function | Imm i -> i - | Lab l -> (byte 16 (fst (Imap.find l p.lbls))) lsr 8 in + | Lab l -> try (byte 16 (fst (Imap.find l p.lbls))) lsr 8 with Not_found -> raise (No_such_label l) in let get_reps = function | R (o,r1,r2,r3) -> r (code o) r1 r2 r3, sprintf "%s %s %s %s" (List.assoc o rev_keywords) (rts r1) (rts r2) (rts r3) |