Example #1
0
        public static void ThrowsWhenEvaluated <TException>(ILispValue expression, ILispEnvironment environment = null) where TException : LispException
        {
            Assert.IsNotNull(expression);

            try
            {
                ILispValue actual = Evaluator.Evaluate(expression, environment ?? new GlobalEnvironment());
                throw new AssertFailedException(string.Format(
                                                    "Expression returned value instead of throwing: {1}{0}Expected: {2}, Actual: {3}",
                                                    System.Environment.NewLine,
                                                    expression,
                                                    typeof(TException).FullName,
                                                    actual));
            }
            catch (LispException ex)
            {
                if (!(ex is TException))
                {
                    throw new AssertFailedException(string.Format(
                                                        "Expression threw incorrect exception type: {1}{0}Expected: {2}{0}Actual: {3}",
                                                        System.Environment.NewLine,
                                                        expression,
                                                        typeof(TException).FullName,
                                                        ex));
                }
            }
        }
Example #2
0
        public void ProperListToString()
        {
            ILispValue properList = Lisp.List(Lisp.Symbol("test"), Lisp.Constant(1), Lisp.Constant("foo"), Lisp.List(Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3)), Lisp.Constant(true));

            Assert.IsInstanceOfType(properList, typeof(ConsBox));
            Assert.AreEqual("(test 1 \"foo\" (1 2 3) #t)", properList.ToString());
        }
Example #3
0
        bool IEquatable <ILispValue> .Equals(ILispValue other)
        {
            if (other == null)
            {
                return(false);
            }
            if (!(other is List))
            {
                return(false);
            }

            List otherList = (List)other;

            if (this.IsEmpty != otherList.IsEmpty)
            {
                return(false);
            }
            else if (this.IsEmpty && otherList.IsEmpty)
            {
                return(true);
            }
            else
            {
                return(((ConsBox)this).Equals((ConsBox)other));
            }
        }
Example #4
0
        private static ILispValue EvaluateProgn(IList <ILispValue> args, ILispEnvironment environment)
        {
            ILispValue result = Nil.Instance;

            foreach (ILispValue arg in args)
            {
                result = Evaluate(arg, environment);
            }
            return(result);
        }
Example #5
0
 bool IEquatable <ILispValue> .Equals(ILispValue other)
 {
     if (other is Symbol)
     {
         return(Equals((Symbol)other));
     }
     else
     {
         return(false);
     }
 }
Example #6
0
 bool IEquatable <ILispValue> .Equals(ILispValue other)
 {
     if (other == null)
     {
         return(false);
     }
     if (!(other is SimpleValue <T>))
     {
         return(false);
     }
     return(this.Value.Equals(((SimpleValue <T>)other).Value));
 }
Example #7
0
 public ILispValue execute(LispArray array)
 {
     if (array.getSize() == 2)
     {
         value = array [1];
         return(value);
     }
     else
     {
         return(value);
     }
 }
Example #8
0
        private static ILispValue EvaluateInvocation(Symbol funcName, IList <ILispValue> args, ILispEnvironment environment)
        {
            ILispValue func = environment.Lookup(funcName);

            if (func.Type != LispValueType.Lambda)
            {
                throw new TypeMismatchException(new Symbol("function"), LispValueType.Lambda, func.Type);
            }

            ILispLambda        lambda          = (ILispLambda)func;
            IList <ILispValue> parameterValues = args.Select(arg => Evaluate(arg, environment)).ToList();

            return(lambda.Execute(BindParameters(lambda, parameterValues)));
        }
Example #9
0
        public static void AreEqual(ILispValue expected, ILispValue actual)
        {
            Assert.IsNotNull(expected);
            Assert.IsNotNull(actual);

            if (!EqualityComparer <ILispValue> .Default.Equals(expected, actual))
            {
                throw new AssertFailedException(string.Format(
                                                    "Values are different.{0}Expected: {1}, Actual: {2}",
                                                    System.Environment.NewLine,
                                                    expected,
                                                    actual));
            }
        }
