Make LuaTypes internal, and only return the actual values
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -3,7 +3,7 @@ using Upsilon.Binder;
|
||||
|
||||
namespace Upsilon.BaseTypes
|
||||
{
|
||||
public class LuaFunction : LuaType
|
||||
internal class LuaFunction : LuaType
|
||||
{
|
||||
public LuaFunction(ImmutableArray<VariableSymbol> parameters, BoundBlockStatement block)
|
||||
{
|
||||
@@ -12,6 +12,10 @@ namespace Upsilon.BaseTypes
|
||||
}
|
||||
|
||||
public override Type Type => Type.Function;
|
||||
public override object ToCSharpObject()
|
||||
{
|
||||
return Block;
|
||||
}
|
||||
|
||||
public ImmutableArray<VariableSymbol> Parameters { get; }
|
||||
public BoundBlockStatement Block { get; }
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Upsilon.BaseTypes
|
||||
{
|
||||
public abstract class LuaType
|
||||
internal abstract class LuaType
|
||||
{
|
||||
public abstract Type Type { get; }
|
||||
public abstract object ToCSharpObject();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Upsilon.BaseTypes.Number
|
||||
{
|
||||
public abstract class Number : LuaType
|
||||
internal abstract class Number : LuaType
|
||||
{
|
||||
protected abstract bool IsFloat { get; }
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<FunctionVariableSymbol, UnboundFunctionStatement> _unboundFunctions =
|
||||
new Dictionary<FunctionVariableSymbol, UnboundFunctionStatement>();
|
||||
@@ -19,7 +19,7 @@ namespace Upsilon.Binder
|
||||
public Binder(Diagnostics diagnostics, Dictionary<VariableSymbol, LuaType> 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<FunctionVariableSymbol, UnboundFunctionStatement>();
|
||||
@@ -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<VariableSymbol>();
|
||||
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;
|
||||
|
||||
@@ -2,7 +2,7 @@ using Upsilon.BaseTypes;
|
||||
|
||||
namespace Upsilon.Binder
|
||||
{
|
||||
public class BoundLiteralExpression : BoundExpression
|
||||
internal class BoundLiteralExpression : BoundExpression
|
||||
{
|
||||
public BoundLiteralExpression(LuaType value)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using Upsilon.BaseTypes;
|
||||
|
||||
namespace Upsilon.Binder
|
||||
{
|
||||
public class BoundScope
|
||||
internal class BoundScope
|
||||
{
|
||||
public readonly BoundScope ParentScope;
|
||||
private readonly Dictionary<string, VariableSymbol> _variables;
|
||||
|
||||
@@ -4,7 +4,7 @@ using Upsilon.Binder;
|
||||
|
||||
namespace Upsilon.Evaluator
|
||||
{
|
||||
public class EvaluationScope
|
||||
internal class EvaluationScope
|
||||
{
|
||||
private readonly EvaluationScope _parentScope;
|
||||
private readonly Dictionary<VariableSymbol, LuaType> _variables;
|
||||
|
||||
@@ -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<VariableSymbol, LuaType> variables)
|
||||
|
||||
@@ -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<VariableSymbol, LuaType> 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<VariableSymbol, LuaType>();
|
||||
Binder = new Binder.Binder(Diagnostics, variables);
|
||||
Evaluator = new Evaluator( Diagnostics, variables);
|
||||
Binder = new Binder.Binder(Diagnostics, new Dictionary<VariableSymbol, LuaType>());
|
||||
Evaluator = new Evaluator( Diagnostics, new Dictionary<VariableSymbol, LuaType>());
|
||||
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<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>();
|
||||
if (parameters != null)
|
||||
@@ -68,7 +87,22 @@ namespace Upsilon.Evaluator
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user