Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: echinuz echinuz <echinuz@yahoo.com>
To: caml-list@inria.fr
Subject: Re: [Caml-list] How to Create Sensible Debugging Information when Dynamically Typechecking Code Generated with camlp5 Quotations
Date: Sat, 15 Dec 2007 11:32:55 -0800 (PST)	[thread overview]
Message-ID: <266122.53415.qm@web60121.mail.yahoo.com> (raw)
In-Reply-To: <1197733590-sup-3933@ausone.local>

[-- Attachment #1: Type: text/plain, Size: 3609 bytes --]

Allow me to clarify what I meant by type errors and antiquotations.  Here is a very simple program that contains the parser, type checker, and quotation generator:

---------------------------------------
#load "pa_extend.cmo";;
#load "q_MLast.cmo";;

(* Parser *)
type palg=
| PApp of string*palg list
| PInt of string
| PFlo of string;;


let g=Grammar.gcreate (Plexer.gmake ());;
let exp_eoi = Grammar.Entry.create g "exp_eoi";;

EXTEND
    GLOBAL: exp_eoi;
    exp_eoi:
        [[ x = exp; EOI -> x ]] ;
    exp:
        [[x=INT -> PInt x
        | x=FLOAT -> PFlo x
        | f = LIDENT; "("; xs=LIST1 SELF SEP ","; ")"-> PApp (f,xs)]];
END;;

let parse s = Grammar.Entry.parse exp_eoi (Stream.of_string s);;

(* Type Checker *)
exception TypeError;;
type integer=[`Int];;
type real=[integer | `Real];;
let rec type_expr=function
    | PApp (f,args) ->
        (match f with
        | "add" ->
            if List.length args != 2 then
                raise TypeError
            else
                let args=List.map type_expr args in
                (match (List.nth args 0,List.nth args 1) with
                | #integer,#integer -> `Int
                | #real,#real -> `Real)
        | _ -> raise TypeError)
    | PInt _ -> `Int
    | PFlo _ -> `Real
;;


(* Quotations *)
type alg=
| App of string*alg list
| Int of int
| Flo of float;;

let loc=Ploc.dummy;;
let rec to_expr=function
    | PInt x-> <:expr< Int $int:x$ >>
    | PFlo x-> <:expr< Flo $flo:x$ >>
    | PApp (f,el)->
        let rec make_el=function
            | x::xs -> <:expr< [$x$::$make_el xs$] >>
            | [] -> <:expr< [] >>
        in
        let el=List.map to_expr el in
        let el=make_el el in
        <:expr< App ($str:f$,$el$) >>
;;
let rec to_patt=function
    | PInt x-> <:patt< Int $int:x$ >>
    | PFlo x-> <:patt< Flo $flo:x$ >>
    | PApp (f,el)->
        let rec make_el=function
            | x::xs -> <:patt< [$x$::$make_el xs$] >>
            | [] -> <:patt< [] >>
        in
        let el=List.map to_patt el in
        let el=make_el el in
        <:patt< App ($str:f$,$el$) >>
;;

let expand_expr s=
    let p=parse s in
    let t=type_expr p in
    to_expr p
;;
let expand_patt s=
    let p=parse s in
    let t=type_expr p in
    to_patt p
;;
Quotation.add "exp" (Quotation.ExAst (expand_expr,expand_patt));;
 ---------------------------------------

Thus, by type check, I mean actually verifying the typing rules of the DSL.  In this case, it means that the only function allowed is "add" and that this function requires two arguments.  Now, imagine the above language where antiquotations are allowed.  The parsed AST would have datatype

type palg=
| PApp of string*palg list
| PInt of string
| PFlo of string
| PQuote of Ploc.t*string

and it becomes impossible to type check in the above sense since we can not ascertain the type of PQuote.  Now, we can still type check the resulting AST of type alg (not palg).  But, this must occur at runtime rather than during the preprocessing step at compile time.  Therein lies the problem.

If we discover a type error during runtime, it would be nice to give the user some indication of where the error occurs short of saying, "Add expects two arguments."  Since the location information provided is relative to the quote, it can still be challenging to determine exactly where the type error occurs.  Thus, I'm either trying to obtain better location information or perhaps learn that there's a better place or method to type check than what I'm using.

       
---------------------------------
Never miss a thing.   Make Yahoo your homepage.

[-- Attachment #2: Type: text/html, Size: 5789 bytes --]

  reply	other threads:[~2007-12-15 19:32 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-14 21:22 echinuz echinuz
2007-12-15 15:47 ` [Caml-list] " Nicolas Pouillard
2007-12-15 19:32   ` echinuz echinuz [this message]
2007-12-16 16:50     ` Daniel de Rauglaudre
2007-12-17 10:54     ` Nicolas Pouillard
2007-12-17  3:29   ` echinuz echinuz
2007-12-17  5:28     ` Daniel de Rauglaudre
2007-12-17  9:11   ` echinuz echinuz
2007-12-17 12:41     ` Daniel de Rauglaudre
2007-12-18 23:05   ` echinuz echinuz
2007-12-19  9:50     ` Daniel de Rauglaudre
2007-12-15 16:54 ` Daniel de Rauglaudre

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=266122.53415.qm@web60121.mail.yahoo.com \
    --to=echinuz@yahoo.com \
    --cc=caml-list@inria.fr \
    /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