Example #10
0
 bool IEquatable <ILispValue> .Equals(ILispValue other)
 {
     if (other == null)
     {
         return(false);
     }
     else if (other is String)
     {
         return(string.Equals(this.Value, ((String)other).Value));
     }
     else
     {
         return(false);
     }
 }
Example #11
0
        public static void EvaluatesTo(ILispValue expected, ILispValue expression, ILispEnvironment environment = null)
        {
            Assert.IsNotNull(expected);
            Assert.IsNotNull(expression);

            ILispValue actual = Evaluator.Evaluate(expression, environment ?? new GlobalEnvironment());

            if (!EqualityComparer <ILispValue> .Default.Equals(expected, actual))
            {
                throw new AssertFailedException(string.Format(
                                                    "Computed incorrect value while evaluating {1}.{0}Expected: {2}, Actual: {3}",
                                                    System.Environment.NewLine,
                                                    expression,
                                                    expected,
                                                    actual));
            }
        }
Example #12
0
        public void ProperListConstruction()
        {
            ILispValue helperConstructedList = Lisp.List(
                Lisp.Symbol("test"),
                Lisp.Constant(1),
                Lisp.Constant("foo"),
                Lisp.List(Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3)),
                Lisp.Constant(true));

            ILispValue manuallyConstructedList = new ConsBox
            {
                Head = Lisp.Symbol("test"),
                Tail = new ConsBox
                {
                    Head = Lisp.Constant(1),
                    Tail = new ConsBox
                    {
                        Head = Lisp.Constant("foo"),
                        Tail = new ConsBox
                        {
                            Head = new ConsBox
                            {
                                Head = Lisp.Constant(1),
                                Tail = new ConsBox
                                {
                                    Head = Lisp.Constant(2),
                                    Tail = new ConsBox
                                    {
                                        Head = Lisp.Constant(3),
                                        Tail = Nil.Instance
                                    }
                                }
                            },
                            Tail = new ConsBox
                            {
                                Head = Lisp.Constant(true),
                                Tail = Nil.Instance
                            }
                        }
                    }
                }
            };

            // Do not use Assert.AreEqual here since it doesn't use IEquatable.
            LispAssert.AreEqual(manuallyConstructedList, helperConstructedList);
        }
Example #13
0
        private static ILispValue EvaluateList(List list, ILispEnvironment environment)
        {
            if (list.IsEmpty)
            {
                return(list);
            }

            ILispValue         head       = list.GetHead();
            IList <ILispValue> parameters = list.CollectProperList().Skip(1).ToList();

            if (head.Type == LispValueType.Symbol)
            {
                // Look for special forms and process them, um..., specially.
                switch (((Symbol)head).Name)
                {
                case "quote":
                    return(EvaluateQuote(parameters, environment));

                case "if":
                    return(EvaluateIf(parameters, environment));

                case "progn":
                    return(EvaluateProgn(parameters, environment));

                case "set!":
                    return(EvaluateSet(parameters, environment));

                case "lambda":
                    return(EvaluateLambdaDefinition(parameters, environment));

                default:
                    return(EvaluateInvocation((Symbol)head, parameters, environment));
                }
            }
            else
            {
                head = Evaluate(head, environment);
                if (head.Type != LispValueType.Symbol)
                {
                    throw new TypeMismatchException(new Symbol("function"), LispValueType.Symbol, head.Type);
                }
                return(EvaluateInvocation((Symbol)head, parameters, environment));
            }
        }
Example #14
0
        public static ILispValue Evaluate(ILispValue value, ILispEnvironment environment)
        {
            switch (value.Type)
            {
            case LispValueType.Boolean:
            case LispValueType.Char:
            case LispValueType.Lambda:
            case LispValueType.Number:
            case LispValueType.String:
            default:
                return(value);

            case LispValueType.Symbol:
                return(environment.Lookup((Symbol)value));

            case LispValueType.List:
                return(EvaluateList((List)value, environment));
            }
        }
