caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "David McClain" <barabh@qwest.net>
To: <caml-list@inria.fr>
Subject: Re: [Caml-list] Error Reporting
Date: Thu, 27 Sep 2001 13:36:49 -0700	[thread overview]
Message-ID: <001c01c14794$230b4e80$210148bf@dylan> (raw)
In-Reply-To: <B1E4D3274D57D411BE8400D0B783FF322E872A@exchange1.cswv.com>

Thanks for the suggestions everybody...

I need to spend some time studying what Neel sent along. But it seems to me
that we have some misunderstandings between us about what I mean by CPS.

In a tail call, and all continuations are tail calls, there is no record of
past history -- hence no trail of continuation frames. I can easily report
the location of the present error, but there is no history to report.

but let me study what Neel sent along before I go off the wall any
further....

Cheers,

- DM

----- Original Message -----
From: "Krishnaswami, Neel" <neelk@cswcasa.com>
To: <caml-list@inria.fr>
Sent: Thursday, September 27, 2001 6:32 AM
Subject: Re: [Caml-list] Error Reporting


> David McClain [mailto:barabh@qwest.net] wrote:
> >
> > I am looking for some ideas on handling program error reporting for
> > a compiler that is built largely on CPS. Since there are no stack
> > frames to crawl for traceback, I have a first cut based on keeping a
> > finite length queue of last visited closures. But this becomes
> > problematic when there are circularities in the code, i.e.,
> > recursion. Also, I think I have way too much error tracking going on
> > at each incremental execution step and so runtime performance is cut
> > back compared to what it could be.
>
> Since you're using CPS, it seems like you have most of the infrastructure
> you need already. If you track source locations from parsing down to code
> generation, you can place a source location into each frame as you
allocate
> it. Then, when you have an error, you can simply walk back down the
> contination, emitting the source location of each frame. Since the
> continuation represents the rest of the computation, you automatically get
> the exact execution context of the erroneous statement.
>
> The overhead for this is one word per frame, plus initializing it
> at each continuation allocation. This is probably acceptable unless
> you are writing a really high-performance compiler. Also, tail-call
> optimization will make the traceback only approximate, but this is
> IME not a big deal in practice.
>
> Below is a small CPS-style lambda calculus interpreter that uses this
> idea to generate tracebacks of its evaluation. It's a treecode
> interpreter, but the ideas ought to carry over directly to bytecode too.
>
> -*-*-*-
>
> type var = string
> type pos = int
>
> (* Expressions carry the source location with them *)
>
> type expr =
>   | Lit of pos * int
>   | Var of pos * var
>   | Fun of pos * var * expr
>   | App of pos * expr * expr
>
> (*
>    Continuation frames have the position as an extra argument, so that
>    the continuation as a whole contains the backtrace info. Primitive
>    functions take the continuation as an extra argument so that they
>    can generate a backtrace on an error.
> *)
>
> type denot =
>   | Int of int
>   | Closure of env * var * expr
>   | Primop of (denot -> cont -> denot)
> and frame =
>   | KFun of pos * env * expr
>   | KArg of pos * env * denot
> and env = (var * denot) list
> and cont = frame list
>
> (*
>    Here are the guts of the machinery to generate a backtrace. We
>    need to extract a position from a frame and then just map over
>    the whole continuation to get the backtrace.
> *)
>
> exception Eval_error of string * pos list
>
> let framepos frame =
>   match frame with
>   | KFun(pos, _, _) -> pos
>   | KArg(pos, _, _) -> pos
>
> let backtrace k = List.map framepos k
>
> (*
>   We augment variable lookup so that failed lookups generate backtraces.
>   If you check statically for unbound variables this is unneccesary.
> *)
>
> let bind v d r = (v,d) :: r
>
> let lookup v r k =
>   try
>     List.assoc v r
>   with
>     Not_found -> raise (Eval_error("Unbound variable " ^ v, backtrace k))
>
>
> (*
>    In the interpreter proper, the only place where a backtrace is
>    generated is when an argument is applied to a non-function. If an
>    if-statement is added, then that should be too. Likewise, if
>    exceptions are added then an uncaught exception should generate
>    one also.
> *)
>
> let rec eval e r k =
>   match e with
>   | Lit(pos, n) ->
>       next (Int n) k
>   | Var(pos, v) ->
>       next (lookup v r k) k
>   | Fun(pos, formal, body) ->
>       next (Closure(r, formal, body)) k
>   | App(pos, f, arg) ->
>       eval f r (KFun(pos, r, arg) :: k)
> and next d k =
>   match k with
>   | [] -> d
>   | KFun(pos, r, arg) :: k' ->
>       eval arg r k'
>   | KArg(pos, r, func) :: k' ->
>       (match func with
>       | Int _ ->
>           raise (Eval_error("Not a function!", backtrace k))
>       | Closure(r, formal, body) ->
>           eval body (bind formal d r) k'
>       | Primop f ->
>           next (f d k) k')
> --
> Neel Krishnaswami
> neelk@cswcasa.com
> -------------------
> Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ:
http://caml.inria.fr/FAQ/
> To unsubscribe, mail caml-list-request@inria.fr  Archives:
http://caml.inria.fr
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


  reply	other threads:[~2001-09-28 13:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-09-27 13:32 Krishnaswami, Neel
2001-09-27 20:36 ` David McClain [this message]
2001-09-28 15:24   ` Frank Atanassow
2001-09-28 16:41     ` David McClain
2001-09-27 22:34 ` David McClain
  -- strict thread matches above, loose matches on Subject: below --
2001-09-28 16:49 David McClain
2001-10-01  0:52 ` John Prevost
2001-10-01 14:17 ` Frank Atanassow
2001-10-01 15:44   ` David McClain
2001-09-27 13:00 Damien Doligez
2001-09-26 22:55 David McClain

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='001c01c14794$230b4e80$210148bf@dylan' \
    --to=barabh@qwest.net \
    --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;
as well as URLs for NNTP newsgroup(s).