1 package kawa.lang; 2 import gnu.mapping.*; 3 import gnu.expr.*; 4 import gnu.lists.*; 5 import java.io.*; 6 import gnu.text.*; 7 8 public class SyntaxRules extends Procedure1 implements Printable, Externalizable 9 { 10 13 Object [] literal_identifiers; 14 15 SyntaxRule[] rules; 16 17 18 int maxVars = 0; 19 20 public SyntaxRules () 21 { 22 } 23 24 25 public SyntaxRules (Object [] literal_identifiers, SyntaxRule[] rules, 26 int maxVars) 27 { 28 this.literal_identifiers = literal_identifiers; 29 this.rules = rules; 30 this.maxVars = maxVars; 31 } 32 33 public SyntaxRules (Object [] literal_identifiers, Object srules, 34 Translator tr) 35 { 36 this.literal_identifiers = literal_identifiers; 37 int rules_count = Translator.listLength(srules); 38 if (rules_count < 0) 39 { 40 rules_count = 0; 41 tr.syntaxError ("missing or invalid syntax-rules"); 42 } 43 this.rules = new SyntaxRule [rules_count]; 44 Pair rules_pair; 45 SyntaxForm rules_syntax = null; 47 for (int i = 0; i < rules_count; i++, srules = rules_pair.cdr) 48 { 49 while (srules instanceof SyntaxForm) 50 { 51 rules_syntax = (SyntaxForm) srules; 52 srules = rules_syntax.form; 53 } 54 rules_pair = (Pair) srules; 55 56 SyntaxForm rule_syntax = rules_syntax; 58 Object syntax_rule = rules_pair.car; 59 while (syntax_rule instanceof SyntaxForm) 60 { 61 rule_syntax = (SyntaxForm) syntax_rule; 62 syntax_rule = rule_syntax.form; 63 } 64 if (! (syntax_rule instanceof Pair)) 65 { 66 tr.syntaxError ("missing pattern in " + i + "'th syntax rule"); 67 return; 68 } 69 SyntaxForm pattern_syntax = rule_syntax; 71 Pair syntax_rule_pair = (Pair) syntax_rule; 72 Object pattern = syntax_rule_pair.car; 73 74 String save_filename = tr.getFileName(); 75 int save_line = tr.getLineNumber(); 76 int save_column = tr.getColumnNumber(); 77 78 try 79 { 80 SyntaxForm template_syntax = rule_syntax; 82 tr.setLine(syntax_rule_pair); 83 syntax_rule = syntax_rule_pair.cdr; 84 while (syntax_rule instanceof SyntaxForm) 85 { 86 template_syntax = (SyntaxForm) syntax_rule; 87 syntax_rule = template_syntax.form; 88 } 89 if (! (syntax_rule instanceof Pair)) 90 { 91 tr.syntaxError ("missing template in " + i + "'th syntax rule"); 92 return; 93 } 94 syntax_rule_pair = (Pair) syntax_rule; 95 if (syntax_rule_pair.cdr != LList.Empty) 96 { 97 tr.syntaxError ("junk after "+i+"'th syntax rule"); 98 return; 99 } 100 Object template = syntax_rule_pair.car; 101 102 PatternScope patternScope = PatternScope.push(tr); 103 tr.push(patternScope); 104 105 while (pattern instanceof SyntaxForm) 106 { 107 pattern_syntax = (SyntaxForm) pattern; 108 pattern = pattern_syntax.form; 109 } 110 111 StringBuffer programbuf = new StringBuffer (); 112 113 if (pattern instanceof Pair) 116 { 117 literal_identifiers[0] = ((Pair)pattern).car; 119 120 Pair p = (Pair) pattern; 121 programbuf.append((char) ((1 << 3) | SyntaxPattern.MATCH_PAIR)); 122 programbuf.append((char) SyntaxPattern.MATCH_IGNORE); 123 pattern = p.cdr; 124 } 125 else 126 { 127 tr.syntaxError ("pattern does not start with name"); 129 return; 130 } 131 SyntaxPattern spattern = new SyntaxPattern(programbuf, pattern, 132 pattern_syntax, literal_identifiers, tr); 133 134 this.rules[i] = new SyntaxRule(spattern, 135 template, template_syntax, tr); 136 137 PatternScope.pop(tr); 138 tr.pop(); 139 } 140 finally 141 { 142 tr.setLine(save_filename, save_line, save_column); 143 } 144 } 145 146 for (int i = this.rules.length; --i >= 0; ) 148 { 149 int size = this.rules[i].patternNesting.length(); 150 if (size > maxVars) 151 maxVars = size; 152 } 153 } 154 155 162 163 public Object apply1 (Object arg) 164 { 165 if (arg instanceof SyntaxForm) 166 { 167 SyntaxForm sf = (SyntaxForm) arg; 168 Translator tr = (Translator) Compilation.getCurrent(); 169 ScopeExp save_scope = tr.currentScope(); 170 tr.setCurrentScope(sf.scope); 171 try 172 { 173 return expand(sf, tr); 174 } 175 finally 176 { 177 tr.setCurrentScope(save_scope); 178 } 179 } 180 else 181 return expand(arg, (Translator) Compilation.getCurrent()); 182 } 183 184 203 204 public Object expand (Object obj, Translator tr) 205 { 206 Object [] vars = new Object [maxVars]; 207 Macro macro = (Macro) tr.getCurrentSyntax(); 208 212 for (int i = 0; i < rules.length; i++) 213 { 214 SyntaxRule rule = rules[i]; 215 if (rule==null) 216 return new ErrorExp("error defining "+macro); 217 Pattern pattern = rule.pattern; 219 boolean matched = pattern.match (obj, vars, 0); 220 if (matched) 221 { 222 if (true) { 224 239 } 240 241 if (true) 242 { 243 249 } 250 Object expansion = rule.execute(vars, tr, TemplateScope.make(tr)); 251 252 if (false) { 254 OutPort err = OutPort.errDefault(); 255 err.print("{Expansion of "); 256 err.print(macro); 257 err.println(":"); 258 err.startLogicalBlock(" ", "}", 2); 259 kawa.standard.Scheme.writeFormat.writeObject(expansion, err); 260 err.endLogicalBlock("}"); 261 err.println(); 262 err.flush(); 263 } 264 return expansion; 265 } 266 } 267 272 return tr.syntaxError ("no matching syntax-rule for " 273 + literal_identifiers[0]); 274 } 275 276 public void print (Consumer out) 277 { 278 out.write("#<macro "); 279 ReportFormat.print(literal_identifiers[0], out); 280 out.write('>'); 281 } 282 283 287 public void writeExternal(ObjectOutput out) throws IOException 288 { 289 out.writeObject(literal_identifiers); 290 out.writeObject(rules); 291 out.writeInt(maxVars); 292 } 293 294 public void readExternal(ObjectInput in) 295 throws IOException, ClassNotFoundException 296 { 297 literal_identifiers = (Object []) in.readObject(); 298 rules = (SyntaxRule[]) in.readObject(); 299 maxVars = in.readInt(); 300 } 301 } 302 | Popular Tags |