Skip to content

Commit

Permalink
Improve error checking when calling functions
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanmoffat committed Feb 3, 2022
1 parent 46730be commit 1b72feb
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 10 deletions.
21 changes: 13 additions & 8 deletions EOBot/Interpreter/States/FunctionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ public FunctionEvaluator(IEnumerable<IScriptEvaluator> evaluators)

if (input.OperationStack.Count == 0)
return StackEmptyError(input.Current());
var endParen = input.OperationStack.Pop();
if (endParen.TokenType != BotTokenType.RParen)
return StackTokenError(BotTokenType.RParen, endParen);
var rParen = input.OperationStack.Pop();
if (rParen.TokenType != BotTokenType.RParen)
return StackTokenError(BotTokenType.RParen, rParen);

var parameters = new List<VariableBotToken>();
while (input.OperationStack.Count > 0 && input.OperationStack.Peek().TokenType != BotTokenType.LParen)
Expand All @@ -46,20 +46,25 @@ public FunctionEvaluator(IEnumerable<IScriptEvaluator> evaluators)
parameters.Insert(0, parameter);
}

// todo: check this result
input.OperationStack.Pop(); // LParen
var lParen = input.OperationStack.Pop();
if (lParen.TokenType != BotTokenType.LParen)
return StackTokenError(BotTokenType.LParen, lParen);

if (input.OperationStack.Count == 0)
return StackEmptyError(input.Current());
var functionToken = input.OperationStack.Pop();

// todo: error when function not found
if (!input.SymbolTable.ContainsKey(functionToken.TokenValue))
return IdentifierNotFoundError(new IdentifierBotToken(BotTokenType.Identifier, functionToken.TokenValue, functionToken.LineNumber, functionToken.Column));

var function = input.SymbolTable[functionToken.TokenValue].Identifiable;

if (function is IAsyncFunction)
return await CallAsync(input, functionToken, (dynamic)function, parameters.Select(x => x.VariableValue).ToArray());

return Call(input, functionToken, (dynamic)function, parameters.Select(x => x.VariableValue).ToArray());
else if (function is IFunction)
return Call(input, functionToken, (dynamic)function, parameters.Select(x => x.VariableValue).ToArray());
else
return (EvalResult.Failed, $"Expected identifier {functionToken.TokenValue} to be a function, but it was {function.GetType().Name}", functionToken);
}

private (EvalResult, string, BotToken) Call(ProgramState input, BotToken functionToken, ICallable function, params IVariable[] variables)
Expand Down
5 changes: 3 additions & 2 deletions EOBot/Interpreter/Variables/ICallable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

namespace EOBot.Interpreter.Variables
{
public interface ICallable : IIdentifiable
public interface IFunction : IIdentifiable { }
public interface ICallable : IFunction
{
void Call(params IIdentifiable[] parameters);
}

public interface ICallable<T> : IIdentifiable
public interface ICallable<T> : IFunction
{
T Call(params IIdentifiable[] parameters);
}
Expand Down

0 comments on commit 1b72feb

Please sign in to comment.