Better support for binding functions, specifically nested functions
This commit is contained in:
parent
71397f5db2
commit
576273ac56
|
@ -192,7 +192,8 @@ namespace Upsilon.Binder
|
|||
if (expression.Type != Type.Function && expression.Type != Type.Unknown)
|
||||
{
|
||||
//TODO Better error
|
||||
throw new Exception();
|
||||
_diagnostics.LogError($"Unknown function called.", e.Span);
|
||||
return new BoundLiteralExpression(new ScriptNull(), e.Span);
|
||||
}
|
||||
|
||||
var parameters = ImmutableArray.CreateBuilder<BoundExpression>();
|
||||
|
@ -203,10 +204,8 @@ namespace Upsilon.Binder
|
|||
}
|
||||
|
||||
var returnType = Type.Unknown;
|
||||
if (expression.Kind == BoundKind.VariableExpression)
|
||||
if (ResolveVariable(expression) is FunctionVariableSymbol function)
|
||||
{
|
||||
var variableExpression =(BoundVariableExpression) expression;
|
||||
var function = (FunctionVariableSymbol)variableExpression.Variable.VariableSymbol;
|
||||
if (!function.IsBound)
|
||||
{
|
||||
Scope = new BoundScope(Scope);
|
||||
|
@ -221,20 +220,38 @@ namespace Upsilon.Binder
|
|||
var unboundFunctionStatement = _unboundFunctions[function.Name];
|
||||
unboundFunctionStatement.Block =
|
||||
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.UnboundBlock);
|
||||
returnType = Scope.ReturnType;
|
||||
Scope = Scope.ParentScope;
|
||||
function.IsBound = true;
|
||||
returnType = Scope.ReturnType;
|
||||
Scope = Scope.ParentScope;
|
||||
function.IsBound = true;
|
||||
function.ResultType = returnType;
|
||||
_unboundFunctions.Remove(function.Name);
|
||||
}
|
||||
|
||||
returnType = function.ResultType;
|
||||
|
||||
}
|
||||
|
||||
//TODO: validate parameters
|
||||
return new BoundFunctionCallExpression(expression, parameters.ToImmutable(), e.Span, returnType);
|
||||
}
|
||||
|
||||
private VariableSymbol ResolveVariable(BoundExpression expression)
|
||||
{
|
||||
if (expression.Kind == BoundKind.VariableExpression)
|
||||
{
|
||||
var variableExpression = (BoundVariableExpression) expression;
|
||||
return variableExpression.Variable.VariableSymbol;
|
||||
}
|
||||
if (expression.Kind == BoundKind.BoundFullstopIndexExpression)
|
||||
{
|
||||
var fullStopIndexExpression = (BoundFullStopIndexExpression) expression;
|
||||
var indexerExpression = fullStopIndexExpression.Expression;
|
||||
var indexerVariable = (TableVariableSymbol)ResolveVariable(indexerExpression);
|
||||
return indexerVariable.Variables[fullStopIndexExpression.Index];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private BoundExpression BindVariableExpression(VariableExpressionSyntax e)
|
||||
{
|
||||
var name = e.Identifier.Name;
|
||||
|
@ -461,6 +478,7 @@ namespace Upsilon.Binder
|
|||
};
|
||||
variable = functionVariable;
|
||||
functionVariable.IsBound = !(func is UnboundFunctionExpression);
|
||||
functionVariable.ResultType = func.ReturnType;
|
||||
if (isLocal)
|
||||
Scope.DefineLocalVariable(variable);
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue