Need Help with Macros 
Author Message
 Need Help with Macros

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.

I've create a definition macro that, given the name of the attribute and a
class name, creates getter and setter methods for the class - here's where
the trouble comes in. The macro expands just fine (at least to my tired
eyes) with FD's macroexpand facility in their text editor (a *very* cool
feature), but when I try to compile, I get errors on every invocation of the
macro.

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 ?

// ====================================================
//  <hns-node>
//
// - a hierarchical namespace node
// - allows access to values by name
//   (i.e. "alpha.beta.theta"
//   where "alpha.beta" is an attributed object,
//   and "theta" is the name of a named attribute value )
// ====================================================

define class <hns-node> (<object>)

    slot name :: <byte-string>,
        init-keyword: name:;

    slot value :: <object>,
      init-keyword: value:;

    slot attributes :: <string-table>               // here are the "named"
attributes
         = make(<string-table>);

    slot parent :: false-or(<hns-node>) = #f,
        init-keyword: parent:;

    virtual slot children? :: <boolean>;

    virtual slot children :: <vector>;

end class;

// ====================================================
//        <hns-node>
// ====================================================
// a macro to help define getter/setter methods for
// attributed values.
// ====================================================

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;

// ====================================================
//        <siso-simulator>
// ====================================================

define class <siso-simulator> (<hns-node>)

  // these virtual slots will have a getter/setter defined by the
  // "define attribute" macro used later

  virtual slot input-tag;                     // name of the input value for
this siso
  virtual slot pv;                            // process value
  virtual slot k;                             // process gain
  virtual slot t1;                            // process response (in
minutes)
  virtual slot td;                            // process delay (in minutes)
  virtual slot bias;                          // bias

end class;

// initialize
//
define method initialize (a :: <siso-simulator>, #keys)

  next-method(a);

  a.value := a;

  a.attributes["input-tag"] := make(<hns-node>, name: "input-tag", value:
"", parent: a);
  a.attributes["pv"]        := make(<hns-node>, name: "pv", value: 0.0,
parent: a);
  a.attributes["k"]         := make(<hns-node>, name: "k", value: 1.0,
parent: a);
  a.attributes["t1"]        := make(<hns-node>, name: "t1", value: 0.0,
parent: a);
  a.attributes["td"]        := make(<hns-node>, name: "td", value: 0.0,
parent: a);
  a.attributes["bias"]      := make(<hns-node>, name: "bias", value: 0.0,
parent: a);

end method;

// ====================================================
//        <siso-simulator>
// ====================================================
// attribute getter/setters
// ====================================================

define attribute input-tag (<siso-simulator>);                 // here's my
attempt to use the macro (line #118)

this is what the macro expands to ...
--------------------------------------------------------------
define inline method input-tag (a :: <siso-simulator>)
 a.attributes ["input-tag"];
end method;

define inline method input-tag-setter (v :: <object>,
                                         a :: <siso-simulator>)
 a.attributes ["input-tag"] := v;
end method;
--------------------------------------------------------------

This the is error I get from FD during compile ...
--------------------------------------------------------------
Serious warning at simulation:118:

Reference to undefined binding {"input-tag" in Simulation}.

simulation:117:                  ---------
simulation:118: define attribute input-tag (<siso-simulator>);
simulation:119:                  ---------
--------------------------------------------------------------

Sorry for the long post, but I couldn't figure out how to describe the
probelm without lots of context.

Ron Franke-Polz



Mon, 18 Nov 2002 03:00:00 GMT  
 Need Help with Macros

Quote:

> 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. :)

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



Tue, 19 Nov 2002 03:00:00 GMT  
 Need Help with Macros
Thanks Neel,

That did the trick!

I guess I got caught thinking to "text oriented" instead of remembering that
Dylan's macro system works at the lexical/syntactic level.

Ron Franke-Polz

[snip]

Quote:

>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;

[snip]

>Neel



Tue, 19 Nov 2002 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Need help using MACROS!!

2. Need help with macro writing

3. A macro involving two sub-macros - where the 2nd macro needs results from the first

4. Help needed with Macro coding

5. Need help locating a shareware 386+ macro assembler

6. Need help with complex macros

7. Reinventing the readstring macro!!?? ARRGH - NEED HELP

8. Newbie needs macro help

9. need loop macro help

10. Help needed - Read Macros

11. Help with macros writing macros in Bigloo

12. help sought for macro defining macro

 

 
Powered by phpBB® Forum Software