syntactic_ast: unwrapped the central GADT into several related types.
core_ast: related to the above, reorganized core_ast to use the new syntactic ast
This commit is contained in:
@@ -28,12 +28,10 @@ type top_level =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
let rec pair_of_def : Syntactic_ast.definition Syntactic_ast.t -> string * expression = function
|
let rec pair_of_def : Syntactic_ast.def -> string * expression =
|
||||||
| Syntactic_ast.Define (s, e) -> (s, of_expr e)
|
fun (s, e) -> (s, of_expr e)
|
||||||
and pair_of_binding = function
|
and pair_of_binding (s, e) = (s, of_expr e)
|
||||||
| Syntactic_ast.LetBinding (s, e) -> (s, of_expr e)
|
and pair_of_clause (e1, e2) = (of_expr e1, of_expr e2)
|
||||||
and pair_of_clause = function
|
|
||||||
| Syntactic_ast.CondClause (e1, e2) -> (of_expr e1, of_expr e2)
|
|
||||||
|
|
||||||
and make_lambda args body =
|
and make_lambda args body =
|
||||||
match args with
|
match args with
|
||||||
@@ -65,11 +63,11 @@ and make_let bs body =
|
|||||||
of expressions. The definitions behave exactly as a letrec, so
|
of expressions. The definitions behave exactly as a letrec, so
|
||||||
it makes sense to convert the body into a normal letrec.
|
it makes sense to convert the body into a normal letrec.
|
||||||
*)
|
*)
|
||||||
and of_body : Syntactic_ast.body Syntactic_ast.t -> expression = function
|
and of_body : Syntactic_ast.body -> expression = function
|
||||||
| Body ([], exprs) ->
|
| ([], exprs) ->
|
||||||
let exprs = List.map of_expr exprs in
|
let exprs = List.map of_expr exprs in
|
||||||
Begin exprs
|
Begin exprs
|
||||||
| Body (defs, exprs) ->
|
| (defs, exprs) ->
|
||||||
let exprs = List.map of_expr exprs in
|
let exprs = List.map of_expr exprs in
|
||||||
let defs = List.map pair_of_def defs in
|
let defs = List.map pair_of_def defs in
|
||||||
let b = Begin exprs in
|
let b = Begin exprs in
|
||||||
@@ -77,16 +75,19 @@ and of_body : Syntactic_ast.body Syntactic_ast.t -> expression = function
|
|||||||
|
|
||||||
(* TODO: currently this ignores the "optional" part of the lambda list,
|
(* TODO: currently this ignores the "optional" part of the lambda list,
|
||||||
fix this *)
|
fix this *)
|
||||||
and of_ll : Syntactic_ast.lambda_list Syntactic_ast.t -> string list = function
|
and of_ll : Syntactic_ast.lambda_list -> string list = function
|
||||||
| LambdaList (sl, _) -> sl
|
| (sl, _) -> sl
|
||||||
|
|
||||||
and of_expr : Syntactic_ast.expression Syntactic_ast.t -> expression = function
|
and of_literal : Syntactic_ast.literal -> literal = function
|
||||||
| LitNil -> Literal Nil
|
| LitInt x -> Int x
|
||||||
| LitInt x -> Literal (Int x)
|
| LitDouble x -> Double x
|
||||||
| LitDouble x -> Literal (Double x)
|
| LitString x -> String x
|
||||||
| LitString x -> Literal (String x)
|
| LitCons (a, b) -> Cons (of_literal a, of_literal b)
|
||||||
|
| LitNil -> Nil
|
||||||
|
|
||||||
|
and of_expr : Syntactic_ast.expr -> expression = function
|
||||||
|
| Literal l -> Literal (of_literal l)
|
||||||
| Var x -> Var x
|
| Var x -> Var x
|
||||||
| QuotedList _ -> failwith "TODO: rethink how quoted lists should work, the current definition makes no sense."
|
|
||||||
| Lambda (ll, b) -> make_lambda (of_ll ll) b
|
| Lambda (ll, b) -> make_lambda (of_ll ll) b
|
||||||
| Let (bindings, b) -> make_let bindings b
|
| Let (bindings, b) -> make_let bindings b
|
||||||
| LetRec (bindings, b) -> LetRec (List.map pair_of_binding bindings, of_body b)
|
| LetRec (bindings, b) -> LetRec (List.map pair_of_binding bindings, of_body b)
|
||||||
@@ -102,7 +103,7 @@ and of_expr : Syntactic_ast.expression Syntactic_ast.t -> expression = function
|
|||||||
|
|
||||||
|
|
||||||
and of_syntactic : Syntactic_ast.top_level -> top_level = function
|
and of_syntactic : Syntactic_ast.top_level -> top_level = function
|
||||||
| Def (Define (s, e)) -> Define (s, of_expr e)
|
| Def (s, e) -> Define (s, of_expr e)
|
||||||
| Exp (e) -> Expr (of_expr e)
|
| Exp (e) -> Expr (of_expr e)
|
||||||
| _ -> .
|
| _ -> .
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,35 @@
|
|||||||
|
|
||||||
(* The entire point of this module is to transform a given sexpr tree into
|
(* The entire point of this module is to transform a given sexpr tree into
|
||||||
an intermediary typed AST.
|
an intermediary AST that directly represents the grammar.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
type symbol = string
|
(* Literals *)
|
||||||
|
type literal =
|
||||||
|
| LitInt of int
|
||||||
|
| LitDouble of float
|
||||||
|
| LitString of string
|
||||||
|
| LitCons of literal * literal
|
||||||
|
| LitNil
|
||||||
|
|
||||||
(* These are just used for the GADT *)
|
type lambda_list = string list * string option
|
||||||
type expression = Phantom_expr
|
|
||||||
type definition = Phantom_def
|
|
||||||
type clause = Phantom_clause (* for cond *)
|
|
||||||
type binding = Phantom_binding(* for let *)
|
|
||||||
type lambda_list = Phantom_lambda_list
|
|
||||||
type body = Phantom_body
|
|
||||||
|
|
||||||
type _ t =
|
type expr =
|
||||||
(* Literals *)
|
| Literal of literal
|
||||||
| LitInt : int -> expression t
|
| Lambda of lambda_list * body
|
||||||
| LitDouble : float -> expression t
|
| Let of (string * expr) list * body
|
||||||
| LitString : string -> expression t
|
| LetRec of (string * expr) list * body
|
||||||
| LitNil : expression t
|
| Cond of (expr * expr) list
|
||||||
| QuotedList : expression t list * expression t option -> expression t
|
| If of expr * expr * expr
|
||||||
|
| Set of string * expr
|
||||||
| Body : definition t list * expression t list -> body t
|
| Var of string
|
||||||
| LambdaList : symbol list * symbol option -> lambda_list t
|
| Apply of expr * expr list
|
||||||
| Lambda : lambda_list t * body t -> expression t
|
and def = string * expr
|
||||||
| Define : symbol * expression t -> definition t
|
and body = def list * expr list
|
||||||
|
|
||||||
| LetBinding : symbol * expression t -> binding t
|
|
||||||
| Let : binding t list * body t -> expression t
|
|
||||||
| LetRec : binding t list * body t -> expression t
|
|
||||||
|
|
||||||
| CondClause : expression t * expression t -> clause t
|
|
||||||
| Cond : clause t list -> expression t
|
|
||||||
|
|
||||||
| If : expression t * expression t * expression t -> expression t
|
|
||||||
| Set : string * expression t -> expression t
|
|
||||||
|
|
||||||
| Var : symbol -> expression t
|
|
||||||
| Apply : expression t * expression t list -> expression t
|
|
||||||
|
|
||||||
(* On the top-level we only allow definitions and expressions *)
|
(* On the top-level we only allow definitions and expressions *)
|
||||||
type top_level =
|
type top_level =
|
||||||
| Def of definition t
|
| Def of def
|
||||||
| Exp of expression t
|
| Exp of expr
|
||||||
|
|
||||||
|
|
||||||
(* we use result here to make things nicer *)
|
(* we use result here to make things nicer *)
|
||||||
@@ -57,7 +44,7 @@ let traverse f l =
|
|||||||
let map = List.map
|
let map = List.map
|
||||||
|
|
||||||
|
|
||||||
let exp x = Ok (Exp x)
|
|
||||||
let unwrap_exp = function
|
let unwrap_exp = function
|
||||||
| Ok (Exp x) -> Ok x
|
| Ok (Exp x) -> Ok x
|
||||||
| Error _ as e -> e
|
| Error _ as e -> e
|
||||||
@@ -67,6 +54,8 @@ let unwrap_def x =
|
|||||||
match x with
|
match x with
|
||||||
| Def d -> Ok d
|
| Def d -> Ok d
|
||||||
| _ -> Error "Expression found in Definition context"
|
| _ -> Error "Expression found in Definition context"
|
||||||
|
let exp x = Ok (Exp x)
|
||||||
|
let lit x = Ok (Exp (Literal x))
|
||||||
let def x = Ok (Def x)
|
let def x = Ok (Def x)
|
||||||
|
|
||||||
|
|
||||||
@@ -109,10 +98,10 @@ let rec list_of_sexpr = function
|
|||||||
let parse_lambda_list cons =
|
let parse_lambda_list cons =
|
||||||
let rec aux acc = function
|
let rec aux acc = function
|
||||||
| LCons (LSymbol a, LSymbol b) ->
|
| LCons (LSymbol a, LSymbol b) ->
|
||||||
Ok (LambdaList (List.rev (a :: acc), Some b))
|
Ok (List.rev (a :: acc), Some b)
|
||||||
| LCons (LSymbol a, rest) ->
|
| LCons (LSymbol a, rest) ->
|
||||||
aux (a :: acc) rest
|
aux (a :: acc) rest
|
||||||
| LNil -> Ok (LambdaList (List.rev acc, None))
|
| LNil -> Ok (List.rev acc, None)
|
||||||
| _ -> Error "Improper lambda list."
|
| _ -> Error "Improper lambda list."
|
||||||
in aux [] cons
|
in aux [] cons
|
||||||
|
|
||||||
@@ -139,7 +128,7 @@ let rec parse_body body =
|
|||||||
*)
|
*)
|
||||||
let* defs = traverse (Fun.compose unwrap_def transform) defs in
|
let* defs = traverse (Fun.compose unwrap_def transform) defs in
|
||||||
let* exprs = traverse (Fun.compose unwrap_exp transform) exprs in
|
let* exprs = traverse (Fun.compose unwrap_exp transform) exprs in
|
||||||
Ok (Body (defs, exprs))
|
Ok (defs, exprs)
|
||||||
|
|
||||||
and builtin_define cons =
|
and builtin_define cons =
|
||||||
let* second = sexpr_cadr cons in
|
let* second = sexpr_cadr cons in
|
||||||
@@ -148,13 +137,13 @@ and builtin_define cons =
|
|||||||
(* regular, symbol/variable definition *)
|
(* regular, symbol/variable definition *)
|
||||||
let* third = sexpr_caddr cons in
|
let* third = sexpr_caddr cons in
|
||||||
let* value = unwrap_exp (transform third) in
|
let* value = unwrap_exp (transform third) in
|
||||||
def (Define (sym, value))
|
Ok (Def (sym, value))
|
||||||
| LCons (LSymbol sym, ll) ->
|
| LCons (LSymbol sym, ll) ->
|
||||||
(* function definition, we treat this as a define + lambda *)
|
(* function definition, we treat this as a define + lambda *)
|
||||||
let* lambda_list = parse_lambda_list ll in
|
let* lambda_list = parse_lambda_list ll in
|
||||||
let* body = sexpr_cddr cons in
|
let* body = sexpr_cddr cons in
|
||||||
let* body = parse_body body in
|
let* body = parse_body body in
|
||||||
def (Define (sym, Lambda (lambda_list, body)))
|
Ok (Def (sym, Lambda (lambda_list, body)))
|
||||||
| _ -> Error "invalid definition!"
|
| _ -> Error "invalid definition!"
|
||||||
|
|
||||||
and builtin_lambda cons =
|
and builtin_lambda cons =
|
||||||
@@ -170,7 +159,7 @@ and parse_bindings cons =
|
|||||||
let* sym = expect_sym sym in
|
let* sym = expect_sym sym in
|
||||||
let* expr = sexpr_cadr cons in
|
let* expr = sexpr_cadr cons in
|
||||||
let* expr = unwrap_exp (transform expr) in
|
let* expr = unwrap_exp (transform expr) in
|
||||||
Ok (LetBinding (sym, expr))
|
Ok (sym, expr)
|
||||||
in
|
in
|
||||||
let* l = list_of_sexpr cons in
|
let* l = list_of_sexpr cons in
|
||||||
traverse parse_one l
|
traverse parse_one l
|
||||||
@@ -188,7 +177,7 @@ and parse_clauses cons =
|
|||||||
let* test = unwrap_exp (transform test) in
|
let* test = unwrap_exp (transform test) in
|
||||||
let* expr = sexpr_cadr cons in
|
let* expr = sexpr_cadr cons in
|
||||||
let* expr = unwrap_exp (transform expr) in
|
let* expr = unwrap_exp (transform expr) in
|
||||||
Ok (CondClause (test, expr))
|
Ok (test, expr)
|
||||||
in
|
in
|
||||||
let* l = list_of_sexpr cons in
|
let* l = list_of_sexpr cons in
|
||||||
traverse parse_one l
|
traverse parse_one l
|
||||||
@@ -239,14 +228,14 @@ and builtin_symbol = function
|
|||||||
| _ -> Error "Invalid function application!")
|
| _ -> Error "Invalid function application!")
|
||||||
|
|
||||||
and transform : lisp_ast -> (top_level, string) result = function
|
and transform : lisp_ast -> (top_level, string) result = function
|
||||||
| LInt x -> exp (LitInt x)
|
| LInt x -> lit (LitInt x)
|
||||||
| LDouble x -> exp (LitDouble x)
|
| LDouble x -> lit (LitDouble x)
|
||||||
| LString x -> exp (LitString x)
|
| LString x -> lit (LitString x)
|
||||||
(* NOTE: not all symbols are automatically Variable expressions,
|
(* NOTE: not all symbols are automatically Variable expressions,
|
||||||
Some must be further parsed (such as inside a definition)
|
Some must be further parsed (such as inside a definition)
|
||||||
*)
|
*)
|
||||||
| LSymbol x -> exp (Var x)
|
| LSymbol x -> exp (Var x)
|
||||||
| LNil -> exp (LitNil)
|
| LNil -> lit (LitNil)
|
||||||
| LCons (LSymbol s, _) as cons -> (builtin_symbol s) cons
|
| LCons (LSymbol s, _) as cons -> (builtin_symbol s) cons
|
||||||
| LCons (f, args) -> apply f args
|
| LCons (f, args) -> apply f args
|
||||||
|
|
||||||
@@ -257,36 +246,36 @@ let make (expr : Parser.Ast.lisp_ast) : (top_level, string) result =
|
|||||||
|
|
||||||
(* Printing, for debug purposes *)
|
(* Printing, for debug purposes *)
|
||||||
let pf = Printf.sprintf
|
let pf = Printf.sprintf
|
||||||
let rec print_as_list l =
|
let rec print_lambda_list = function
|
||||||
let l = map print_expr l in
|
| (strs, None) -> ("(" ^ (String.concat " " strs) ^ ")")
|
||||||
String.concat " " l
|
| (strs, Some x) -> ("(" ^ (String.concat " " strs) ^ " . " ^ x ^ ")")
|
||||||
and print_lambda_list = function
|
|
||||||
| LambdaList (strs, None) -> ("(" ^ (String.concat " " strs) ^ ")")
|
|
||||||
| LambdaList (strs, Some x) -> ("(" ^ (String.concat " " strs) ^ " . " ^ x ^ ")")
|
|
||||||
and print_let_binding x =
|
and print_let_binding x =
|
||||||
let (LetBinding (s, expr)) = x in
|
let (s, expr) = x in
|
||||||
pf "(%s %s)" s (print_expr expr)
|
pf "(%s %s)" s (print_expr expr)
|
||||||
and print_bindings l =
|
and print_bindings l =
|
||||||
("(" ^ (String.concat "\n" (map print_let_binding l)) ^ ")")
|
("(" ^ (String.concat "\n" (map print_let_binding l)) ^ ")")
|
||||||
and print_clause x =
|
and print_clause x =
|
||||||
let (CondClause (test, expr)) = x in
|
let (test, expr) = x in
|
||||||
pf "(%s %s)" (print_expr test) (print_expr expr)
|
pf "(%s %s)" (print_expr test) (print_expr expr)
|
||||||
and print_clauses l =
|
and print_clauses l =
|
||||||
(String.concat "\n" (map print_clause l))
|
(String.concat "\n" (map print_clause l))
|
||||||
and print_def = function
|
and print_def = function
|
||||||
| Define (s, expr) ->
|
| (s, expr) ->
|
||||||
pf "(define %s
|
pf "(define %s
|
||||||
%s)" s (print_expr expr)
|
%s)" s (print_expr expr)
|
||||||
and print_defs l =
|
and print_defs l =
|
||||||
String.concat "\n" (map print_def l)
|
String.concat "\n" (map print_def l)
|
||||||
and print_expr = function
|
|
||||||
|
and print_literal = function
|
||||||
| LitDouble x -> pf "%f" x
|
| LitDouble x -> pf "%f" x
|
||||||
| LitInt x -> pf "%d" x
|
| LitInt x -> pf "%d" x
|
||||||
| LitString x -> pf "\"%s\"" x
|
| LitString x -> pf "\"%s\"" x
|
||||||
| LitNil -> pf "nil"
|
| LitNil -> pf "nil"
|
||||||
| QuotedList (exprs, None) -> "(" ^ (print_as_list exprs) ^ ")"
|
| LitCons (a, b) -> pf "(%s . %s)" (print_literal a) (print_literal b)
|
||||||
| QuotedList (exprs, Some ex) -> "(" ^ (print_as_list exprs) ^ " . " ^ (print_expr ex) ^ ")"
|
|
||||||
| Lambda (ll, Body (defs, exprs)) ->
|
and print_expr = function
|
||||||
|
| Literal l -> print_literal l
|
||||||
|
| Lambda (ll, (defs, exprs)) ->
|
||||||
pf "(lambda %s
|
pf "(lambda %s
|
||||||
; DEFINITIONS
|
; DEFINITIONS
|
||||||
%s
|
%s
|
||||||
@@ -295,7 +284,7 @@ and print_expr = function
|
|||||||
(print_lambda_list ll)
|
(print_lambda_list ll)
|
||||||
(String.concat "\n" (map print_def defs))
|
(String.concat "\n" (map print_def defs))
|
||||||
(String.concat "\n" (map print_expr exprs))
|
(String.concat "\n" (map print_expr exprs))
|
||||||
| Let (binds, Body (defs, exprs)) ->
|
| Let (binds, (defs, exprs)) ->
|
||||||
pf "(let
|
pf "(let
|
||||||
; BINDINGS
|
; BINDINGS
|
||||||
%s
|
%s
|
||||||
@@ -306,7 +295,7 @@ and print_expr = function
|
|||||||
(print_bindings binds)
|
(print_bindings binds)
|
||||||
(print_defs defs)
|
(print_defs defs)
|
||||||
(print_exprs exprs)
|
(print_exprs exprs)
|
||||||
| LetRec (binds, Body (defs, exprs)) ->
|
| LetRec (binds, (defs, exprs)) ->
|
||||||
pf "(letrec
|
pf "(letrec
|
||||||
; BINDINGS
|
; BINDINGS
|
||||||
%s
|
%s
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
type symbol = string
|
|
||||||
|
|
||||||
(* These are just used for the GADT *)
|
|
||||||
type expression = Phantom_expr
|
|
||||||
type definition = Phantom_def
|
|
||||||
type clause = Phantom_clause (* for cond *)
|
|
||||||
type binding = Phantom_binding(* for let *)
|
|
||||||
type lambda_list = Phantom_lambda_list
|
|
||||||
type body = Phantom_body
|
|
||||||
|
|
||||||
type _ t =
|
|
||||||
(* Literals *)
|
|
||||||
| LitInt : int -> expression t
|
|
||||||
| LitDouble : float -> expression t
|
|
||||||
| LitString : string -> expression t
|
|
||||||
| LitNil : expression t
|
|
||||||
| QuotedList : expression t list * expression t option -> expression t
|
|
||||||
|
|
||||||
| Body : definition t list * expression t list -> body t
|
|
||||||
| LambdaList : symbol list * symbol option -> lambda_list t
|
|
||||||
| Lambda : lambda_list t * body t -> expression t
|
|
||||||
| Define : symbol * expression t -> definition t
|
|
||||||
|
|
||||||
| LetBinding : symbol * expression t -> binding t
|
|
||||||
| Let : binding t list * body t -> expression t
|
|
||||||
| LetRec : binding t list * body t -> expression t
|
|
||||||
|
|
||||||
| CondClause : expression t * expression t -> clause t
|
|
||||||
| Cond : clause t list -> expression t
|
|
||||||
|
|
||||||
| If : expression t * expression t * expression t -> expression t
|
|
||||||
| Set : string * expression t -> expression t
|
|
||||||
|
|
||||||
| Var : symbol -> expression t
|
|
||||||
| Apply : expression t * expression t list -> expression t
|
|
||||||
|
|
||||||
type top_level =
|
|
||||||
| Def of definition t
|
|
||||||
| Exp of expression t
|
|
||||||
|
|
||||||
|
|
||||||
val make : Parser.Ast.lisp_ast -> (top_level, string) result
|
|
||||||
|
|
||||||
val print_def : definition t -> string
|
|
||||||
val print_expr : expression t -> string
|
|
||||||
val print : top_level -> string
|
|
||||||
Reference in New Issue
Block a user