Permalink
Browse files

Big Richard update coming through.

Hey hey hey, it's that scripting system you asked for! (Closes #46) The
code is two fuzzy equality operators short of a war crime, but it's here!
Most parts of it have tests, including every part of the standard library.
The standard library is in RichardFunctions.cs, but most of it is just
list functions and math functions. There are a lot of math functions.

But no Pow function. I think I missed something.
  • Loading branch information...
cpancake committed Jun 25, 2015
1 parent 275a2ad commit 901be7f109701df7711586338d6b94e9d39f17e5
Showing with 4,002 additions and 542 deletions.
  1. +1 −0 Rant.Tests/ExpressionTests.playlist
  2. +56 −0 Rant.Tests/Expressions/Arithmetic.cs
  3. +16 −0 Rant.Tests/Expressions/Blocks.cs
  4. +34 −0 Rant.Tests/Expressions/ControlFlow.cs
  5. +52 −0 Rant.Tests/Expressions/Functions.cs
  6. +17 −0 Rant.Tests/Expressions/Invalid.cs
  7. +36 −0 Rant.Tests/Expressions/Lists.cs
  8. +16 −0 Rant.Tests/Expressions/StdLib/Console.cs
  9. +76 −0 Rant.Tests/Expressions/StdLib/Lists.cs
  10. +83 −0 Rant.Tests/Expressions/StdLib/Math.cs
  11. +16 −0 Rant.Tests/Expressions/StdLib/Strings.cs
  12. +16 −0 Rant.Tests/Expressions/StdLib/Type.cs
  13. +41 −0 Rant.Tests/Expressions/Strings.cs
  14. +17 −0 Rant.Tests/Rant.Tests.csproj
  15. +1 −0 Rant.Tests/packages.config
  16. +5 −1 Rant/Engine/Compiler/R.cs
  17. +7 −0 Rant/Engine/Compiler/RantCompiler.cs
  18. +547 −0 Rant/Engine/Compiler/RantExpressionCompiler.cs
  19. +134 −133 Rant/Engine/Compiler/RantLexer.cs
  20. +372 −350 Rant/Engine/Delegates/Witchcraft.cs
  21. +17 −1 Rant/Engine/ObjectModel/ObjectStack.cs
  22. +4 −4 Rant/Engine/ObjectModel/RantObject.cs
  23. +26 −22 Rant/Engine/RantFunctionInfo.cs
  24. +5 −1 Rant/Engine/RantParameterType.cs
  25. +727 −0 Rant/Engine/RichardFunctions.cs
  26. +87 −9 Rant/Engine/Sandbox.cs
  27. +17 −0 Rant/Engine/Syntax/Expressions/Operators/REAAdditionOperator.cs
  28. +44 −0 Rant/Engine/Syntax/Expressions/Operators/REAConcatOperator.cs
  29. +17 −0 Rant/Engine/Syntax/Expressions/Operators/READivisionOperator.cs
  30. +25 −0 Rant/Engine/Syntax/Expressions/Operators/REAEqualityOperator.cs
  31. +30 −0 Rant/Engine/Syntax/Expressions/Operators/REAGreaterThanOperator.cs
  32. +45 −0 Rant/Engine/Syntax/Expressions/Operators/REAInfixOperator.cs
  33. +30 −0 Rant/Engine/Syntax/Expressions/Operators/REALessThanOperator.cs
  34. +17 −0 Rant/Engine/Syntax/Expressions/Operators/REAMultiplicationOperator.cs
  35. +17 −0 Rant/Engine/Syntax/Expressions/Operators/REASubtractionOperator.cs
  36. +24 −0 Rant/Engine/Syntax/Expressions/REAArgumentSeperator.cs
  37. +31 −0 Rant/Engine/Syntax/Expressions/REABlock.cs
  38. +33 −0 Rant/Engine/Syntax/Expressions/REABoolean.cs
  39. +25 −0 Rant/Engine/Syntax/Expressions/REABreak.cs
  40. +30 −0 Rant/Engine/Syntax/Expressions/READummy.cs
  41. +65 −0 Rant/Engine/Syntax/Expressions/REAFor.cs
  42. +66 −0 Rant/Engine/Syntax/Expressions/REAFunction.cs
  43. +80 −0 Rant/Engine/Syntax/Expressions/REAFunctionCall.cs
  44. +32 −0 Rant/Engine/Syntax/Expressions/REAFunctionInfo.cs
  45. +67 −0 Rant/Engine/Syntax/Expressions/REAGroup.cs
  46. +38 −0 Rant/Engine/Syntax/Expressions/REAIfStatement.cs
  47. +64 −0 Rant/Engine/Syntax/Expressions/REAList.cs
  48. +25 −0 Rant/Engine/Syntax/Expressions/REAMaybe.cs
  49. +57 −0 Rant/Engine/Syntax/Expressions/REANativeFunction.cs
  50. +33 −0 Rant/Engine/Syntax/Expressions/REANumber.cs
  51. +42 −0 Rant/Engine/Syntax/Expressions/REAObject.cs
  52. +29 −0 Rant/Engine/Syntax/Expressions/REAObjectKeyValue.cs
  53. +81 −0 Rant/Engine/Syntax/Expressions/REAObjectProperty.cs
  54. +123 −0 Rant/Engine/Syntax/Expressions/REAObjectPropertyAssignment.cs
  55. +62 −0 Rant/Engine/Syntax/Expressions/REAPatternString.cs
  56. +33 −0 Rant/Engine/Syntax/Expressions/REAReturn.cs
  57. +33 −0 Rant/Engine/Syntax/Expressions/REAString.cs
  58. +32 −0 Rant/Engine/Syntax/Expressions/REAVariable.cs
  59. +40 −0 Rant/Engine/Syntax/Expressions/REAWhile.cs
  60. +31 −0 Rant/Engine/Syntax/Expressions/RantExpressionAction.cs
  61. +48 −0 Rant/Engine/Syntax/RAExpression.cs
  62. +21 −0 Rant/Engine/TokenReader.cs
  63. +28 −0 Rant/Engine/Util.cs
  64. +39 −0 Rant/Rant.csproj
  65. +1 −0 Rant/RantEngine.cs
  66. +13 −5 Rant/RantRuntimeException.cs
  67. +25 −16 Rant/Vocabulary/Rhymer.cs
