summaryrefslogtreecommitdiff
path: root/asm
diff options
context:
space:
mode:
Diffstat (limited to 'asm')
-rw-r--r--asm/Makefile10
-rw-r--r--asm/_tags2
-rw-r--r--asm/asm.ml2
-rw-r--r--asm/asmlex.mll11
-rw-r--r--asm/asmpars.mly26
-rw-r--r--asm/assembler.ml8
6 files changed, 40 insertions, 19 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
diff --git a/asm/_tags b/asm/_tags
index b2f3704..3ed8b5a 100644
--- a/asm/_tags
+++ b/asm/_tags
@@ -1,2 +1,4 @@
true: use_menhir
+<*.ml>: debug
+<*.byte>: use_unix, debug
diff --git a/asm/asm.ml b/asm/asm.ml
index b52eda4..21e83d4 100644
--- a/asm/asm.ml
+++ b/asm/asm.ml
@@ -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 cace4b7..1f598e9 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 }
@@ -128,3 +132,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 76b5ce2..258396e 100644
--- a/asm/asmpars.mly
+++ b/asm/asmpars.mly
@@ -58,23 +58,23 @@ program:
lbls = !lbls2 } }
data:
- DATA d=datas* { d }
-
+ DATA d=datas* { d }
+
datas:
| labeld datas { () }
| BYTE n=INT { add ram n }
| WORD n=INT { 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 i=instr { i }
- | i=_instr { i }
-
+ | labeli i=instr { i }
+ | i=_instr { i }
+
_instr:
| o=ROP r1=REG r2=REG r3=REG { add pc 2; [R (o,r1,r2,r3)] }
| o=RIOP r1=REG r2=REG imm=imm
@@ -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+ SEMIC { 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)