1 package kawa.standard; 2 import gnu.expr.*; 3 import kawa.lang.*; 4 import gnu.lists.*; 5 import java.util.Vector ; 6 import gnu.mapping.Symbol; 7 import gnu.bytecode.Type; 8 import gnu.kawa.functions.Convert; 9 10 public class object extends Syntax 11 { 12 public static final object objectSyntax 13 = new kawa.standard.object(Scheme.lambda); 14 static { objectSyntax.setName("object"); } 15 16 Lambda lambda; 17 public static final Keyword accessKeyword = Keyword.make("access"); 18 public static final Keyword throwsKeyword = Keyword.make("throws"); 19 static final Keyword typeKeyword = Keyword.make("type"); 20 public static final Keyword allocationKeyword = Keyword.make("allocation"); 21 static final Keyword initKeyword = Keyword.make("init"); 22 static final Keyword initformKeyword = Keyword.make("initform"); 23 static final Keyword init_formKeyword = Keyword.make("init-form"); 24 static final Keyword init_valueKeyword = Keyword.make("init-value"); 25 static final Keyword init_keywordKeyword = Keyword.make("init-keyword"); 26 27 public object(Lambda lambda) 28 { 29 this.lambda = lambda; 30 } 31 32 public Expression rewriteForm (Pair form, Translator tr) 33 { 34 if (! (form.cdr instanceof Pair)) 35 return tr.syntaxError("missing superclass specification in object"); 36 Pair pair = (Pair) form.cdr; 37 ObjectExp oexp = new ObjectExp(); 38 if (pair.car instanceof FString) 39 { 40 if (! (pair.cdr instanceof Pair)) 42 return tr.syntaxError("missing superclass specification after object class name"); 43 pair = (Pair) pair.cdr; 44 } 45 Object [] saved = scanClassDef(pair, oexp, tr); 46 if (saved != null) 47 rewriteClassDef(saved, tr); 48 return oexp; 49 } 50 51 54 public Object [] scanClassDef (Pair pair, ClassExp oexp, Translator tr) 55 { 56 tr.mustCompileHere(); 57 Object superlist = pair.car; 58 Object components = pair.cdr; 59 LambdaExp method_list = null; 60 LambdaExp last_method = null; 61 Vector inits = new Vector (20); 63 for (Object obj = components; obj != LList.Empty; ) 64 { 65 while (obj instanceof SyntaxForm) 68 obj = ((SyntaxForm) obj).form; 69 if (! (obj instanceof Pair)) 70 { 71 tr.error('e', "object member not a list"); 72 return null; 73 } 74 pair = (Pair) obj; 75 Object pair_car = pair.car; 76 while (pair_car instanceof SyntaxForm) 77 pair_car = ((SyntaxForm) pair_car).form; 78 if (! (pair_car instanceof Pair)) 79 { 80 tr.error('e', "object member not a list"); 81 return null; 82 } 83 obj = pair.cdr; Object savedPos1 = tr.pushPositionOf(pair); 85 pair = (Pair) pair_car; 86 pair_car = pair.car; 87 while (pair_car instanceof SyntaxForm) 88 pair_car = ((SyntaxForm) pair_car).form; 89 if (pair_car instanceof String || pair_car instanceof Symbol 90 || pair_car instanceof Keyword) 91 { Pair typePair = null; 93 Object sname = pair_car; 94 Object args; 95 Declaration decl; 96 int allocationFlag = 0; 97 String accessFlagName = null; 98 int accessFlag = 0; 99 if (sname instanceof Keyword) 100 { 101 decl = null; 102 args = pair; 103 } 104 else 105 { 106 decl = oexp.addDeclaration(sname); 107 decl.setSimple(false); 108 decl.setFlag(Declaration.FIELD_OR_METHOD); 109 Translator.setLine(decl, pair); 110 args = pair.cdr; 111 } 112 int nKeywords = 0; 113 boolean seenInit = false; 114 Pair initPair = null; 115 while (args instanceof Pair) 116 { 117 pair = (Pair) args; 118 Pair keyPair = pair; 119 Object key = pair.car; 120 Object savedPos2 = tr.pushPositionOf(pair); 121 args = pair.cdr; 122 if ((key == "::" || key instanceof Keyword) 123 && args instanceof Pair) 124 { 125 nKeywords++; 126 pair = (Pair) args; 127 Object value = pair.car; 128 args = pair.cdr; 129 if (key == "::" || key == typeKeyword) 130 typePair = pair; 131 else if (key == allocationKeyword) 132 { 133 if (allocationFlag != 0) 134 tr.error('e', "duplicate allocation: specification"); 135 if (matches(value, "class", tr) 136 || matches(value, "static", tr)) 137 allocationFlag = Declaration.STATIC_SPECIFIED; 138 else if (matches(value, "instance", tr)) 139 allocationFlag = Declaration.NONSTATIC_SPECIFIED; 140 else 141 tr.error('e', "unknown allocation kind '"+value+"'"); 142 } 143 else if (key == initKeyword 144 || key == initformKeyword 145 || key == init_formKeyword 146 || key == init_valueKeyword) 147 { 148 if (seenInit) 149 tr.error('e', "duplicate initialization"); 150 seenInit = true; 151 if (key != initKeyword) 155 initPair = pair; 156 } 157 else if (key == init_keywordKeyword) 158 { 159 if (! (value instanceof Keyword)) 160 tr.error('e', "invalid 'init-keyword' - not a keyword"); 161 else if (((Keyword) value).getName() 162 != sname.toString()) 163 tr.error('w', "init-keyword option ignored"); 164 } 165 else if (key == accessKeyword) 166 { 167 String newAccessFlag = null; 168 if (matches(value, "private", tr)) 169 { 170 newAccessFlag = "private"; 171 accessFlag = Declaration.PRIVATE_ACCESS; 172 } 173 else if (matches(value, "protected", tr)) 174 { 175 newAccessFlag = "protected"; 176 accessFlag = Declaration.PROTECTED_ACCESS; 177 } 178 else if (matches(value, "public", tr)) 179 { 180 newAccessFlag = "public"; 181 accessFlag = Declaration.PUBLIC_ACCESS; 182 } 183 else if (matches(value, "package", tr)) 184 { 185 newAccessFlag = "package"; 186 accessFlag = Declaration.PACKAGE_ACCESS; 187 } 188 else 189 { 190 tr.error('e', "unknown access specifier"); 191 } 192 if (accessFlagName != null && newAccessFlag != null) 193 { 194 tr.error('e', "duplicate access specifiers - " 195 + accessFlagName + " and " 196 + newAccessFlag); 197 } 198 accessFlagName = newAccessFlag; 199 } 200 else 201 { 202 tr.error('w', "unknown slot keyword '"+key+"'"); 203 } 204 } 205 else if (args == LList.Empty && ! seenInit) 206 { 207 initPair = keyPair; 209 seenInit = true; 210 } 211 else if (args instanceof Pair 212 && nKeywords == 0 && ! seenInit && typePair == null 213 && (pair = (Pair) args).cdr == LList.Empty) 214 { 215 typePair = keyPair; 217 initPair = pair; 218 args = pair.cdr; 219 seenInit = true; 220 } 221 else 222 { 223 args = null; break; 225 } 226 tr.popPositionOf(savedPos2); 227 } 228 if (args != LList.Empty) 229 { 230 tr.error('e', "invalid argument list for slot '" 231 + sname + '\''+" args:"+(args==null?"null":args.getClass().getName())); 232 return null; 233 } 234 if (seenInit) 235 { 236 boolean isStatic 237 = allocationFlag == Declaration.STATIC_SPECIFIED; 238 inits.addElement(decl != null ? (Object ) decl 239 : isStatic ? Boolean.TRUE : Boolean.FALSE); 240 inits.addElement(initPair); 241 } 242 if (decl == null) 243 { 244 if (! seenInit) 245 { 246 tr.error('e', "missing field name"); 247 return null; 248 } 249 } 250 else 251 { 252 if (typePair != null) 253 decl.setType(tr.exp2Type(typePair)); 254 if (allocationFlag != 0) 255 decl.setFlag(allocationFlag); 256 if (accessFlag != 0) 257 decl.setFlag(accessFlag); 258 decl.setCanRead(true); 259 decl.setCanWrite(true); 260 } 261 } 262 else if (pair_car instanceof Pair) 263 { Pair mpair = (Pair) pair_car; 265 Object mname = mpair.car; 266 if (! (mname instanceof String ) 267 && ! (mname instanceof Symbol)) 268 { 269 tr.error('e', "missing method name"); 270 return null; 271 } 272 Declaration decl 273 = oexp.addDeclaration(mname, Compilation.typeProcedure); 274 Translator.setLine(decl, mpair); 275 LambdaExp lexp = new LambdaExp(); 276 lexp.outer = oexp; 277 lexp.setClassMethod(true); 278 decl.noteValue(lexp); 279 decl.setFlag(Declaration.FIELD_OR_METHOD); 280 decl.setProcedureDecl(true); 281 lexp.setSymbol(mname); 282 if (last_method == null) 283 method_list = lexp; 284 else 285 last_method.nextSibling = lexp; 286 last_method = lexp; 287 } 288 else 289 tr.error ('e', "invalid field/method definition"); 290 tr.popPositionOf(savedPos1); 291 } 292 Object [] result = { 293 oexp, 294 components, 295 inits, 296 method_list, 297 superlist 298 }; 299 return result; 300 } 301 302 public void rewriteClassDef (Object [] saved, Translator tr) 303 { 304 ClassExp oexp = (ClassExp) saved[0]; 305 Object components = saved[1]; 306 Vector inits = (Vector ) saved[2]; 307 LambdaExp method_list = (LambdaExp) saved[3]; 308 Object superlist = saved[4]; 309 oexp.firstChild = method_list; 310 311 int num_supers = Translator.listLength(superlist); 312 if (num_supers < 0) 313 { 314 tr.error('e', "object superclass specification not a list"); 315 num_supers = 0; 316 } 317 Expression[] supers = new Expression[num_supers]; 318 for (int i = 0; i < num_supers; i++) 319 { 320 while (superlist instanceof SyntaxForm) 321 { 322 superlist = ((SyntaxForm) superlist).form; 324 } 325 Pair superpair = (Pair) superlist; 326 supers[i] = tr.rewrite_car(superpair, false); 327 superlist = superpair.cdr; 328 } 329 oexp.supers = supers; 330 331 oexp.setClassName(tr); 332 oexp.setTypes(tr); 333 334 int len = inits.size(); 337 for (int i = 0; i < len; i += 2) 338 { 339 Object init = inits.elementAt(i+1); 340 if (init != null) 341 rewriteInit(inits.elementAt(i), oexp, (Pair) init, tr, null); 342 } 343 344 tr.push(oexp); 345 346 LambdaExp meth = method_list; 348 int init_index = 0; SyntaxForm componentsSyntax = null; 350 for (Object obj = components; obj != LList.Empty; ) 351 { 352 while (obj instanceof SyntaxForm) 353 { 354 componentsSyntax = (SyntaxForm) obj; 355 obj = componentsSyntax.form; 356 } 357 Pair pair = (Pair) obj; 358 Object savedPos1 = tr.pushPositionOf(pair); 359 Object pair_car = pair.car; 360 SyntaxForm memberSyntax = componentsSyntax; 361 while (pair_car instanceof SyntaxForm) 362 { 363 memberSyntax = (SyntaxForm) pair_car; 364 pair_car = memberSyntax.form; 365 } 366 try 367 { 368 obj = pair.cdr; pair = (Pair) pair_car; 370 pair_car = pair.car; 371 SyntaxForm memberCarSyntax = memberSyntax; 372 while (pair_car instanceof SyntaxForm) 373 { 374 memberCarSyntax = (SyntaxForm) pair_car; 375 pair_car = memberCarSyntax.form; 376 } 377 if (pair_car instanceof String || pair_car instanceof Symbol 378 || pair_car instanceof Keyword) 379 { Object type = null; 381 int nKeywords = 0; 382 Object args = pair_car instanceof Keyword ? pair : pair.cdr; 383 Pair initPair = null; 384 while (args instanceof Pair) 385 { 386 pair = (Pair) args; 387 Object key = pair.car; 388 Object savedPos2 = tr.pushPositionOf(pair); 389 args = pair.cdr; 390 if ((key == "::" || key instanceof Keyword) 391 && args instanceof Pair) 392 { 393 nKeywords++; 394 pair = (Pair) args; 395 Object value = pair.car; 396 args = pair.cdr; 397 if (key == "::" || key == typeKeyword) 398 type = value; 399 else if (key == initKeyword 400 || key == initformKeyword 401 || key == init_formKeyword 402 || key == init_valueKeyword) 403 { 404 initPair = pair; 405 } 406 else 407 { 408 } 410 } 411 else if (args == LList.Empty && initPair == null) 412 { 413 initPair = pair; 415 } 416 else if (args instanceof Pair && nKeywords == 0 417 && initPair == null && type == null 418 && (pair = (Pair) args).cdr == LList.Empty) 419 { 420 type = key; 422 initPair = pair; 423 args = pair.cdr; 424 } 425 else 426 { 427 args = null; break; 429 } 430 tr.popPositionOf(savedPos2); 431 } 432 if (initPair != null) 433 { 434 Object d = inits.elementAt(init_index++); 435 boolean isStatic = d instanceof Declaration 436 ? ((Declaration) d).getFlag(Declaration.STATIC_SPECIFIED) 437 : d == Boolean.TRUE; 438 if (inits.elementAt(init_index++) == null) 439 rewriteInit(d, oexp, initPair, tr, memberSyntax); 440 } 441 } 442 else if (pair_car instanceof Pair) 443 { ScopeExp save_scope = tr.currentScope(); 445 if (memberSyntax != null) 450 tr.setCurrentScope(memberSyntax.scope); 451 if ("*init*".equals(meth.getName())) 452 { 453 meth.setReturnType(Type.void_type); 454 if (! oexp.isSimple()) 455 tr.error('e', "'*init*' methods only supported for simple classes"); 456 } 457 Translator.setLine(meth, pair); 458 LambdaExp saveLambda = tr.curMethodLambda; 459 tr.curMethodLambda = meth; 460 lambda.rewrite(meth, ((Pair) pair_car).cdr, pair.cdr, tr, 461 memberCarSyntax != null 462 && (memberSyntax == null 463 || memberCarSyntax.scope != memberSyntax.scope) 464 ? memberCarSyntax.scope 465 : null); 466 tr.curMethodLambda = saveLambda; 467 if (memberSyntax != null) 468 tr.setCurrentScope(save_scope); 469 meth = meth.nextSibling; 470 } 471 else 472 tr.syntaxError("invalid field/method definition"); 473 } 474 finally 475 { 476 tr.popPositionOf(savedPos1); 477 } 478 479 } 480 if (oexp.initMethod != null) 483 oexp.initMethod.outer = oexp; 484 if (oexp.clinitMethod != null) 485 oexp.clinitMethod.outer = oexp; 486 tr.pop(oexp); 487 oexp.declareParts(tr); 488 } 489 490 private static void rewriteInit (Object d, ClassExp oexp, Pair initPair, 491 Translator tr, SyntaxForm memberSyntax) 492 { 493 boolean isStatic = d instanceof Declaration 494 ? ((Declaration) d).getFlag(Declaration.STATIC_SPECIFIED) 495 : d == Boolean.TRUE; 496 LambdaExp initMethod = isStatic ? oexp.clinitMethod : oexp.initMethod; 497 if (initMethod == null) 498 { 499 initMethod = new LambdaExp(new BeginExp()); 500 initMethod.setClassMethod(true); 501 if (isStatic) 502 { 503 initMethod.setName("$clinit$"); 504 oexp.clinitMethod = initMethod; 505 } 506 else 507 { 508 initMethod.setName("$finit$"); 509 oexp.initMethod = initMethod; 510 initMethod.add(null, new Declaration(ThisExp.THIS_NAME)); 513 } 514 initMethod.nextSibling = oexp.firstChild; 515 oexp.firstChild = initMethod; 516 } 517 tr.push(initMethod); 518 LambdaExp saveLambda = tr.curMethodLambda; 519 tr.curMethodLambda = initMethod; 520 Expression initValue = tr.rewrite_car(initPair, memberSyntax); 521 if (d instanceof Declaration) 522 { 523 Declaration decl = (Declaration) d; 524 SetExp sexp = new SetExp(decl, initValue); 525 sexp.setLocation(decl); 526 decl.noteValue(null); 527 initValue = sexp; 528 } 529 else 530 initValue = Convert.makeCoercion(initValue, new QuoteExp(Type.void_type)); 531 ((BeginExp) initMethod.body).add(initValue); 532 tr.curMethodLambda = saveLambda; 533 tr.pop(initMethod); 534 } 535 536 539 static boolean matches (Object exp, String tag, Translator tr) 540 { 541 String value; 542 Pair pair; 543 if (exp instanceof Keyword) 544 value = ((Keyword) exp).getName(); 545 else if (exp instanceof FString) 546 value = ((FString) exp).toString(); 547 else if (exp instanceof Pair 548 && tr.matches((pair = (Pair) exp).car, Scheme.quote_sym) 549 && pair.cdr instanceof Pair 550 && (pair = (Pair) pair.cdr).cdr == LList.Empty 551 && pair.car instanceof String ) 552 value = (String ) pair.car; 553 else 554 return false; 555 return tag == null || tag.equals(value); 556 } 557 } 558 | Popular Tags |