Implements binding and evaluating function declarations

This commit is contained in:
2019-06-01 12:33:52 +02:00
parent c407ba2f50
commit 6936b26cae
11 changed files with 215 additions and 10 deletions

View File

@@ -0,0 +1,57 @@
#ifndef PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP
#define PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP
#include "../../ScriptType.hpp"
#include "EvalValue.hpp"
#include "../../Binder/BoundStatements/BoundStatement.hpp"
#include "../Evaluator.hpp"
class ScriptFunctionEvalValue : public EvalValue{
BoundBlockStatement* _innerBlock;
FunctionScriptType _type;
public:
explicit ScriptFunctionEvalValue(BoundBlockStatement* innerBlock, const FunctionScriptType& type)
: _type(type)
{
_innerBlock = innerBlock;
}
EvalValue* Clone() final{
return new ScriptFunctionEvalValue(_innerBlock, _type);
}
~ScriptFunctionEvalValue() final{
delete _innerBlock;
}
ScriptType* GetType() final{
return &_type;
};
bool operator ==(EvalValue* b) final{
if (b->GetType()->GetClass() != TypeClass::Function)
return false;
return this->_innerBlock == ((ScriptFunctionEvalValue*)b)->_innerBlock;
};
EvalValue* EvaluateFunction(Evaluator* evaluator, const vector<EvalValue*>& parameters){
auto parameterTypes = _type.GetParameterTypes();
auto parameterKeys = _type.GetParameterKeys();
auto scope = evaluator->GetScope();
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++){
auto parameter = parameters[i];
auto requiredType = parameterTypes[i];
if (parameter->GetType() != requiredType){
throw EvaluationException("Passed wrong type to function.");
}
auto key = parameterKeys[i];
scope->CreateVariable(_type.GetScopeId(), key, parameter->Clone());
}
evaluator->EvaluateBlockStatement(_innerBlock);
return nullptr;
}
};
#endif //PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP

View File

@@ -3,6 +3,7 @@
#include "EvaluationException.hpp"
#include "../Script.hpp"
#include "EvaluationScope/EvaluationScope.hpp"
#include "EvalValues/ScriptFunctionEvalValue.hpp"
void Evaluator::Evaluate(BoundScriptStatement *statement) {
this->_evaluationScope = new EvaluationScope(this->_scriptData->_scriptVariables, statement->GetDeepestScope());
@@ -15,6 +16,7 @@ void Evaluator::EvaluateStatement(BoundStatement *statement) {
case BoundStatementKind ::Block: return this -> EvaluateBlockStatement((BoundBlockStatement*)statement);
case BoundStatementKind ::Expression: return this -> EvaluateExpressionStatement((BoundExpressionStatement*)statement);
case BoundStatementKind ::Assignment: return this -> EvaluateAssignmentStatement((BoundAssignmentStatement*)statement);
case BoundStatementKind ::FunctionDeclaration: return this->EvaluateFunctionDeclarationStatement((BoundFunctionDeclarationStatement*)statement);
case BoundStatementKind::Bad:
throw;
@@ -46,6 +48,18 @@ void Evaluator::EvaluateAssignmentStatement(BoundAssignmentStatement *statement)
}
}
void Evaluator::EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement) {
auto type = statement->GetType();
auto key = statement->GetKey();
auto block = statement->GetBlock();
auto value = new ScriptFunctionEvalValue(block, *type);
if (key->IsCreation()){
this->_evaluationScope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), value);
} else{
this->_evaluationScope->SetVariable(key->GetScopeId(), key->GetIdentifier(), value);
}
}
EvalValue *Evaluator::EvaluateExpression(BoundExpression *expression) {
auto type = expression -> GetType();
switch (type->GetClass()){

View File

@@ -20,9 +20,9 @@ class Evaluator {
EvaluationScope* _evaluationScope;
void EvaluateStatement(BoundStatement* statement);
void EvaluateBlockStatement(BoundBlockStatement* statement);
void EvaluateExpressionStatement(BoundExpressionStatement* statement);
void EvaluateAssignmentStatement(BoundAssignmentStatement* statement);
void EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement);
EvalValue* EvaluateExpression(BoundExpression* expression);
NumericEvalValue* EvaluateIntegerExpression(BoundExpression* expression);
@@ -50,7 +50,11 @@ public:
}
void Evaluate(BoundScriptStatement* statement);
void EvaluateBlockStatement(BoundBlockStatement* statement);
EvaluationScope* GetScope(){
return _evaluationScope;
}
};

View File

@@ -37,3 +37,4 @@ BooleanEvalValue *Evaluator::EvaluateBooleanUnary(BoundUnaryExpression *expressi
throw;
}
}