使用四十行Mathematica写一个LISP解释器

代码

Eval[cmd_] := (
   If[Length[cmd] > 1,
    car[cmd] @@ cdr[cmd]
    , cmd]
   );
car[lis_] := lis[[1]];
cdr[lis_] := (If[Length[lis] <= 1, {},
    lis[[2 ;; Length[lis]]]]);
resetcar[lis_] := Clear[Evaluate[car[lis]]];
lambda[params_, expr_] :=
  (
   Module
     [params, params = List[##];
     Eval[expr]] &
   );
setfunc[name_, expr_, params_] := (
   DownValues[Evaluate[name]] = HoldPattern[
       Evaluate[name @@ params]] ->
      Eval[expr];
   );
define[funclis_, expr_] :=
  (
   resetcar[funclis];
   Module[
    {params, body},
    setfunc[car[funclis], expr, cdr[funclis]];
    ];
   );
defwithrule[rule_] := (
   DownValues[Evaluate[car[rule]]] = HoldPattern[
       Evaluate[car[rule] @@ rule[[2]]]
       ] -> Eval[rule[[3]]];
   );
defsyntax[rules_] := (
   resetcar[rules];
   defwithrule /@ cdr[rules];
   );

eval[cmds_] := Eval /@ cmds;

以上包含了lambda算子,宏声明和展开等。

上面是代码,下面是一个例程

eval[
 {
  {Set, haohao, 2},
  {define, {plus, c_, d_}, {Plus, c, d}},
  {plus, 3, 2},
  {defsyntax,
   {prefix,
    {prefix,
     {a_, plus, b_},
     {plus, a, b}}
    }
   },
  {Integrate, x^2, {x, 0, haohao}},
  {prefix, 2, plus, 10},
  {Plot, Sin[x/2], {x, 1, 100} },
  {Sin, $$!Pi]}
  }
 ]

屏幕快照 2015-04-04 下午11.46.14

明天再写说明好了

其实,mathematica所用的wolfram语言的本质就是LISP了啦。