Better support for binding functions, specifically nested functions

This commit is contained in:
Deukhoofd 2018-11-28 13:30:24 +01:00
parent 71397f5db2
commit 576273ac56
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
1 changed files with 25 additions and 7 deletions

View File

@ -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