Re: More than one #v(expression) in a single line of a macro
Ben Dugan <[email protected]>
| Newsgroups | gmane.comp.hardware.microcontrollers.gnupic |
|---|---|
| Message-ID | <[email protected]> |
Scott, Thanks very much for your email. It provides some very helpful explanation. I will give this some thought and I may get into trying to make some changes, but I have to re-emphasize that this type of work is really at the edge of my ability as a programmer. Recursion, in particular, almost always confuses me, and it sounds like it would be part of the solution in this case. As I said in a post earlier today, I think I've found a work-around in the assembly program I'm working on. Ben Scott Dattalo wrote: > 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 > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > > >