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
next prev parent 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