This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Beguiling a text interpreter...


Bruce Korb <korb@datadesign.com> writes:

I'm looking at autogen as an attempt to create a new language.  So:

> I have two basic inputs.  The first is my set of definitions
> which simply map names to values.  The values may be either strings
> or nested name-value pairs.  Multiple copies of the same name create
> an implicit array.  The index values for any entry of the array may
> be (optionally) specified explicitly.  The definitions do not and
> will not have any other semantics.  (This has been stable in my code
> for years.)

This would just lead to a bunch of defines.  I'd be inclined to map:

a=7 -> (define a '()) (set! a (cons 7 a))
a=8 -> (set! a (cons 8 a))

etc.

Or, define a function autogen-add-value which tests whether that name
is defined, defines it if it isn't, and then paste new values onto the
front of the list of values. 

> The second is the template that is to be interpreted based on the
> definitions found above.  This is what makes sense to beguile.
> However, because to me, a human, it is easier to comprehend what
> I want the output to look like rather than to figure out how to build
> control structures, the syntax is inside-out with respect to "normal"
> code/text generation programs.  E.g.

Here, you'd construct code which does what the template tells it to,
then executes that code. 

>    This is a text document.  The definitions for this contain
>    several points.  They are:
>    <<FOR point>>
>        <<point_name>> is described as follows:
>             <<point_text>>
>    <</point>>
>    END-OF-DOCUMENT.

You'd construct something like the following list:

(begin
 (autogen-out "This is a text ... are:")
 (autogen-for point
   (autogen-out (autogen-name point) 
	        " is described as follows:\n" 
	        (autogen-text point))))
 
and then when you want to run your text, eval it in a module
containing appropriate definitions for autogen-out and autogen-for.

> In other words, it is the syntax between the `<<' and `>>' that is
> to be beguiled, the text outside the markers is to be copied to the
> output once for every pass the interpreter makes over that portion of text.
> I have now reworked the code such that the template scanner restructures
> the template into a tree.  Each node has a function code, an associated text
> pointer and a next node.  Certain functions (FOR, CASE and IF, specifically)
> are "block" functions and have member links as well.  I know how to
> use "snarf" to set up and activate my various functions.  I do not know
> how to make my tree into a list that Guile will then be able to interpret.

I'd be inclined to include the text as strings into your (constructed)
source code, rather than have the parser try to do something
intellignet with it. 

If you want to do it in C you can use gh_cons, gh_list, and gh_eval.
It might be less painful to do it in Scheme. 

> So, finally, here are my questions:
> 
> 1.  Am I missing something documented in guile-ref.info?
> 2.  Is there any particular source that would be good to use as a pattern
>     for writing what I want to write?
> 3.  Is this possible using the "gh_*" interface, or should I forget that
>     and go anhead and plunge into the "scm_*" interface?
> 4.  Is there some subset of the guile-core code that would be most
>     relevent for me to study?

The approach of generating code isn't listed in the guile docs; many
scheme books will have something useful.  The guile-lang-allover
source code is also worth looking at; although it constructs lists
from scheme, it does something like what you want. 

Andrew