@@ -0,0 +1 @@
<Playlist Version="1.0"><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathE" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListFill" /><Add Test="Rant.Tests.Expressions.Arithmetic.AssignmentOperators(&quot;0&quot;,&quot;-&quot;)" /><Add Test="Rant.Tests.Expressions.ControlFlow.WhileLoop" /><Add Test="Rant.Tests.Expressions.Strings.PatternStrings(&quot;&lt;noun&gt;&quot;)" /><Add Test="Rant.Tests.Expressions.Arithmetic.OrderOfOperations(&quot;2 + 2 / 2&quot;,&quot;3&quot;)" /><Add Test="Rant.Tests.Expressions.Lists.ListInitConcat" /><Add Test="Rant.Tests.Expressions.Arithmetic.BasicOperators(2,3,&quot;+&quot;,&quot;5&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;sqrt&quot;)" /><Add Test="Rant.Tests.Expressions.Arithmetic.AssignmentOperators(&quot;25&quot;,&quot;*&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;log&quot;)" /><Add Test="Rant.Tests.Expressions.Invalid.SemicolonRecursion" /><Add Test="Rant.Tests.Expressions.StdLib.Type.TypeGet" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;round&quot;)" /><Add Test="Rant.Tests.Expressions.Functions.BasicFunctionArgs" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;log10&quot;)" /><Add Test="Rant.Tests.Expressions.Arithmetic.AssignmentOperators(&quot;1&quot;,&quot;/&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathPI" /><Add Test="Rant.Tests.Expressions.Strings.Concatenation" /><Add Test="Rant.Tests.Expressions.ControlFlow.WhileLoopBreak" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;exp&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;sinh&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListJoin" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;asin&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;tan&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;tanh&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.Strings.StringLength" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;ceil&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListPopFront" /><Add Test="Rant.Tests.Expressions.Strings.PatternStringConcat" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListLength" /><Add Test="Rant.Tests.Expressions.Arithmetic.BasicOperators(4,2,&quot;*&quot;,&quot;8&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;acos&quot;)" /><Add Test="Rant.Tests.Expressions.Lists.ListInitBrackets" /><Add Test="Rant.Tests.Expressions.Strings.RegularStrings(&quot;&lt;noun&gt;&quot;)" /><Add Test="Rant.Tests.Expressions.Arithmetic.AssignmentOperators(&quot;10&quot;,&quot;+&quot;)" /><Add Test="Rant.Tests.Expressions.Strings.RegularStrings(&quot;test&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;cosh&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;cos&quot;)" /><Add Test="Rant.Tests.Expressions.Arithmetic.VariableAssignment" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListInsert" /><Add Test="Rant.Tests.Expressions.Functions.LambdaEndExpression" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListPushFront" /><Add Test="Rant.Tests.Expressions.Functions.LambdaFunctionArgs" /><Add Test="Rant.Tests.Expressions.Functions.LambdaFunction" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListRemove" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;floor&quot;)" /><Add Test="Rant.Tests.Expressions.Arithmetic.VarVariableScoping" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListReverse" /><Add Test="Rant.Tests.Expressions.StdLib.Console.ConsolePrint" /><Add Test="Rant.Tests.Expressions.Arithmetic.VariableScoping" /><Add Test="Rant.Tests.Expressions.Arithmetic.BasicOperators(8,4,&quot;/&quot;,&quot;2&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListCopy" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListPush" /><Add Test="Rant.Tests.Expressions.Functions.ReturnValue" /><Add Test="Rant.Tests.Expressions.ControlFlow.ForLoop" /><Add Test="Rant.Tests.Expressions.Lists.ListInitBare" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMod" /><Add Test="Rant.Tests.Expressions.Arithmetic.BasicOperators(5,1,&quot;-&quot;,&quot;4&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathAtan2" /><Add Test="Rant.Tests.Expressions.Arithmetic.OrderOfOperations(&quot;(2 + 2) / 2&quot;,&quot;2&quot;)" /><Add Test="Rant.Tests.Expressions.Functions.MultipleArgs" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;atan&quot;)" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;sin&quot;)" /><Add Test="Rant.Tests.Expressions.Blocks.MultipleLines" /><Add Test="Rant.Tests.Expressions.StdLib.StdMath.MathMethods(&quot;truncate&quot;)" /><Add Test="Rant.Tests.Expressions.ControlFlow.IfStatement" /><Add Test="Rant.Tests.Expressions.StdLib.Lists.ListPop" /><Add Test="Rant.Tests.Expressions.Functions.BasicFunction" /><Add Test="Rant.Tests.Expressions.Lists.ListAsBlock" /></Playlist>
@@ -0,0 +1,56 @@
using NUnit.Framework;
namespace Rant.Tests.Expressions
{
[TestFixture]
public class Arithmetic
{
private readonly RantEngine rant = new RantEngine();
[Test]
[TestCase(2, 3, "+", "5")]
[TestCase(5, 1, "-", "4")]
[TestCase(4, 2, "*", "8")]
[TestCase(8, 4, "/", "2")]
public void BasicOperators(int a, int b, string op, string result)
{
Assert.AreEqual(result, rant.Do($"[@ {a} {op} {b} ]").Main);
}
[Test]
[TestCase("2 + 2 / 2", "3")]
[TestCase("(2 + 2) / 2", "2")]
public void OrderOfOperations(string expr, string result)
{
Assert.AreEqual(result, rant.Do($"[@ {expr} ]").Main);
}
[Test]
public void VariableAssignment()
{
Assert.AreEqual("2", rant.Do("[@ x = 2; x ]").Main);
}
[Test]
public void VariableScoping()
{
Assert.AreEqual("no", rant.Do("[@ { x = 4; } x ]").Main);
}
[Test]
public void VarVariableScoping()
{
Assert.AreEqual("4", rant.Do("[@ var x; { x = 4; }; x ]").Main);
}
[Test]
[TestCase("10", "+")]
[TestCase("0", "-")]
[TestCase("25", "*")]
[TestCase("1", "/")]
public void AssignmentOperators(string result, string op)
{
Assert.AreEqual(result, rant.Do($"[@ x = 5; x {op}= 5; x ]").Main);
}
}
}
@@ -0,0 +1,16 @@
using NUnit.Framework;
namespace Rant.Tests.Expressions
{
[TestFixture]
public class Blocks
{
private readonly RantEngine rant = new RantEngine();
[Test]
public void MultipleLines()
{
Assert.AreEqual("2", rant.Do("[@ { 4; 2 } ]").Main);
}
}
}
@@ -0,0 +1,34 @@
using NUnit.Framework;
namespace Rant.Tests.Expressions
{
[TestFixture]
public class ControlFlow
{
private readonly RantEngine rant = new RantEngine();
[Test]
public void IfStatement()
{
Assert.AreEqual("2", rant.Do("[@ if(yes) 2 ]").Main);
}
[Test]
public void WhileLoop()
{
Assert.AreEqual("4", rant.Do("[@ x = 10; while(x > 4) { x -= 1; } x]").Main);
}
[Test]
public void WhileLoopBreak()
{
Assert.AreEqual("6", rant.Do("[@ x = 10; while(x > 2) { if(x <= 6) break; x -= 1; } x]").Main);
}
[Test]
public void ForLoop()
{
Assert.AreEqual("01234", rant.Do("[@ x = list 5; for(var i in x) Console.print(i); ]").Main);
}
}
}
@@ -0,0 +1,52 @@
using NUnit.Framework;
namespace Rant.Tests.Expressions
{
[TestFixture]
public class Functions
{
private readonly RantEngine rant = new RantEngine();
[Test]
public void BasicFunction()
{
Assert.AreEqual("2", rant.Do("[@ x = function() { 2 }; x() ]").Main);
}
[Test]
public void BasicFunctionArgs()
{
Assert.AreEqual("2", rant.Do("[@ x = function(a) { a }; x(2) ]").Main);
}
[Test]
public void LambdaFunction()
{
Assert.AreEqual("2", rant.Do("[@ x = () => 2; x() ]").Main);
}
[Test]
public void LambdaFunctionArgs()
{
Assert.AreEqual("2", rant.Do("[@ x = (a) => a; x(2) ]").Main);
}
[Test]
public void LambdaEndExpression()
{
Assert.AreEqual("2", rant.Do("[@ x = () => 2 ][@ x() ]").Main);
}
[Test]
public void ReturnValue()
{
Assert.AreEqual("4", rant.Do("[@ x = function() { return 4; 2 }; x() ]").Main);
}
[Test]
public void MultipleArgs()
{
Assert.AreEqual("8", rant.Do("[@ x = function(a, b) { a - b; }; x(10, 2) ]").Main);
}
}
}
@@ -0,0 +1,17 @@
using NUnit.Framework;
namespace Rant.Tests.Expressions
{
public class Invalid
{
private readonly RantEngine rant = new RantEngine();
[Test]
// this was causing a huge amount of recursion for some reason
public void SemicolonRecursion()
{
rant.Do(@"[@ test = 1; test; ]");
Assert.Pass();
}
}
}
@@ -0,0 +1,36 @@
using NUnit.Framework;
using System.Linq;
namespace Rant.Tests.Expressions
{
[TestFixture]
public class Lists
{
private readonly RantEngine rant = new RantEngine();
[Test]
public void ListInitBare()
{
Assert.AreEqual("5", rant.Do("[@ x = 1, 2, 3, 4, 5; x.length ]").Main);
}
[Test]
public void ListInitBrackets()
{
Assert.AreEqual("5", rant.Do("[@ x = [1, 2, 3, 4, 5]; x.length ]").Main);
}
[Test]
public void ListInitConcat()
{
Assert.AreEqual("5", rant.Do("[@ x = 1, 2, 3; y = x, 4, 5; y.length ]").Main);
}
[Test]
public void ListAsBlock()
{
string[] possibleResults = new string[] { "1", "2", "3", "4" };
Assert.GreaterOrEqual(possibleResults.ToList().IndexOf(rant.Do("[@ x = 1, 2, 3, 4; x ]").Main), 0);
}
}
}
@@ -0,0 +1,16 @@
using NUnit.Framework;
namespace Rant.Tests.Expressions.StdLib
{
[TestFixture]
public class Console
{
private readonly RantEngine rant = new RantEngine();
[Test]
public void ConsolePrint()
{
Assert.AreEqual("test string", rant.Do("[@ Console.print(\"test string\") ]").Main);
}
}
}
@@ -0,0 +1,76 @@
using NUnit.Framework;
namespace Rant.Tests.Expressions.StdLib
{
[TestFixture]
public class Lists
{
private readonly RantEngine rant = new RantEngine();
[Test]
public void ListLength()
{
Assert.AreEqual("4", rant.Do("[@ var x = 1, 2, 3, 4; x.length ]").Main);
}
[Test]
public void ListPush()
{
Assert.AreEqual("5", rant.Do("[@ var x = 1, 2, 3, 4; x.push(5); x[4] ]").Main);
}
[Test]
public void ListPop()
{
Assert.AreEqual("4", rant.Do("[@ var x = 1, 2, 3, 4, 5; x.pop(); x.length ]").Main);
}
[Test]
public void ListPopFront()
{
Assert.AreEqual("1", rant.Do("[@ var x = 1, 2, 3, 4, 5; x.popFront() ]").Main);
}
[Test]
public void ListPushFront()
{
Assert.AreEqual("0", rant.Do("[@ var x = 1, 2, 3, 4, 5; x.pushFront(0); x[0] ]").Main);
}
[Test]
public void ListCopy()
{
Assert.AreEqual("5", rant.Do("[@ var x = 1, 2, 3, 4, 5; var y = x.copy(); x.pop(); y.length ]").Main);
}
[Test]
public void ListFill()
{
Assert.AreEqual("8", rant.Do("[@ var x = list 12; x.fill(8); x[4] ]").Main);
}
[Test]
public void ListReverse()
{
Assert.AreEqual("5", rant.Do("[@ var x = 1, 2, 3, 4, 5; x.reverse(); x[0] ]").Main);
}
[Test]
public void ListJoin()
{
Assert.AreEqual("1,2,3,4,5", rant.Do("[@ var x = 1, 2, 3, 4, 5; x.join(\",\") ]").Main);
}
[Test]
public void ListInsert()
{
Assert.AreEqual("4", rant.Do("[@ var x = 1, 2, 3, 5; x.insert(4, 3); x[3] ]").Main);
}
[Test]
public void ListRemove()
{
Assert.AreEqual("4", rant.Do("[@ var x = 1, 2, 3, 4, 5; x.remove(3); x.length ]").Main);
}
}
}
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
namespace Rant.Tests.Expressions.StdLib
{
[TestFixture]
public class StdMath
{
private readonly RantEngine rant = new RantEngine();
[Test]
public void MathPI()
{
Assert.AreEqual(Math.PI.ToString(), rant.Do("[@ Math.PI ]").Main);
}
[Test]
public void MathE()
{
Assert.AreEqual(Math.E.ToString(), rant.Do("[@ Math.E ]").Main);
}
[Test]
public void MathAtan2()
{
Assert.AreEqual(Math.Atan2(1, 4).ToString(), rant.Do("[@ Math.atan2(1, 4) ]").Main);
}
[Test]
public void MathMod()
{
Assert.AreEqual((5 % 2).ToString(), rant.Do("[@ Math.mod(5, 2) ]").Main);
}
private static readonly Dictionary<string, Func<double, double>> testCases =
new Dictionary<string, Func<double, double>>()
{
{ "acos", Math.Acos },
{ "asin", Math.Asin },
{ "atan", Math.Atan },
{ "ceil", Math.Ceiling },
{ "cos", Math.Cos },
{ "cosh", Math.Cosh },
{ "exp", Math.Exp },
{ "floor", Math.Floor },
{ "log", Math.Log },
{ "log10", Math.Log10 },
{ "round", Math.Round },
{ "sin", Math.Sin },
{ "sinh", Math.Sinh },
{ "sqrt", Math.Sqrt },
{ "tan", Math.Tan },
{ "tanh", Math.Tanh },
{ "truncate", Math.Truncate }
};
[Test]
[TestCase("acos")]
[TestCase("asin")]
[TestCase("atan")]
[TestCase("ceil")]
[TestCase("cos")]
[TestCase("cosh")]
[TestCase("exp")]
[TestCase("floor")]
[TestCase("log")]
[TestCase("log10")]
[TestCase("round")]
[TestCase("sin")]
[TestCase("sinh")]
[TestCase("sqrt")]
[TestCase("tan")]
[TestCase("tanh")]
[TestCase("truncate")]
public void MathMethods(string action)
{
var method = testCases[action];
var result = method(1.5);
Assert.AreEqual(result.ToString(), rant.Do($"[@ Math.{action}(1.5) ]").Main);
}
}
}
Oops, something went wrong.

0 comments on commit 901be7f

Please sign in to comment.