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 let to_string = function
| Int n -> string_of_int n | Int n -> string_of_int n
| Float n -> string_of_float n | Float n -> string_of_float n
| String s -> s | String s -> "\"" ^ s ^ "\""
| Nop -> "nop" | Nop -> "nop"
let of_token = function
| Token.Int n -> Int n
| Float n -> Float n
| _ -> invalid_arg "Value.of_token"
let typeof = function let typeof = function
| Int _ -> Type.Int | Int _ -> Type.Int
| Float _ -> Type.Float | Float _ -> Type.Float

32
lex.ml
View file

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

View file

@ -7,6 +7,7 @@ let version = "%%VERSION%%"
let error_to_string e = let error_to_string e =
try raise e with try raise e with
| Lex.Token_not_found -> sprintf "invalid token" | Lex.Token_not_found -> sprintf "invalid token"
| Lex.Unclosed_quote -> sprintf "string not closed"
| Parser.Expected t -> sprintf "expected %s" t | Parser.Expected t -> sprintf "expected %s" t
| Parser.Unexpected_token t -> sprintf "unexpected token \"%s\"" t | Parser.Unexpected_token t -> sprintf "unexpected token \"%s\"" t
| Ast.Invalid_type t -> sprintf "invalid type %s" (Ast.Type.to_string 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 match seq () with
| Seq.Nil -> raise End_of_tokens | Seq.Nil -> raise End_of_tokens
| Seq.Cons (x, seq) -> begin match x with | Seq.Cons (x, seq) -> begin match x with
| Token.Int n -> Value (Int n), seq | Token.Value x -> Value x, seq
| Float n -> Value (Float n), seq
| Ident id -> Var id, seq | Ident id -> Var id, seq
| LParen -> | LParen ->
let e, seq = expr min_int seq in let e, seq = expr min_int seq in

View file

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