Files
Upsilon/Upsilon/Evaluator/Evaluator.cs

86 lines
3.1 KiB
C#

using System;
using System.Linq;
using Upsilon.BaseTypes;
using Upsilon.BaseTypes.ScriptFunction;
using Upsilon.Binder;
using Upsilon.Evaluator.Debugging;
using Upsilon.Exceptions;
using Upsilon.Text;
using Upsilon.Utilities;
using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Evaluator
{
internal class Evaluator
{
private readonly Script _script;
private Diagnostics _diagnostics;
internal EvaluationScope Scope { get; private set; }
internal Evaluator(Diagnostics diagnostics, EvaluationScope parentScope, Script script)
{
_diagnostics = diagnostics;
_script = script;
Scope = new EvaluationScope(parentScope);
}
private Evaluator(Script script)
{
_script = script;
}
internal static Evaluator CreateWithSetScope(Diagnostics diagnostics, EvaluationScope scope, Script script)
{
return new Evaluator(script) {_diagnostics = diagnostics, Scope = scope};
}
public ScriptType Evaluate(BoundScript e)
{
if (DebugSession.DebuggerAttached && !string.IsNullOrWhiteSpace(e.FileName))
{
var file = DebugSession.GetFileInfo(e.FileName);
if (file != null)
{
foreach (var breakpoint in file.Breakpoints)
{
var debugStatement = e.GetBottomStatementAtPosition(breakpoint.Line, breakpoint.Position);
debugStatement.HasBreakpoint = true;
}
}
}
var evaluationState = new EvaluationState()
{
Script = _script
};
e.Evaluate(Scope, _diagnostics, ref evaluationState);
if (evaluationState.ReturnValue != null)
return evaluationState.ReturnValue;
return evaluationState.LastValue;
}
public ScriptType Evaluate(BoundScript e, string functionName, object[] parameters)
{
if (!Scope.TryGet(functionName, out var statement) || statement.Type != Type.Function)
{
throw new ArgumentException(($"Function '{functionName}' could not be found"));
}
var function = (ScriptRuntimeFunction) statement;
var option = function.GetValidOption(parameters);
if (option == null)
{
if (parameters == null)
{
throw new EvaluationException(_script.FileName,
$"No function found with name '{functionName}' and no parameters.",
e.Span);
}
throw new EvaluationException(_script.FileName,
$"No function found with name '{functionName}' and available parameters {string.Join(", ", parameters.Select(x => $"{x.GetType().Name}"))}",
e.Span);
}
var result = option.Run(_diagnostics, parameters?.Select(x => x.ToScriptType()).ToArray(), _script, Scope, new TextSpan());
return result;
}
}
}