Reworked bound variables into specific LuaType class instead of anonymous objects
This commit is contained in:
parent
dff1ddc0ba
commit
deefe43d9f
|
@ -2,7 +2,7 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Upsilon", "Upsilon\Upsilon.csproj", "{030DBAFB-4E55-427E-82F9-1FD042F96B8F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yc", "Yc\Yc.csproj", "{EF232B73-CDD1-491A-A931-99A9704686E4}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ycicle", "Ycicle\Ycicle.csproj", "{EF232B73-CDD1-491A-A931-99A9704686E4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpsilonTests", "UpsilonTests\UpsilonTests.csproj", "{5CB3C59D-96A1-419E-803B-DE4A7DF806FD}"
|
||||
EndProject
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
namespace Upsilon.BaseTypes
|
||||
{
|
||||
public class Boolean : LuaType
|
||||
{
|
||||
public Boolean(bool value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override Type Type => Type.Boolean;
|
||||
public bool Value { get; }
|
||||
|
||||
public static implicit operator bool(Boolean b)
|
||||
{
|
||||
return b.Value;
|
||||
}
|
||||
|
||||
public static implicit operator Boolean(bool b)
|
||||
{
|
||||
return new Boolean(b);
|
||||
}
|
||||
|
||||
public static Boolean operator ! (Boolean n)
|
||||
{
|
||||
return new Boolean(!n.Value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Upsilon.BaseTypes
|
||||
{
|
||||
public abstract class LuaType
|
||||
{
|
||||
public abstract Type Type { get; }
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
namespace Upsilon.BaseTypes.Number
|
||||
{
|
||||
public abstract class Number
|
||||
public abstract class Number : LuaType
|
||||
{
|
||||
protected abstract bool IsFloat { get; }
|
||||
|
||||
public override Type Type => Type.Number;
|
||||
|
||||
#region Binary Operators
|
||||
|
||||
public static Number operator + (Number a, Number b)
|
||||
|
|
|
@ -21,5 +21,11 @@ namespace Upsilon.BaseTypes.Number
|
|||
{
|
||||
return Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static implicit operator double(NumberDouble n)
|
||||
{
|
||||
return n.Value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ namespace Upsilon.BaseTypes.Number
|
|||
return Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static explicit operator long(NumberLong n)
|
||||
public static implicit operator long(NumberLong n)
|
||||
{
|
||||
return n.Value;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using Upsilon.BaseTypes;
|
||||
using Upsilon.BaseTypes.Number;
|
||||
using Upsilon.Parser;
|
||||
using Boolean = Upsilon.BaseTypes.Boolean;
|
||||
using Type = Upsilon.BaseTypes.Type;
|
||||
|
||||
namespace Upsilon.Binder
|
||||
|
@ -94,7 +96,7 @@ namespace Upsilon.Binder
|
|||
{
|
||||
var value = e.Value;
|
||||
var type = Type.Nil;
|
||||
object outValue = null;
|
||||
LuaType outValue = null;
|
||||
switch (value)
|
||||
{
|
||||
case double d:
|
||||
|
@ -105,9 +107,9 @@ namespace Upsilon.Binder
|
|||
type = Type.Number;
|
||||
outValue = new NumberLong(l);
|
||||
break;
|
||||
case bool _:
|
||||
case bool b:
|
||||
type = Type.Boolean;
|
||||
outValue = value;
|
||||
outValue = new Boolean(b);
|
||||
break;
|
||||
default:
|
||||
_diagnostics.LogUnknownType(e.Span);
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Upsilon.Binder
|
|||
{
|
||||
public class BoundLiteralExpression : BoundExpression
|
||||
{
|
||||
public BoundLiteralExpression(object value, Type type)
|
||||
public BoundLiteralExpression(LuaType value, Type type)
|
||||
{
|
||||
Value = value;
|
||||
Type = type;
|
||||
|
@ -12,6 +12,6 @@ namespace Upsilon.Binder
|
|||
|
||||
public override BoundKind Kind => BoundKind.BoundLiteralExpression;
|
||||
public override Type Type { get; }
|
||||
public object Value { get; }
|
||||
public LuaType Value { get; }
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Upsilon.BaseTypes;
|
||||
|
||||
namespace Upsilon.Binder
|
||||
{
|
||||
|
@ -13,7 +14,7 @@ namespace Upsilon.Binder
|
|||
_parentScope = parentScope;
|
||||
_variables = new Dictionary<string, VariableSymbol>();
|
||||
}
|
||||
public BoundScope(Dictionary<VariableSymbol, object> variables, BoundScope parentScope)
|
||||
public BoundScope(Dictionary<VariableSymbol, LuaType> variables, BoundScope parentScope)
|
||||
{
|
||||
_parentScope = parentScope;
|
||||
_variables = variables.ToDictionary(x => x.Key.Name, x => x.Key);
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Upsilon.BaseTypes;
|
||||
using Upsilon.BaseTypes.Number;
|
||||
using Upsilon.Binder;
|
||||
using Boolean = Upsilon.BaseTypes.Boolean;
|
||||
|
||||
namespace Upsilon.Evaluator
|
||||
{
|
||||
public class Evaluator
|
||||
{
|
||||
private readonly Diagnostics _diagnostics;
|
||||
private object _value;
|
||||
private LuaType _value;
|
||||
private Script Script { get; }
|
||||
private readonly Dictionary<VariableSymbol, object> _variables = new Dictionary<VariableSymbol, object>();
|
||||
private readonly Dictionary<VariableSymbol, LuaType> _variables = new Dictionary<VariableSymbol, LuaType>();
|
||||
|
||||
public Evaluator(Script script, Diagnostics diagnostics)
|
||||
{
|
||||
_diagnostics = diagnostics;
|
||||
Script = script;
|
||||
}
|
||||
public Evaluator(Script script, Diagnostics diagnostics, Dictionary<VariableSymbol, object> vars)
|
||||
public Evaluator(Script script, Diagnostics diagnostics, Dictionary<VariableSymbol, LuaType> vars)
|
||||
{
|
||||
_diagnostics = diagnostics;
|
||||
Script = script;
|
||||
_variables = vars;
|
||||
}
|
||||
|
||||
public object Evaluate(BoundScript e)
|
||||
public LuaType Evaluate(BoundScript e)
|
||||
{
|
||||
EvaluateStatement(e.Statement);
|
||||
return _value;
|
||||
|
@ -55,7 +57,7 @@ namespace Upsilon.Evaluator
|
|||
_value = EvaluateExpression(e.Expression);
|
||||
}
|
||||
|
||||
private object EvaluateExpression(BoundExpression e)
|
||||
private LuaType EvaluateExpression(BoundExpression e)
|
||||
{
|
||||
switch (e.Kind)
|
||||
{
|
||||
|
@ -72,7 +74,7 @@ namespace Upsilon.Evaluator
|
|||
}
|
||||
}
|
||||
|
||||
private object EvaluateUnaryExpression(BoundUnaryExpression e)
|
||||
private LuaType EvaluateUnaryExpression(BoundUnaryExpression e)
|
||||
{
|
||||
var operand = EvaluateExpression(e.InExpression);
|
||||
switch (e.Operator.Kind)
|
||||
|
@ -82,13 +84,13 @@ namespace Upsilon.Evaluator
|
|||
case BoundUnaryOperator.OperatorKind.Negation:
|
||||
return -((Number)operand);
|
||||
case BoundUnaryOperator.OperatorKind.LogicalNegation:
|
||||
return !(bool) operand;
|
||||
return !(Boolean) operand;
|
||||
default:
|
||||
throw new Exception("Invalid Unary Operator: " + e.Operator.Kind);
|
||||
}
|
||||
}
|
||||
|
||||
private object EvaluateBinaryExpression(BoundBinaryExpression e)
|
||||
private LuaType EvaluateBinaryExpression(BoundBinaryExpression e)
|
||||
{
|
||||
var left = EvaluateExpression(e.LeftExpression);
|
||||
var right = EvaluateExpression(e.RightExpression);
|
||||
|
@ -103,9 +105,9 @@ namespace Upsilon.Evaluator
|
|||
case BoundBinaryOperator.OperatorKind.Division:
|
||||
return ((Number)left) / ((Number)right);
|
||||
case BoundBinaryOperator.OperatorKind.Equality:
|
||||
return Equals(left, right);
|
||||
return new Boolean(Equals(left, right));
|
||||
case BoundBinaryOperator.OperatorKind.Inequality:
|
||||
return !Equals(left, right);
|
||||
return new Boolean(!Equals(left, right));
|
||||
default:
|
||||
throw new Exception("Invalid Binary Operator: " + e.Operator);
|
||||
}
|
||||
|
@ -118,7 +120,7 @@ namespace Upsilon.Evaluator
|
|||
_value = val;
|
||||
}
|
||||
|
||||
private object EvaluateVariableExpression(BoundVariableExpression e)
|
||||
private LuaType EvaluateVariableExpression(BoundVariableExpression e)
|
||||
{
|
||||
return _variables[e.Variable];
|
||||
}
|
||||
|
@ -134,7 +136,7 @@ namespace Upsilon.Evaluator
|
|||
private void EvaluateBoundIfStatement(BoundIfStatement boundBlockStatement)
|
||||
{
|
||||
var condition = EvaluateExpression(boundBlockStatement.Condition.Expression);
|
||||
if ((bool) condition)
|
||||
if ((Boolean) condition)
|
||||
{
|
||||
EvaluateBoundBlockStatement(boundBlockStatement.Block);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using Upsilon.BaseTypes;
|
||||
using Upsilon.Binder;
|
||||
using Upsilon.Parser;
|
||||
using Upsilon.Text;
|
||||
|
@ -13,13 +14,13 @@ namespace Upsilon.Evaluator
|
|||
public Diagnostics Diagnostics { get; }
|
||||
private Binder.Binder Binder { get; }
|
||||
|
||||
public Script(string scriptString, Dictionary<VariableSymbol, object> variables = null)
|
||||
public Script(string scriptString, Dictionary<VariableSymbol, LuaType> variables = null)
|
||||
{
|
||||
ScriptString = new SourceText(scriptString);
|
||||
Diagnostics = new Diagnostics(ScriptString);
|
||||
_parsed = Parser.Parser.Parse(scriptString, Diagnostics);
|
||||
if (variables == null)
|
||||
variables = new Dictionary<VariableSymbol, object>();
|
||||
variables = new Dictionary<VariableSymbol, LuaType>();
|
||||
Binder = new Binder.Binder(new BoundScope(variables, null), Diagnostics);
|
||||
Evaluator = new Evaluator(this, Diagnostics, variables);
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ namespace Upsilon.Evaluator
|
|||
return Evaluator.Evaluate(Bind());
|
||||
}
|
||||
|
||||
public T Evaluate<T>()
|
||||
public T Evaluate<T>() where T : LuaType
|
||||
{
|
||||
return (T)Evaluator.Evaluate(Bind());
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Text;
|
||||
using Upsilon.BaseTypes.Number;
|
||||
using Upsilon.Binder;
|
||||
using Boolean = Upsilon.BaseTypes.Boolean;
|
||||
using Type = Upsilon.BaseTypes.Type;
|
||||
|
||||
namespace UpsilonCompiler
|
||||
|
@ -59,7 +60,7 @@ namespace UpsilonCompiler
|
|||
case Type.Nil:
|
||||
return "null";
|
||||
case Type.Boolean:
|
||||
return ((bool)e.Value) ? "true" : "false";
|
||||
return ((Boolean)e.Value) ? "true" : "false";
|
||||
case Type.Number:
|
||||
return ((Number) e.Value).ToString();
|
||||
case Type.String:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Upsilon.BaseTypes.Number;
|
||||
using Upsilon.Evaluator;
|
||||
using Upsilon.Parser;
|
||||
using Xunit;
|
||||
|
@ -16,7 +17,7 @@ namespace UpsilonTests
|
|||
[InlineData("0.005 + 2.2", 2.205)]
|
||||
public void Addition(string input, double expectedOutput)
|
||||
{
|
||||
var actual = new Script(input).Evaluate<double>();
|
||||
var actual = new Script(input).Evaluate<NumberDouble>();
|
||||
Assert.Equal(expectedOutput, actual, 8);
|
||||
}
|
||||
|
||||
|
@ -29,7 +30,7 @@ namespace UpsilonTests
|
|||
[InlineData("10.256-2.8546", 7.4014)]
|
||||
public void Subtraction(string input, double expectedOutput)
|
||||
{
|
||||
var actual = new Script(input).Evaluate<double>();
|
||||
var actual = new Script(input).Evaluate<NumberDouble>();
|
||||
Assert.Equal(expectedOutput, actual, 8);
|
||||
}
|
||||
|
||||
|
@ -39,7 +40,7 @@ namespace UpsilonTests
|
|||
[InlineData("21312 * 41684", 888369408)]
|
||||
public void Multiplication(string input, double expectedOutput)
|
||||
{
|
||||
var actual = new Script(input).Evaluate<double>();
|
||||
var actual = new Script(input).Evaluate<NumberDouble>();
|
||||
Assert.Equal(expectedOutput, actual, 8);
|
||||
}
|
||||
|
||||
|
@ -49,7 +50,7 @@ namespace UpsilonTests
|
|||
[InlineData("656486 / 5146", 127.57209483)]
|
||||
public void Divison(string input, double expectedOutput)
|
||||
{
|
||||
var actual = new Script(input).Evaluate<double>();
|
||||
var actual = new Script(input).Evaluate<NumberDouble>();
|
||||
Assert.Equal(expectedOutput, actual, 8);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Upsilon.BaseTypes;
|
||||
using Upsilon.BaseTypes.Number;
|
||||
using Upsilon.Evaluator;
|
||||
using Xunit;
|
||||
|
@ -12,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<bool>();
|
||||
var actual = script.Evaluate<Boolean>();
|
||||
Assert.True(actual);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Upsilon.BaseTypes.Number;
|
||||
using Upsilon.Evaluator;
|
||||
using Upsilon.Parser;
|
||||
using Xunit;
|
||||
|
@ -11,7 +12,7 @@ namespace UpsilonTests
|
|||
[InlineData("(10 + 5) * 5", 75)]
|
||||
public void Parenthesis(string input, double expectedOutput)
|
||||
{
|
||||
var actual = new Script(input).Evaluate<double>();
|
||||
var actual = new Script(input).Evaluate<NumberDouble>();
|
||||
Assert.Equal(expectedOutput, actual, 8);
|
||||
}
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace UpsilonTests
|
|||
[InlineData("5 + 10 * 5", 55)]
|
||||
public void MultiplicationBeforeAddition(string input, double expectedOutput)
|
||||
{
|
||||
var actual = new Script(input).Evaluate<double>();
|
||||
var actual = new Script(input).Evaluate<NumberDouble>();
|
||||
Assert.Equal(expectedOutput, actual, 8);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Upsilon;
|
||||
using Upsilon.BaseTypes;
|
||||
using Upsilon.Binder;
|
||||
using Upsilon.Evaluator;
|
||||
using UpsilonCompiler;
|
||||
|
||||
namespace Yc
|
||||
namespace Ycicle
|
||||
{
|
||||
static class Program
|
||||
internal static class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
private static void Main()
|
||||
{
|
||||
Console.WriteLine("Upsilon REPL");
|
||||
Dictionary<VariableSymbol, object> variables = new Dictionary<VariableSymbol, object>();
|
||||
var variables = new Dictionary<VariableSymbol, LuaType>();
|
||||
var showTranspiledOutput = false;
|
||||
while (true)
|
||||
{
|
||||
Console.Write("» ");
|
||||
var input = Console.ReadLine();
|
||||
if (input == "exit")
|
||||
switch (input)
|
||||
{
|
||||
return;
|
||||
case "exit":
|
||||
return;
|
||||
case "compiled":
|
||||
showTranspiledOutput = !showTranspiledOutput;
|
||||
break;
|
||||
}
|
||||
|
||||
var parsed = new Script(input, variables);
|
||||
|
@ -35,31 +41,36 @@ namespace Yc
|
|||
continue;
|
||||
}
|
||||
|
||||
var compiler = new Transpiler();
|
||||
var compiled = compiler.TranspilerToCSharp(parsed.Bind());
|
||||
Console.WriteLine(compiled);
|
||||
/*
|
||||
var evaluate = parsed.Evaluate();
|
||||
if (parsed.Diagnostics.Messages.Count > 0)
|
||||
if (showTranspiledOutput)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Errors were found during evaluating");
|
||||
foreach (var diagnosticsMessage in parsed.Diagnostics.Messages)
|
||||
{
|
||||
LogError(diagnosticsMessage);
|
||||
}
|
||||
Console.ResetColor();
|
||||
var transpiler = new Transpiler();
|
||||
var transpiled = transpiler.TranspilerToCSharp(parsed.Bind());
|
||||
Console.WriteLine(transpiled);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine(evaluate);
|
||||
Console.ResetColor();
|
||||
}*/
|
||||
var evaluate = parsed.Evaluate();
|
||||
if (parsed.Diagnostics.Messages.Count > 0)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Errors were found during evaluating");
|
||||
foreach (var diagnosticsMessage in parsed.Diagnostics.Messages)
|
||||
{
|
||||
LogError(diagnosticsMessage);
|
||||
}
|
||||
Console.ResetColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine(evaluate);
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void LogError(DiagnosticsMessage message)
|
||||
private static void LogError(DiagnosticsMessage message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(message.Message);
|
Loading…
Reference in New Issue