Handle variables
This commit is contained in:
parent
0693698f28
commit
ab61a01573
|
@ -3,19 +3,28 @@ using Upsilon.Parser;
|
||||||
|
|
||||||
namespace Upsilon.Evaluator
|
namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
public static class Evaluator
|
public class Evaluator
|
||||||
{
|
{
|
||||||
public static object Evaluate(this ScriptSyntax e)
|
public Script Script { get; }
|
||||||
|
public VariableScope Scope { get; }
|
||||||
|
|
||||||
|
public Evaluator(Script script, VariableScope scope)
|
||||||
|
{
|
||||||
|
Script = script;
|
||||||
|
Scope = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Evaluate(ScriptSyntax e)
|
||||||
{
|
{
|
||||||
return EvaluateExpression(e.Statement);
|
return EvaluateExpression(e.Statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object Evaluate(this ExpressionSyntax e)
|
public object Evaluate(ExpressionSyntax e)
|
||||||
{
|
{
|
||||||
return EvaluateExpression(e);
|
return EvaluateExpression(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static object EvaluateExpression(ExpressionSyntax e)
|
private object EvaluateExpression(ExpressionSyntax e)
|
||||||
{
|
{
|
||||||
switch (e.Kind)
|
switch (e.Kind)
|
||||||
{
|
{
|
||||||
|
@ -26,13 +35,17 @@ namespace Upsilon.Evaluator
|
||||||
case SyntaxKind.LiteralExpression:
|
case SyntaxKind.LiteralExpression:
|
||||||
return ((LiteralExpressionSyntax) e).Value;
|
return ((LiteralExpressionSyntax) e).Value;
|
||||||
case SyntaxKind.ParenthesizedExpression:
|
case SyntaxKind.ParenthesizedExpression:
|
||||||
return ((ParenthesizedExpressionSyntax) e).Expression.Evaluate();
|
return Evaluate(((ParenthesizedExpressionSyntax)e).Expression);
|
||||||
|
case SyntaxKind.AssignmentExpression:
|
||||||
|
return EvaluateAssignmentExpression((AssignmentExpressionSyntax)e);
|
||||||
|
case SyntaxKind.VariableExpression:
|
||||||
|
return EvaluateVariableExpression((VariableExpressionSyntax) e);
|
||||||
default:
|
default:
|
||||||
throw new Exception("Invalid expression: " + e.Kind);
|
throw new Exception("Invalid expression: " + e.Kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static object EvaluateUnaryExpression(UnaryExpressionSyntax e)
|
private object EvaluateUnaryExpression(UnaryExpressionSyntax e)
|
||||||
{
|
{
|
||||||
var operand = EvaluateExpression(e.Expression);
|
var operand = EvaluateExpression(e.Expression);
|
||||||
switch (e.Operator.Kind)
|
switch (e.Operator.Kind)
|
||||||
|
@ -48,7 +61,7 @@ namespace Upsilon.Evaluator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static object EvaluateBinaryExpression(BinaryExpressionSyntax e)
|
private object EvaluateBinaryExpression(BinaryExpressionSyntax e)
|
||||||
{
|
{
|
||||||
var left = EvaluateExpression(e.Left);
|
var left = EvaluateExpression(e.Left);
|
||||||
var right = EvaluateExpression(e.Right);
|
var right = EvaluateExpression(e.Right);
|
||||||
|
@ -75,5 +88,30 @@ namespace Upsilon.Evaluator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private object EvaluateAssignmentExpression(AssignmentExpressionSyntax e)
|
||||||
|
{
|
||||||
|
var variableName = e.Identifier.Name;
|
||||||
|
var val = EvaluateExpression(e.Expression);
|
||||||
|
if (e.LocalToken == null)
|
||||||
|
{
|
||||||
|
Scope.SetGlobalVariable(variableName, val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Scope.SetVariable(variableName, val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private object EvaluateVariableExpression(VariableExpressionSyntax e)
|
||||||
|
{
|
||||||
|
var varName = e.Identifier.Name;
|
||||||
|
if (Scope.TryGetVariable(varName, out var value))
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
throw new Exception("Unknown variable: " + varName);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Upsilon.Parser;
|
||||||
|
|
||||||
|
namespace Upsilon.Evaluator
|
||||||
|
{
|
||||||
|
public class Script : VariableScope
|
||||||
|
{
|
||||||
|
private string ScriptString { get; }
|
||||||
|
private Evaluator Evaluator { get; }
|
||||||
|
public readonly ScriptSyntax Parsed;
|
||||||
|
|
||||||
|
public Script(string scriptString)
|
||||||
|
{
|
||||||
|
ScriptString = scriptString;
|
||||||
|
Evaluator = new Evaluator(this, this);
|
||||||
|
Parsed = Parser.Parser.Parse(scriptString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Script(string scriptString, Dictionary<string, object> variables = null)
|
||||||
|
:base(variables: variables)
|
||||||
|
{
|
||||||
|
ScriptString = scriptString;
|
||||||
|
Evaluator = new Evaluator(this, this);
|
||||||
|
Parsed = Parser.Parser.Parse(scriptString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Evaluate()
|
||||||
|
{
|
||||||
|
return Evaluator.Evaluate(Parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Evaluate<T>()
|
||||||
|
{
|
||||||
|
return (T)Evaluator.Evaluate(Parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Upsilon.Evaluator
|
||||||
|
{
|
||||||
|
public class VariableScope
|
||||||
|
{
|
||||||
|
private VariableScope _parentScope;
|
||||||
|
public readonly Dictionary<string, object> Variables = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
public VariableScope(VariableScope parentScope = null, Dictionary<string, object> variables = null)
|
||||||
|
{
|
||||||
|
_parentScope = parentScope;
|
||||||
|
if (variables != null)
|
||||||
|
Variables = variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetVariable(string key, object value)
|
||||||
|
{
|
||||||
|
if (Variables.ContainsKey(key))
|
||||||
|
Variables[key] = value;
|
||||||
|
else
|
||||||
|
Variables.Add(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetGlobalVariable(string key, object value)
|
||||||
|
{
|
||||||
|
if (_parentScope == null)
|
||||||
|
{
|
||||||
|
SetVariable(key, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_parentScope.SetGlobalVariable(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool TryGetVariable(string key, out object result)
|
||||||
|
{
|
||||||
|
if (Variables.TryGetValue(key, out result))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (_parentScope != null)
|
||||||
|
{
|
||||||
|
return _parentScope.TryGetVariable(key, out result);
|
||||||
|
}
|
||||||
|
throw new Exception("Variable not found: " + key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Upsilon.Parser
|
||||||
|
{
|
||||||
|
public class AssignmentExpressionSyntax : ExpressionSyntax
|
||||||
|
{
|
||||||
|
public AssignmentExpressionSyntax(SyntaxToken localToken, IdentifierToken identifier, SyntaxToken equalsToken,
|
||||||
|
ExpressionSyntax expression)
|
||||||
|
{
|
||||||
|
LocalToken = localToken;
|
||||||
|
Identifier = identifier;
|
||||||
|
EqualsToken = equalsToken;
|
||||||
|
Expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SyntaxKind Kind => SyntaxKind.AssignmentExpression;
|
||||||
|
|
||||||
|
public SyntaxToken LocalToken { get; }
|
||||||
|
public IdentifierToken Identifier { get; }
|
||||||
|
public SyntaxToken EqualsToken { get; }
|
||||||
|
public ExpressionSyntax Expression { get; }
|
||||||
|
|
||||||
|
public override IEnumerable<SyntaxNode> ChildNodes()
|
||||||
|
{
|
||||||
|
yield return Identifier;
|
||||||
|
yield return Expression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Upsilon.Parser
|
||||||
|
{
|
||||||
|
public class VariableExpressionSyntax : ExpressionSyntax
|
||||||
|
{
|
||||||
|
public IdentifierToken Identifier { get; }
|
||||||
|
|
||||||
|
public VariableExpressionSyntax(IdentifierToken identifier)
|
||||||
|
{
|
||||||
|
Identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SyntaxKind Kind => SyntaxKind.VariableExpression;
|
||||||
|
public override IEnumerable<SyntaxNode> ChildNodes()
|
||||||
|
{
|
||||||
|
yield return Identifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Upsilon.Parser
|
||||||
|
{
|
||||||
|
public class IdentifierToken : SyntaxToken
|
||||||
|
{
|
||||||
|
public IdentifierToken(string name, int position, int length) : base(SyntaxKind.Identifier, position, name, null)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
public override SyntaxKind Kind => SyntaxKind.Identifier;
|
||||||
|
public override IEnumerable<SyntaxNode> ChildNodes()
|
||||||
|
{
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,16 +127,21 @@ namespace Upsilon.Parser
|
||||||
private SyntaxToken LexIdentifierOrKeyword()
|
private SyntaxToken LexIdentifierOrKeyword()
|
||||||
{
|
{
|
||||||
var start = _position;
|
var start = _position;
|
||||||
var numStr = new StringBuilder();
|
var stringBuilder = new StringBuilder();
|
||||||
numStr.Append(Current);
|
stringBuilder.Append(Current);
|
||||||
while (char.IsLetterOrDigit(Next) || Next == '_')
|
while (char.IsLetterOrDigit(Next) || Next == '_')
|
||||||
{
|
{
|
||||||
numStr.Append(Next);
|
stringBuilder.Append(Next);
|
||||||
_position++;
|
_position++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var kind = SyntaxKeyWords.GetSyntaxKind(numStr.ToString());
|
var kind = SyntaxKeyWords.GetSyntaxKind(stringBuilder.ToString());
|
||||||
return new SyntaxToken(kind, start, numStr.ToString(), null);
|
var str = stringBuilder.ToString();
|
||||||
|
if (kind == SyntaxKind.Identifier)
|
||||||
|
{
|
||||||
|
return new IdentifierToken(str, start, str.Length);
|
||||||
|
}
|
||||||
|
return new SyntaxToken(kind, start, str, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -53,9 +53,30 @@ namespace Upsilon.Parser
|
||||||
|
|
||||||
public ExpressionSyntax ParseExpression()
|
public ExpressionSyntax ParseExpression()
|
||||||
{
|
{
|
||||||
|
if (Current.Kind == SyntaxKind.Identifier && Next.Kind == SyntaxKind.Equals)
|
||||||
|
{
|
||||||
|
return AssignmentExpression();
|
||||||
|
}
|
||||||
|
if (Current.Kind == SyntaxKind.LocalKeyword && Next.Kind == SyntaxKind.Identifier)
|
||||||
|
{
|
||||||
|
return AssignmentExpression();
|
||||||
|
}
|
||||||
return ParseBinaryExpression();
|
return ParseBinaryExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AssignmentExpressionSyntax AssignmentExpression()
|
||||||
|
{
|
||||||
|
SyntaxToken localKeyword = null;
|
||||||
|
if (Current.Kind == SyntaxKind.LocalKeyword)
|
||||||
|
{
|
||||||
|
localKeyword = MatchToken(SyntaxKind.LocalKeyword);
|
||||||
|
}
|
||||||
|
var identifier = (IdentifierToken)MatchToken(SyntaxKind.Identifier);
|
||||||
|
var assignmentToken = MatchToken(SyntaxKind.Equals);
|
||||||
|
var expression = ParseExpression();
|
||||||
|
return new AssignmentExpressionSyntax(localKeyword, identifier, assignmentToken, expression);
|
||||||
|
}
|
||||||
|
|
||||||
private ExpressionSyntax ParseBinaryExpression(SyntaxKindPrecedence.Precedence parentPrecedence = SyntaxKindPrecedence.Precedence.None)
|
private ExpressionSyntax ParseBinaryExpression(SyntaxKindPrecedence.Precedence parentPrecedence = SyntaxKindPrecedence.Precedence.None)
|
||||||
{
|
{
|
||||||
ExpressionSyntax left;
|
ExpressionSyntax left;
|
||||||
|
@ -96,6 +117,9 @@ namespace Upsilon.Parser
|
||||||
case SyntaxKind.TrueKeyword:
|
case SyntaxKind.TrueKeyword:
|
||||||
case SyntaxKind.FalseKeyword:
|
case SyntaxKind.FalseKeyword:
|
||||||
return ParseBoolean();
|
return ParseBoolean();
|
||||||
|
case SyntaxKind.Identifier:
|
||||||
|
var token = MatchToken(SyntaxKind.Identifier);
|
||||||
|
return new VariableExpressionSyntax((IdentifierToken) token);
|
||||||
default:
|
default:
|
||||||
throw new Exception("Unknown primary expression type: " + Current.Kind);
|
throw new Exception("Unknown primary expression type: " + Current.Kind);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ namespace Upsilon.Parser
|
||||||
return SyntaxKind.AndKeyword;
|
return SyntaxKind.AndKeyword;
|
||||||
case "or":
|
case "or":
|
||||||
return SyntaxKind.OrKeyword;
|
return SyntaxKind.OrKeyword;
|
||||||
|
case "local":
|
||||||
|
return SyntaxKind.LocalKeyword;
|
||||||
default:
|
default:
|
||||||
return SyntaxKind.Identifier;
|
return SyntaxKind.Identifier;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Upsilon.Parser
|
||||||
NotKeyword,
|
NotKeyword,
|
||||||
AndKeyword,
|
AndKeyword,
|
||||||
OrKeyword,
|
OrKeyword,
|
||||||
|
LocalKeyword,
|
||||||
|
|
||||||
Identifier,
|
Identifier,
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@ namespace Upsilon.Parser
|
||||||
BinaryExpression,
|
BinaryExpression,
|
||||||
LiteralExpression,
|
LiteralExpression,
|
||||||
ParenthesizedExpression,
|
ParenthesizedExpression,
|
||||||
|
AssignmentExpression,
|
||||||
|
VariableExpression,
|
||||||
|
|
||||||
// script unit
|
// script unit
|
||||||
ScriptUnit,
|
ScriptUnit,
|
||||||
|
|
|
@ -30,17 +30,23 @@ namespace Upsilon.Parser
|
||||||
{
|
{
|
||||||
switch (kind)
|
switch (kind)
|
||||||
{
|
{
|
||||||
|
// equality operators
|
||||||
case SyntaxKind.EqualsEquals:
|
case SyntaxKind.EqualsEquals:
|
||||||
return Precedence.Equality;
|
return Precedence.Equality;
|
||||||
case SyntaxKind.TildeEquals:
|
case SyntaxKind.TildeEquals:
|
||||||
return Precedence.Equality;
|
return Precedence.Equality;
|
||||||
|
|
||||||
|
// logical operators
|
||||||
case SyntaxKind.AndKeyword:
|
case SyntaxKind.AndKeyword:
|
||||||
return Precedence.And;
|
return Precedence.And;
|
||||||
case SyntaxKind.OrKeyword:
|
case SyntaxKind.OrKeyword:
|
||||||
return Precedence.Or;
|
return Precedence.Or;
|
||||||
|
|
||||||
|
// math operators
|
||||||
case SyntaxKind.Plus:
|
case SyntaxKind.Plus:
|
||||||
case SyntaxKind.Minus:
|
case SyntaxKind.Minus:
|
||||||
return Precedence.PlusMinus;
|
return Precedence.PlusMinus;
|
||||||
|
|
||||||
case SyntaxKind.Star:
|
case SyntaxKind.Star:
|
||||||
case SyntaxKind.Slash:
|
case SyntaxKind.Slash:
|
||||||
return Precedence.StarSlash;
|
return Precedence.StarSlash;
|
||||||
|
|
|
@ -3,7 +3,7 @@ using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Parser
|
namespace Upsilon.Parser
|
||||||
{
|
{
|
||||||
public sealed class SyntaxToken : SyntaxNode
|
public class SyntaxToken : SyntaxNode
|
||||||
{
|
{
|
||||||
public SyntaxToken(SyntaxKind kind, int position, string text, object value)
|
public SyntaxToken(SyntaxKind kind, int position, string text, object value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,10 @@ namespace Upsilon.Utilities
|
||||||
sb.Append("|-- ");
|
sb.Append("|-- ");
|
||||||
}
|
}
|
||||||
sb.Append(token.Kind);
|
sb.Append(token.Kind);
|
||||||
|
if (token is SyntaxToken node && node.Value != null)
|
||||||
|
{
|
||||||
|
sb.Append($" - {node.Value}");
|
||||||
|
}
|
||||||
foreach (var syntaxNode in token.ChildNodes())
|
foreach (var syntaxNode in token.ChildNodes())
|
||||||
{
|
{
|
||||||
sb.Append("\n");
|
sb.Append("\n");
|
||||||
|
|
|
@ -16,7 +16,7 @@ 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 = (double)Parser.Parse(input).Evaluate();
|
var actual = new Script(input).Evaluate<double>();
|
||||||
Assert.Equal(expectedOutput, actual, 8);
|
Assert.Equal(expectedOutput, actual, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ 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 = (double)Parser.Parse(input).Evaluate();
|
var actual = new Script(input).Evaluate<double>();
|
||||||
Assert.Equal(expectedOutput, actual, 8);
|
Assert.Equal(expectedOutput, actual, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ 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 = (double)Parser.Parse(input).Evaluate();
|
var actual = new Script(input).Evaluate<double>();
|
||||||
Assert.Equal(expectedOutput, actual, 8);
|
Assert.Equal(expectedOutput, actual, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace UpsilonTests
|
||||||
[InlineData("656486 / 5146", 127.57209483)]
|
[InlineData("656486 / 5146", 127.57209483)]
|
||||||
public void Divison(string input, double expectedOutput)
|
public void Divison(string input, double expectedOutput)
|
||||||
{
|
{
|
||||||
var actual = (double)Parser.Parse(input).Evaluate();
|
var actual = new Script(input).Evaluate<double>();
|
||||||
Assert.Equal(expectedOutput, actual, 8);
|
Assert.Equal(expectedOutput, actual, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,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 = (double)Parser.Parse(input).Evaluate();
|
var actual = new Script(input).Evaluate<double>();
|
||||||
Assert.Equal(expectedOutput, actual, 8);
|
Assert.Equal(expectedOutput, actual, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,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 = (double)Parser.Parse(input).Evaluate();
|
var actual = new Script(input).Evaluate<double>();
|
||||||
Assert.Equal(expectedOutput, actual, 8);
|
Assert.Equal(expectedOutput, actual, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
using Upsilon.Parser;
|
using Upsilon.Utilities;
|
||||||
|
|
||||||
namespace Yc
|
namespace Yc
|
||||||
{
|
{
|
||||||
|
@ -9,6 +10,7 @@ namespace Yc
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Upsilon REPL");
|
Console.WriteLine("Upsilon REPL");
|
||||||
|
Dictionary<string, object> variables = new Dictionary<string, object>();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Console.Write("» ");
|
Console.Write("» ");
|
||||||
|
@ -18,9 +20,10 @@ namespace Yc
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parser = Parser.Parse(input);
|
var parsed = new Script(input, variables);
|
||||||
//Console.WriteLine(parser.Print());
|
//Console.WriteLine(parsed.Parsed.Print());
|
||||||
Console.WriteLine(parser.Evaluate());
|
Console.WriteLine(parsed.Evaluate());
|
||||||
|
variables = parsed.Variables;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue