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)
|
if (expression.Type != Type.Function && expression.Type != Type.Unknown)
|
||||||
{
|
{
|
||||||
//TODO Better error
|
//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>();
|
var parameters = ImmutableArray.CreateBuilder<BoundExpression>();
|
||||||
|
@ -203,10 +204,8 @@ namespace Upsilon.Binder
|
||||||
}
|
}
|
||||||
|
|
||||||
var returnType = Type.Unknown;
|
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)
|
if (!function.IsBound)
|
||||||
{
|
{
|
||||||
Scope = new BoundScope(Scope);
|
Scope = new BoundScope(Scope);
|
||||||
|
@ -221,20 +220,38 @@ namespace Upsilon.Binder
|
||||||
var unboundFunctionStatement = _unboundFunctions[function.Name];
|
var unboundFunctionStatement = _unboundFunctions[function.Name];
|
||||||
unboundFunctionStatement.Block =
|
unboundFunctionStatement.Block =
|
||||||
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.UnboundBlock);
|
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.UnboundBlock);
|
||||||
returnType = Scope.ReturnType;
|
returnType = Scope.ReturnType;
|
||||||
Scope = Scope.ParentScope;
|
Scope = Scope.ParentScope;
|
||||||
function.IsBound = true;
|
function.IsBound = true;
|
||||||
function.ResultType = returnType;
|
function.ResultType = returnType;
|
||||||
_unboundFunctions.Remove(function.Name);
|
_unboundFunctions.Remove(function.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
returnType = function.ResultType;
|
returnType = function.ResultType;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: validate parameters
|
//TODO: validate parameters
|
||||||
return new BoundFunctionCallExpression(expression, parameters.ToImmutable(), e.Span, returnType);
|
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)
|
private BoundExpression BindVariableExpression(VariableExpressionSyntax e)
|
||||||
{
|
{
|
||||||
var name = e.Identifier.Name;
|
var name = e.Identifier.Name;
|
||||||
|
@ -461,6 +478,7 @@ namespace Upsilon.Binder
|
||||||
};
|
};
|
||||||
variable = functionVariable;
|
variable = functionVariable;
|
||||||
functionVariable.IsBound = !(func is UnboundFunctionExpression);
|
functionVariable.IsBound = !(func is UnboundFunctionExpression);
|
||||||
|
functionVariable.ResultType = func.ReturnType;
|
||||||
if (isLocal)
|
if (isLocal)
|
||||||
Scope.DefineLocalVariable(variable);
|
Scope.DefineLocalVariable(variable);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue