gnupic: Re: [gnupic] More than one #v(expression) in a single line of a macro


Previous by date: 8 Sep 2005 15:12:46 +0100 Re: [gnupic] More than one #v(expression) in a single line of a macro, Ben Dugan
Next by date: 8 Sep 2005 15:12:46 +0100 Re: [gnupic] More than one #v(expression) in a single line of a macro, Ben Dugan
Previous in thread: 8 Sep 2005 15:12:46 +0100 Re: [gnupic] More than one #v(expression) in a single line of a macro, Ben Dugan
Next in thread: 8 Sep 2005 15:12:46 +0100 Re: [gnupic] More than one #v(expression) in a single line of a macro, Ben Dugan

Subject: Re: [gnupic] More than one #v(expression) in a single line of a macro
From: "Scott Dattalo" ####@####.####
Date: 8 Sep 2005 15:12:46 +0100
Message-Id: <63437.67.118.98.117.1126188761.squirrel@67.118.98.117>

On Wed, 2005-09-07 at 09:35 -0400, Ben Dugan wrote:

<snip> info about gpasm macro limitations.

> Does anyone have a clever suggestion for a workaround, or do the
> developers have any pointers about how I might, for example, tweak
> scan.l to do this?  (I was thinking a brute force approach might be to
> add a #w(expression) "operator", but that's not very good.)

Ben,

I'm not an expert with Bison/Flex, but the real solution to gpasm macro
problems lies there. The (or maybe 'a') proper way to tackle this problem
is by introduce recursive parsing. This can be done by adding a new lexer
state that is entered during the #v() processing. The idea here is that
the #v() really needs to be evaluated when it is encountered, turned into
a string (actually that's the result of the evaluation), and then fed back
into yybuffer. The recursive aspect is that it's possible for an
expression to be evaluated and recycled in the input stream multiple times
until something stable eventually pops out. Your particular example,
didn't involve recursion so it may be much simpler then what I am about to
describe... but

I recently solved a somewhat similar problem in gpsim's parser. Let me
describe the problem and the solution and then maybe this can inspire you
to tackle gpasm.

gpsim supports parameterized macros. These are defined with the macro
command. When a macro is defined, it's pretty much stored verbatim in a
structure. The only parsing done is that the text names for the parameters
are stored in a list separate from the text for the body. The only
difficult part is that you have to differentiate text that is for a macro
definition from text that is for a command that needs to be executed now.
This is accomplished with a lexer state. A lexer state or mode defines how
an incoming stream is to be lexed. In other words, it controls how the
lexer should turn the input strings into tokens. A simple example could be
something like a numeric string. In one mode it could be interpreted as a
number where as in another it could be interpreted as an identifier. (This
example is trivial and there are better ways of deciphering how a numeric
string should be interpreted.) gpsim has a MACRO_BODY lexer mode to handle
macro definitions.

Expanding macros in gpsim is also a fairly straightforward process. When
an identifier is encountered and recognized to be macro, then the macro
arguments are stored in a list and the macro body along with its
parameters are accessed for the macro expansion.  During an expansion,
unidentifiable identifiers (i.e. strings of text that are neither commands
or symbols) are compared against the macro parameter list. If a match is
found then the unidentified text is substituted with the invocation
argument. The expansion process involves creating text and feeding it back
into the lexer. One challenge here is that the normal input stream (i.e.
the command line) has to be interrupted while the macro is being expanded.
But the idea is that a single command line consisting of a macro
invocation can turn into many gpsim commands that ultimately are fed back
into the lexer.

Macro definitions and expansions are relatively simple until you consider
nested macro invocations. A nested macro invocation consists of a macro
that references another macro. For example, you may create a "step and
examine" macro to execute the step instruction N times and to examine the
contents of a variable. The number of steps and the variable to examine
are both parameters. Now you may also create the "run and examine macro"
where this macro will set a break 1000 cycles into the future, call the
"step and examine" macro, start running, and examine a variable when the
simulation stops. The variable to be examined is a parameter to both
macros. There are several challenges with nested macro invocations. First,
while expanding a nested macro, the expansion state of the previous macro
has to be saved. gpsim handles this with a macro invocation stack. Second,
parameters for an outer invocation may be passed down as arguments to
nested invocations. Again, the argument and parameter lists are saved in
stacks.

I'd say there are many challenges involved here: one is to identify if a
new lexer state is even needed. Then if so, how are the input and output
streams to be handled. Another related issue is how to manage input
streams in the context of the current design. Fortunately Craig has
created a regression test suite so you'll know when something breaks!

I hope this helps.

Scott


Previous by date: 8 Sep 2005 15:12:46 +0100 Re: [gnupic] More than one #v(expression) in a single line of a macro, Ben Dugan
Next by date: 8 Sep 2005 15:12:46 +0100 Re: [gnupic] More than one #v(expression) in a single line of a macro, Ben Dugan
Previous in thread: 8 Sep 2005 15:12:46 +0100 Re: [gnupic] More than one #v(expression) in a single line of a macro, Ben Dugan
Next in thread: 8 Sep 2005 15:12:46 +0100 Re: [gnupic] More than one #v(expression) in a single line of a macro, Ben Dugan


Powered by ezmlm-browse 0.20.