Version française
Home     About     Download     Resources     Contact us    
Browse thread
How to Create Sensible Debugging Information when Dynamically Typechecking Code Generated with camlp5 Quotations
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: echinuz echinuz <echinuz@y...>
Subject: Re: [Caml-list] How to Create Sensible Debugging Information when Dynamically Typechecking Code Generated with camlp5 Quotations
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.