*** empty log message ***
[m17n/m17n-lib-cs.git] / MExpression.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.IO;
5 using M17N;
6 using M17N.Core;
7
8 namespace M17N.Core
9 {
10   public class MExpression
11   {
12     public delegate object Evaluator (object[] args, MPlist bindings);
13
14     internal delegate void PrettyPrinter (MFunction func,
15                                          string indent, object[] args);
16
17     internal class MFunction
18     {
19       internal MSymbol name;
20       internal readonly Evaluator eval;
21       internal int min_arg;
22       internal int max_arg;
23       internal Type[] arg_types;
24       internal object[] data;
25
26       public PrettyPrinter pp;
27
28       private static PrettyPrinter default_pretty_printer;
29       private static PrettyPrinter set_pretty_printer;
30       internal static MFunction literal, varref, block, defun;
31
32       public MFunction (MSymbol name, Evaluator eval,
33                         int min_arg, int max_arg, params Type[] arg_types)
34       {
35         this.name = name;
36         this.eval = eval;
37         this.min_arg = min_arg;
38         this.max_arg = max_arg;
39         this.arg_types = (Type []) arg_types.Clone ();
40         if (arg_types.Length == 2 && arg_types[0] == typeof (MSymbol))
41           pp = set_pretty_printer;
42         else
43           pp = default_pretty_printer;
44       }
45
46       static MFunction ()
47       {
48         default_pretty_printer = new PrettyPrinter (default_pp);
49         set_pretty_printer = new PrettyPrinter (set_pp);
50         literal = Defun ("nil", null, 1, 1);
51         varref = Defun ("symbol", new Evaluator (get_value), 1, 1);
52         block = Defun ("plist", new Evaluator (progn), 1, -1);
53
54         Defun ("set", new Evaluator (set_value), 2, 2,
55                typeof (MSymbol), typeof (MExpression));
56         Defun ("=", new Evaluator (set_value), 2, 2,
57                typeof (MSymbol), typeof (MExpression));
58         Defun ("+", new Evaluator (plus), 1, -1);
59         Defun ("*", new Evaluator (multi), 2, -1);
60         Defun ("-", new Evaluator (minus), 1, -1);
61         Defun ("/", new Evaluator (divide), 2, -1);
62         Defun ("%", new Evaluator (percent), 2, -1);
63         Defun ("|", new Evaluator (logior), 2, -1);
64         Defun ("&", new Evaluator (logand), 2, -1);
65         Defun ("+=", new Evaluator (pluseq), 2, -1,
66                typeof (MSymbol), typeof (MExpression));
67         Defun ("*=", new Evaluator (multieq), 2, -1,
68                typeof (MSymbol), typeof (MExpression));
69         Defun ("-=", new Evaluator (minuseq), 2, -1,
70                typeof (MSymbol), typeof (MExpression));
71         Defun ("/=", new Evaluator (divideeq), 2, -1,
72                typeof (MSymbol), typeof (MExpression));
73         Defun ("%=", new Evaluator (percenteq), 2, -1,
74                typeof (MSymbol), typeof (MExpression));
75         Defun ("|=", new Evaluator (logioreq), 2, -1,
76                typeof (MSymbol), typeof (MExpression));
77         Defun ("&=", new Evaluator (logandeq), 2, -1,
78                typeof (MSymbol), typeof (MExpression));
79         Defun ("<<", new Evaluator (lshift), 2, 2);
80         Defun (">>", new Evaluator (rshift), 2, 2);
81         Defun ("<<=", new Evaluator (lshifteq), 2, 2,
82                typeof (MSymbol), typeof (MExpression));
83         Defun (">>=", new Evaluator (rshifteq), 2, 2,
84                typeof (MSymbol), typeof (MExpression));
85         Defun ("==", new Evaluator (eq), 2, -1);
86         Defun ("!=", new Evaluator (noteq), 2, 2);
87         Defun ("<", new Evaluator (less), 2, -1);
88         Defun ("<=", new Evaluator (lesseq), 2, -1);
89         Defun (">", new Evaluator (more), 2, -1);
90         Defun (">=", new Evaluator (moreeq), 2, -1);
91         block = Defun ("progn", new Evaluator (progn), 1, -1);
92         block.pp = new PrettyPrinter (block_pp);
93         Defun ("cond", new Evaluator (cond), 1, -1,
94                typeof (MExpression[])).pp = new PrettyPrinter (cond_pp);
95         Defun ("if", new Evaluator (ifclause), 2, -1,
96                typeof (MExpression)).pp = new PrettyPrinter (if_pp);
97         Defun ("while", new Evaluator (whileclause), 1, -1,
98                typeof (MExpression)).pp = new PrettyPrinter (while_pp);
99         defun = Defun ("defun", new Evaluator (define_function), 4, -1,
100                        typeof (FunctionTable),
101                        typeof (MSymbol),
102                        typeof (MPlist),
103                        typeof (MExpression));
104         defun.pp = new PrettyPrinter (defun_pp);
105       }
106
107       private static MPlist find_binding (object[] args, MPlist bindings)
108       {
109         MSymbol var = (MSymbol) args[0];
110         MPlist slot = bindings.Find (var);
111
112         if (slot == null)
113           throw new Exception ("Unbound variable: " + var);
114         return slot;
115       }
116
117       public object Call (object[] args, MPlist bindings)
118       {
119         if (name == MSymbol.nil)
120           return args[0];
121         if (eval != null)
122           return eval (args, bindings);
123
124         MPlist arg_symbols = (MPlist) data[0];
125         for (int i = 0; i < args.Length; i++, arg_symbols = arg_symbols.next)
126           bindings = bindings.Cons (arg_symbols.Symbol,
127                                     ((MExpression) args[i]).Eval (bindings));
128         object result = 0;
129         for (int i = 1; i < data.Length; i++)
130           result = ((MExpression) data[i]).Eval (bindings);
131         return result;
132       }
133
134       // Commonly used pretty-printers.
135
136       public static void default_pp (MFunction func,
137                                      string indent, object[] args)
138       {
139         Console.Write ("(" + func.name);
140         indent += "  ";
141         foreach (MExpression o in args)
142           {
143             Console.Write (" ");
144             o.pp (indent);
145           }
146         Console.Write (")");
147       }
148
149       private static void set_pp (MFunction func, string indent, object[] args)
150       {
151         Console.Write ("(" + func.name + " " + (MSymbol) args[0] + " ");
152         ((MExpression) args[1]).pp (indent);
153         Console.Write (")");
154       }
155
156       private static object get_value (object[] args, MPlist bindings)
157       {
158         return find_binding (args, bindings).val;
159       }
160
161       private static object set_value (object[] args, MPlist bindings)
162       {
163         MSymbol var = (MSymbol) args[0];
164         MPlist slot = bindings.Find (var);
165
166         if (slot == null)
167           slot = bindings.Push (var, null);
168         slot.val = ((MExpression) args[1]).Eval (bindings);
169         if (slot.val is MText)
170           slot.val = ((MText) slot.val).Dup ();
171         return slot.val;
172       }
173
174       private static object plus (object[] args, MPlist bindings)
175       {
176         object val = ((MExpression) args[0]).Eval (bindings);
177
178         if (val is int)
179           {
180             int n = 0;
181             foreach (MExpression e in args)
182               n += (int) e.Eval (bindings);
183             val = n;
184           }
185         else if (val is MText)
186           {
187             MText mt = new MText ();
188             foreach (MExpression e in args)
189               mt += (MText) e.Eval (bindings);
190             val = mt;
191           }
192         return val;
193       }
194
195       private static object multi (object[] args, MPlist bindings)
196       {
197         int n = 1;
198         foreach (MExpression e in args)
199           n *= (int) e.Eval (bindings);
200         return n;
201       }
202
203       private static object minus (object[] args, MPlist bindings)
204       {
205         int n = (int) ((MExpression) args[0]).Eval (bindings);
206         if (args.Length == 1)
207           return - n;
208         for (int i = 1; i < args.Length; i++)
209           n -= (int) ((MExpression) args[i]).Eval (bindings);
210         return n;
211       }
212
213       private static object divide (object[] args, MPlist bindings)
214       {
215         int n = (int) ((MExpression) args[0]).Eval (bindings);
216         for (int i = 1; i < args.Length; i++)
217           n /= (int) ((MExpression) args[i]).Eval (bindings);
218         return n;
219       }
220
221       private static object percent (object[] args, MPlist bindings)
222       {
223         int n = (int) ((MExpression) args[0]).Eval (bindings);
224         for (int i = 1; i < args.Length; i++)
225           n %= (int) ((MExpression) args[i]).Eval (bindings);
226         return n;
227       }
228
229       private static object logior (object[] args, MPlist bindings)
230       {
231         int n = (int) ((MExpression) args[0]).Eval (bindings);
232         for (int i = 1; i < args.Length; i++)
233           n |= (int) ((MExpression) args[i]).Eval (bindings);
234         return n;
235       }
236
237       private static object logand (object[] args, MPlist bindings)
238       {
239         int n = (int) ((MExpression) args[0]).Eval (bindings);
240         for (int i = 1; i < args.Length; i++)
241           n &= (int) ((MExpression) args[i]).Eval (bindings);
242         return n;
243       }
244
245       private static object pluseq (object[] args, MPlist bindings)
246       {
247         MPlist slot = find_binding (args, bindings);
248         object val = slot.val;
249
250         if (val is int)
251           {
252             int n = (int) val;
253             for (int i = 1; i < args.Length; i++)
254               n += (int) ((MExpression) args[i]).Eval (bindings);
255             slot.val = n;
256           }
257         else if (val is MText)
258           {
259             MText mt = (MText) val;
260             for (int i = 1; i < args.Length; i++)
261               mt.Cat ((MText) ((MExpression) args[i]).Eval (bindings));
262           }
263         return slot.val;
264       }
265
266       private static object multieq (object[] args, MPlist bindings)
267       {
268         MPlist slot = find_binding (args, bindings);
269         int n = (int) slot.val;
270         for (int i = 1; i < args.Length; i++)
271           n *= (int) ((MExpression) args[i]).Eval (bindings);
272         return (slot.val = n);
273       }
274
275       private static object minuseq (object[] args, MPlist bindings)
276       {
277         MPlist slot = find_binding (args, bindings);
278         int n = (int) slot.val;
279         for (int i = 1; i < args.Length; i++)
280           n -= (int) ((MExpression) args[i]).Eval (bindings);
281         return (slot.val = n);
282       }
283
284       private static object divideeq (object[] args, MPlist bindings)
285       {
286         MPlist slot = find_binding (args, bindings);
287         int n = (int) slot.val;
288         for (int i = 1; i < args.Length; i++)
289           n /= (int) ((MExpression) args[i]).Eval (bindings);
290         return (slot.val = n);
291       }
292
293       private static object percenteq (object[] args, MPlist bindings)
294       {
295         MPlist slot = find_binding (args, bindings);
296         int n = (int) slot.val;
297         for (int i = 1; i < args.Length; i++)
298           n %= (int) ((MExpression) args[i]).Eval (bindings);
299         return (slot.val = n);
300       }
301
302       private static object logioreq (object[] args, MPlist bindings)
303       {
304         MPlist slot = find_binding (args, bindings);
305         int n = (int) slot.val;
306         for (int i = 1; i < args.Length; i++)
307           n |= (int) ((MExpression) args[i]).Eval (bindings);
308         return (slot.val = n);
309       }
310
311       private static object logandeq (object[] args, MPlist bindings)
312       {
313         MPlist slot = find_binding (args, bindings);
314         int n = (int) slot.val;
315         for (int i = 1; i < args.Length; i++)
316           n &= (int) ((MExpression) args[i]).Eval (bindings);
317         return (slot.val = n);
318       }
319
320       private static object lshift (object[] args, MPlist bindings)
321       {
322         int n1 = (int) ((MExpression) args[0]).Eval (bindings);
323         int n2 = (int) ((MExpression) args[1]).Eval (bindings);
324         return n1 << n2;
325       }
326
327       private static object lshifteq (object[] args, MPlist bindings)
328       {
329         MPlist slot = find_binding (args, bindings);
330         int n1 = (int) slot.val;
331         int n2 = (int) ((MExpression) args[1]).Eval (bindings);
332         return (slot.val = (n1 << n2));
333       }
334
335       private static object rshift (object[] args, MPlist bindings)
336       {
337         int n1 = (int) ((MExpression) args[0]).Eval (bindings);
338         int n2 = (int) ((MExpression) args[1]).Eval (bindings);
339         return n1 >> n2;
340       }
341
342       private static object rshifteq (object[] args, MPlist bindings)
343       {
344         MPlist slot = find_binding (args, bindings);
345         int n1 = (int) slot.val;
346         int n2 = (int) ((MExpression) args[1]).Eval (bindings);
347         return (slot.val = (n1 >> n2));
348       }
349
350       private static object eq (object[] args, MPlist bindings)
351       {
352         int n = (int) ((MExpression) args[0]).Eval (bindings);
353         for (int i = 1; i < args.Length; i++)
354           if (n != (int) ((MExpression) args[i]).Eval (bindings))
355             return 0;
356         return 1;
357       }
358
359       private static object noteq (object[] args, MPlist bindings)
360       {
361         int n1 = (int) ((MExpression) args[0]).Eval (bindings);
362         int n2 = (int) ((MExpression) args[1]).Eval (bindings);
363         return (n1 != n2);
364       }
365
366       private static object less (object[] args, MPlist bindings)
367       {
368         int n = (int) ((MExpression) args[0]).Eval (bindings);
369         for (int i = 1; i < args.Length; i++)
370           {
371             int n1 = (int) ((MExpression) args[i]).Eval (bindings);
372             if (n >= n1)
373               return 0;
374             n = n1;
375           }
376         return 1;
377       }
378
379       private static object lesseq (object[] args, MPlist bindings)
380       {
381         int n = (int) ((MExpression) args[0]).Eval (bindings);
382         for (int i = 1; i < args.Length; i++)
383           {
384             int n1 = (int) ((MExpression) args[i]).Eval (bindings);
385             if (n > n1)
386               return 0;
387             n = n1;
388           }
389         return 1;
390       }
391
392       private static object more (object[] args, MPlist bindings)
393       {
394         int n = (int) ((MExpression) args[0]).Eval (bindings);
395         for (int i = 1; i < args.Length; i++)
396           {
397             int n1 = (int) ((MExpression) args[i]).Eval (bindings);
398             if (n <= n1)
399               return 0;
400             n = n1;
401           }
402         return 1;
403       }
404
405       private static object moreeq (object[] args, MPlist bindings)
406       {
407         int n = (int) ((MExpression) args[0]).Eval (bindings);
408         for (int i = 1; i < args.Length; i++)
409           {
410             int n1 = (int) ((MExpression) args[i]).Eval (bindings);
411             if (n < n1)
412               return 0;
413             n = n1;
414           }
415         return 1;
416       }
417
418       private static object progn (object[] args, MPlist bindings)
419       {
420         object result = null;
421
422         foreach (MExpression e in args)
423           result = e.Eval (bindings);
424         return result;
425       }
426
427       private static void block_pp (MFunction func,
428                                     string indent, object[] args)
429       {
430         bool first = true;
431
432         Console.Write ("(");
433         indent += " ";
434         foreach (MExpression e in args)
435           {
436             if (first)
437               first = false;
438             else
439               Console.Write ("\n" + indent);
440             e.pp (indent);
441           }
442         Console.Write (")");
443       }
444
445       private static object cond (object[] args, MPlist bindings)
446       {
447         foreach (MExpression[] elist in args)
448           {
449             int i = (int) elist[0].Eval (bindings);
450             if (i != 0)
451               return progn ((object[]) elist, bindings);
452           }
453         return 0;
454       }
455
456       private static void cond_pp (MFunction func,
457                                     string indent, object[] args)
458       {
459         Console.Write ("(cond");
460         indent += "  ";
461         foreach (MExpression[] expr_list in args)
462           {
463             Console.Write ("\n" + indent + "(");
464             bool first = true;
465             foreach (MExpression e in expr_list)
466               {
467                 if (first)
468                   first = false;
469                 else
470                   Console.Write (" ");
471                 e.pp (indent);
472               }
473             Console.Write (")");
474           }
475         Console.Write (")");
476       }
477
478       private static object ifclause (object[] args, MPlist bindings)
479       {
480         object result = 0;
481
482         if ((int) ((MExpression) args[0]).Eval (bindings) != 0)
483           result = ((MExpression) args[1]).Eval (bindings);
484         else
485           for (int i = 2; i < args.Length; i++)
486             result = ((MExpression) args[i]).Eval (bindings);
487         return result;
488       }
489
490       private static void if_pp (MFunction func,
491                                  string indent, object[] args)
492       {
493         Console.Write ("(if ");
494         ((MExpression) args[0]).pp (indent + "    ");
495         Console.Write ("\n" + indent + "    ");
496         ((MExpression) args[1]).pp (indent + "    ");
497         bool first = true;
498         indent += "  ";
499         for (int i = 2; i < args.Length; i++)
500           {
501             if (first)
502               {
503                 Console.Write ("\n" + indent);
504                 first = false;
505               }
506             else
507               Console.Write (" ");
508             ((MExpression) args[i]).pp (indent);
509           }
510       }
511
512       private static object whileclause (object[] args, MPlist bindings)
513       {
514         object result = 0;
515
516         while ((int) ((MExpression) args[0]).Eval (bindings) != 0)
517           for (int i = 1; i < args.Length; i++)
518             result = ((MExpression) args[i]).Eval (bindings);
519         return result;
520       }
521
522       private static void while_pp (MFunction func,
523                                     string indent, object[] args)
524       {
525         Console.Write ("(while ");
526         ((MExpression) args[0]).pp (indent + "       ");
527         bool first = true;
528         indent += "  ";
529         for (int i = 1; i < args.Length; i++)
530           {
531             if (first)
532               {
533                 Console.Write ("\n" + indent);
534                 first = false;
535               }
536             else
537               Console.Write (" ");
538             ((MExpression) args[i]).pp (indent);
539           }
540       }
541
542       private static object define_function (object[] args, MPlist bindings)
543       {
544         FunctionTable table = (FunctionTable) args[0];
545         MSymbol sym = (MSymbol) args[1];
546         MPlist arg_symbols = (MPlist) args[2];
547         int nargs = arg_symbols.Count;
548         object[] data = new object[args.Length - 2];
549
550         data[0] = args[2];
551         for (int i = 3; i < args.Length; i++)
552           data[i - 2] = args[i];
553
554         MFunction func = new MFunction (sym, null, nargs, nargs,
555                                         typeof (MExpression));
556         table.table[sym] = func;
557         func.data = data;
558         return null;
559       }
560
561       private static void defun_pp (MFunction func,
562                                     string indent, object[] args)
563       {
564         Console.Write ("(defun " + args[1] + " " + args[2]);
565         bool first = true;
566         indent += "  ";
567         for (int i = 3; i < args.Length; i++)
568           {
569             if (first)
570               {
571                 Console.Write ("\n" + indent);
572                 first = false;
573               }
574             else
575               Console.Write (" ");
576             ((MExpression) args[i]).pp (indent);
577           }
578       }
579     }
580
581     public class FunctionTable
582     {
583       internal Dictionary<MSymbol, MFunction> table
584         = new Dictionary<MSymbol, MFunction> ();
585     }
586
587     private static FunctionTable basic_table = new FunctionTable ();
588
589     public static void Defun (FunctionTable table, string name,
590                               Evaluator evaluator, int min_arg, int max_arg,
591                               params Type[] arg_types)
592     {
593       MFunction func = Defun (name, evaluator, min_arg, max_arg, arg_types);
594       table.table[func.name] = func;
595     }
596
597     private static MFunction Defun (string name, Evaluator evaluator,
598                                     int min_arg, int max_arg,
599                                     params Type[] arg_types)
600     {
601       MSymbol sym = MSymbol.Of (name);
602       MFunction func = new MFunction (sym, evaluator, min_arg, max_arg,
603                                       arg_types);
604       basic_table.table[sym] = func;
605       return func;
606     }
607
608     private static MFunction Defun (string name, Evaluator evaluator,
609                                     int min_arg, int max_arg)
610     {
611       return Defun (name, evaluator, min_arg, max_arg, typeof (MExpression));
612     }
613
614     private static MFunction Find (MSymbol name, FunctionTable table)
615     {
616       if (name == MSymbol.integer
617           || name == MSymbol.mtext)
618         return MFunction.literal;
619
620       MFunction func;
621       if ((table == null
622            || ! table.table.TryGetValue (name, out func))
623           && ! basic_table.table.TryGetValue (name, out func))
624         return null;
625       return func;
626     }
627
628     private void invalid_expression (object o)
629     {
630       throw new Exception ("Invalid expresssion: " + o);
631     }
632
633     private void invalid_argument (object o)
634     {
635       throw new Exception ("Invalid argument: " + o);
636     }
637
638     private MFunction function;
639     private object[] args;
640
641     public MExpression (MSymbol function_name, object[] args,
642                         FunctionTable function_table)
643     {
644       function = Find (function_name, function_table);
645       int nargs = args.Length;
646       if (nargs < function.min_arg
647           || (function.max_arg >= 0 && nargs > function.max_arg))
648         throw new Exception ("Invalid number of arguments: " + args);
649       this.args = (object[]) args.Clone ();
650     }
651
652     private MExpression[] expression_list (MPlist plist, FunctionTable table)
653     {
654       int len = plist.Count;
655       MExpression[] expr_list = new MExpression[len];
656
657       for (int i = 0; i < len; i++, plist = plist.next)
658         {
659           if (plist.IsSymbol)
660             expr_list[i] = new MExpression (plist.Symbol);
661           else if (plist.IsMText || plist.IsInteger)
662             expr_list[i] = new MExpression (plist.val);
663           else if (plist.IsPlist)
664             {
665               MPlist p = plist.Plist;
666               if (p.IsSymbol)
667                 expr_list[i] = new MExpression (p.Symbol, p.next, table);
668               else
669                 expr_list[i] = new MExpression (p, table);
670             }
671           else
672             invalid_expression (plist.val);
673         }
674       return expr_list;
675     }
676
677     // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | EXPRLIST
678     // FUNCALL = '(' SYMBOL EXPR* ')'
679     // EXPRLIST = '(' EXPR* ')'
680
681     // EXPRLIST: PLIST = EXPR ...
682     public MExpression (MPlist plist, FunctionTable table)
683     {
684       function = MFunction.block;
685       args = expression_list (plist, table);
686     }
687
688     // FUNCALL: NAME = FUNCTION-NAME, ARG-LIST = EXPR ...
689     private MExpression (MSymbol name, MPlist arg_list, FunctionTable table)
690     {
691       function = Find (name, table);
692       if (function == null)
693         throw new Exception ("Unknown function: " + name);
694
695       int nargs = arg_list.Count;
696       if (nargs < function.min_arg
697           || (function.max_arg >= 0 && nargs > function.max_arg))
698         throw new Exception ("Invalid number of arguments: " + nargs);
699
700       int i = 0;
701       Type arg_type = typeof (MExpression);
702       if (function.arg_types.Length > 0)
703         {
704           arg_type = function.arg_types[0];
705           if (arg_type == typeof (FunctionTable))
706             {
707               nargs++;
708               args = new object[nargs];
709               args[i++] = table;
710             }
711           else
712             args = new object[nargs];
713         }
714       else
715         args = new object[nargs];
716
717       foreach (MPlist p in arg_list)
718         {
719           if (i < function.arg_types.Length)
720             arg_type = function.arg_types[i];
721           if (arg_type == typeof (MExpression))
722             {
723               if (p.IsSymbol)
724                 args[i++] = new MExpression (p.Symbol);
725               else if (p.IsMText || p.IsInteger)
726                 args[i++] = new MExpression (p.val);
727               else if (p.IsPlist)
728                 {
729                   MPlist p0 = p.Plist;
730                   if (p0.IsSymbol)
731                     args[i++] = new MExpression (p0.Symbol, p0.next, table);
732                   else
733                     args[i++] = new MExpression (p0, table);
734                 }
735               else
736                 invalid_expression (p.val);
737             }
738           else if (arg_type == typeof (MExpression[]))
739             {
740               if (! p.IsPlist)
741                 invalid_argument (p.val);
742               args[i++] = expression_list (p.Plist, table);
743             }
744           else if (arg_type == typeof (MSymbol))
745             {
746               if (! p.IsSymbol)
747                 invalid_argument (p.val);
748               args[i++] = p.Symbol;
749             }
750           else
751             args[i++] = p.val;
752         }
753       if (function == MFunction.defun)
754         function.Call (args, null);
755     }
756
757     public MExpression (MSymbol sym)
758     {
759       function = MFunction.varref;
760       args = new object[1];
761       args[0] = sym;
762     }
763
764     public MExpression (object obj)
765     {
766       function = MFunction.literal;
767       args = new object[1];
768       args[0] = obj;
769     }
770
771     public object Eval (MPlist bindings)
772     {
773       return function.Call (args, bindings);
774     }
775
776     private void pp (string indent)
777     {
778       if (function == MFunction.varref
779           || function == MFunction.literal)
780         {
781           if (args[0] is MText)
782             Console.Write ("\"{0}\"", args[0]);
783           else
784             Console.Write (args[0]);
785         }
786       else
787         function.pp (function, indent, args);
788     }
789
790     public void PrettyPrint () { pp (""); }
791   }
792 }