2 using System.Collections;
3 using System.Collections.Generic;
10 public class MExpression
12 private static MSymbol Mvarref = MSymbol.Of ("symbol-value");
13 private static MSymbol Mdefun = MSymbol.Of ("defun");
14 private static MSymbol Mcond = MSymbol.Of ("cond");
15 private static MSymbol Mprogn = MSymbol.Of ("progn");
16 private static MSymbol Mwhen = MSymbol.Of ("when");
20 internal MPlist functions;
21 internal MPlist bindings;
22 internal Translator translator;
23 public object context;
27 functions = new MPlist ();
28 bindings = new MPlist ();
31 public Domain (object context)
33 functions = basic.functions;
34 bindings = basic.bindings;
35 translator = basic.translator;
36 this.context = context;
39 public Domain (Domain parent, object context)
41 functions = parent.functions;
42 bindings = parent.bindings;
43 translator = parent.translator;
44 this.context = context;
47 public void AddTranslator (Translator translator)
49 if (this.translator == null)
50 this.translator = translator;
52 this.translator += translator;
55 public void Bind (MSymbol sym, object value)
57 bindings = bindings.Cons (sym, value);
60 public void Defun (string name, Evaluator evaluator,
61 int min_arg, int max_arg)
63 Defun (name, evaluator, min_arg, max_arg, false);
66 public void Defun (string name, Evaluator evaluator,
67 int min_arg, int max_arg, bool special)
69 MSymbol sym = MSymbol.Of (name);
70 Function func = new Function (sym, evaluator,
71 min_arg, max_arg, special);
73 functions = functions.Cons (sym, func);
76 internal void Defun (MSymbol sym, MPlist args, MPlist body)
78 Function func = new Function (sym, args, body, this);
80 functions = functions.Cons (sym, func);
83 internal Function GetFunc (MSymbol name)
85 Function func = (Function) functions.Get (name);
88 throw new Exception ("Unknown function: " + name);
92 public object GetValue (MSymbol name)
94 MPlist slot = bindings.Find (name);
97 throw new Exception ("Unbound variable: " + name);
101 public object SetValue (MSymbol name, object val)
103 MPlist slot = bindings.Find (name);
106 bindings = bindings.Cons (name, val);
112 public bool IsBound (MSymbol name)
114 return (bindings.Find (name) != null);
117 public void Translate (MPlist plist)
119 if (translator != null)
120 for (MPlist p = plist; ! p.IsEmpty; p = p.next)
121 translator (p, this);
124 public override string ToString ()
126 string str = "<(functions";
127 foreach (MPlist p in functions)
129 str += ") (bindings " + bindings + ")";
131 str += " (" + context + ")";
137 public delegate object Evaluator (MExpression[] args, Domain domain);
138 public delegate void Translator (MPlist plist, Domain domain);
140 internal class Function
144 internal readonly MSymbol[] args;
145 internal readonly MExpression[] body;
147 public Lambda (MPlist args, MPlist body, Domain domain)
152 this.args = new MSymbol[len];
153 for (int i = 0; ! args.IsEmpty; i++, args = args.next)
154 this.args[i] = args.Symbol;
156 this.body = new MExpression[len];
157 for (int i = 0; ! body.IsEmpty; i++, body = body.next)
158 this.body[i] = new MExpression (body.key, body.val, domain);
162 public readonly MSymbol Name;
163 private readonly Evaluator eval;
164 public readonly int min_arg, max_arg;
165 private readonly Lambda lambda;
166 private readonly bool specialp = false;
168 internal static Function ignore, varref, block;
170 public Function (MSymbol name, Evaluator eval,
171 int min_arg, int max_arg, bool specialp)
175 this.min_arg = min_arg;
176 this.max_arg = max_arg;
177 this.specialp = specialp;
180 internal Function (MSymbol name, MPlist args, MPlist body, Domain domain)
183 lambda = new Lambda (args, body, domain);
184 this.min_arg = this.max_arg = lambda.args.Length;
194 ignore = new Function ();
195 varref = new Function (Mvarref, new Evaluator (get_value), 1, 1, true);
196 block = new Function (Mprogn, new Evaluator (progn), 0, -1, true);
199 private static object get_value (MExpression[] args, Domain domain)
201 return domain.GetValue ((MSymbol) args[0].val);
204 public object Call (MExpression[] args, Domain domain)
209 foreach (MExpression e in args)
211 return eval (args, domain);
215 MPlist orig_bindings = domain.bindings;
216 object result = false;
219 foreach (MSymbol arg in lambda.args)
220 domain.Bind (arg, args[i++].Eval (domain));
221 foreach (MExpression e in lambda.body)
222 result = e.Eval (domain);
224 domain.bindings = orig_bindings;
230 private static Domain basic;
232 static MExpression ()
234 basic = new Domain ();
236 basic.Defun ("set", new Evaluator (set_value), 2, 2, true);
237 basic.Defun ("=", new Evaluator (set_value), 2, 2, true);
238 basic.Defun ("+", new Evaluator (plus), 2, -1, false);
239 basic.Defun ("*", new Evaluator (multi), 2, -1, false);
240 basic.Defun ("-", new Evaluator (minus), 1, -1, false);
241 basic.Defun ("/", new Evaluator (divide), 2, -1, false);
242 basic.Defun ("%", new Evaluator (percent), 2, -1, false);
243 basic.Defun ("|", new Evaluator (logior), 2, -1, false);
244 basic.Defun ("&", new Evaluator (logand), 2, -1, false);
245 basic.Defun ("+=", new Evaluator (pluseq), 2, -1, true);
246 basic.Defun ("*=", new Evaluator (multieq), 2, -1, true);
247 basic.Defun ("-=", new Evaluator (minuseq), 2, -1, true);
248 basic.Defun ("/=", new Evaluator (divideeq), 2, -1, true);
249 basic.Defun ("%=", new Evaluator (percenteq), 2, -1, true);
250 basic.Defun ("|=", new Evaluator (logioreq), 2, -1, true);
251 basic.Defun ("&=", new Evaluator (logandeq), 2, -1, true);
252 basic.Defun ("<<", new Evaluator (lshift), 2, 2, false);
253 basic.Defun (">>", new Evaluator (rshift), 2, 2, false);
254 basic.Defun ("<<=", new Evaluator (lshifteq), 2, 2, true);
255 basic.Defun (">>=", new Evaluator (rshifteq), 2, 2, true);
256 basic.Defun ("==", new Evaluator (eq), 2, -1, false);
257 basic.Defun ("!=", new Evaluator (noteq), 2, 2, false);
258 basic.Defun ("<", new Evaluator (less), 2, -1, false);
259 basic.Defun ("<=", new Evaluator (lesseq), 2, -1, false);
260 basic.Defun (">", new Evaluator (more), 2, -1, false);
261 basic.Defun (">=", new Evaluator (moreeq), 2, -1, false);
262 basic.Defun ("progn", new Evaluator (progn), 0, -1, true);
263 basic.Defun ("if", new Evaluator (ifclause), 2, -1, true);
264 basic.Defun ("when", new Evaluator (whenclause), 2, -1, true);
265 basic.Defun ("while", new Evaluator (whileclause), 1, -1, true);
267 basic.AddTranslator (new Translator (translate_cond));
270 private static object set_value (MExpression[] args, Domain domain)
272 return domain.SetValue ((MSymbol) args[0].args[0].val,
273 args[1].Eval (domain));
276 private static object plus (MExpression[] args, Domain domain)
278 if (args[0].val is int)
281 foreach (MExpression e in args)
285 else if (args[0].val is MText)
287 MText mt = new MText ();
288 foreach (MExpression e in args)
292 throw new Exception ("Not an integer nor MText: " + args[0].val);
295 private static object multi (MExpression[] args, Domain domain)
298 foreach (MExpression e in args)
303 private static object minus (MExpression[] args, Domain domain)
305 int n = (int) args[0].val;
306 if (args.Length == 1)
308 for (int i = 1; i < args.Length; i++)
309 n -= (int) args[i].val;
313 private static object divide (MExpression[] args, Domain domain)
315 int n = (int) args[0].val;
316 for (int i = 1; i < args.Length; i++)
317 n /= (int) args[i].val;
321 private static object percent (MExpression[] args, Domain domain)
323 int n = (int) args[0].val;
324 for (int i = 1; i < args.Length; i++)
325 n %= (int) args[i].val;
329 private static object logior (MExpression[] args, Domain domain)
332 foreach (MExpression e in args)
337 private static object logand (MExpression[] args, Domain domain)
340 foreach (MExpression e in args)
345 private static object pluseq (MExpression[] args, Domain domain)
347 MSymbol sym = (MSymbol) args[0].args[0].val;
348 object val = domain.GetValue (sym);
353 for (int i = 1; i < args.Length; i++)
354 n += (int) args[i].Eval (domain);
357 else if (val is MText)
359 MText mt = (MText) val;
360 for (int i = 1; i < args.Length; i++)
361 mt.Cat ((MText) args[i].Eval (domain));
364 domain.SetValue (sym, val);
368 private static object multieq (MExpression[] args, Domain domain)
370 MSymbol sym = (MSymbol) args[0].args[0].val;
371 int n = (int) domain.GetValue (sym);
373 for (int i = 1; i < args.Length; i++)
374 n *= (int) args[i].Eval (domain);
375 return domain.SetValue (sym, (object) n);
378 private static object minuseq (MExpression[] args, Domain domain)
380 MSymbol sym = (MSymbol) args[0].args[0].val;
381 int n = (int) domain.GetValue (sym);
383 for (int i = 1; i < args.Length; i++)
384 n -= (int) args[i].Eval (domain);
385 return domain.SetValue (sym, (object) n);
388 private static object divideeq (MExpression[] args, Domain domain)
390 MSymbol sym = (MSymbol) args[0].args[0].val;
391 int n = (int) domain.GetValue (sym);
393 for (int i = 1; i < args.Length; i++)
394 n /= (int) args[i].Eval (domain);
395 return domain.SetValue (sym, (object) n);
398 private static object percenteq (MExpression[] args, Domain domain)
400 MSymbol sym = (MSymbol) args[0].args[0].val;
401 int n = (int) domain.GetValue (sym);
403 for (int i = 1; i < args.Length; i++)
404 n %= (int) args[i].Eval (domain);
405 return domain.SetValue (sym, (object) n);
408 private static object logioreq (MExpression[] args, Domain domain)
410 MSymbol sym = (MSymbol) args[0].args[0].val;
411 int n = (int) domain.GetValue (sym);
413 for (int i = 1; i < args.Length; i++)
414 n |= (int) args[i].Eval (domain);
415 return domain.SetValue (sym, (object) n);
418 private static object logandeq (MExpression[] args, Domain domain)
420 MSymbol sym = (MSymbol) args[0].args[0].val;
421 int n = (int) domain.GetValue (sym);
423 for (int i = 1; i < args.Length; i++)
424 n &= (int) args[i].Eval (domain);
425 return domain.SetValue (sym, (object) n);
428 private static object lshift (MExpression[] args, Domain domain)
430 return (int) args[0].val << (int) args[1].val;
433 private static object lshifteq (MExpression[] args, Domain domain)
435 MSymbol sym = (MSymbol) args[0].args[0].val;
436 int n = (int) domain.GetValue (sym);
438 n <<= (int) args[1].Eval (domain);
439 return domain.SetValue (sym, (object) n);
442 private static object rshift (MExpression[] args, Domain domain)
444 return (int) args[0].val >> (int) args[1].val;
447 private static object rshifteq (MExpression[] args, Domain domain)
449 MSymbol sym = (MSymbol) args[0].args[0].val;
450 int n = (int) domain.GetValue (sym);
452 n >>= (int) args[1].Eval (domain);
453 return domain.SetValue (sym, (object) n);
456 private static object eq (MExpression[] args, Domain domain)
458 int n = (int) args[0].val;
460 for (int i = 1; i < args.Length; i++)
461 if (n != (int) args[i].val)
466 private static object noteq (MExpression[] args, Domain domain)
468 return ((int) args[0].val != (int) args[1].val);
471 private static object less (MExpression[] args, Domain domain)
473 int n = (int) args[0].val;
475 for (int i = 1; i < args.Length; i++)
477 int n1 = (int) args[i].val;
485 private static object lesseq (MExpression[] args, Domain domain)
487 int n = (int) args[0].val;
488 for (int i = 1; i < args.Length; i++)
490 int n1 = (int) args[i].val;
498 private static object more (MExpression[] args, Domain domain)
500 int n = (int) args[0].val;
501 for (int i = 1; i < args.Length; i++)
503 int n1 = (int) args[i].val;
511 private static object moreeq (MExpression[] args, Domain domain)
513 int n = (int) args[0].val;
514 for (int i = 1; i < args.Length; i++)
516 int n1 = (int) args[i].val;
524 private static object progn (MExpression[] args, Domain domain)
526 object result = false;
528 foreach (MExpression e in args)
529 result = e.Eval (domain);
533 private static bool check_condition (MExpression condition, Domain domain)
535 object result = condition.Eval (domain);
536 return (result is bool ? (bool) result
537 : result is int ? ((int) result) != 0
541 private static object ifclause (MExpression[] args, Domain domain)
543 object result = false;
545 if (check_condition (args[0], domain))
546 result = args[1].Eval (domain);
548 for (int i = 2; i < args.Length; i++)
549 result = args[i].Eval (domain);
553 private static object whenclause (MExpression[] args, Domain domain)
555 object result = false;
557 if (check_condition (args[0], domain))
558 for (int i = 1; i < args.Length; i++)
559 result = args[i].Eval (domain);
563 private static object whileclause (MExpression[] args, Domain domain)
565 while (check_condition (args[0], domain))
566 for (int i = 1; i < args.Length; i++)
567 args[i].Eval (domain);
571 // (cond (COND1 ...) (COND2 ...) ...)
572 // => (progn (when COND1 ...) (when COND2 ...) ...)
573 private static void translate_cond (MPlist plist, Domain domain)
578 if (plist.IsSymbol && plist.Symbol == Mcond)
581 for (plist = plist.next; ! plist.IsEmpty; plist = plist.next)
584 throw new Exception ("Invalid cond form: " + plist);
585 plist.Plist.Push (MSymbol.symbol, Mwhen);
591 private Function function;
592 private MExpression[] args;
595 private MExpression (object val)
600 // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN
601 // FUNCALL = '(' SYMBOL EXPR* ')'
602 // PROGN = '(' EXPR * ')'
603 private MExpression (MSymbol key, object val, Domain domain)
605 if (key == MSymbol.symbol)
607 function = Function.varref;
608 args = new MExpression[1];
609 args[0] = new MExpression (val);
611 else if (key == MSymbol.integer
612 || key == MSymbol.mtext)
616 else if (key == MSymbol.plist)
618 MPlist p = (MPlist) val;
622 MSymbol sym = p.Symbol;
628 throw new Exception ("Invalid function argument: "
633 throw new Exception ("Invalid function argument: "
635 domain.Defun (sym, p.Plist, p.next);
636 // This Mexpression is just a dummy.
640 function = domain.GetFunc (sym);
643 if (nargs < function.min_arg
644 || (function.max_arg >= 0 && nargs > function.max_arg))
645 throw new Exception ("Invalid number of arguments to: "
646 + sym + " " + nargs);
647 args = new MExpression[nargs];
648 for (int i = 0; i < nargs; i++, p = p.next)
649 args[i] = new MExpression (p.key, p.val, domain);
654 args = new MExpression[1];
655 args[0] = new MExpression (p, domain);
659 throw new Exception ("Invalid expression: " + key + ":" + val);
662 public MExpression (MPlist plist, Domain domain)
664 function = Function.block;
665 args = new MExpression[plist.Count];
666 domain.Translate (plist);
667 for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next)
668 args[i] = new MExpression (plist.key, plist.val, domain);
671 public object Val { get { return val; } }
673 public object Eval (Domain domain)
675 if (function == null)
678 val = domain.GetValue ((MSymbol) val);
681 val = function.Call (args, domain);
685 public override string ToString ()
689 if (function != null)
691 str = "(" + function.Name.Name;
693 foreach (MExpression e in args)
694 str += " " + e.ToString ();
697 else if (val != null)
698 str = val.ToString ();