aboutsummaryrefslogtreecommitdiffstats
path: root/lib/lexer.mll
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-07-11 03:07:56 -0300
committerMarcos Magueta <maguetamarcos@gmail.com>2026-07-11 03:07:56 -0300
commitc530682030e80ee2de2c263471e5eda7a3392e84 (patch)
tree43099c96f71f01ad1ebd04724fbf7f39852b30b9 /lib/lexer.mll
parent5d5a6e68032f263bfd524794f75174dafd04bf3f (diff)
downloadSOL-c530682030e80ee2de2c263471e5eda7a3392e84.tar.gz
SOL-c530682030e80ee2de2c263471e5eda7a3392e84.zip
working vm: parser, admission with totality checks, solver and repl
Diffstat (limited to 'lib/lexer.mll')
-rw-r--r--lib/lexer.mll54
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/lexer.mll b/lib/lexer.mll
new file mode 100644
index 0000000..53ef04a
--- /dev/null
+++ b/lib/lexer.mll
@@ -0,0 +1,54 @@
+{
+open Parser
+
+exception Error of string
+
+let unescape s =
+ let buffer = Buffer.create (String.length s) in
+ let rec go i =
+ if i < String.length s then
+ match s.[i] with
+ | '\\' when i + 1 < String.length s ->
+ (match s.[i + 1] with
+ | 'n' -> Buffer.add_char buffer '\n'
+ | 't' -> Buffer.add_char buffer '\t'
+ | c -> Buffer.add_char buffer c);
+ go (i + 2)
+ | c ->
+ Buffer.add_char buffer c;
+ go (i + 1)
+ in
+ go 0;
+ Buffer.contents buffer
+}
+
+let digit = ['0'-'9']
+let ident = ['A'-'Z' 'a'-'z'] ['A'-'Z' 'a'-'z' '0'-'9' '_']*
+let string_body = ([^ '"' '\\'] | '\\' _)*
+
+rule token = parse
+ | [' ' '\t' '\r' '\n']+ { token lexbuf }
+ | '%' [^ '\n']* { token lexbuf }
+ | "#(" { HASH_LPAREN }
+ | '(' { LPAREN }
+ | ')' { RPAREN }
+ | '[' { LBRACKET }
+ | ']' { RBRACKET }
+ | '{' { LBRACE }
+ | '}' { RBRACE }
+ | '|' { BAR }
+ | ":and" { AND }
+ | ":or" { OR }
+ | '-'? digit+ '/' digit+ as s
+ { match String.index_opt s '/' with
+ | Some i ->
+ RAT
+ ( Z.of_string (String.sub s 0 i),
+ Z.of_string (String.sub s (i + 1) (String.length s - i - 1)) )
+ | None -> assert false }
+ | '-'? digit+ as s { INT (Z.of_string s) }
+ | (ident as name) ':' { LABEL name }
+ | ident as name { NAME name }
+ | '"' (string_body as s) '"' { STR (unescape s) }
+ | eof { EOF }
+ | _ as c { raise (Error (Printf.sprintf "unexpected character %C" c)) }