86 lines
3.1 KiB
C#
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;
|
|
}
|
|
}
|
|
} |