Replace Token.(Values) with Token.Value of Ast.Value.t and add String type

This commit is contained in:
백현웅 2022-01-21 02:17:34 +09:00
parent 2be0b7f794
commit c2308d7939
5 changed files with 29 additions and 20 deletions

7
ast.ml
View file

@ -30,14 +30,9 @@ module Value = struct
let to_string = function
| Int n -> string_of_int n
| Float n -> string_of_float n
| String s -> s
| String s -> "\"" ^ s ^ "\""
| Nop -> "nop"
let of_token = function
| Token.Int n -> Int n
| Float n -> Float n
| _ -> invalid_arg "Value.of_token"
let typeof = function
| Int _ -> Type.Int
| Float _ -> Type.Float

32
lex.ml
View file

@ -1,6 +1,9 @@
open Ast.Value
type tokens = Token.t Seq.t
exception Token_not_found
exception Unclosed_quote
let either f g c =
f c || g c
@ -58,24 +61,37 @@ let tokenize (str : string) : tokens =
let open Token in
match seq () with
| Seq.Nil -> Seq.Nil
| Seq.Cons (x, s) ->
| Seq.Cons (x, seq) ->
if is_whitespace x then
aux s () (* skip whitespace *)
aux seq () (* skip whitespace *)
else if x = '"' then
let str, seq = partition_while ((<>) '"') seq in
let str = String (String.of_seq str) in
begin match seq () with
| Seq.Nil -> raise Unclosed_quote
| Seq.Cons (x, seq) ->
if x = '"' then Seq.Cons (Value str, aux seq)
else raise Unclosed_quote
end
else if is_digit x then
let n, s = partition_while is_num s in
let n, seq = partition_while is_num seq in
let n = String.of_seq @@ Seq.cons x n in
let n =
if String.contains n '.' (* float *)
then Float (float_of_string n)
else Int (int_of_string n)
in
Seq.Cons (n, aux s)
Seq.Cons (Value n, aux seq)
else if is_ident_start x then
let id, s = partition_while is_ident seq in
let id = String.of_seq id in
Seq.Cons (Ident id, aux s)
let id, seq = partition_while is_ident seq in
let id = String.of_seq @@ Seq.cons x id in
Seq.Cons (Ident id, aux seq)
else
match find_token seq with
match find_token @@ Seq.cons x seq with
| None -> raise Token_not_found
| Some (t, s) -> Seq.Cons (t, aux s)
in

View file

@ -7,6 +7,7 @@ let version = "%%VERSION%%"
let error_to_string e =
try raise e with
| Lex.Token_not_found -> sprintf "invalid token"
| Lex.Unclosed_quote -> sprintf "string not closed"
| Parser.Expected t -> sprintf "expected %s" t
| Parser.Unexpected_token t -> sprintf "unexpected token \"%s\"" t
| Ast.Invalid_type t -> sprintf "invalid type %s" (Ast.Type.to_string t)

View file

@ -173,8 +173,7 @@ and value seq =
match seq () with
| Seq.Nil -> raise End_of_tokens
| Seq.Cons (x, seq) -> begin match x with
| Token.Int n -> Value (Int n), seq
| Float n -> Value (Float n), seq
| Token.Value x -> Value x, seq
| Ident id -> Var id, seq
| LParen ->
let e, seq = expr min_int seq in

View file

@ -1,6 +1,5 @@
type t =
| Int of int
| Float of float
| Value of Ast.Value.t
| Ident of string
| Plus
| Minus
@ -25,8 +24,7 @@ let tokens = ref [
]
let to_string = function
| Int n -> Printf.sprintf "[int: %d]" n
| Float n -> Printf.sprintf "[float: %f]" n
| Value v -> Ast.Value.to_string v
| Ident s -> s
| t ->
begin match List.find_opt (fun (_, tok) -> t = tok) !tokens with