Example #15
0
        private static ILispValue EvaluateSet(IList <ILispValue> args, ILispEnvironment environment)
        {
            if (args.Count < 2)
            {
                throw new SignatureMismatchException("too few arguments supplied");
            }
            if (args.Count > 2)
            {
                throw new SignatureMismatchException("too many arguments supplied");
            }
            // this is a special form since we do not evaluate the first argument, which must be a symbol
            if (args[0].Type != LispValueType.Symbol)
            {
                throw new TypeMismatchException(new Symbol("variable"), LispValueType.Symbol, args[0].Type);
            }
            ILispValue value = Evaluate(args[1], environment);

            environment.Set((Symbol)args[0], value);
            return(value);
        }
Example #16
0
        private static ILispValue EvaluateIf(IList <ILispValue> args, ILispEnvironment environment)
        {
            if (args.Count < 3)
            {
                throw new SignatureMismatchException("too few arguments supplied");
            }
            if (args.Count > 3)
            {
                throw new SignatureMismatchException("too many arguments supplied");
            }
            ILispValue test = Evaluate(args[0], environment);

            switch (test.Type)
            {
            case LispValueType.Boolean:
                if (!((TiaLisp.Values.Boolean)test).Value)
                {
                    return(Evaluate(args[2], environment));
                }
                else
                {
                    return(Evaluate(args[1], environment));
                }

            case LispValueType.List:
                if (((List)test).IsEmpty)
                {
                    return(Evaluate(args[2], environment));
                }
                else
                {
                    return(Evaluate(args[1], environment));
                }

            default:
                // Any other value than #f or () is considered true:
                return(Evaluate(args[1], environment));
            }
        }
Example #17
0
 public static void ThrowsWhenEvaluated(ILispValue expression, ILispEnvironment environment = null)
 {
     ThrowsWhenEvaluated <LispException>(expression, environment);
 }
Example #18
0
 public void Set(Symbol name, ILispValue value)
 {
     _Variables[name] = value;
 }
Example #19
0
        private static Dictionary <string, ILispValue> BindParameters(ILispLambda lambda, IList <ILispValue> parameters)
        {
            Dictionary <string, ILispValue> bindings = new Dictionary <string, ILispValue>();

            Queue <ILispValue> actualParameters = new Queue <ILispValue>(parameters);

            foreach (LambdaParameter definedParameter in lambda.Parameters)
            {
                switch (definedParameter.ParameterType)
                {
                case LambdaParameterType.Normal:
                {
                    if (actualParameters.Count == 0)
                    {
                        throw new SignatureMismatchException("missing required argument: " + definedParameter.Name);
                    }
                    ILispValue value = actualParameters.Dequeue();
                    if (definedParameter.ValueType != LispValueType.Unknown && definedParameter.ValueType != value.Type)
                    {
                        throw new TypeMismatchException(definedParameter.Name, definedParameter.ValueType, value.Type);
                    }
                    bindings[definedParameter.Name.Name] = value;
                }
                break;

                case LambdaParameterType.Optional:
                {
                    if (actualParameters.Count > 0)
                    {
                        goto case LambdaParameterType.Normal;
                    }
                    switch (definedParameter.ValueType)
                    {
                    case LispValueType.Unknown:
                    case LispValueType.List:
                        bindings[definedParameter.Name.Name] = Nil.Instance;
                        break;

                    case LispValueType.Boolean:
                        bindings[definedParameter.Name.Name] = new TiaLisp.Values.Boolean(false);
                        break;

                    case LispValueType.String:
                        bindings[definedParameter.Name.Name] = new TiaLisp.Values.String(string.Empty);
                        break;

                    case LispValueType.Number:
                        bindings[definedParameter.Name.Name] = new Number(0);
                        break;

                    case LispValueType.Char:
                        bindings[definedParameter.Name.Name] = new Character(default(char));
                        break;

                    default:
                        throw new LispException("do not know how to construct a default value for type " + definedParameter.ValueType);
                    }
                }
                break;

                case LambdaParameterType.Rest:
                {
                    foreach (ILispValue actualParameter in actualParameters)
                    {
                        if (definedParameter.ValueType != LispValueType.Unknown && definedParameter.ValueType != actualParameter.Type)
                        {
                            throw new TypeMismatchException(definedParameter.Name, definedParameter.ValueType, actualParameter.Type);
                        }
                    }
                    bindings[definedParameter.Name.Name] = Lisp.List(actualParameters.ToArray());
                    actualParameters.Clear();
                }
                break;
                }
            }

            if (actualParameters.Count > 0)
            {
                throw new SignatureMismatchException("too many arguments supplied");
            }

            return(bindings);
        }
