diff options
Diffstat (limited to 'asm/asmlex.mll')
-rw-r--r-- | asm/asmlex.mll | 47 |
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 } |