summaryrefslogtreecommitdiff
path: root/asm/asmlex.mll
diff options
context:
space:
mode:
Diffstat (limited to 'asm/asmlex.mll')
-rw-r--r--asm/asmlex.mll47
1 files changed, 32 insertions, 15 deletions
diff --git a/asm/asmlex.mll b/asm/asmlex.mll
index 22f77d7..7be493e 100644
--- a/asm/asmlex.mll
+++ b/asm/asmlex.mll
@@ -27,12 +27,13 @@
"move",MOVE;
"jz",JZ;
"jnz",JNZ;
- "asciiz",ASCIIZ;
"_clock",INT 0x4000;
"_input",INT 0x4100;
"_output",INT 0x4102;
"word",WORD;
- "byte",BYTE
+ "byte",BYTE;
+ "hlt",HLT;
+ "ascii",ASCII
]
let regs = [
@@ -48,15 +49,19 @@
"SP",7
]
+ let vald d = Char.code d - (Char.code '0')
+
+ 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') + 10
+ else c - (Char.code 'A') + 10
+
let read_16 n =
let res = ref 0 in
for i = 0 to String.length n - 1 do
res := 16 * !res;
- let v =
- let c = Char.code n.[i] 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') + 10
- else c - (Char.code 'A') + 10 in
+ let v = valh n.[i] in
res := !res + v
done;
!res
@@ -69,6 +74,7 @@
res := !res + v
done;
!res
+
}
let digit = ['0'-'9']
@@ -90,7 +96,6 @@ rule token = parse
{ INT (read_16 n) }
| (digit)+ as n { INT (int_of_string n) }
| "0b" (['0' '1']+ as n) { INT (read_2 n) }
- | '"' { STR (lex_str "" lexbuf) }
| ['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 }
@@ -98,16 +103,28 @@ rule token = parse
| '-' { MINUS }
| '(' { LP }
| ')' { RP }
+ | '"' { str [] lexbuf }
+
+and str acc = parse
+ | "\\\\" { str ('\\' :: acc) lexbuf }
+ | '"' { STR (List.rev ('\000' :: acc)) }
+ | "\\t" { str ('\t' :: acc) lexbuf }
+ | "\\n" { str ('\n' :: acc) lexbuf }
+ | "\\r" { str ('\r' :: acc) lexbuf }
+ | "\\\"" { str ('"' :: acc) lexbuf }
+ | "\\a" { str ((Char.chr 7) :: acc) lexbuf }
+ | '\\' (digit as d1) (digit as d2) (digit as d3)
+ { let c = 100 * (vald d1) + 10 * (vald d2) + (vald d3) in
+ str ((Char.chr c) :: acc) lexbuf }
+ | "\\x" (hexdigit as h1) (hexdigit as h2)
+ { let c = 16 * (valh h1) + (valh h2) in
+ str ((Char.chr c)::acc) lexbuf }
+ | eof { raise Lexer_error }
+ | '\n' { raise Lexer_error }
+ | [^ '\\' '"' '\n'] as c { str (c::acc) lexbuf }
and comment = parse
| eof { EOF }
| '\n' { Lexing.new_line lexbuf; token lexbuf }
| _ { comment lexbuf }
-and lex_str q = parse
- | eof { q }
- | '"' { q }
- | "\\\"" { lex_str (q ^ "\"") lexbuf }
- | "\\\\" { lex_str (q ^ "\\") lexbuf }
- | "\\n" { lex_str (q ^ "\n") lexbuf }
- | _ as c { lex_str (q ^ String.make 1 c) lexbuf }