Make coroutine functions be forced to be created with the coroutine keyword.
This commit is contained in:
parent
dbf4d8a82e
commit
8da35b4e71
|
@ -6,6 +6,11 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
{
|
{
|
||||||
public abstract class ScriptFunction : ScriptType
|
public abstract class ScriptFunction : ScriptType
|
||||||
{
|
{
|
||||||
|
protected ScriptFunction(bool isCoroutine)
|
||||||
|
{
|
||||||
|
IsCoroutine = isCoroutine;
|
||||||
|
}
|
||||||
|
|
||||||
public override TypeContainer Type => BaseTypes.Type.Function;
|
public override TypeContainer Type => BaseTypes.Type.Function;
|
||||||
public override object ToCSharpObject()
|
public override object ToCSharpObject()
|
||||||
{
|
{
|
||||||
|
@ -17,6 +22,8 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsCoroutine { get; }
|
||||||
|
|
||||||
public abstract ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script, EvaluationScope scope, TextSpan span);
|
public abstract ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script, EvaluationScope scope, TextSpan span);
|
||||||
public abstract IEnumerator RunCoroutine(Diagnostics diagnostics, ScriptType[] variables, Script script, EvaluationScope scope, TextSpan span);
|
public abstract IEnumerator RunCoroutine(Diagnostics diagnostics, ScriptType[] variables, Script script, EvaluationScope scope, TextSpan span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
public class ScriptMethodInfoFunction : ScriptFunction
|
public class ScriptMethodInfoFunction : ScriptFunction
|
||||||
{
|
{
|
||||||
public ScriptMethodInfoFunction(UserDataMethod method, object o, bool directTypeManipulation,
|
public ScriptMethodInfoFunction(UserDataMethod method, object o, bool directTypeManipulation,
|
||||||
bool passScriptReference = false, bool passScopeReference = false)
|
bool isCoroutine, bool passScriptReference = false, bool passScopeReference = false) : base(isCoroutine)
|
||||||
{
|
{
|
||||||
Method = method;
|
Method = method;
|
||||||
_object = o;
|
_object = o;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
{
|
{
|
||||||
public List<ScriptRuntimeFunctionOption> Options { get; }
|
public List<ScriptRuntimeFunctionOption> Options { get; }
|
||||||
|
|
||||||
public ScriptRuntimeFunction(List<ScriptRuntimeFunctionOption> options)
|
public ScriptRuntimeFunction(List<ScriptRuntimeFunctionOption> options, bool isCoroutine) : base(isCoroutine)
|
||||||
{
|
{
|
||||||
Options = options;
|
Options = options;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (parameter.VariableSymbol is TableVariableSymbol tableVariableSymbol)
|
else if (parameter.VariableSymbol is TableVariableSymbol)
|
||||||
{
|
{
|
||||||
if (parameterType.GetScriptType() != BaseTypes.Type.Table)
|
if (parameterType.GetScriptType() != BaseTypes.Type.Table)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -77,7 +78,8 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
}
|
}
|
||||||
if (Methods.TryGetValue(member, out var method))
|
if (Methods.TryGetValue(member, out var method))
|
||||||
{
|
{
|
||||||
return (new ScriptMethodInfoFunction(method, value, false), false, null);
|
var isCoroutine = typeof(IEnumerator).IsAssignableFrom(method.ReturnType);
|
||||||
|
return (new ScriptMethodInfoFunction(method, value, false, isCoroutine), false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (null, true, $"Can't find public member '{member}' on type '{Type}'.");
|
return (null, true, $"Can't find public member '{member}' on type '{Type}'.");
|
||||||
|
|
|
@ -691,7 +691,8 @@ namespace Upsilon.Binder
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var unbound = new UnboundFunctionExpression(parameters.ToImmutable(), e.Block, e.Span, innerScope, functionVariableSymbol);
|
var unbound = new UnboundFunctionExpression(parameters.ToImmutable(), e.Block, e.Span, innerScope,
|
||||||
|
functionVariableSymbol, e.IsCoroutine);
|
||||||
_unboundFunctions.Add(unbound);
|
_unboundFunctions.Add(unbound);
|
||||||
return unbound;
|
return unbound;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,8 @@ namespace Upsilon.Binder
|
||||||
internal override ScriptType Evaluate(EvaluationScope scope, Diagnostics diagnostics, ref EvaluationState state)
|
internal override ScriptType Evaluate(EvaluationScope scope, Diagnostics diagnostics, ref EvaluationState state)
|
||||||
{
|
{
|
||||||
var option = new ScriptRuntimeFunction.ScriptRuntimeFunctionOption(Parameters, Block, scope);
|
var option = new ScriptRuntimeFunction.ScriptRuntimeFunctionOption(Parameters, Block, scope);
|
||||||
var func = new ScriptRuntimeFunction(new List<ScriptRuntimeFunction.ScriptRuntimeFunctionOption>(){option});
|
var func = new ScriptRuntimeFunction(new List<ScriptRuntimeFunction.ScriptRuntimeFunctionOption>() {option},
|
||||||
|
IsCoroutine);
|
||||||
return func;
|
return func;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
throw new EvaluationException(state.Script.FileName, $"Variable is not a function.", functionCall.Identifier.Span);
|
throw new EvaluationException(state.Script.FileName, $"Variable is not a function.", functionCall.Identifier.Span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (function.IsCoroutine)
|
||||||
|
{
|
||||||
var ls = new List<ScriptType>();
|
var ls = new List<ScriptType>();
|
||||||
foreach (var t in functionCall.Parameters)
|
foreach (var t in functionCall.Parameters)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +58,7 @@ namespace Upsilon.Binder
|
||||||
}
|
}
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var value = Expression.Evaluate(scope, diagnostics, ref state);
|
var value = Expression.Evaluate(scope, diagnostics, ref state);
|
||||||
yield return value;
|
yield return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ namespace Upsilon.Binder
|
||||||
public class UnboundFunctionExpression : BoundFunctionExpression
|
public class UnboundFunctionExpression : BoundFunctionExpression
|
||||||
{
|
{
|
||||||
public UnboundFunctionExpression(ImmutableArray<BoundVariableSymbol> parameters,
|
public UnboundFunctionExpression(ImmutableArray<BoundVariableSymbol> parameters,
|
||||||
BlockStatementSyntax unboundBlock, TextSpan span, BoundScope scope, string name)
|
BlockStatementSyntax unboundBlock, TextSpan span, BoundScope scope, string name, bool isCoroutine)
|
||||||
: base(parameters, null, span, scope, BaseTypes.Type.Unknown, false)
|
: base(parameters, null, span, scope, BaseTypes.Type.Unknown, isCoroutine)
|
||||||
{
|
{
|
||||||
UnboundBlock = unboundBlock;
|
UnboundBlock = unboundBlock;
|
||||||
Name = name;
|
Name = name;
|
||||||
|
|
|
@ -91,6 +91,11 @@ namespace Upsilon.Evaluator
|
||||||
throw new ArgumentException(($"Function '{functionName}' could not be found"));
|
throw new ArgumentException(($"Function '{functionName}' could not be found"));
|
||||||
}
|
}
|
||||||
var function = (ScriptRuntimeFunction) statement;
|
var function = (ScriptRuntimeFunction) statement;
|
||||||
|
if (!function.IsCoroutine)
|
||||||
|
{
|
||||||
|
throw new EvaluationException(_script.FileName,
|
||||||
|
$"Function with name '{functionName}' is not a coroutine, and can't be executed as such.", e.Span);
|
||||||
|
}
|
||||||
var option = function.GetValidOption(parameters);
|
var option = function.GetValidOption(parameters);
|
||||||
if (option == null)
|
if (option == null)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue