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 public 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 bool CopyFunc (MSymbol name, Domain domain)
94 Function func = (Function) functions.Get (name);
97 domain.functions = domain.functions.Cons (name, func);
101 public void CopyFunc (Domain domain)
103 foreach (MPlist p in functions)
104 domain.functions = domain.functions.Cons (p.key, p.val);
107 public object GetValue (MSymbol name)
109 MPlist slot = bindings.Find (name);
112 throw new Exception ("Unbound variable: " + name);
116 public object SetValue (MSymbol name, object val)
118 MPlist slot = bindings.Find (name);
121 bindings = bindings.Cons (name, val);
127 public bool IsBound (MSymbol name)
129 return (bindings.Find (name) != null);
132 public void Translate (MPlist plist)
134 if (translator != null)
135 for (MPlist p = plist; ! p.IsEmpty; p = p.next)
136 translator (p, this);
139 public override string ToString ()
141 string str = "<(functions";
142 foreach (MPlist p in functions)
144 str += ") (bindings " + bindings + ")";
146 str += " (" + context + ")";
152 public delegate object Evaluator (MExpression[] args, Domain domain);
153 public delegate void Translator (MPlist plist, Domain domain);
155 internal class Function
159 internal readonly MSymbol[] args;
160 internal readonly MExpression[] body;
162 public Lambda (MPlist args, MPlist body, Domain domain)
167 this.args = new MSymbol[len];
168 for (int i = 0; ! args.IsEmpty; i++, args = args.next)
169 this.args[i] = args.Symbol;
171 this.body = new MExpression[len];
172 for (int i = 0; ! body.IsEmpty; i++, body = body.next)
174 domain.Translate (body);
175 this.body[i] = new MExpression (body.key, body.val, domain);
180 public readonly MSymbol Name;
181 private readonly Evaluator eval;
182 public readonly int min_arg, max_arg;
183 private readonly Lambda lambda;
184 private readonly bool specialp = false;
186 internal static Function ignore, varref, block;
188 public Function (MSymbol name, Evaluator eval,
189 int min_arg, int max_arg, bool specialp)
193 this.min_arg = min_arg;
194 this.max_arg = max_arg;
195 this.specialp = specialp;
198 internal Function (MSymbol name, MPlist args, MPlist body, Domain domain)
201 lambda = new Lambda (args, body, domain);
202 this.min_arg = this.max_arg = lambda.args.Length;
212 ignore = new Function ();
213 varref = new Function (Mvarref, get_value, 1, 1, true);
214 block = new Function (Mprogn, progn, 0, -1, true);
217 private static object get_value (MExpression[] args, Domain domain)
219 return domain.GetValue ((MSymbol) args[0].val);
222 public object Call (MExpression[] args, Domain domain)
227 foreach (MExpression e in args)
229 return eval (args, domain);
233 MPlist orig_bindings = domain.bindings;
234 object result = false;
237 foreach (MSymbol arg in lambda.args)
238 domain.Bind (arg, args[i++].Eval (domain));
239 foreach (MExpression e in lambda.body)
240 result = e.Eval (domain);
242 domain.bindings = orig_bindings;
248 private static Domain basic;
250 static MExpression ()
252 basic = new Domain ();
254 basic.Defun ("set", set_value, 2, 2, true);
255 basic.Defun ("=", set_value, 2, 2, true);
256 basic.Defun ("+", plus, 2, -1, false);
257 basic.Defun ("*", multi, 2, -1, false);
258 basic.Defun ("-", minus, 1, -1, false);
259 basic.Defun ("/", divide, 2, -1, false);
260 basic.Defun ("%", percent, 2, -1, false);
261 basic.Defun ("|", logior, 2, -1, false);
262 basic.Defun ("&", logand, 2, -1, false);
263 basic.Defun ("+=", pluseq, 2, -1, true);
264 basic.Defun ("*=", multieq, 2, -1, true);
265 basic.Defun ("-=", minuseq, 2, -1, true);
266 basic.Defun ("/=", divideeq, 2, -1, true);
267 basic.Defun ("%=", percenteq, 2, -1, true);
268 basic.Defun ("|=", logioreq, 2, -1, true);
269 basic.Defun ("&=", logandeq, 2, -1, true);
270 basic.Defun ("<<", lshift, 2, 2, false);
271 basic.Defun (">>", rshift, 2, 2, false);
272 basic.Defun ("<<=", lshifteq, 2, 2, true);
273 basic.Defun (">>=", rshifteq, 2, 2, true);
274 basic.Defun ("==", eq, 2, -1, false);
275 basic.Defun ("!=", noteq, 2, 2, false);
276 basic.Defun ("<", less, 2, -1, false);
277 basic.Defun ("<=", lesseq, 2, -1, false);
278 basic.Defun (">", more, 2, -1, false);
279 basic.Defun (">=", moreeq, 2, -1, false);
280 basic.Defun ("progn", progn, 0, -1, true);
281 basic.Defun ("if", ifclause, 2, -1, true);
282 basic.Defun ("when", whenclause, 2, -1, true);
283 basic.Defun ("while", whileclause, 1, -1, true);
285 basic.AddTranslator (new Translator (translate_cond));
288 private static object set_value (MExpression[] args, Domain domain)
290 return domain.SetValue ((MSymbol) args[0].args[0].val,
291 args[1].Eval (domain));
294 private static object plus (MExpression[] args, Domain domain)
296 if (args[0].val is int)
299 foreach (MExpression e in args)
303 else if (args[0].val is MText)
305 MText mt = new MText ();
306 foreach (MExpression e in args)
310 throw new Exception ("Not an integer nor MText: " + args[0].val);
313 private static object multi (MExpression[] args, Domain domain)
316 foreach (MExpression e in args)
321 private static object minus (MExpression[] args, Domain domain)
323 int n = (int) args[0].val;
324 if (args.Length == 1)
326 for (int i = 1; i < args.Length; i++)
327 n -= (int) args[i].val;
331 private static object divide (MExpression[] args, Domain domain)
333 int n = (int) args[0].val;
334 for (int i = 1; i < args.Length; i++)
335 n /= (int) args[i].val;
339 private static object percent (MExpression[] args, Domain domain)
341 int n = (int) args[0].val;
342 for (int i = 1; i < args.Length; i++)
343 n %= (int) args[i].val;
347 private static object logior (MExpression[] args, Domain domain)
350 foreach (MExpression e in args)
355 private static object logand (MExpression[] args, Domain domain)
358 foreach (MExpression e in args)
363 private static object pluseq (MExpression[] args, Domain domain)
365 MSymbol sym = (MSymbol) args[0].args[0].val;
366 object val = domain.GetValue (sym);
371 for (int i = 1; i < args.Length; i++)
372 n += (int) args[i].Eval (domain);
375 else if (val is MText)
377 MText mt = (MText) val;
378 for (int i = 1; i < args.Length; i++)
379 mt.Cat ((MText) args[i].Eval (domain));
382 domain.SetValue (sym, val);
386 private static object multieq (MExpression[] args, Domain domain)
388 MSymbol sym = (MSymbol) args[0].args[0].val;
389 int n = (int) domain.GetValue (sym);
391 for (int i = 1; i < args.Length; i++)
392 n *= (int) args[i].Eval (domain);
393 return domain.SetValue (sym, (object) n);
396 private static object minuseq (MExpression[] args, Domain domain)
398 MSymbol sym = (MSymbol) args[0].args[0].val;
399 int n = (int) domain.GetValue (sym);
401 for (int i = 1; i < args.Length; i++)
402 n -= (int) args[i].Eval (domain);
403 return domain.SetValue (sym, (object) n);
406 private static object divideeq (MExpression[] args, Domain domain)
408 MSymbol sym = (MSymbol) args[0].args[0].val;
409 int n = (int) domain.GetValue (sym);
411 for (int i = 1; i < args.Length; i++)
412 n /= (int) args[i].Eval (domain);
413 return domain.SetValue (sym, (object) n);
416 private static object percenteq (MExpression[] args, Domain domain)
418 MSymbol sym = (MSymbol) args[0].args[0].val;
419 int n = (int) domain.GetValue (sym);
421 for (int i = 1; i < args.Length; i++)
422 n %= (int) args[i].Eval (domain);
423 return domain.SetValue (sym, (object) n);
426 private static object logioreq (MExpression[] args, Domain domain)
428 MSymbol sym = (MSymbol) args[0].args[0].val;
429 int n = (int) domain.GetValue (sym);
431 for (int i = 1; i < args.Length; i++)
432 n |= (int) args[i].Eval (domain);
433 return domain.SetValue (sym, (object) n);
436 private static object logandeq (MExpression[] args, Domain domain)
438 MSymbol sym = (MSymbol) args[0].args[0].val;
439 int n = (int) domain.GetValue (sym);
441 for (int i = 1; i < args.Length; i++)
442 n &= (int) args[i].Eval (domain);
443 return domain.SetValue (sym, (object) n);
446 private static object lshift (MExpression[] args, Domain domain)
448 return (int) args[0].val << (int) args[1].val;
451 private static object lshifteq (MExpression[] args, Domain domain)
453 MSymbol sym = (MSymbol) args[0].args[0].val;
454 int n = (int) domain.GetValue (sym);
456 n <<= (int) args[1].Eval (domain);
457 return domain.SetValue (sym, (object) n);
460 private static object rshift (MExpression[] args, Domain domain)
462 return (int) args[0].val >> (int) args[1].val;
465 private static object rshifteq (MExpression[] args, Domain domain)
467 MSymbol sym = (MSymbol) args[0].args[0].val;
468 int n = (int) domain.GetValue (sym);
470 n >>= (int) args[1].Eval (domain);
471 return domain.SetValue (sym, (object) n);
474 private static object eq (MExpression[] args, Domain domain)
476 int n = (int) args[0].val;
478 for (int i = 1; i < args.Length; i++)
479 if (n != (int) args[i].val)
484 private static object noteq (MExpression[] args, Domain domain)
486 return ((int) args[0].val != (int) args[1].val);
489 private static object less (MExpression[] args, Domain domain)
491 int n = (int) args[0].val;
493 for (int i = 1; i < args.Length; i++)
495 int n1 = (int) args[i].val;
503 private static object lesseq (MExpression[] args, Domain domain)
505 int n = (int) args[0].val;
506 for (int i = 1; i < args.Length; i++)
508 int n1 = (int) args[i].val;
516 private static object more (MExpression[] args, Domain domain)
518 int n = (int) args[0].val;
519 for (int i = 1; i < args.Length; i++)
521 int n1 = (int) args[i].val;
529 private static object moreeq (MExpression[] args, Domain domain)
531 int n = (int) args[0].val;
532 for (int i = 1; i < args.Length; i++)
534 int n1 = (int) args[i].val;
542 private static object progn (MExpression[] args, Domain domain)
544 object result = false;
546 foreach (MExpression e in args)
547 result = e.Eval (domain);
551 private static bool check_condition (MExpression condition, Domain domain)
553 object result = condition.Eval (domain);
554 return (result is bool ? (bool) result
555 : result is int ? ((int) result) != 0
559 private static object ifclause (MExpression[] args, Domain domain)
561 object result = false;
563 if (check_condition (args[0], domain))
564 result = args[1].Eval (domain);
566 for (int i = 2; i < args.Length; i++)
567 result = args[i].Eval (domain);
571 private static object whenclause (MExpression[] args, Domain domain)
573 object result = false;
575 if (check_condition (args[0], domain))
576 for (int i = 1; i < args.Length; i++)
577 result = args[i].Eval (domain);
581 private static object whileclause (MExpression[] args, Domain domain)
583 while (check_condition (args[0], domain))
584 for (int i = 1; i < args.Length; i++)
585 args[i].Eval (domain);
589 // (cond (COND1 ...) (COND2 ...) ...)
590 // => (progn (when COND1 ...) (when COND2 ...) ...)
591 private static void translate_cond (MPlist plist, Domain domain)
596 if (plist.IsSymbol && plist.Symbol == Mcond)
599 for (plist = plist.next; ! plist.IsEmpty; plist = plist.next)
602 throw new Exception ("Invalid cond form: " + plist);
603 plist.Plist.Push (MSymbol.symbol, Mwhen);
609 private Function function;
610 private MExpression[] args;
613 public MExpression[] Args { get { return args; } }
614 public object Val { get { return val; } }
616 private MExpression (object val)
621 // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN
622 // FUNCALL = '(' SYMBOL EXPR* ')'
623 // PROGN = '(' EXPR * ')'
624 private MExpression (MSymbol key, object val, Domain domain)
626 if (key == MSymbol.symbol)
628 function = Function.varref;
629 args = new MExpression[1];
630 args[0] = new MExpression (val);
632 else if (key == MSymbol.integer
633 || key == MSymbol.mtext)
637 else if (key == MSymbol.plist)
639 MPlist p = (MPlist) val;
643 MSymbol sym = p.Symbol;
649 throw new Exception ("Invalid function argument: "
654 throw new Exception ("Invalid function argument: "
656 domain.Defun (sym, p.Plist, p.next);
657 // This Mexpression is just a dummy.
661 function = domain.GetFunc (sym);
664 if (nargs < function.min_arg
665 || (function.max_arg >= 0 && nargs > function.max_arg))
666 throw new Exception ("Invalid number of arguments to: "
667 + sym + " " + nargs);
668 args = new MExpression[nargs];
669 for (int i = 0; i < nargs; i++, p = p.next)
671 domain.Translate (p);
672 args[i] = new MExpression (p.key, p.val, domain);
678 args = new MExpression[1];
679 args[0] = new MExpression (p, domain);
683 throw new Exception ("Invalid expression: " + key + ":" + val);
686 public MExpression (MPlist plist, Domain domain)
688 function = Function.block;
689 args = new MExpression[plist.Count];
690 for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next)
692 domain.Translate (plist);
693 args[i] = new MExpression (plist.key, plist.val, domain);
697 public object Eval (Domain domain)
699 if (function == null)
702 val = domain.GetValue ((MSymbol) val);
705 val = function.Call (args, domain);
709 public override string ToString ()
713 if (function != null)
715 str = "(" + function.Name.Name;
717 foreach (MExpression e in args)
718 str += " " + e.ToString ();
721 else if (val != null)
722 str = val.ToString ();