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