public void If() { ILispEnvironment environment = new GlobalEnvironment(); environment.Set(new Symbol("kablooey"), new NativeLambda { Body = parameters => { throw new LispException("kablooey!"); } }); // Ensure only the "then" clause is evaluated on a true condition. LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("if"), Lisp.Constant(true), Lisp.Constant(1), Lisp.List(Lisp.Symbol("kablooey"))), environment); LispAssert.ThrowsWhenEvaluated( Lisp.List(Lisp.Symbol("if"), Lisp.Constant(true), Lisp.List(Lisp.Symbol("kablooey")), Lisp.Constant(1)), environment); // Ensure only the "else" clause is evaluated on a false condition. LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("if"), Lisp.Constant(false), Lisp.List(Lisp.Symbol("kablooey")), Lisp.Constant(1)), environment); LispAssert.ThrowsWhenEvaluated( Lisp.List(Lisp.Symbol("if"), Lisp.Constant(false), Lisp.Constant(1), Lisp.List(Lisp.Symbol("kablooey"))), environment); // Ensure the test condition clause is evaluated. In this case, a non-empty list would be true if not // evaluated, but evaluating the expression will produce false. LispAssert.EvaluatesTo(Lisp.Constant(2), Lisp.List(Lisp.Symbol("if"), Lisp.List(Lisp.Symbol("number?"), Lisp.Symbol("car")), Lisp.Constant(1), Lisp.Constant(2))); // Test truth / falsiness of non-boolean - only #f and () should count as false. LispAssert.EvaluatesTo(Lisp.Constant(2), Lisp.List(Lisp.Symbol("if"), Lisp.Nil, Lisp.Constant(1), Lisp.Constant(2))); LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("if"), Lisp.Quote(Lisp.List(Lisp.Constant(false))), Lisp.Constant(1), Lisp.Constant(2))); LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("if"), Lisp.Constant(""), Lisp.Constant(1), Lisp.Constant(2))); LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("if"), Lisp.Symbol("cdr"), Lisp.Constant(1), Lisp.Constant(2))); }
public void StringLength() { LispAssert.EvaluatesTo(Lisp.Constant(4), Lisp.List(Lisp.Symbol("string-length"), Lisp.Constant("test"))); LispAssert.EvaluatesTo(Lisp.Constant(0), Lisp.List(Lisp.Symbol("string-length"), Lisp.Constant(""))); }
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()); }
public void StringToList() { LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant('t'), Lisp.Constant('e'), Lisp.Constant('s'), Lisp.Constant('t')), Lisp.List(Lisp.Symbol("string->list"), Lisp.Constant("test"))); LispAssert.EvaluatesTo(Lisp.Nil, Lisp.List(Lisp.Symbol("string->list"), Lisp.Constant(""))); }
public void ListToString() { LispAssert.EvaluatesTo(Lisp.Constant("test"), Lisp.List(Lisp.Symbol("list->string"), Lisp.Quote(Lisp.List(Lisp.Constant('t'), Lisp.Constant('e'), Lisp.Constant('s'), Lisp.Constant('t'))))); LispAssert.EvaluatesTo(Lisp.Constant(""), Lisp.List(Lisp.Symbol("list->string"), Lisp.Nil)); }
public void MakeString() { LispAssert.EvaluatesTo(Lisp.Constant("xxxxxxxxxx"), Lisp.List(Lisp.Symbol("make-string"), Lisp.Constant(10), Lisp.Constant('x'))); LispAssert.ThrowsWhenEvaluated( Lisp.List(Lisp.Symbol("make-string"), Lisp.Constant(9.3m), Lisp.Constant('x'))); LispAssert.EvaluatesTo(Lisp.Constant(8), Lisp.List(Lisp.Symbol("string-length"), Lisp.List(Lisp.Symbol("make-string"), Lisp.Constant(8)))); }
public void List() { LispAssert.EvaluatesTo(Lisp.Nil, Lisp.List(Lisp.Symbol("list"))); LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant(1)), Lisp.List(Lisp.Symbol("list"), Lisp.Constant(1))); LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant(1), Lisp.Constant(2)), Lisp.List(Lisp.Symbol("list"), Lisp.Constant(1), Lisp.Constant(2))); }
public void Cons() { LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant(1)), Lisp.List(Lisp.Symbol("cons"), Lisp.Constant(1), Lisp.Nil)); LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant(1), Lisp.Constant(2)), Lisp.List(Lisp.Symbol("cons"), Lisp.Constant(1), Lisp.Quote(Lisp.List(Lisp.Constant(2))))); LispAssert.EvaluatesTo(Lisp.Cons(Lisp.Constant(1), Lisp.Constant(2)), Lisp.List(Lisp.Symbol("cons"), Lisp.Constant(1), Lisp.Constant(2))); }
public void StringP() { LispAssert.EvaluatesTo(Lisp.Constant(true), Lisp.List(Lisp.Symbol("string?"), Lisp.Constant("test"))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("string?"), Lisp.Constant(true))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("string?"), Lisp.Constant('x'))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("string?"), Nil.Instance)); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("string?"), Lisp.Constant(5))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("string?"), Lisp.Quote(Lisp.Symbol("test")))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("string?"), new UndefinedValue())); }
public void Length() { LispAssert.EvaluatesTo(Lisp.Constant(0), Lisp.List(Lisp.Symbol("length"), Lisp.Nil)); LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("length"), Lisp.Quote(Lisp.List(Lisp.Constant(1))))); LispAssert.EvaluatesTo(Lisp.Constant(2), Lisp.List(Lisp.Symbol("length"), Lisp.Quote(Lisp.List(Lisp.Constant(1), Lisp.Constant(2))))); LispAssert.EvaluatesTo(Lisp.Constant(5), Lisp.List(Lisp.Symbol("length"), Lisp.Quote(Lisp.List(Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3), Lisp.Constant(4), Lisp.Constant(5))))); }
public void Reverse() { LispAssert.EvaluatesTo(Lisp.Nil, Lisp.List(Lisp.Symbol("reverse"), Lisp.Nil)); LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant(1)), Lisp.List(Lisp.Symbol("reverse"), Lisp.Quote(Lisp.List(Lisp.Constant(1))))); LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant(2), Lisp.Constant(1)), Lisp.List(Lisp.Symbol("reverse"), Lisp.Quote(Lisp.List(Lisp.Constant(1), Lisp.Constant(2))))); LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant(5), Lisp.Constant(4), Lisp.Constant(3), Lisp.Constant(2), Lisp.Constant(1)), Lisp.List(Lisp.Symbol("reverse"), Lisp.Quote(Lisp.List(Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3), Lisp.Constant(4), Lisp.Constant(5))))); }
public void ListP() { LispAssert.EvaluatesTo(Lisp.Constant(true), Lisp.List(Lisp.Symbol("list?"), Lisp.Nil)); LispAssert.EvaluatesTo(Lisp.Constant(true), Lisp.List(Lisp.Symbol("list?"), Lisp.Quote(Lisp.List(Lisp.Constant(1), Lisp.Symbol("a"))))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("list?"), Lisp.Constant(true))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("list?"), Lisp.Constant('x'))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("list?"), Lisp.Constant(5))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("list?"), Lisp.Constant("test"))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("list?"), Lisp.Quote(Lisp.Symbol("test")))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("list?"), new UndefinedValue())); }
public void NumberP() { LispAssert.EvaluatesTo(Lisp.Constant(true), Lisp.List(Lisp.Symbol("number?"), Lisp.Constant(5))); LispAssert.EvaluatesTo(Lisp.Constant(true), Lisp.List(Lisp.Symbol("number?"), Lisp.Constant(9.95m))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("number?"), Lisp.Constant(true))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("number?"), Lisp.Constant('x'))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("number?"), Nil.Instance)); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("number?"), Lisp.Constant("test"))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("number?"), Lisp.Quote(Lisp.Symbol("test")))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("number?"), new UndefinedValue())); }
public void StringRef() { LispAssert.EvaluatesTo(Lisp.Constant('t'), Lisp.List(Lisp.Symbol("string-ref"), Lisp.Constant("test"), Lisp.Constant(0))); LispAssert.EvaluatesTo(Lisp.Constant('s'), Lisp.List(Lisp.Symbol("string-ref"), Lisp.Constant("test test test"), Lisp.Constant(12))); LispAssert.ThrowsWhenEvaluated( Lisp.List(Lisp.Symbol("string-ref"), Lisp.Constant("test"), Lisp.Constant(-1))); LispAssert.ThrowsWhenEvaluated( Lisp.List(Lisp.Symbol("string-ref"), Lisp.Constant("test"), Lisp.Constant(4))); LispAssert.ThrowsWhenEvaluated( Lisp.List(Lisp.Symbol("string-ref"), Lisp.Constant("test"), Lisp.Constant(2.2m))); }
public void LambdaP() { LispAssert.EvaluatesTo(Lisp.Constant(true), Lisp.List(Lisp.Symbol("lambda?"), Lisp.Symbol("lambda?"))); // TODO: add test for user-defined function LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("lambda?"), Lisp.Constant(true))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("lambda?"), Lisp.Constant('x'))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("lambda?"), Nil.Instance)); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("lambda?"), Lisp.Constant(5))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("lambda?"), Lisp.Constant("test"))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("lambda?"), Lisp.Quote(Lisp.Symbol("test")))); LispAssert.EvaluatesTo(Lisp.Constant(false), Lisp.List(Lisp.Symbol("lambda?"), new UndefinedValue())); }
public void Cdr() { LispAssert.EvaluatesTo(Lisp.List(Lisp.Constant(2), Lisp.Constant(3)), Lisp.List(Lisp.Symbol("cdr"), Lisp.Quote(Lisp.List(Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3))))); LispAssert.EvaluatesTo(Lisp.Nil, Lisp.List(Lisp.Symbol("cdr"), Lisp.Quote(Lisp.List(Lisp.Constant(1))))); LispAssert.EvaluatesTo(Lisp.Constant(2), Lisp.List(Lisp.Symbol("cdr"), Lisp.Quote(Lisp.Cons(Lisp.Constant(1), Lisp.Constant(2))))); LispAssert.ThrowsWhenEvaluated(Lisp.List(Lisp.Symbol("cdr"), Lisp.Nil)); LispAssert.ThrowsWhenEvaluated <TypeMismatchException>(Lisp.List(Lisp.Symbol("cdr"), Lisp.Constant(3))); LispAssert.ThrowsWhenEvaluated <SignatureMismatchException>(Lisp.List(Lisp.Symbol("cdr"))); }
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); }
public void Add() { LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("+"), Lisp.Constant(1))); LispAssert.EvaluatesTo(Lisp.Constant(3), Lisp.List(Lisp.Symbol("+"), Lisp.Constant(1), Lisp.Constant(2))); LispAssert.EvaluatesTo(Lisp.Constant(6), Lisp.List(Lisp.Symbol("+"), Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3))); LispAssert.EvaluatesTo(Lisp.Constant(6.3m), Lisp.List(Lisp.Symbol("+"), Lisp.Constant(1.1m), Lisp.Constant(2.1m), Lisp.Constant(3.1m))); LispAssert.EvaluatesTo(Lisp.Constant(6.1m), Lisp.List(Lisp.Symbol("+"), Lisp.Constant(1.1m), Lisp.Constant(2), Lisp.Constant(3))); LispAssert.EvaluatesTo(Lisp.Constant(6.1m), Lisp.List(Lisp.Symbol("+"), Lisp.Constant(1), Lisp.Constant(2.1m), Lisp.Constant(3))); LispAssert.EvaluatesTo(Lisp.Constant(6.1m), Lisp.List(Lisp.Symbol("+"), Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3.1m))); }
public void Subtract() { LispAssert.EvaluatesTo(Lisp.Constant(-1), Lisp.List(Lisp.Symbol("-"), Lisp.Constant(1))); LispAssert.EvaluatesTo(Lisp.Constant(-1), Lisp.List(Lisp.Symbol("-"), Lisp.Constant(1), Lisp.Constant(2))); LispAssert.EvaluatesTo(Lisp.Constant(-4), Lisp.List(Lisp.Symbol("-"), Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3))); LispAssert.EvaluatesTo(Lisp.Constant(-0.1m), Lisp.List(Lisp.Symbol("-"), Lisp.Constant(3.1m), Lisp.Constant(2.1m), Lisp.Constant(1.1m))); LispAssert.EvaluatesTo(Lisp.Constant(0.1m), Lisp.List(Lisp.Symbol("-"), Lisp.Constant(3.1m), Lisp.Constant(2), Lisp.Constant(1))); LispAssert.EvaluatesTo(Lisp.Constant(-0.1m), Lisp.List(Lisp.Symbol("-"), Lisp.Constant(3), Lisp.Constant(2.1m), Lisp.Constant(1))); LispAssert.EvaluatesTo(Lisp.Constant(-0.1m), Lisp.List(Lisp.Symbol("-"), Lisp.Constant(3), Lisp.Constant(2), Lisp.Constant(1.1m))); }
public void Divide() { LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("/"), Lisp.Constant(1))); LispAssert.EvaluatesTo(Lisp.Constant(0.5m), Lisp.List(Lisp.Symbol("/"), Lisp.Constant(1), Lisp.Constant(2))); LispAssert.EvaluatesTo(Lisp.Constant(1m / 2m / 3m), Lisp.List(Lisp.Symbol("/"), Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3))); LispAssert.EvaluatesTo(Lisp.Constant(1m / 2m / 3m / 4m), Lisp.List(Lisp.Symbol("/"), Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3), Lisp.Constant(4))); LispAssert.EvaluatesTo(Lisp.Constant(3.1m / 2.1m / 1.1m), Lisp.List(Lisp.Symbol("/"), Lisp.Constant(3.1m), Lisp.Constant(2.1m), Lisp.Constant(1.1m))); LispAssert.EvaluatesTo(Lisp.Constant(2.1m / 3m / 4m), Lisp.List(Lisp.Symbol("/"), Lisp.Constant(2.1m), Lisp.Constant(3), Lisp.Constant(4))); LispAssert.EvaluatesTo(Lisp.Constant(2m / 3.1m / 4m), Lisp.List(Lisp.Symbol("/"), Lisp.Constant(2), Lisp.Constant(3.1m), Lisp.Constant(4))); LispAssert.EvaluatesTo(Lisp.Constant(2m / 3m / 4.1m), Lisp.List(Lisp.Symbol("/"), Lisp.Constant(2), Lisp.Constant(3), Lisp.Constant(4.1m))); }
public void Multiply() { LispAssert.EvaluatesTo(Lisp.Constant(1), Lisp.List(Lisp.Symbol("*"), Lisp.Constant(1))); LispAssert.EvaluatesTo(Lisp.Constant(2), Lisp.List(Lisp.Symbol("*"), Lisp.Constant(1), Lisp.Constant(2))); LispAssert.EvaluatesTo(Lisp.Constant(6), Lisp.List(Lisp.Symbol("*"), Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3))); LispAssert.EvaluatesTo(Lisp.Constant(24), Lisp.List(Lisp.Symbol("*"), Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3), Lisp.Constant(4))); LispAssert.EvaluatesTo(Lisp.Constant(3.1m * 2.1m * 1.1m), Lisp.List(Lisp.Symbol("*"), Lisp.Constant(3.1m), Lisp.Constant(2.1m), Lisp.Constant(1.1m))); LispAssert.EvaluatesTo(Lisp.Constant(2.1m * 3 * 4), Lisp.List(Lisp.Symbol("*"), Lisp.Constant(2.1m), Lisp.Constant(3), Lisp.Constant(4))); LispAssert.EvaluatesTo(Lisp.Constant(2 * 3.1m * 4), Lisp.List(Lisp.Symbol("*"), Lisp.Constant(2), Lisp.Constant(3.1m), Lisp.Constant(4))); LispAssert.EvaluatesTo(Lisp.Constant(2 * 3 * 4.1m), Lisp.List(Lisp.Symbol("*"), Lisp.Constant(2), Lisp.Constant(3), Lisp.Constant(4.1m))); }
public void MixedImproperListToString() { ConsBox improperList = new ConsBox { Head = Lisp.Symbol("test"), Tail = new ConsBox { Head = Lisp.Constant(1), Tail = new ConsBox { Head = Lisp.Constant("foo"), Tail = new ConsBox { Head = Lisp.List(Lisp.Constant(1), Lisp.Constant(2), Lisp.Constant(3)), Tail = Lisp.Constant(true) } } } }; Assert.AreEqual("(test 1 \"foo\" (1 2 3) . #t)", improperList.ToString()); }
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); }
public void Quote() { LispAssert.EvaluatesTo(Lisp.List(Lisp.Symbol("car"), Lisp.Nil), Lisp.Quote(Lisp.List(Lisp.Symbol("car"), Lisp.Nil))); }