[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: