From: oleg@okmij.org
To: martin.potier@gmail.com
Cc: caml-list@inria.fr
Subject: Re: Caml typed AST
Date: Wed, 9 Jun 2010 00:47:03 -0700 (PDT) [thread overview]
Message-ID: <20100609074703.E3754173BB@Adric.ern.nps.edu> (raw)
Martin Potier wrote:
> I'd like to know if there is a way to retrieve a typped AST from Caml.
The function read_type_exp : string -> Typedtree.expression
takes a string of OCaml code, parses it, typechecks and returns the
typed tree. For example, evaluating
let test1 = read_type_exp "let x = 21 and twice y = 2 * y in twice x";;
prints
val test1 : Typedtree.expression =
{Typedtree.exp_desc =
Typedtree.Texp_let (Asttypes.Nonrecursive,
[({Typedtree.pat_desc = Typedtree.Tpat_var <abstr>;
Typedtree.pat_loc =
{Location.loc_start =
{Lexing.pos_fname = ""; Lexing.pos_lnum = 1; Lexing.pos_bol = 0;
Lexing.pos_cnum = 4};
Location.loc_end =
{Lexing.pos_fname = ""; Lexing.pos_lnum = 1; Lexing.pos_bol = 0;
Lexing.pos_cnum = 5};
Location.loc_ghost = false};
Typedtree.pat_type =
{Types.desc =
Types.Tlink
{Types.desc =
Types.Tconstr (Path.Pident <abstr>, [],
{contents = Types.Mnil});
Types.level = 100000000; Types.id = 649};
Types.level = 59; Types.id = 647};
Typedtree.pat_env = <abstr>},
{Typedtree.exp_desc = Typedtree.Texp_constant (Asttypes.Const_int 21);
Typedtree.exp_loc =
{Location.loc_start =
{Lexing.pos_fname = ""; Lexing.pos_lnum = 1; Lexing.pos_bol = 0;
Lexing.pos_cnum = 8};
Location.loc_end =
{Lexing.pos_fname = ""; Lexing.pos_lnum = 1; Lexing.pos_bol = 0;
Lexing.pos_cnum = 10};
Location.loc_ghost = false};
Typedtree.exp_type =
{Types.desc =
Types.Tconstr (Path.Pident <abstr>, [], {contents = Types.Mnil});
Types.level = 100000000; Types.id = 649};
Typedtree.exp_env = <abstr>});
...plus many more lines....
(and this is only the part that corresponds let x = 21). As you can
see (although probably not easily) the type-checker has figured
out that both x and 21 have the type int. The module
typing/printtyp.mli in the OCaml distribution has a few nicer printing
functions.
Here is the code (top-level script)
(* In the directory directives below, replace
/usr/ports/lang/ocaml/work/ocaml-3.11.1/
with the complete path to your ocaml distribution.
It is assumed the directory contains the made OCaml.
*)
#directory "/usr/ports/lang/ocaml/work/ocaml-3.11.1/parsing";;
#directory "/usr/ports/lang/ocaml/work/ocaml-3.11.1/typing";;
#directory "/usr/ports/lang/ocaml/work/ocaml-3.11.1/toplevel";;
#directory "/usr/ports/lang/ocaml/work/ocaml-3.11.1/utils";;
(* Please do NOT change the order of the following directives! *)
(* This must be loaded first! It is stateful, and affects Predef *)
#load "ident.cmo";;
(* Load the rest of the compiler *)
#load "misc.cmo";;
#load "path.cmo";;
#load "types.cmo";;
#load "btype.cmo";;
#load "tbl.cmo";;
#load "subst.cmo";;
#load "predef.cmo";;
#load "datarepr.cmo";;
#load "config.cmo";;
#load "consistbl.cmo";;
#load "clflags.cmo";;
#load "env.cmo";;
#load "ctype.cmo";;
#load "printast.cmo";;
#load "oprint.cmo";;
#load "primitive.cmo";;
#load "printtyp.cmo";;
#load "linenum.cmo";;
#load "warnings.cmo";;
#load "location.cmo";;
#load "typetexp.cmo";;
#load "includecore.cmo";;
#load "typedecl.cmo";;
#load "typedtree.cmo";;
#load "stypes.cmo";;
#load "parmatch.cmo";;
#load "typecore.cmo";;
#load "includeclass.cmo";;
#load "typeclass.cmo";;
#load "mtype.cmo";;
#load "includemod.cmo";;
#load "longident.cmo";;
#load "typemod.cmo";;
#load "ccomp.cmo";;
#load "lexer.cmo";;
#load "syntaxerr.cmo";;
#load "parser.cmo";;
#load "parse.cmo";;
(* from driver/compile.ml *)
let initial_env () =
Config.load_path := [""; "/usr/local/lib/ocaml"];
Env.reset_cache ();
Ident.reinit();
try
Env.open_pers_signature "Pervasives" Env.initial
with Not_found ->
failwith "cannot open pervasives.cmi"
;;
let env = initial_env()
;;
(* toplevel/toploop.ml *)
let read_type_exp src_string =
let lb = Lexing.from_string src_string in
match Parse.implementation lb with
| [{Parsetree.pstr_desc = Parsetree.Pstr_eval exp}] ->
Ctype.init_def(Ident.current_time());
Typecore.reset_delayed_checks ();
let texp = Typecore.type_expression env exp
in Typecore.force_delayed_checks (); texp
| _ -> failwith "Only expressions are expected"
;;
let test1 = read_type_exp "let x = 21 and twice y = 2 * y in twice x";;
next reply other threads:[~2010-06-09 7:51 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-09 7:47 oleg [this message]
-- strict thread matches above, loose matches on Subject: below --
2010-06-08 21:29 Martin Potier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100609074703.E3754173BB@Adric.ern.nps.edu \
--to=oleg@okmij.org \
--cc=caml-list@inria.fr \
--cc=martin.potier@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox