define_class.java 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package kawa.standard;
  2. import kawa.lang.*;
  3. import gnu.lists.*;
  4. import gnu.expr.*;
  5. import gnu.mapping.Symbol;
  6. import gnu.bytecode.ClassType;
  7. public class define_class extends Syntax
  8. {
  9. public static final define_class define_class
  10. = new define_class("define-class", false);
  11. public static final define_class define_simple_class
  12. = new define_class("define-simple-class", true);
  13. boolean isSimple;
  14. object objectSyntax;
  15. define_class (object objectSyntax, boolean isSimple)
  16. {
  17. this.objectSyntax = objectSyntax;
  18. this.isSimple = isSimple;
  19. }
  20. define_class (String name, boolean isSimple)
  21. {
  22. super(name);
  23. this.objectSyntax = object.objectSyntax;
  24. this.isSimple = isSimple;
  25. }
  26. @Override
  27. public boolean scanForDefinitions(Pair st, ScopeExp defs, Translator tr)
  28. {
  29. Object st_cdr = st.getCdr();
  30. SyntaxForm nameSyntax = null;
  31. while (st_cdr instanceof SyntaxForm)
  32. {
  33. nameSyntax = (SyntaxForm) st_cdr;
  34. st_cdr = nameSyntax.getDatum();
  35. }
  36. Object name;
  37. if (st_cdr instanceof Pair)
  38. {
  39. name = ((Pair) st_cdr).getCar();
  40. while (name instanceof SyntaxForm)
  41. {
  42. nameSyntax = (SyntaxForm) name;
  43. name = nameSyntax.getDatum();
  44. }
  45. name = tr.namespaceResolve(name);
  46. }
  47. else
  48. name = null;
  49. if (! (name instanceof String || name instanceof Symbol))
  50. {
  51. tr.error('e', "missing class name");
  52. return false;
  53. }
  54. Pair p = (Pair) st_cdr;
  55. Declaration decl = tr.define(name, nameSyntax, defs);
  56. if (p instanceof PairWithPosition)
  57. decl.setLocation((PairWithPosition) p);
  58. ClassExp oexp = new ClassExp(isSimple, null);
  59. decl.noteValue(oexp);
  60. decl.setFlag(Declaration.IS_CONSTANT|Declaration.EARLY_INIT);
  61. decl.setType(isSimple ? Compilation.typeClass : Compilation.typeClassType);
  62. tr.mustCompileHere();
  63. String cname = name instanceof Symbol ? ((Symbol) name).getName()
  64. : name.toString();
  65. int nlen = cname.length();
  66. if (nlen > 2 && cname.charAt(0) == '<' && cname.charAt(nlen-1) == '>')
  67. cname = cname.substring(1, nlen-1);
  68. oexp.setName(cname);
  69. Object members = p.getCdr();
  70. while (members instanceof SyntaxForm)
  71. {
  72. nameSyntax = (SyntaxForm) members;
  73. members = nameSyntax.getDatum();
  74. }
  75. if (! (members instanceof Pair))
  76. {
  77. tr.error('e', "missing class members");
  78. return false;
  79. }
  80. p = (Pair) members;
  81. ScopeExp save_scope = tr.currentScope();
  82. if (nameSyntax != null)
  83. tr.setCurrentScope(nameSyntax.getScope());
  84. Object[] saved = objectSyntax.scanClassDef(p, oexp, tr);
  85. if (nameSyntax != null)
  86. tr.setCurrentScope(save_scope);
  87. ClassType mtype = tr.getModule().classFor(tr);
  88. String clname = oexp.getClassName(tr);
  89. String mname = mtype.getName();
  90. ClassType ctype;
  91. if (clname.equals(mname))
  92. {
  93. ctype = mtype;
  94. tr.getModule().setFlag(ModuleExp.USE_DEFINED_CLASS);
  95. }
  96. else
  97. ctype = new ClassType(clname);
  98. oexp.setClassType(ctype);
  99. oexp.createFields(tr);
  100. if (saved == null)
  101. return false;
  102. st = Translator.makePair(st, this, Translator.makePair(p, decl, saved));
  103. tr.pushForm(st);
  104. return true;
  105. }
  106. public Expression rewriteForm (Pair form, Translator tr)
  107. {
  108. Object form_cdr = form.getCdr();
  109. if (form_cdr instanceof Pair)
  110. {
  111. form = (Pair) form_cdr;
  112. Object form_car = form.getCar();
  113. if (form_car instanceof Declaration)
  114. {
  115. Declaration decl = (Declaration) form_car;
  116. ClassExp oexp = (ClassExp) decl.getValue();
  117. objectSyntax.rewriteClassDef((Object[]) form.getCdr(), tr);
  118. SetExp sexp = new SetExp(decl, oexp);
  119. sexp.setDefining (true);
  120. return sexp;
  121. }
  122. }
  123. return tr.syntaxError(this.getName() + " can only be used in <body>");
  124. }
  125. }