1 package gnu.jemacs.lang; 2 import gnu.mapping.*; 3 import gnu.lists.*; 4 import gnu.expr.*; 5 import gnu.text.*; 6 import kawa.standard.Scheme; 7 import gnu.bytecode.Type; 8 import gnu.kawa.lispexpr.*; 9 import gnu.commonlisp.lang.*; 10 11 public class ELisp extends Lisp2 12 { 13 static boolean charIsInt = false; 14 15 16 public static Object getCharacter(int c) 17 { 18 if (charIsInt) 19 return gnu.math.IntNum.make(c); 20 else 21 return Char.make((char)c); 22 } 23 24 public static gnu.math.Numeric asNumber(Object arg) 25 { 26 if (arg instanceof Char) 27 return gnu.math.IntNum.make(((Char) arg).intValue()); 28 if (arg instanceof javax.swing.text.Position ) 29 return gnu.math.IntNum.make(1 + ((javax.swing.text.Position ) arg).getOffset()); 30 return (gnu.math.Numeric) arg; 31 } 32 33 public static char asChar(Object x) 34 { 35 if (x instanceof Char) 36 return ((Char) x).charValue(); 37 int i; 38 if (x instanceof gnu.math.Numeric) 39 i = ((gnu.math.Numeric) x).intValue(); 40 else if (x instanceof javax.swing.text.Position ) 41 i = ((javax.swing.text.Position ) x).getOffset() + 1; 42 else 43 i = -1; 44 if (i < 0 || i > 0xffff) 45 throw new gnu.jemacs.buffer.Signal("error", "not a character value"); 46 return (char) i; 47 } 48 49 public String getName() 50 { 51 return "Emacs-Lisp"; 52 } 53 54 static final ELisp instance; 55 56 public static final Environment elispEnvironment 57 = Environment.make("elisp-environment"); 58 59 static 60 { 61 instance = new ELisp(); 62 63 instance.define("t", TRUE); 64 instance.define("nil", FALSE); 65 CallContext ctx = CallContext.getInstance(); 66 Environment saveEnv = ctx.getEnvironmentRaw(); 67 try 68 { 69 ctx.setEnvironmentRaw(elispEnvironment); 70 instance.initELisp(); 71 } 72 finally 73 { 74 ctx.setEnvironmentRaw(saveEnv); 75 } 76 } 77 78 ELisp () 79 { 80 environ = elispEnvironment; 81 } 82 83 private void initELisp () 84 { 85 try 86 { 87 loadClass("gnu.commonlisp.lisp.PrimOps"); 89 loadClass("gnu.jemacs.lang.NumberOps"); 90 loadClass("gnu.jemacs.lang.MiscOps"); 91 92 defProcStFld("emacs", "gnu.jemacs.buffer.emacs"); 93 } 94 catch (java.lang.ClassNotFoundException ex) 95 { 96 } 98 99 defSntxStFld("if", "gnu.jemacs.lang.MiscOps", "if"); 100 defProcStFld("invoke", "gnu.kawa.reflect.Invoke", "invoke"); 101 102 defProcStFld("+", "gnu.jemacs.lang.AddOp", "$Pl"); 103 defProcStFld("-", "gnu.jemacs.lang.AddOp", "$Mn"); 104 defProcStFld("/", "gnu.jemacs.lang.DivideOp", "$Sl"); 105 defProcStFld("=", "gnu.jemacs.lang.NumberCompare", "$Eq"); 106 defProcStFld("<", "gnu.jemacs.lang.NumberCompare", "$Ls"); 107 defProcStFld(">", "gnu.jemacs.lang.NumberCompare", "$Gr"); 108 defProcStFld("<=", "gnu.jemacs.lang.NumberCompare", "$Ls$Eq"); 109 defProcStFld(">=", "gnu.jemacs.lang.NumberCompare", "$Gr$Eq"); 110 111 defun("self-insert-command", new gnu.jemacs.buffer.SelfInsertCommand()); 112 113 lambda lambda = new gnu.jemacs.lang.lambda(); 114 lambda.setKeywords(getSymbol("&optional"), 115 getSymbol("&rest"), 116 getSymbol("&key")); 117 lambda.defaultDefault = nilExpr; 118 defun("lambda", lambda); 119 defun("defun", new gnu.commonlisp.lang.defun(lambda)); 120 defun("function", new gnu.commonlisp.lang.function(lambda)); 121 122 defun(gnu.kawa.lispexpr.LispLanguage.quote_sym, 123 kawa.lang.Quote.plainQuote); 124 defun("defgroup", new defgroup()); 125 defun("defcustom", new defcustom()); 126 defun("defvar", new gnu.commonlisp.lang.defvar(false)); 127 defun("defconst", new gnu.commonlisp.lang.defvar(true)); 128 defun("defsubst", new gnu.commonlisp.lang.defun(lambda)); 129 defun("setq", new gnu.commonlisp.lang.setq()); 130 defun("prog1", gnu.commonlisp.lang.prog1.prog1); 131 defun("prog2", gnu.commonlisp.lang.prog1.prog2); 132 defun("progn", new kawa.standard.begin()); 133 defun("while", new gnu.jemacs.lang.While()); 134 defun("unwind-protect", new gnu.commonlisp.lang.UnwindProtect()); 135 defun("save-excursion", new gnu.jemacs.lang.SaveExcursion(false)); 136 defun("save-current-buffer", new gnu.jemacs.lang.SaveExcursion(true)); 137 defun("let", new kawa.standard.fluid_let(false, nilExpr)); 138 defun("%let", kawa.standard.let.let); 139 defun("let*", new kawa.standard.fluid_let(true, nilExpr)); 140 defProcStFld("concat", "kawa.lib.strings", "string$Mnappend"); 141 Procedure not = new kawa.standard.not(this); 142 defun("not", not); 143 defun("null", not); 144 defun("eq", new gnu.kawa.functions.IsEq(this, "eq")); 145 defun("equal", new gnu.kawa.functions.IsEqual(this, "equal")); 146 defun("typep", new gnu.kawa.reflect.InstanceOf(this)); 147 defun("princ", displayFormat); 148 defun("prin1", writeFormat); 149 LocationEnumeration e = Scheme.builtin().enumerateAllLocations(); 150 while (e.hasMoreElements()) 151 { 152 importLocation(e.nextLocation()); 153 } 154 try 155 { 156 loadClass("gnu.jemacs.lisp.primitives"); 157 loadClass("gnu.jemacs.buffer.emacs"); 158 loadClass("gnu.jemacs.lisp.simple"); 159 loadClass("gnu.jemacs.lisp.autoloads"); 160 loadClass("gnu.jemacs.lisp.keymap"); 161 loadClass("gnu.jemacs.lisp.editfns"); 162 loadClass("gnu.jemacs.lisp.keydefs"); 163 } 164 catch (java.lang.ClassNotFoundException ex) 165 { 166 } 168 } 169 170 public static ELisp getInstance() 171 { 172 return instance; 173 } 174 175 176 public static void registerEnvironment() 177 { 178 Language.setDefaults(instance); 179 } 180 181 static final AbstractFormat writeFormat = new Print(true); 182 static final AbstractFormat displayFormat = new Print(false); 183 184 public AbstractFormat getFormat(boolean readable) 185 { 186 return readable ? writeFormat : displayFormat; 187 } 188 189 LangPrimType booleanType; 190 191 public Type getTypeFor(String name) 192 { 193 if (name == "t") 194 name = "java.lang.Object"; 195 else if (name == "marker") 196 name = "gnu.jemacs.buffer.Marker"; 197 else if (name == "buffer") 198 name = "gnu.jemacs.buffer.Buffer"; 199 else if (name == "window") 200 name = "gnu.jemacs.buffer.Window"; 201 return Scheme.string2Type(name); 202 } 203 204 public Type getTypeFor (Class clas) 205 { 206 if (clas.isPrimitive()) 207 { 208 String name = clas.getName(); 209 if (name.equals("boolean")) 210 { 211 if (booleanType == null) 212 booleanType = new LangPrimType(Type.boolean_type, this); 213 return booleanType; 214 } 215 return Scheme.getNamedType(name); 216 } 217 return Type.make(clas); 218 } 219 220 public ReadTable createReadTable () 221 { 222 ReadTable rt = super.createReadTable(); 223 rt.set('[', new ReaderVector(']')); 224 rt.remove(']'); 225 rt.set('?', new ELispReadTableEntry('?')); 226 return rt; 227 } 228 229 public static void readableChar(char ch, StringBuffer buf, boolean quote) 230 { 231 if (quote && (ch == '\\' || ch == '\'' || ch == '\"')) 232 { 233 buf.append('\\'); 234 buf.append(ch); 235 } 236 else if (ch > 127) 237 { 238 buf.append("\\u"); 239 String hex = Integer.toHexString(ch); 240 for (int i = hex.length(); i < 4; i++) buf.append('0'); 241 buf.append(hex); 242 } 243 else if (ch >= ' ') 244 buf.append(ch); 245 else if (ch == '\t') buf.append("\\t"); 246 else if (ch == '\r') buf.append("\\r"); 247 else if (ch == '\n') buf.append("\\n"); 248 else 249 { 250 buf.append("\\0"); 251 buf.append((ch >> 3) & 7); 252 buf.append(ch & 7); 253 } 254 } 255 256 260 public static String readableString(Object obj) 261 { 262 String str = obj.toString(); 263 StringBuffer buf = new StringBuffer (200); 264 for (int i = 0; i < str.length(); i++) 265 readableChar(str.charAt(i), buf, false); 266 return buf.toString(); 267 } 268 269 public static void main(String [] args) 270 { 271 kawa.repl.processArgs(new String [] { "--elisp" }, 0, 1); 272 if (args.length == 0) 273 args = new String [] { "-e", "(emacs)", "--" }; 274 kawa.repl.main(args); 275 } 276 } 277 278 class ELispReadTableEntry extends ReaderDispatchMisc 279 { 280 public ELispReadTableEntry(int code) 281 { 282 super(code); 283 } 284 285 public Object read (Lexer in, int ch, int count) 286 throws java.io.IOException , SyntaxException 287 { 288 LispReader reader = (LispReader) in; 289 if (code >= 0) 290 ch = code; 291 switch (ch) 292 { 293 case '?': 294 ch = reader.read(); 295 if (ch == '\\') 296 { 297 ch = reader.read(); 298 if (ch != ' ' && ch >= 0) 299 ch = reader.readEscape(ch); 300 } 301 if (ch < 0) 302 { 303 reader.error("unexpected EOF in character literal"); 304 ch = '?'; 305 } 306 return ELisp.getCharacter(ch); 307 } 308 reader.error("unexpected dispatch character"); 309 return null; 310 } 311 } 312 313 | Popular Tags |