Example #20
0
 ILispValue execute(ILispValue a)
 {
     throw new NotImplementedException();
 }
Example #21
0
 public static List Quote(ILispValue value)
 {
     return(Lisp.List(Lisp.Symbol("quote"), value));
 }
Example #22
0
 public static ConsBox Cons(ILispValue head, ILispValue tail)
 {
     return(new ConsBox {
         Head = head, Tail = tail
     });
 }
Example #23
0
 bool IEquatable <ILispValue> .Equals(ILispValue other)
 {
     return(false);
 }
Example #24
0
 bool IEquatable <ILispValue> .Equals(ILispValue other)
 {
     return(object.ReferenceEquals(this, other));
 }
Example #25
0
 bool IEquatable <ILispValue> .Equals(ILispValue other)
 {
     // TODO: implement
     return(object.ReferenceEquals(this, other));
 }
Example #26
0
 public LispBoundValue(ILispValue val)
 {
     value = val;
 }
Example #27
0
        /// <summary>
        /// Parse the specified code using a specified registry and bank.
        /// </summary>
        /// <param name="data">The code to parse</param>
        /// <param name="registry">Registry of the context</param>
        /// <param name="bank">Bank of the context</param>
        public ILispValue parse(string data, Dictionary <string, ILispNative> registry, Dictionary <string, ILispValue> bank)
        {
            ParserState state = new ParserState();

            state.position = 0;
            state.data     = data + " ";
            state.root     = new List <ILispValue>();

            for (; state.position < state.data.Length; state.position++)
            {
                int  sign = 1;
                bool no_eval;
                switch (state.data [state.position])
                {
                case '\'':
                case '(':
                    if (state.data [state.position] == '\'')
                    {
                        no_eval = true;
                        state.position++;
                    }
                    else
                    {
                        no_eval = false;
                    }
                    var       n            = resolve_parenthesis(ref state);
                    string    child        = state.data.Substring(n.beg + 1, n.end - n.beg - 1);
                    LispArray tmp_insertee = (LispArray)parse(child, registry, bank);
                    tmp_insertee.force_eval = !no_eval;
                    state.root.Add(tmp_insertee);
                    state.position--;
                    break;

                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                case '.':
                case '-':
                    if (
                        Char.IsDigit(state.data [state.position]) ||
                        state.data [state.position] == '.' ||
                        (
                            Char.IsDigit(state.data [state.position + 1]) &&
                            state.data [state.position] == '-'
                        ))
                    {
                        if (state.data [state.position] == '-')
                        {
                            sign = -1;
                            state.position++;
                        }
                        ILispValue symn = resolve_numeric(ref state, sign);
                        state.root.Add(symn);
                        state.position--;
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case '"':
                    ILispValue symst = new LispString(resolve_string(ref state));
                    state.root.Add(symst);
                    break;

                case ' ':
                case '\t':
                case '\n':
                    break;

                default:
                    string syms = resolve_symbol(ref state);
                    if (syms != "")
                    {
                        state.root.Add(registry [syms]);
                        state.position--;
                    }
                    break;
                }
            }

            return(new LispArray(state.root));
        }