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

Complicated macro expansion question



Hi!  I'm working on a definer macro that'll do this kind
transformation:

{ define unit constraints (min, max) end } =>
 { define class <min> (<unit>)
    inherited slot name = #"min";
   end class;
   *constraints*[#"min"] := <min>;
   
   define class <max> (<unit>)
    inherited slot name = #"max";
   end class;
   *constraints*[#"max"] := <max>;

   define constant <units> = one-of(#"min", #"max"); }


Anybody have suggestions on how to do this?  I've tried:

// --- start code ----
define macro constraints-symbol-helper
  { constraints-helper(?parent:name, ?subclasses:*) } =>
    { define constant "<" ## ?parent ## "s>" = one-of(?subclasses) }

    subclasses:
    { } => { }
    { ?subclass:name, ... } => { ?#"subclass", ... }
end macro constraints-symbol-helper;

define macro constraints-class-helper
  { constraints-class-helper(?parent:name) } => { } 
  { constraints-class-helper(?parent:name, ?subclass:name,
?subclasses:*) } =>
    { define class "<" ## ?subclass ## ">" ("<" ## ?parent ## ">")
          inherited slot name = ?#"subclass";
      end class;
      *constraints*[?#"subclass"] := "<" ## ?subclass ## ">";
      constraints-class-helper(?parent, ?subclasses) }

    subclasses:
    { } => { }
    { ?subclass:name, ... } => { ?subclass, ... }
end macro constraints-class-helper;

define macro constraints-definer
  { define ?parent:name constraints (?subclasses:*) end } => 
    { constraints-class-helper(?parent, ?subclasses);
        constraints-symbol-helper(?parent, ?subclasses) }
end macro constraints-definer;

define group constraints(allowed, forbidden) end;
define single constraints(min, max, required) end;
define constraint constraints (eof, eol, basic) end;
// ---- end code ---

But d2c complains that definitions must appear at the top level (?!?)
-- wrapping begin ... end around various pieces doesn't help.  Should
these macros work as written?  Is there a better way to do these
macros?

Sincerely,
Doug Auclair



Follow-Ups: