Make LuaTypes internal, and only return the actual values

This commit is contained in:
Deukhoofd 2018-11-17 12:40:28 +01:00
parent f74992e47b
commit a631d3b377
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
21 changed files with 159 additions and 114 deletions

View File

@ -6,8 +6,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ycicle", "Ycicle\Ycicle.csp
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpsilonTests", "UpsilonTests\UpsilonTests.csproj", "{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpsilonTests", "UpsilonTests\UpsilonTests.csproj", "{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpsilonCompiler", "UpsilonCompiler\UpsilonCompiler.csproj", "{BC98BE8D-D3F5-46CC-9873-51F19D8E05C1}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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}.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.ActiveCfg = Release|Any CPU
{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}.Release|Any CPU.Build.0 = 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 EndGlobalSection
EndGlobal EndGlobal

View File

@ -1,6 +1,6 @@
namespace Upsilon.BaseTypes namespace Upsilon.BaseTypes
{ {
public class LuaBoolean : LuaType internal class LuaBoolean : LuaType
{ {
public LuaBoolean(bool value) public LuaBoolean(bool value)
{ {
@ -8,6 +8,11 @@ namespace Upsilon.BaseTypes
} }
public override Type Type => Type.Boolean; public override Type Type => Type.Boolean;
public override object ToCSharpObject()
{
return Value;
}
public bool Value { get; } public bool Value { get; }
public static implicit operator bool(LuaBoolean b) public static implicit operator bool(LuaBoolean b)

View File

@ -3,7 +3,7 @@ using Upsilon.Binder;
namespace Upsilon.BaseTypes namespace Upsilon.BaseTypes
{ {
public class LuaFunction : LuaType internal class LuaFunction : LuaType
{ {
public LuaFunction(ImmutableArray<VariableSymbol> parameters, BoundBlockStatement block) public LuaFunction(ImmutableArray<VariableSymbol> parameters, BoundBlockStatement block)
{ {
@ -12,6 +12,10 @@ namespace Upsilon.BaseTypes
} }
public override Type Type => Type.Function; public override Type Type => Type.Function;
public override object ToCSharpObject()
{
return Block;
}
public ImmutableArray<VariableSymbol> Parameters { get; } public ImmutableArray<VariableSymbol> Parameters { get; }
public BoundBlockStatement Block { get; } public BoundBlockStatement Block { get; }

View File

@ -1,8 +1,12 @@
namespace Upsilon.BaseTypes namespace Upsilon.BaseTypes
{ {
public class LuaNull : LuaType internal class LuaNull : LuaType
{ {
public override Type Type => Type.Nil; public override Type Type => Type.Nil;
public override object ToCSharpObject()
{
return null;
}
public override string ToString() public override string ToString()
{ {

View File

@ -1,7 +1,8 @@
namespace Upsilon.BaseTypes namespace Upsilon.BaseTypes
{ {
public abstract class LuaType internal abstract class LuaType
{ {
public abstract Type Type { get; } public abstract Type Type { get; }
public abstract object ToCSharpObject();
} }
} }

View File

@ -1,6 +1,6 @@
namespace Upsilon.BaseTypes.Number namespace Upsilon.BaseTypes.Number
{ {
public abstract class Number : LuaType internal abstract class Number : LuaType
{ {
protected abstract bool IsFloat { get; } protected abstract bool IsFloat { get; }

View File

@ -2,7 +2,7 @@ using System.Globalization;
namespace Upsilon.BaseTypes.Number namespace Upsilon.BaseTypes.Number
{ {
public class NumberDouble : Number internal class NumberDouble : Number
{ {
public double Value { get; } public double Value { get; }
protected override bool IsFloat { get; } = true; protected override bool IsFloat { get; } = true;
@ -27,5 +27,9 @@ namespace Upsilon.BaseTypes.Number
return n.Value; return n.Value;
} }
public override object ToCSharpObject()
{
return Value;
}
} }
} }

View File

@ -3,7 +3,7 @@ using System.Globalization;
namespace Upsilon.BaseTypes.Number namespace Upsilon.BaseTypes.Number
{ {
public class NumberLong : Number internal class NumberLong : Number
{ {
public long Value { get; } public long Value { get; }
protected override bool IsFloat { get; } = false; protected override bool IsFloat { get; } = false;
@ -29,5 +29,10 @@ namespace Upsilon.BaseTypes.Number
return 0; return 0;
return n.Value; return n.Value;
} }
public override object ToCSharpObject()
{
return Value;
}
} }
} }

View File

@ -3,7 +3,7 @@ using Upsilon.BaseTypes.Number;
namespace Upsilon.BaseTypes namespace Upsilon.BaseTypes
{ {
public static class TypeConversion internal static class TypeConversion
{ {
public static LuaType ToLuaType(this object o) public static LuaType ToLuaType(this object o)
{ {

View File

@ -8,10 +8,10 @@ using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Binder namespace Upsilon.Binder
{ {
public class Binder internal class Binder
{ {
private readonly Diagnostics _diagnostics; private readonly Diagnostics _diagnostics;
private BoundScope _scope; public BoundScope Scope { get; private set; }
private Dictionary<FunctionVariableSymbol, UnboundFunctionStatement> _unboundFunctions = private Dictionary<FunctionVariableSymbol, UnboundFunctionStatement> _unboundFunctions =
new Dictionary<FunctionVariableSymbol, UnboundFunctionStatement>(); new Dictionary<FunctionVariableSymbol, UnboundFunctionStatement>();
@ -19,7 +19,7 @@ namespace Upsilon.Binder
public Binder(Diagnostics diagnostics, Dictionary<VariableSymbol, LuaType> variables) public Binder(Diagnostics diagnostics, Dictionary<VariableSymbol, LuaType> variables)
{ {
_diagnostics = diagnostics; _diagnostics = diagnostics;
_scope = new BoundScope(variables, null); Scope = new BoundScope(variables, null);
} }
public BoundScript BindScript(BlockStatementSyntax e) public BoundScript BindScript(BlockStatementSyntax e)
@ -27,14 +27,14 @@ namespace Upsilon.Binder
var bound = BindStatement(e); var bound = BindStatement(e);
foreach (var unboundFunctionStatement in _unboundFunctions) foreach (var unboundFunctionStatement in _unboundFunctions)
{ {
_scope = new BoundScope(_scope); Scope = new BoundScope(Scope);
foreach (var valueParameter in unboundFunctionStatement.Value.Parameters) foreach (var valueParameter in unboundFunctionStatement.Value.Parameters)
{ {
_scope.SetVariable(valueParameter); Scope.SetVariable(valueParameter);
} }
unboundFunctionStatement.Value.Block = unboundFunctionStatement.Value.Block =
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.Value.UnboundBlock); (BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.Value.UnboundBlock);
_scope = _scope.ParentScope; Scope = Scope.ParentScope;
unboundFunctionStatement.Key.IsBound = true; unboundFunctionStatement.Key.IsBound = true;
} }
_unboundFunctions = new Dictionary<FunctionVariableSymbol, UnboundFunctionStatement>(); _unboundFunctions = new Dictionary<FunctionVariableSymbol, UnboundFunctionStatement>();
@ -147,7 +147,7 @@ namespace Upsilon.Binder
private BoundExpression BindFunctionCallExpression(FunctionCallExpressionSyntax e) private BoundExpression BindFunctionCallExpression(FunctionCallExpressionSyntax e)
{ {
var name = e.Identifier.Name; 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); _diagnostics.LogUnknownVariable(e.Identifier.Span, name);
return new BoundLiteralExpression(new LuaNull()); return new BoundLiteralExpression(new LuaNull());
@ -164,19 +164,19 @@ namespace Upsilon.Binder
if (!function.IsBound) if (!function.IsBound)
{ {
_scope = new BoundScope(_scope); Scope = new BoundScope(Scope);
for (var index = 0; index < function.Parameters.Length; index++) for (var index = 0; index < function.Parameters.Length; index++)
{ {
var functionVariable = function.Parameters[index]; var functionVariable = function.Parameters[index];
var callingVariable = parameters[index]; var callingVariable = parameters[index];
functionVariable.Type = callingVariable.Type; functionVariable.Type = callingVariable.Type;
_scope.SetVariable(functionVariable); Scope.SetVariable(functionVariable);
} }
var unboundFunctionStatement = _unboundFunctions[function]; var unboundFunctionStatement = _unboundFunctions[function];
unboundFunctionStatement.Block = unboundFunctionStatement.Block =
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.UnboundBlock); (BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.UnboundBlock);
_scope = _scope.ParentScope; Scope = Scope.ParentScope;
function.IsBound = true; function.IsBound = true;
_unboundFunctions.Remove(function); _unboundFunctions.Remove(function);
} }
@ -188,7 +188,7 @@ namespace Upsilon.Binder
private BoundExpression BindVariableExpression(VariableExpressionSyntax e) private BoundExpression BindVariableExpression(VariableExpressionSyntax e)
{ {
var name = e.Identifier.Name; 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); _diagnostics.LogUnknownVariable(e.Identifier.Span, name);
return new BoundLiteralExpression(new LuaNull()); return new BoundLiteralExpression(new LuaNull());
@ -209,13 +209,13 @@ namespace Upsilon.Binder
var boundExpression = BindExpression(e.Expression); var boundExpression = BindExpression(e.Expression);
var isLocal = e.LocalToken != null; 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); variable = new VariableSymbol(name, boundExpression.Type, isLocal);
if (isLocal) if (isLocal)
_scope.SetVariable(variable); Scope.SetVariable(variable);
else else
_scope.SetGlobalVariable(variable); Scope.SetGlobalVariable(variable);
} }
else else
{ {
@ -260,10 +260,10 @@ namespace Upsilon.Binder
private BoundStatement BindIfStatement(IfStatementSyntax e) private BoundStatement BindIfStatement(IfStatementSyntax e)
{ {
_scope = new BoundScope(_scope); Scope = new BoundScope(Scope);
var condition = BindExpressionStatement(e.Condition); var condition = BindExpressionStatement(e.Condition);
var block = BindBlockStatement(e.Block); var block = BindBlockStatement(e.Block);
_scope = _scope.ParentScope; Scope = Scope.ParentScope;
if (e.NextElseIfStatement != null) if (e.NextElseIfStatement != null)
{ {
var nextElseIf = BindIfStatement(e.NextElseIfStatement); var nextElseIf = BindIfStatement(e.NextElseIfStatement);
@ -276,10 +276,10 @@ namespace Upsilon.Binder
} }
else else
{ {
_scope = new BoundScope(_scope); Scope = new BoundScope(Scope);
var elseBlock = BindBlockStatement(e.ElseStatement.Block); var elseBlock = BindBlockStatement(e.ElseStatement.Block);
var elseStatement = new BoundElseStatement((BoundBlockStatement) elseBlock); var elseStatement = new BoundElseStatement((BoundBlockStatement) elseBlock);
_scope = _scope.ParentScope; Scope = Scope.ParentScope;
return new BoundIfStatement((BoundExpressionStatement) condition, (BoundBlockStatement) block, return new BoundIfStatement((BoundExpressionStatement) condition, (BoundBlockStatement) block,
elseStatement); elseStatement);
@ -291,7 +291,7 @@ namespace Upsilon.Binder
var name = e.Identifier.Name; var name = e.Identifier.Name;
var isLocal = e.LocalToken != null; var isLocal = e.LocalToken != null;
var innerScope = new BoundScope(_scope); var innerScope = new BoundScope(Scope);
var parameters = ImmutableArray.CreateBuilder<VariableSymbol>(); var parameters = ImmutableArray.CreateBuilder<VariableSymbol>();
foreach (var identifierToken in e.Parameters) foreach (var identifierToken in e.Parameters)
{ {
@ -300,13 +300,13 @@ namespace Upsilon.Binder
innerScope.SetVariable(vari); 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()); variable = new FunctionVariableSymbol(name, Type.Function, isLocal, parameters.ToImmutable());
if (isLocal) if (isLocal)
_scope.SetVariable(variable); Scope.SetVariable(variable);
else else
_scope.SetGlobalVariable(variable); Scope.SetGlobalVariable(variable);
} }
else else
{ {
@ -327,9 +327,9 @@ namespace Upsilon.Binder
if (parameters.Count == 0) if (parameters.Count == 0)
{ {
_scope = innerScope; Scope = innerScope;
var block = BindBlockStatement(e.Block); var block = BindBlockStatement(e.Block);
_scope = _scope.ParentScope; Scope = Scope.ParentScope;
((FunctionVariableSymbol) variable).IsBound = true; ((FunctionVariableSymbol) variable).IsBound = true;
var func = new BoundFunctionStatement(variable, parameters.ToImmutable(), (BoundBlockStatement) block); var func = new BoundFunctionStatement(variable, parameters.ToImmutable(), (BoundBlockStatement) block);
return func; return func;

View File

@ -2,7 +2,7 @@ using Upsilon.BaseTypes;
namespace Upsilon.Binder namespace Upsilon.Binder
{ {
public class BoundLiteralExpression : BoundExpression internal class BoundLiteralExpression : BoundExpression
{ {
public BoundLiteralExpression(LuaType value) public BoundLiteralExpression(LuaType value)
{ {

View File

@ -4,7 +4,7 @@ using Upsilon.BaseTypes;
namespace Upsilon.Binder namespace Upsilon.Binder
{ {
public class BoundScope internal class BoundScope
{ {
public readonly BoundScope ParentScope; public readonly BoundScope ParentScope;
private readonly Dictionary<string, VariableSymbol> _variables; private readonly Dictionary<string, VariableSymbol> _variables;

View File

@ -4,7 +4,7 @@ using Upsilon.Binder;
namespace Upsilon.Evaluator namespace Upsilon.Evaluator
{ {
public class EvaluationScope internal class EvaluationScope
{ {
private readonly EvaluationScope _parentScope; private readonly EvaluationScope _parentScope;
private readonly Dictionary<VariableSymbol, LuaType> _variables; private readonly Dictionary<VariableSymbol, LuaType> _variables;

View File

@ -8,12 +8,12 @@ using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Evaluator namespace Upsilon.Evaluator
{ {
public class Evaluator internal class Evaluator
{ {
private readonly Diagnostics _diagnostics; private readonly Diagnostics _diagnostics;
private LuaType _lastValue; private LuaType _lastValue;
private LuaType _returnValue; private LuaType _returnValue;
public EvaluationScope Scope { get; } internal EvaluationScope Scope { get; }
private bool HasReturned { get; set; } private bool HasReturned { get; set; }
internal Evaluator(Diagnostics diagnostics, Dictionary<VariableSymbol, LuaType> variables) internal Evaluator(Diagnostics diagnostics, Dictionary<VariableSymbol, LuaType> variables)

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using Upsilon.BaseTypes; using Upsilon.BaseTypes;
@ -11,25 +12,29 @@ namespace Upsilon.Evaluator
public class Script public class Script
{ {
private SourceText ScriptString { get; } private SourceText ScriptString { get; }
private Evaluator Evaluator { get; } private Evaluator Evaluator { get; set; }
private readonly BlockStatementSyntax _parsed; private readonly BlockStatementSyntax _parsed;
private BoundScript _bound; private BoundScript _bound;
public Diagnostics Diagnostics { get; } public Diagnostics Diagnostics { get; }
private Binder.Binder Binder { get; } private Binder.Binder Binder { get; set; }
public EvaluationScope Scope { get; } internal EvaluationScope Scope { get; }
public Script(string scriptString, Dictionary<VariableSymbol, LuaType> variables = null) public Script(string scriptString)
{ {
ScriptString = new SourceText(scriptString); ScriptString = new SourceText(scriptString);
Diagnostics = new Diagnostics(ScriptString); Diagnostics = new Diagnostics(ScriptString);
_parsed = Parser.Parser.Parse(scriptString, Diagnostics); _parsed = Parser.Parser.Parse(scriptString, Diagnostics);
if (variables == null) Binder = new Binder.Binder(Diagnostics, new Dictionary<VariableSymbol, LuaType>());
variables = new Dictionary<VariableSymbol, LuaType>(); Evaluator = new Evaluator( Diagnostics, new Dictionary<VariableSymbol, LuaType>());
Binder = new Binder.Binder(Diagnostics, variables);
Evaluator = new Evaluator( Diagnostics, variables);
Scope = Evaluator.Scope; 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() public BoundScript Bind()
{ {
return _bound ?? (_bound = Binder.BindScript(_parsed)); return _bound ?? (_bound = Binder.BindScript(_parsed));
@ -50,15 +55,29 @@ namespace Upsilon.Evaluator
luaParameters.Add(parameter.ToLuaType()); luaParameters.Add(parameter.ToLuaType());
} }
} }
return Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()); return Convert(Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()));
} }
public T Evaluate<T>() where T : LuaType private T Convert<T>(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<T>(string functionName, object[] parameters = null) where T : LuaType private object Convert(LuaType t)
{
return t.ToCSharpObject();
}
public T Evaluate<T>()
{
return Convert<T>(Evaluator.Evaluate(Bind()));
}
public T EvaluateFunction<T>(string functionName, object[] parameters = null)
{ {
var luaParameters = ImmutableArray.CreateBuilder<LuaType>(); var luaParameters = ImmutableArray.CreateBuilder<LuaType>();
if (parameters != null) if (parameters != null)
@ -68,7 +87,22 @@ namespace Upsilon.Evaluator
luaParameters.Add(parameter.ToLuaType()); luaParameters.Add(parameter.ToLuaType());
} }
} }
return (T)Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()); return Convert<T>(Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()));
}
public T GetVariable<T>(string variableName)
{
if (!Scope.TryGet(variableName, out var variable))
{
throw new NullReferenceException();
}
return Convert<T>(variable);
}
public bool HasVariable(string variableName)
{
return Scope.TryGet(variableName, out _);
} }
public string PrettyPrintSyntaxTree() public string PrettyPrintSyntaxTree()

View File

@ -1,6 +1,4 @@
using Upsilon.BaseTypes.Number;
using Upsilon.Evaluator; using Upsilon.Evaluator;
using Upsilon.Parser;
using Xunit; using Xunit;
namespace UpsilonTests namespace UpsilonTests
@ -17,8 +15,8 @@ namespace UpsilonTests
[InlineData("0.005 + 2.2", 2.205)] [InlineData("0.005 + 2.2", 2.205)]
public void Addition(string input, double expectedOutput) public void Addition(string input, double expectedOutput)
{ {
var actual = new Script(input).Evaluate<Number>(); var actual = new Script(input).Evaluate<double>();
Assert.Equal(expectedOutput, (double)actual, 8); Assert.Equal(expectedOutput, actual, 8);
} }
[Theory] [Theory]
@ -30,8 +28,8 @@ namespace UpsilonTests
[InlineData("10.256-2.8546", 7.4014)] [InlineData("10.256-2.8546", 7.4014)]
public void Subtraction(string input, double expectedOutput) public void Subtraction(string input, double expectedOutput)
{ {
var actual = new Script(input).Evaluate<Number>(); var actual = new Script(input).Evaluate<double>();
Assert.Equal(expectedOutput, (double)actual, 8); Assert.Equal(expectedOutput, actual, 8);
} }
[Theory] [Theory]
@ -40,8 +38,8 @@ namespace UpsilonTests
[InlineData("21312 * 41684", 888369408)] [InlineData("21312 * 41684", 888369408)]
public void Multiplication(string input, double expectedOutput) public void Multiplication(string input, double expectedOutput)
{ {
var actual = new Script(input).Evaluate<Number>(); var actual = new Script(input).Evaluate<double>();
Assert.Equal(expectedOutput, (double)actual, 8); Assert.Equal(expectedOutput, actual, 8);
} }
[Theory] [Theory]
@ -51,8 +49,8 @@ namespace UpsilonTests
[InlineData("656486 / 5146.0", 127.57209483)] [InlineData("656486 / 5146.0", 127.57209483)]
public void Divison(string input, double expectedOutput) public void Divison(string input, double expectedOutput)
{ {
var actual = new Script(input).Evaluate<Number>(); var actual = new Script(input).Evaluate<double>();
Assert.Equal(expectedOutput, (double)actual, 8); Assert.Equal(expectedOutput, actual, 8);
} }
} }

View File

@ -21,10 +21,8 @@ testFunc()
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); script.Evaluate();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("testFunc", out var func)); var a = script.GetVariable<long>("a");
Assert.IsType<LuaFunction>(func); Assert.Equal(100, a);
Assert.True(script.Scope.TryGet("a", out var a));
Assert.Equal(100, (long)(NumberLong)a);
} }
[Fact] [Fact]
@ -41,10 +39,8 @@ testFunc(100)
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); script.Evaluate();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("testFunc", out var func)); var a = script.GetVariable<long>("a");
Assert.IsType<LuaFunction>(func); Assert.Equal(100, a);
Assert.True(script.Scope.TryGet("a", out var a));
Assert.Equal(100, (long)(NumberLong)a);
} }
[Fact] [Fact]
@ -58,10 +54,9 @@ testFunc(100)
"; ";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); var val = script.Evaluate();
Assert.Single(script.Diagnostics.Messages); Assert.Single(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("testFunc", out var func)); Assert.True(script.HasVariable("testFunc"));
Assert.IsType<LuaFunction>(func);
} }
[Fact] [Fact]
@ -74,11 +69,9 @@ end
"; ";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); var val = script.Evaluate();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("testFunc", out var func)); Assert.True(script.HasVariable("testFunc"));
var castType = Assert.IsType<LuaFunction>(func);
Assert.NotNull(castType.Block);
} }
[Fact] [Fact]
@ -94,8 +87,8 @@ a = testFunc()
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); script.Evaluate();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("a", out var result)); var a = script.GetVariable<long>("a");
Assert.Equal(5, (long)(NumberLong)result); Assert.Equal(5, a);
} }
[Fact] [Fact]
@ -112,8 +105,8 @@ a = testFunc()
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); script.Evaluate();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("a", out var result)); var a = script.GetVariable<long>("a");
Assert.Equal(5, (long)(NumberLong)result); Assert.Equal(5, a);
} }
[Fact] [Fact]
@ -132,8 +125,8 @@ a = testFunc()
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); script.Evaluate();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("a", out var result)); var a = script.GetVariable<long>("a");
Assert.Equal(5, (long)(NumberLong)result); Assert.Equal(5, a);
} }
[Fact] [Fact]
@ -146,9 +139,9 @@ a = 87
"; ";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
var result = script.Evaluate<NumberLong>(); var result = script.Evaluate<long>();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.Equal(60, (long)(NumberLong)result); Assert.Equal(60, result);
} }
[Fact] [Fact]
@ -161,9 +154,9 @@ end
"; ";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
var result = script.EvaluateFunction<NumberLong>("testFunc"); var result = script.EvaluateFunction<long>("testFunc");
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.Equal(100, (long)result); Assert.Equal(100, result);
} }
[Fact] [Fact]
@ -180,12 +173,12 @@ end
"; ";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
var result = script.EvaluateFunction<NumberLong>("testFunc", new object[] {true}); var result = script.EvaluateFunction<long>("testFunc", new object[] {true});
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.Equal(100, (long)result); Assert.Equal(100, result);
var result2 = script.EvaluateFunction<NumberLong>("testFunc", new object[] {false}); var result2 = script.EvaluateFunction<long>("testFunc", new object[] {false});
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.Equal(50, (long)result2); Assert.Equal(50, result2);
} }
@ -199,9 +192,9 @@ end
"; ";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
var result = script.EvaluateFunction<NumberLong>("add", new object[] {400, 128}); var result = script.EvaluateFunction<long>("add", new object[] {400, 128});
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.Equal(528, (long)result); Assert.Equal(528, result);
} }

View File

@ -13,7 +13,7 @@ namespace UpsilonTests
var input = "if true then val = true end"; var input = "if true then val = true end";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
var actual = script.Evaluate<LuaBoolean>(); var actual = script.Evaluate<bool>();
Assert.True(actual); Assert.True(actual);
} }
@ -32,7 +32,7 @@ else
end"; end";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
var actual = (long)(NumberLong)script.Evaluate(); var actual = script.Evaluate<long>();
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
@ -52,7 +52,7 @@ else
end"; end";
var script = new Script(input); var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
var actual = (long)(NumberLong)script.Evaluate(); var actual = script.Evaluate<long>();
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }

View File

@ -12,7 +12,7 @@ namespace UpsilonTests
[InlineData("(10 + 5) * 5", 75)] [InlineData("(10 + 5) * 5", 75)]
public void Parenthesis(string input, double expectedOutput) public void Parenthesis(string input, double expectedOutput)
{ {
var actual = new Script(input).Evaluate<NumberLong>(); var actual = new Script(input).Evaluate<long>();
Assert.Equal(expectedOutput, actual, 8); Assert.Equal(expectedOutput, actual, 8);
} }
@ -21,7 +21,7 @@ namespace UpsilonTests
[InlineData("5 + 10 * 5", 55)] [InlineData("5 + 10 * 5", 55)]
public void MultiplicationBeforeAddition(string input, double expectedOutput) public void MultiplicationBeforeAddition(string input, double expectedOutput)
{ {
var actual = new Script(input).Evaluate<NumberLong>(); var actual = new Script(input).Evaluate<long>();
Assert.Equal(expectedOutput, actual, 8); Assert.Equal(expectedOutput, actual, 8);
} }

View File

@ -19,8 +19,8 @@ end
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); script.Evaluate();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("a", out var obj)); var a = script.GetVariable<long>("a");
Assert.Equal((long)10, (NumberLong)obj); Assert.Equal(10, a);
} }
[Fact] [Fact]
@ -37,8 +37,8 @@ b = a
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
script.Evaluate(); script.Evaluate();
Assert.Empty(script.Diagnostics.Messages); Assert.Empty(script.Diagnostics.Messages);
Assert.True(script.Scope.TryGet("a", out var obj)); var a = script.GetVariable<long>("a");
Assert.Equal((long)100, (NumberLong)obj); Assert.Equal(100, a);
} }
} }

View File

@ -13,8 +13,8 @@ namespace Ycicle
private static void Main() private static void Main()
{ {
Console.WriteLine("Upsilon REPL"); Console.WriteLine("Upsilon REPL");
var variables = new Dictionary<VariableSymbol, LuaType>();
var showTranspiledOutput = false; var showTranspiledOutput = false;
Script script = null;
while (true) while (true)
{ {
Console.Write("» "); Console.Write("» ");
@ -28,13 +28,16 @@ namespace Ycicle
break; 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.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Errors were found during parsing"); Console.WriteLine("Errors were found during parsing");
foreach (var diagnosticsMessage in parsed.Diagnostics.Messages) foreach (var diagnosticsMessage in script.Diagnostics.Messages)
{ {
LogError(diagnosticsMessage); LogError(diagnosticsMessage);
} }
@ -45,19 +48,19 @@ namespace Ycicle
if (showTranspiledOutput) if (showTranspiledOutput)
{ {
var transpiler = new Transpiler(); var transpiler = new Transpiler();
var transpiled = transpiler.TranspilerToCSharp(parsed.Bind()); var transpiled = transpiler.TranspilerToCSharp(script.Bind());
Console.WriteLine(transpiled); Console.WriteLine(transpiled);
} }
else else
{ {
var evaluate = parsed.Evaluate(); var evaluate = script.Evaluate();
if (evaluate == null) if (evaluate == null)
continue; continue;
if (parsed.Diagnostics.Messages.Count > 0) if (script.Diagnostics.Messages.Count > 0)
{ {
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Errors were found during evaluating"); Console.WriteLine("Errors were found during evaluating");
foreach (var diagnosticsMessage in parsed.Diagnostics.Messages) foreach (var diagnosticsMessage in script.Diagnostics.Messages)
{ {
LogError(diagnosticsMessage); LogError(diagnosticsMessage);
} }