From a631d3b3773e43d8c2a1c871065fafcba4543472 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 17 Nov 2018 12:40:28 +0100 Subject: [PATCH] Make LuaTypes internal, and only return the actual values --- Upsilon.sln | 6 -- Upsilon/BaseTypes/LuaBoolean.cs | 7 ++- Upsilon/BaseTypes/LuaFunction.cs | 6 +- Upsilon/BaseTypes/LuaNull.cs | 6 +- Upsilon/BaseTypes/LuaType.cs | 3 +- Upsilon/BaseTypes/Number/Number.cs | 2 +- Upsilon/BaseTypes/Number/NumberDouble.cs | 6 +- Upsilon/BaseTypes/Number/NumberLong.cs | 7 ++- Upsilon/BaseTypes/TypeConversion.cs | 2 +- Upsilon/Binder/Binder.cs | 48 +++++++-------- .../BoundLiteralExpression.cs | 2 +- Upsilon/Binder/BoundScope.cs | 2 +- Upsilon/Evaluator/EvaluationScope.cs | 2 +- Upsilon/Evaluator/Evaluator.cs | 4 +- Upsilon/Evaluator/Script.cs | 60 +++++++++++++++---- UpsilonTests/BasicMathExpressions.cs | 18 +++--- UpsilonTests/FunctionTests.cs | 55 ++++++++--------- UpsilonTests/IfTests.cs | 6 +- UpsilonTests/MathPrecedence.cs | 4 +- UpsilonTests/ScopeTests.cs | 8 +-- Ycicle/Program.cs | 19 +++--- 21 files changed, 159 insertions(+), 114 deletions(-) diff --git a/Upsilon.sln b/Upsilon.sln index 8106d0d..fc27262 100644 --- a/Upsilon.sln +++ b/Upsilon.sln @@ -6,8 +6,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ycicle", "Ycicle\Ycicle.csp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpsilonTests", "UpsilonTests\UpsilonTests.csproj", "{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpsilonCompiler", "UpsilonCompiler\UpsilonCompiler.csproj", "{BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -26,9 +24,5 @@ Global {5CB3C59D-96A1-419E-803B-DE4A7DF806FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {5CB3C59D-96A1-419E-803B-DE4A7DF806FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {5CB3C59D-96A1-419E-803B-DE4A7DF806FD}.Release|Any CPU.Build.0 = Release|Any CPU - {BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Upsilon/BaseTypes/LuaBoolean.cs b/Upsilon/BaseTypes/LuaBoolean.cs index d9bd3a6..d654904 100644 --- a/Upsilon/BaseTypes/LuaBoolean.cs +++ b/Upsilon/BaseTypes/LuaBoolean.cs @@ -1,6 +1,6 @@ namespace Upsilon.BaseTypes { - public class LuaBoolean : LuaType + internal class LuaBoolean : LuaType { public LuaBoolean(bool value) { @@ -8,6 +8,11 @@ namespace Upsilon.BaseTypes } public override Type Type => Type.Boolean; + public override object ToCSharpObject() + { + return Value; + } + public bool Value { get; } public static implicit operator bool(LuaBoolean b) diff --git a/Upsilon/BaseTypes/LuaFunction.cs b/Upsilon/BaseTypes/LuaFunction.cs index 7630ea6..3456276 100644 --- a/Upsilon/BaseTypes/LuaFunction.cs +++ b/Upsilon/BaseTypes/LuaFunction.cs @@ -3,7 +3,7 @@ using Upsilon.Binder; namespace Upsilon.BaseTypes { - public class LuaFunction : LuaType + internal class LuaFunction : LuaType { public LuaFunction(ImmutableArray parameters, BoundBlockStatement block) { @@ -12,6 +12,10 @@ namespace Upsilon.BaseTypes } public override Type Type => Type.Function; + public override object ToCSharpObject() + { + return Block; + } public ImmutableArray Parameters { get; } public BoundBlockStatement Block { get; } diff --git a/Upsilon/BaseTypes/LuaNull.cs b/Upsilon/BaseTypes/LuaNull.cs index 82637c5..4ce1ec6 100644 --- a/Upsilon/BaseTypes/LuaNull.cs +++ b/Upsilon/BaseTypes/LuaNull.cs @@ -1,8 +1,12 @@ namespace Upsilon.BaseTypes { - public class LuaNull : LuaType + internal class LuaNull : LuaType { public override Type Type => Type.Nil; + public override object ToCSharpObject() + { + return null; + } public override string ToString() { diff --git a/Upsilon/BaseTypes/LuaType.cs b/Upsilon/BaseTypes/LuaType.cs index 5298f9b..f76791e 100644 --- a/Upsilon/BaseTypes/LuaType.cs +++ b/Upsilon/BaseTypes/LuaType.cs @@ -1,7 +1,8 @@ namespace Upsilon.BaseTypes { - public abstract class LuaType + internal abstract class LuaType { public abstract Type Type { get; } + public abstract object ToCSharpObject(); } } \ No newline at end of file diff --git a/Upsilon/BaseTypes/Number/Number.cs b/Upsilon/BaseTypes/Number/Number.cs index fc92c45..ca537e3 100644 --- a/Upsilon/BaseTypes/Number/Number.cs +++ b/Upsilon/BaseTypes/Number/Number.cs @@ -1,6 +1,6 @@ namespace Upsilon.BaseTypes.Number { - public abstract class Number : LuaType + internal abstract class Number : LuaType { protected abstract bool IsFloat { get; } diff --git a/Upsilon/BaseTypes/Number/NumberDouble.cs b/Upsilon/BaseTypes/Number/NumberDouble.cs index 86187d7..a9d29f9 100644 --- a/Upsilon/BaseTypes/Number/NumberDouble.cs +++ b/Upsilon/BaseTypes/Number/NumberDouble.cs @@ -2,7 +2,7 @@ using System.Globalization; namespace Upsilon.BaseTypes.Number { - public class NumberDouble : Number + internal class NumberDouble : Number { public double Value { get; } protected override bool IsFloat { get; } = true; @@ -27,5 +27,9 @@ namespace Upsilon.BaseTypes.Number return n.Value; } + public override object ToCSharpObject() + { + return Value; + } } } \ No newline at end of file diff --git a/Upsilon/BaseTypes/Number/NumberLong.cs b/Upsilon/BaseTypes/Number/NumberLong.cs index 413a0a2..b68cd9a 100644 --- a/Upsilon/BaseTypes/Number/NumberLong.cs +++ b/Upsilon/BaseTypes/Number/NumberLong.cs @@ -3,7 +3,7 @@ using System.Globalization; namespace Upsilon.BaseTypes.Number { - public class NumberLong : Number + internal class NumberLong : Number { public long Value { get; } protected override bool IsFloat { get; } = false; @@ -29,5 +29,10 @@ namespace Upsilon.BaseTypes.Number return 0; return n.Value; } + + public override object ToCSharpObject() + { + return Value; + } } } \ No newline at end of file diff --git a/Upsilon/BaseTypes/TypeConversion.cs b/Upsilon/BaseTypes/TypeConversion.cs index 2514d80..221a2e0 100644 --- a/Upsilon/BaseTypes/TypeConversion.cs +++ b/Upsilon/BaseTypes/TypeConversion.cs @@ -3,7 +3,7 @@ using Upsilon.BaseTypes.Number; namespace Upsilon.BaseTypes { - public static class TypeConversion + internal static class TypeConversion { public static LuaType ToLuaType(this object o) { diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index 4e29cfb..0621b1d 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -8,10 +8,10 @@ using Type = Upsilon.BaseTypes.Type; namespace Upsilon.Binder { - public class Binder + internal class Binder { private readonly Diagnostics _diagnostics; - private BoundScope _scope; + public BoundScope Scope { get; private set; } private Dictionary _unboundFunctions = new Dictionary(); @@ -19,7 +19,7 @@ namespace Upsilon.Binder public Binder(Diagnostics diagnostics, Dictionary variables) { _diagnostics = diagnostics; - _scope = new BoundScope(variables, null); + Scope = new BoundScope(variables, null); } public BoundScript BindScript(BlockStatementSyntax e) @@ -27,14 +27,14 @@ namespace Upsilon.Binder var bound = BindStatement(e); foreach (var unboundFunctionStatement in _unboundFunctions) { - _scope = new BoundScope(_scope); + Scope = new BoundScope(Scope); foreach (var valueParameter in unboundFunctionStatement.Value.Parameters) { - _scope.SetVariable(valueParameter); + Scope.SetVariable(valueParameter); } unboundFunctionStatement.Value.Block = (BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.Value.UnboundBlock); - _scope = _scope.ParentScope; + Scope = Scope.ParentScope; unboundFunctionStatement.Key.IsBound = true; } _unboundFunctions = new Dictionary(); @@ -147,7 +147,7 @@ namespace Upsilon.Binder private BoundExpression BindFunctionCallExpression(FunctionCallExpressionSyntax e) { var name = e.Identifier.Name; - if (!_scope.TryGetVariable(name, true, out var functionObj)) + if (!Scope.TryGetVariable(name, true, out var functionObj)) { _diagnostics.LogUnknownVariable(e.Identifier.Span, name); return new BoundLiteralExpression(new LuaNull()); @@ -164,19 +164,19 @@ namespace Upsilon.Binder if (!function.IsBound) { - _scope = new BoundScope(_scope); + Scope = new BoundScope(Scope); for (var index = 0; index < function.Parameters.Length; index++) { var functionVariable = function.Parameters[index]; var callingVariable = parameters[index]; functionVariable.Type = callingVariable.Type; - _scope.SetVariable(functionVariable); + Scope.SetVariable(functionVariable); } var unboundFunctionStatement = _unboundFunctions[function]; unboundFunctionStatement.Block = (BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.UnboundBlock); - _scope = _scope.ParentScope; + Scope = Scope.ParentScope; function.IsBound = true; _unboundFunctions.Remove(function); } @@ -188,7 +188,7 @@ namespace Upsilon.Binder private BoundExpression BindVariableExpression(VariableExpressionSyntax e) { var name = e.Identifier.Name; - if (!_scope.TryGetVariable(name, true, out var variable)) + if (!Scope.TryGetVariable(name, true, out var variable)) { _diagnostics.LogUnknownVariable(e.Identifier.Span, name); return new BoundLiteralExpression(new LuaNull()); @@ -209,13 +209,13 @@ namespace Upsilon.Binder var boundExpression = BindExpression(e.Expression); var isLocal = e.LocalToken != null; - if (!_scope.TryGetVariable(name, !isLocal, out var variable)) + if (!Scope.TryGetVariable(name, !isLocal, out var variable)) { variable = new VariableSymbol(name, boundExpression.Type, isLocal); if (isLocal) - _scope.SetVariable(variable); + Scope.SetVariable(variable); else - _scope.SetGlobalVariable(variable); + Scope.SetGlobalVariable(variable); } else { @@ -260,10 +260,10 @@ namespace Upsilon.Binder private BoundStatement BindIfStatement(IfStatementSyntax e) { - _scope = new BoundScope(_scope); + Scope = new BoundScope(Scope); var condition = BindExpressionStatement(e.Condition); var block = BindBlockStatement(e.Block); - _scope = _scope.ParentScope; + Scope = Scope.ParentScope; if (e.NextElseIfStatement != null) { var nextElseIf = BindIfStatement(e.NextElseIfStatement); @@ -276,10 +276,10 @@ namespace Upsilon.Binder } else { - _scope = new BoundScope(_scope); + Scope = new BoundScope(Scope); var elseBlock = BindBlockStatement(e.ElseStatement.Block); var elseStatement = new BoundElseStatement((BoundBlockStatement) elseBlock); - _scope = _scope.ParentScope; + Scope = Scope.ParentScope; return new BoundIfStatement((BoundExpressionStatement) condition, (BoundBlockStatement) block, elseStatement); @@ -291,7 +291,7 @@ namespace Upsilon.Binder var name = e.Identifier.Name; var isLocal = e.LocalToken != null; - var innerScope = new BoundScope(_scope); + var innerScope = new BoundScope(Scope); var parameters = ImmutableArray.CreateBuilder(); foreach (var identifierToken in e.Parameters) { @@ -300,13 +300,13 @@ namespace Upsilon.Binder innerScope.SetVariable(vari); } - if (!_scope.TryGetVariable(name, !isLocal, out var variable)) + if (!Scope.TryGetVariable(name, !isLocal, out var variable)) { variable = new FunctionVariableSymbol(name, Type.Function, isLocal, parameters.ToImmutable()); if (isLocal) - _scope.SetVariable(variable); + Scope.SetVariable(variable); else - _scope.SetGlobalVariable(variable); + Scope.SetGlobalVariable(variable); } else { @@ -327,9 +327,9 @@ namespace Upsilon.Binder if (parameters.Count == 0) { - _scope = innerScope; + Scope = innerScope; var block = BindBlockStatement(e.Block); - _scope = _scope.ParentScope; + Scope = Scope.ParentScope; ((FunctionVariableSymbol) variable).IsBound = true; var func = new BoundFunctionStatement(variable, parameters.ToImmutable(), (BoundBlockStatement) block); return func; diff --git a/Upsilon/Binder/BoundExpressions/BoundLiteralExpression.cs b/Upsilon/Binder/BoundExpressions/BoundLiteralExpression.cs index 1533ad7..2b9b57a 100644 --- a/Upsilon/Binder/BoundExpressions/BoundLiteralExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundLiteralExpression.cs @@ -2,7 +2,7 @@ using Upsilon.BaseTypes; namespace Upsilon.Binder { - public class BoundLiteralExpression : BoundExpression + internal class BoundLiteralExpression : BoundExpression { public BoundLiteralExpression(LuaType value) { diff --git a/Upsilon/Binder/BoundScope.cs b/Upsilon/Binder/BoundScope.cs index 5eab156..ce572e1 100644 --- a/Upsilon/Binder/BoundScope.cs +++ b/Upsilon/Binder/BoundScope.cs @@ -4,7 +4,7 @@ using Upsilon.BaseTypes; namespace Upsilon.Binder { - public class BoundScope + internal class BoundScope { public readonly BoundScope ParentScope; private readonly Dictionary _variables; diff --git a/Upsilon/Evaluator/EvaluationScope.cs b/Upsilon/Evaluator/EvaluationScope.cs index 2c2943c..ea4b682 100644 --- a/Upsilon/Evaluator/EvaluationScope.cs +++ b/Upsilon/Evaluator/EvaluationScope.cs @@ -4,7 +4,7 @@ using Upsilon.Binder; namespace Upsilon.Evaluator { - public class EvaluationScope + internal class EvaluationScope { private readonly EvaluationScope _parentScope; private readonly Dictionary _variables; diff --git a/Upsilon/Evaluator/Evaluator.cs b/Upsilon/Evaluator/Evaluator.cs index d0a3f7b..574a8ed 100644 --- a/Upsilon/Evaluator/Evaluator.cs +++ b/Upsilon/Evaluator/Evaluator.cs @@ -8,12 +8,12 @@ using Type = Upsilon.BaseTypes.Type; namespace Upsilon.Evaluator { - public class Evaluator + internal class Evaluator { private readonly Diagnostics _diagnostics; private LuaType _lastValue; private LuaType _returnValue; - public EvaluationScope Scope { get; } + internal EvaluationScope Scope { get; } private bool HasReturned { get; set; } internal Evaluator(Diagnostics diagnostics, Dictionary variables) diff --git a/Upsilon/Evaluator/Script.cs b/Upsilon/Evaluator/Script.cs index 583b7e8..d2af372 100644 --- a/Upsilon/Evaluator/Script.cs +++ b/Upsilon/Evaluator/Script.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Collections.Immutable; using Upsilon.BaseTypes; @@ -11,25 +12,29 @@ namespace Upsilon.Evaluator public class Script { private SourceText ScriptString { get; } - private Evaluator Evaluator { get; } + private Evaluator Evaluator { get; set; } private readonly BlockStatementSyntax _parsed; private BoundScript _bound; public Diagnostics Diagnostics { get; } - private Binder.Binder Binder { get; } - public EvaluationScope Scope { get; } + private Binder.Binder Binder { get; set; } + internal EvaluationScope Scope { get; } - public Script(string scriptString, Dictionary variables = null) + public Script(string scriptString) { ScriptString = new SourceText(scriptString); Diagnostics = new Diagnostics(ScriptString); _parsed = Parser.Parser.Parse(scriptString, Diagnostics); - if (variables == null) - variables = new Dictionary(); - Binder = new Binder.Binder(Diagnostics, variables); - Evaluator = new Evaluator( Diagnostics, variables); + Binder = new Binder.Binder(Diagnostics, new Dictionary()); + Evaluator = new Evaluator( Diagnostics, new Dictionary()); Scope = Evaluator.Scope; } + public static Script ContinueWith(Script previousScript, string scriptString) + { + var s = new Script(scriptString) {Binder = previousScript.Binder, Evaluator = previousScript.Evaluator}; + return s; + } + public BoundScript Bind() { return _bound ?? (_bound = Binder.BindScript(_parsed)); @@ -50,15 +55,29 @@ namespace Upsilon.Evaluator luaParameters.Add(parameter.ToLuaType()); } } - return Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()); + return Convert(Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable())); } - public T Evaluate() where T : LuaType + private T Convert(LuaType t) { - return (T)Evaluator.Evaluate(Bind()); + if (typeof(T) == typeof(double)) + return (T)(object)System.Convert.ToDouble(t.ToCSharpObject()); + if (typeof(T) == typeof(long)) + return (T)(object)System.Convert.ToInt64(t.ToCSharpObject()); + return (T) t.ToCSharpObject(); } - public T EvaluateFunction(string functionName, object[] parameters = null) where T : LuaType + private object Convert(LuaType t) + { + return t.ToCSharpObject(); + } + + public T Evaluate() + { + return Convert(Evaluator.Evaluate(Bind())); + } + + public T EvaluateFunction(string functionName, object[] parameters = null) { var luaParameters = ImmutableArray.CreateBuilder(); if (parameters != null) @@ -68,7 +87,22 @@ namespace Upsilon.Evaluator luaParameters.Add(parameter.ToLuaType()); } } - return (T)Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()); + return Convert(Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable())); + } + + public T GetVariable(string variableName) + { + if (!Scope.TryGet(variableName, out var variable)) + { + throw new NullReferenceException(); + } + + return Convert(variable); + } + + public bool HasVariable(string variableName) + { + return Scope.TryGet(variableName, out _); } public string PrettyPrintSyntaxTree() diff --git a/UpsilonTests/BasicMathExpressions.cs b/UpsilonTests/BasicMathExpressions.cs index 9adcb9c..a47e962 100644 --- a/UpsilonTests/BasicMathExpressions.cs +++ b/UpsilonTests/BasicMathExpressions.cs @@ -1,6 +1,4 @@ -using Upsilon.BaseTypes.Number; using Upsilon.Evaluator; -using Upsilon.Parser; using Xunit; namespace UpsilonTests @@ -17,8 +15,8 @@ namespace UpsilonTests [InlineData("0.005 + 2.2", 2.205)] public void Addition(string input, double expectedOutput) { - var actual = new Script(input).Evaluate(); - Assert.Equal(expectedOutput, (double)actual, 8); + var actual = new Script(input).Evaluate(); + Assert.Equal(expectedOutput, actual, 8); } [Theory] @@ -30,8 +28,8 @@ namespace UpsilonTests [InlineData("10.256-2.8546", 7.4014)] public void Subtraction(string input, double expectedOutput) { - var actual = new Script(input).Evaluate(); - Assert.Equal(expectedOutput, (double)actual, 8); + var actual = new Script(input).Evaluate(); + Assert.Equal(expectedOutput, actual, 8); } [Theory] @@ -40,8 +38,8 @@ namespace UpsilonTests [InlineData("21312 * 41684", 888369408)] public void Multiplication(string input, double expectedOutput) { - var actual = new Script(input).Evaluate(); - Assert.Equal(expectedOutput, (double)actual, 8); + var actual = new Script(input).Evaluate(); + Assert.Equal(expectedOutput, actual, 8); } [Theory] @@ -51,8 +49,8 @@ namespace UpsilonTests [InlineData("656486 / 5146.0", 127.57209483)] public void Divison(string input, double expectedOutput) { - var actual = new Script(input).Evaluate(); - Assert.Equal(expectedOutput, (double)actual, 8); + var actual = new Script(input).Evaluate(); + Assert.Equal(expectedOutput, actual, 8); } } diff --git a/UpsilonTests/FunctionTests.cs b/UpsilonTests/FunctionTests.cs index 7123178..2479cbc 100644 --- a/UpsilonTests/FunctionTests.cs +++ b/UpsilonTests/FunctionTests.cs @@ -21,10 +21,8 @@ testFunc() Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("testFunc", out var func)); - Assert.IsType(func); - Assert.True(script.Scope.TryGet("a", out var a)); - Assert.Equal(100, (long)(NumberLong)a); + var a = script.GetVariable("a"); + Assert.Equal(100, a); } [Fact] @@ -41,10 +39,8 @@ testFunc(100) Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("testFunc", out var func)); - Assert.IsType(func); - Assert.True(script.Scope.TryGet("a", out var a)); - Assert.Equal(100, (long)(NumberLong)a); + var a = script.GetVariable("a"); + Assert.Equal(100, a); } [Fact] @@ -58,10 +54,9 @@ testFunc(100) "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - script.Evaluate(); + var val = script.Evaluate(); Assert.Single(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("testFunc", out var func)); - Assert.IsType(func); + Assert.True(script.HasVariable("testFunc")); } [Fact] @@ -74,11 +69,9 @@ end "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - script.Evaluate(); + var val = script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("testFunc", out var func)); - var castType = Assert.IsType(func); - Assert.NotNull(castType.Block); + Assert.True(script.HasVariable("testFunc")); } [Fact] @@ -94,8 +87,8 @@ a = testFunc() Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("a", out var result)); - Assert.Equal(5, (long)(NumberLong)result); + var a = script.GetVariable("a"); + Assert.Equal(5, a); } [Fact] @@ -112,8 +105,8 @@ a = testFunc() Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("a", out var result)); - Assert.Equal(5, (long)(NumberLong)result); + var a = script.GetVariable("a"); + Assert.Equal(5, a); } [Fact] @@ -132,8 +125,8 @@ a = testFunc() Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("a", out var result)); - Assert.Equal(5, (long)(NumberLong)result); + var a = script.GetVariable("a"); + Assert.Equal(5, a); } [Fact] @@ -146,9 +139,9 @@ a = 87 "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - var result = script.Evaluate(); + var result = script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.Equal(60, (long)(NumberLong)result); + Assert.Equal(60, result); } [Fact] @@ -161,9 +154,9 @@ end "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - var result = script.EvaluateFunction("testFunc"); + var result = script.EvaluateFunction("testFunc"); Assert.Empty(script.Diagnostics.Messages); - Assert.Equal(100, (long)result); + Assert.Equal(100, result); } [Fact] @@ -180,12 +173,12 @@ end "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - var result = script.EvaluateFunction("testFunc", new object[] {true}); + var result = script.EvaluateFunction("testFunc", new object[] {true}); Assert.Empty(script.Diagnostics.Messages); - Assert.Equal(100, (long)result); - var result2 = script.EvaluateFunction("testFunc", new object[] {false}); + Assert.Equal(100, result); + var result2 = script.EvaluateFunction("testFunc", new object[] {false}); Assert.Empty(script.Diagnostics.Messages); - Assert.Equal(50, (long)result2); + Assert.Equal(50, result2); } @@ -199,9 +192,9 @@ end "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - var result = script.EvaluateFunction("add", new object[] {400, 128}); + var result = script.EvaluateFunction("add", new object[] {400, 128}); Assert.Empty(script.Diagnostics.Messages); - Assert.Equal(528, (long)result); + Assert.Equal(528, result); } diff --git a/UpsilonTests/IfTests.cs b/UpsilonTests/IfTests.cs index c093a66..5d76ebb 100644 --- a/UpsilonTests/IfTests.cs +++ b/UpsilonTests/IfTests.cs @@ -13,7 +13,7 @@ namespace UpsilonTests var input = "if true then val = true end"; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - var actual = script.Evaluate(); + var actual = script.Evaluate(); Assert.True(actual); } @@ -32,7 +32,7 @@ else end"; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - var actual = (long)(NumberLong)script.Evaluate(); + var actual = script.Evaluate(); Assert.Equal(expected, actual); } @@ -52,7 +52,7 @@ else end"; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); - var actual = (long)(NumberLong)script.Evaluate(); + var actual = script.Evaluate(); Assert.Equal(expected, actual); } diff --git a/UpsilonTests/MathPrecedence.cs b/UpsilonTests/MathPrecedence.cs index a768cbd..b5c5a07 100644 --- a/UpsilonTests/MathPrecedence.cs +++ b/UpsilonTests/MathPrecedence.cs @@ -12,7 +12,7 @@ namespace UpsilonTests [InlineData("(10 + 5) * 5", 75)] public void Parenthesis(string input, double expectedOutput) { - var actual = new Script(input).Evaluate(); + var actual = new Script(input).Evaluate(); Assert.Equal(expectedOutput, actual, 8); } @@ -21,7 +21,7 @@ namespace UpsilonTests [InlineData("5 + 10 * 5", 55)] public void MultiplicationBeforeAddition(string input, double expectedOutput) { - var actual = new Script(input).Evaluate(); + var actual = new Script(input).Evaluate(); Assert.Equal(expectedOutput, actual, 8); } diff --git a/UpsilonTests/ScopeTests.cs b/UpsilonTests/ScopeTests.cs index 355ea8c..d4dafe9 100644 --- a/UpsilonTests/ScopeTests.cs +++ b/UpsilonTests/ScopeTests.cs @@ -19,8 +19,8 @@ end Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("a", out var obj)); - Assert.Equal((long)10, (NumberLong)obj); + var a = script.GetVariable("a"); + Assert.Equal(10, a); } [Fact] @@ -37,8 +37,8 @@ b = a Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); - Assert.True(script.Scope.TryGet("a", out var obj)); - Assert.Equal((long)100, (NumberLong)obj); + var a = script.GetVariable("a"); + Assert.Equal(100, a); } } diff --git a/Ycicle/Program.cs b/Ycicle/Program.cs index b8e985b..625a622 100644 --- a/Ycicle/Program.cs +++ b/Ycicle/Program.cs @@ -13,8 +13,8 @@ namespace Ycicle private static void Main() { Console.WriteLine("Upsilon REPL"); - var variables = new Dictionary(); var showTranspiledOutput = false; + Script script = null; while (true) { Console.Write("ยป "); @@ -28,13 +28,16 @@ namespace Ycicle break; } - var parsed = new Script(input, variables); + if (script == null) + script = new Script(input); + else + script = Script.ContinueWith(script, input); - if (parsed.Diagnostics.Messages.Count > 0) + if (script.Diagnostics.Messages.Count > 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Errors were found during parsing"); - foreach (var diagnosticsMessage in parsed.Diagnostics.Messages) + foreach (var diagnosticsMessage in script.Diagnostics.Messages) { LogError(diagnosticsMessage); } @@ -45,19 +48,19 @@ namespace Ycicle if (showTranspiledOutput) { var transpiler = new Transpiler(); - var transpiled = transpiler.TranspilerToCSharp(parsed.Bind()); + var transpiled = transpiler.TranspilerToCSharp(script.Bind()); Console.WriteLine(transpiled); } else { - var evaluate = parsed.Evaluate(); + var evaluate = script.Evaluate(); if (evaluate == null) continue; - if (parsed.Diagnostics.Messages.Count > 0) + if (script.Diagnostics.Messages.Count > 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Errors were found during evaluating"); - foreach (var diagnosticsMessage in parsed.Diagnostics.Messages) + foreach (var diagnosticsMessage in script.Diagnostics.Messages) { LogError(diagnosticsMessage); }