[Prev][Next][Index][Thread]

Re: Need Help with Macros



Ron Franke-polz <ron.franke-polz@iac.honeywell.com> wrote:
> I'm trying to create a "defininition macro" that creates getter/setter
> methods for a class. In my new class, I'm keeping track of "attributes" by
> name so that I can create a hierarchical name service and access objects and
> their attributes/slots by a text name.
> 
> Here's a cut-up version of the code - at the bottom of the code is the macro
> call, a sample expansion of the macro, and the error message. Any clues as
> to what I'm doing wrong ?

Yes -- you're using the wrong obscure corner of the macro language. :)
 
> define macro attribute-definer
>     { define attribute ?identifier:name (?type:name) }
>      => {
>          define inline method ?identifier (a :: ?type)
>              a.attributes["\"" ## ?identifier ## "\""];
>          end method;      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
>          define inline method ?identifier ## "-setter" (v :: <object>, 
>                                                         a :: ?type)
>              a.attributes["\"" ## ?identifier ## "\""] := v;
>          end method;      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>        }
> end macro;
>
> [...]
>
> define attribute input-tag (<siso-simulator>);                 

In the underlined bits of the code, you're trying to convert an
name-token into a string, and are so clever you've outsmarted the
compiler. The poor thing is trying to create an identifer named
"input-tag", and instead of giving a clear error it has for reasons I
don't understand tried to interpret this as the binding input-tag --
hence your error message that there's no such binding in scope. (GD
does the same thing, incidentally.)

To convert a name to a string, try this:

  define macro attribute-definer
      { define attribute ?identifier:name (?type:name) }
       => {
           define inline method ?identifier (a :: ?type)
               a.attributes[ ?"identifier" ];
           end method;      

           define inline method ?identifier ## "-setter" (v :: <object>, 
                                                          a :: ?type)
               a.attributes[ ?"identifier" ] := v;
           end method;      
         }
  end macro;

This usage is (badly) described on page 160 of the DRM; it's the
second kind of substitution, right after the description of the ?name
substitution. There's a (confusing) example on page 183, in the
jump-instruction-definer macro. Here's an example that should be
comprehensible:

  define macro foo-definer
    {define foo ?bar:name}
      => {define constant $foo-string = ?"bar";
  	  define constant $foo-symbol = ?#"bar";}
  end macro;
  
  define foo quux-quux;
  
  define method main(name, arguments)
    format-out("%=\n", $foo-string);
    format-out("%=\n", $foo-symbol);
  end method main;

  main(application-name(), application-arguments());

This should print out

  "quux-quux"
  #"quux-quux"

and should make it clear how this construction works. 


Neel



Follow-Ups: References: