Пример #1
0
 public static SExp Eq(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==2, "eq: ");
       SExp lhs = vals[0];
       SExp rhs = vals[1];
       return new Boolean(lhs == rhs);
 }
Пример #2
0
 public static SExp Cons(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==2, "cons: ");
       SExp car = vals[0];
       SExp cdr = vals[1];
       return new Cell(car, cdr);
 }
Пример #3
0
 public static SExp Eval(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==2, "eval: ");
       SExp body = vals[0];
       Environment envGiven = Environment.FromSExpression(vals[1]);
       return Utilities.Eval(body, envGiven);
 }
Пример #4
0
        public static SExp Cond(SExp[] vals, Environment env)
        {
            SExp res = new Undefined();
              foreach (SExp exp in vals)
              {
            if (!(exp is Cell))
            {
              string msg = "cond: malformed clauses.";
              throw new TypeNotMatchException(msg);
            }

            SExp test = (exp as Cell).Car;

            if (!((exp as Cell).Cdr is Cell))
            {
              string msg = "cond: malformed clauses.";
              throw new TypeNotMatchException(msg);
            }

            SExp[] body = ((exp as Cell).Cdr as Cell).ToArray();

            if (Utilities.CanRegardAsTrue(Utilities.Eval(test, env)))
            {
              res = Utilities.Eval(body, env);
              break;

            }
              }
              return res;
        }
Пример #5
0
        public SExp ToSExp()
        {
            var list = SExp.List(SExp.List("success?", IsSuccess()));

            if (IsSuccess())
            {
                list.Push(
                    SExp.List("nodes", SExp.List(Nodes?.Select(n => n.ToSExp()).ToArray())),
                    SExp.List("rest", Rest),
                    SExp.List("message", Message),
                    SExp.List("fail_rest", FailRest));
            }
            else
            {
                list.Push(
                    SExp.List("message", Message),
                    SExp.List("fail_rest", FailRest),
                    SExp.List("rest", Rest),
                    SExp.List("nodes", SExp.List(Nodes?.Select(n => n.ToSExp()).ToArray())));
            }
            if (!string.IsNullOrEmpty(ParserName))
            {
                list.PushFront(SExp.List(SExp.List("parser", ParserName)));
            }
            return(list);
        }
Пример #6
0
        public static SExp Cdr(SExp e)
        {
            Cons c = e as Cons;

            if (c == null)
            {
                return(null);
            }
            return(c.Cdr);
        }
Пример #7
0
 public static SExp And(SExp[] vals, Environment env)
 {
     SExp res = new Boolean(true);
       foreach (SExp exp in vals)
       {
     res = Utilities.Eval(exp, env);
     if (!Utilities.CanRegardAsTrue(res)) return new Boolean(false);
       }
       return res;
 }
Пример #8
0
 public static SExp Cdr(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==1, "cdr: ");
       SExp cell = vals[0];
       if (!(cell is Cell))
       {
     string msg = "cdr: Parameter must be pair.";
     throw new TypeNotMatchException(msg);
       }
       return (cell as Cell).Cdr;
 }
Пример #9
0
 public static SExp EqualNumbers(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==2, "=: ");
       SExp lhs = vals[0];
       SExp rhs = vals[1];
       if (!(lhs is Integer) || !(rhs is Integer))
       {
     string msg = "=: Parameters must be numeric value.";
     throw new TypeNotMatchException(msg);
       }
       return new Boolean(((int)(lhs as Integer).Value) == ((int)(rhs as Integer).Value));
 }
Пример #10
0
        public static Expression From(SExp exp)
        {
            if (exp is SExpAtom a)
            {
                return(From(a));
            }

            if (exp is SExpList l)
            {
                return(From(l));
            }

            throw new NotImplementedException();
        }
Пример #11
0
        public static SExp Add(SExp[] vals, Environment env)
        {
            int sum = 0;
              foreach (SExp exp in vals)
              {
            if (!(exp is Integer))
            {
              string msg = "+: Parameters must be numeric value.";
              throw new TypeNotMatchException(msg);
            }
            sum += ((int)(exp as Integer).Value);
              }

              return new Integer(sum);
        }
Пример #12
0
 public ListSExp ToSExp()
 {
     if (!IsEmpty())
     {
         var lst = SExp.List(SExp.List(
                                 SExp.List("parser", _parser.ToString()),
                                 SExp.List("toks", _toks.ToString())));
         lst.Append(_prev.ToSExp());
         return(lst);
     }
     else
     {
         return(SExp.List());
     }
 }
Пример #13
0
        public static SExp Define(SExp[] vals, Environment env)
        {
            Utilities.CheckArguments(vals, args=>args.Length==2, "define: ");
              SExp name = vals[0];
              if (!(name is Identifier))
              {
            string msg = "define: The first argument must be identifier.";
            throw new TypeNotMatchException(msg);
              }

              SExp exp = Utilities.Eval(vals[1], env);

              env.Add(new Entry((name as Identifier).Value as string, exp));
              return name;
        }
Пример #14
0
 public static SExp If(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==3, "if: ");
       SExp test = vals[0];
       SExp case1 = vals[1];
       SExp case2 = vals[2];
       SExp ret = null;
       if (Utilities.CanRegardAsTrue(Utilities.Eval(test, env)))
       {
     ret = Utilities.Eval(case1, env);
       }
       else
       {
     ret = Utilities.Eval(case2, env);
       }
       return ret;
 }
Пример #15
0
 public SExp ToSExp()
 {
     if (IsLeaf())
     {
         return(SExp.Value(Value));
     }
     else if (TryGetStringValue(out var value))
     {
         var lst = SExp.List(GetNodeMeta());
         if (!string.IsNullOrEmpty(value))
         {
             lst.Push(value);
         }
         return(lst);
     }
     else
     {
         var lst = SExp.List(Children.Select(n => n.ToSExp()).ToArray());
         lst.PushFront(GetNodeMeta());
         return(lst);
     }
 }
Пример #16
0
        public static SExp Setq(SExp[] vals, Environment env)
        {
            Utilities.CheckArguments(vals, args=>args.Length==2, "set!: ");
              if (!(vals[0] is Identifier))
              {
            string msg = "The first argument must be identifier.";
            throw new TypeNotMatchException(msg);
              }

              Identifier name = vals[0] as Identifier;
              SExp val = Utilities.Eval(vals[1], env);
              if (!env.Reassign(name.Value as string, val))
              {
            string msg =
              string.Format("Identifier '{0}' is undefined.", name);
            throw new IdentifierNotDefinedException(msg);
              }
              return name;
        }
Пример #17
0
        public static SExp Let(SExp[] vals, Environment env)
        {
            Utilities.CheckArguments(vals, args=>2<=args.Length, "let: ");
              EnvironmentFrame frame = null;
              try
              {
            frame = EnvironmentFrame.FromSExpression(vals[0]);
            foreach (Entry entry in frame)
            {
              entry.Rest = Utilities.Eval(entry.Rest, env);
            }
              }
              catch (TypeNotMatchException)
              {
            string msg = "let: malformed init list.";
            throw new TypeNotMatchException(msg);
              }

              SExp[] body = Enumerable.Skip(vals, 1).ToArray();
              return Closure.Eval(env, frame, body);
        }
Пример #18
0
 public static SExp Quote(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==1, "quote: ");
       return vals[0];
 }
Пример #19
0
 public static SExp Exit(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==0, "exit: ");
       string msg = "Scalop was terminated.";
       throw new ApplicationTerminationException(msg);
 }
Пример #20
0
 public Cons(SExp Car, SExp Cdr)
 {
     this.Car = Car;
     this.Cdr = Cdr;
 }
Пример #21
0
 public static SExp Input(SExp x) => x;
Пример #22
0
        public static SExp Lambda(SExp[] vals, Environment env)
        {
            Utilities.CheckArguments(vals, args=>2<=args.Length, "lambda: ");
              SExp formal = vals[0];
              if (formal is Atom)
              {
            if (formal is Identifier)
            {
              string msg = "lambda: Variable-length argument is not supported yet.";
              throw new NotSupportedYetException(msg);
            }
            else
            {
              string msg = "lambda: Formal parameter must be pair or identifier.";
              throw new TypeNotMatchException(msg);
            }
              }

              List<string> f = new List<string>();
              for (SExp c = formal; c is Cell; c = (c as Cell).Cdr)
              {
            if (!((c as Cell).Car is Identifier))
            {
              string msg = "lambda: All parameters must be identifier.";
              throw new TypeNotMatchException(msg);
            }
            f.Add(((c as Cell).Car as Identifier).Value as string);
              }

              return
            new Closure(f.ToArray(), Enumerable.Skip(vals,1).ToArray(), env);
        }
Пример #23
0
 public static SExp InteractionEnvironment(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==0, "interaction-environment: ");
       return env.ToSExpression();
 }
Пример #24
0
 public static SExp Select(SExp x) => x;
Пример #25
0
        public static SExp Mul(SExp[] vals, Environment env)
        {
            int n = 1;
              foreach (SExp exp in vals)
              {
            if (!(exp is Integer))
            {
              string msg = "*: Parameters must be numeric value.";
              throw new TypeNotMatchException(msg);
            }
            n *= ((int)(exp as Integer).Value);
              }

              return new Integer(n);
        }
Пример #26
0
 public static SExp Not(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==1, "not: ");
       SExp exp = vals[0];
       return
     Utilities.CanRegardAsTrue(exp) ?
     Boolean.FALSE :
     Boolean.TRUE;
 }
Пример #27
0
 public LexingResult(SExp result)
 {
     this.result = result;
 }
Пример #28
0
        static void Main(string[] args)
        {
            //LispTest.UnitTest();

            bool needHelp = true;

            for (int i = 0; i < args.Length; ++i)
            {
                switch (args[i])
                {
                case "-include":
                    // 読み込むファイルが指定されている。
                    eval(args[i + 1], true);
                    needHelp = false;
                    ++i;
                    break;

                case "-import":
                    // 読み込むファイルが指定されている。
                    eval(args[i + 1], false);
                    needHelp = false;
                    ++i;
                    break;

                case "-test":
                    // UnitTest
                    LispTest.UnitTest();
                    needHelp = false;
                    break;

                // http://d.hatena.ne.jp/ak11/20091122 のpatch
                case "-compile":
                    try
                    {
                        string filename = args[++i];
                        string output   = args[++i];
                        // 出力ファイルよりソースファイルが新しい時のみ処理
                        if (!File.Exists(output) ||
                            File.GetLastWriteTime(output) < File.GetLastWriteTime(filename))
                        {
                            Console.WriteLine(filename + " => " + output);
                            var lisp = new Lisp();
                            lisp.setVar("outfile", new SExp {
                                elms = output
                            });
                            SExp ret = lisp.eval(new ConvSExp().import(filename));
                            //	Console.WriteLine(lisp.SExp2string(ret));
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    needHelp = false;
                    break;


                case "-help":
                case "-h":
                    Help();
                    needHelp = false;
                    break;
                }
            }

            if (needHelp)
            {
                Help();
            }
        }
Пример #29
0
 // Your semantics implementations here
 public static SExp Cons(SExp a, SExp d) => new Cons(a, d);
Пример #30
0
        public static SExp Sub(SExp[] vals, Environment env)
        {
            if (vals.Length == 0)
              {
            string msg = "-: Procedure require at least one argument.";
            throw new ArityNotMatchException(msg);
              }

              else
              {
            SExp exp = vals[0];
            if (!(exp is Integer))
            {
              string msg = "-: Parameters must be numeric value.";
              throw new TypeNotMatchException(msg);
            }
            int n = (int)(exp as Integer).Value;

            if (vals.Length == 1)
            {
              n = -n;
            }
            else
            {
              for (int i = 1; i < vals.Length; i++)
              {
            if (!(vals[i] is Integer))
            {
              string msg = "-: Parameters must be numeric value.";
              throw new TypeNotMatchException(msg);
            }
            n -= ((int)(vals[i] as Integer).Value);
              }
            }
            return new Integer(n);
              }
        }
Пример #31
0
 public static SExp Null(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==1, "null?: ");
       SExp exp = vals[0];
       return
     exp is Nil ?
     Boolean.TRUE :
     Boolean.FALSE;
 }
Пример #32
0
 public static SExp Atom(SExp[] vals, Environment env)
 {
     Utilities.CheckArguments(vals, args=>args.Length==1, "atom?: ");
       SExp exp = vals[0];
       return new Boolean(exp is Atom);
 }
Пример #33
0
 public ListSExp ToSExp()
 {
     return(SExp.List());
 }