Implements binding and evaluating function declarations
This commit is contained in:
@@ -24,6 +24,7 @@ BoundStatement* Binder::BindStatement(ParsedStatement* statement){
|
||||
case ParsedStatementKind ::Block: return this -> BindBlockStatement(statement);
|
||||
case ParsedStatementKind ::Expression: return this -> BindExpressionStatement(statement);
|
||||
case ParsedStatementKind::Assignment: return this -> BindAssignmentStatement(statement);
|
||||
case ParsedStatementKind ::FunctionDeclaration: return this->BindFunctionDeclarationStatement(statement);
|
||||
|
||||
case ParsedStatementKind::Bad: return new BoundBadStatement();
|
||||
}
|
||||
@@ -62,6 +63,41 @@ BoundStatement* Binder::BindAssignmentStatement(ParsedStatement *statement){
|
||||
}
|
||||
}
|
||||
|
||||
ScriptType* ParseTypeIdentifier(HashedString s){
|
||||
switch (s.GetHash()){
|
||||
case HashedString::ConstHash("number"): return new NumericScriptType(false, false);
|
||||
case HashedString::ConstHash("bool"): return new ScriptType(TypeClass::Bool);
|
||||
case HashedString::ConstHash("string"): return new ScriptType(TypeClass::String);
|
||||
default: return new ScriptType(TypeClass::Error); // todo: change to userdata
|
||||
}
|
||||
}
|
||||
|
||||
BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statement) {
|
||||
auto functionStatement = (ParsedFunctionDeclarationStatement*) statement;
|
||||
auto parameters = functionStatement->GetParameters();
|
||||
vector<ScriptType*> parameterTypes = vector<ScriptType*>(parameters.size());
|
||||
vector<int> parameterKeys = vector<int>(parameters.size());
|
||||
this->_scope->GoInnerScope();
|
||||
auto scopeId = this->_scope->GetCurrentScope();
|
||||
for (int i = 0; i < parameters.size(); i++){
|
||||
auto var = parameters[i];
|
||||
auto parsedType = ParseTypeIdentifier(var->GetType());
|
||||
parameterTypes[i] = parsedType;
|
||||
parameterKeys[i] = var->GetIdentifier().GetHash();
|
||||
this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), *parsedType);
|
||||
}
|
||||
auto boundBlock = this -> BindBlockStatement(functionStatement->GetBlock());
|
||||
this->_scope->GoOuterScope();
|
||||
auto identifier = functionStatement->GetIdentifier();
|
||||
auto returnType = new ScriptType(TypeClass::Nil);
|
||||
auto type = new FunctionScriptType(returnType, parameterTypes, parameterKeys, scopeId);
|
||||
auto assignment = this->_scope->AssignVariable(identifier.GetHash(), *type);
|
||||
if (assignment.GetResult() == VariableAssignmentResult::Ok){
|
||||
return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock);
|
||||
}
|
||||
return new BoundBadStatement();
|
||||
}
|
||||
|
||||
BoundExpression* Binder::BindExpression(ParsedExpression* expression){
|
||||
switch (expression -> GetKind()){
|
||||
case ParsedExpressionKind ::LiteralInteger:
|
||||
@@ -226,3 +262,4 @@ BoundExpression* Binder::BindUnaryOperator(UnaryExpression* expression){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ class Binder {
|
||||
BoundStatement *BindBlockStatement(ParsedStatement *statement);
|
||||
BoundStatement *BindExpressionStatement(ParsedStatement *statement);
|
||||
BoundStatement *BindAssignmentStatement(ParsedStatement *statement);
|
||||
BoundStatement *BindFunctionDeclarationStatement(ParsedStatement * statement);
|
||||
|
||||
BoundExpression *BindExpression(ParsedExpression *expression);
|
||||
BoundExpression *BindVariableExpression(VariableExpression *expression);
|
||||
|
||||
@@ -16,6 +16,7 @@ enum class BoundStatementKind{
|
||||
Block,
|
||||
Expression,
|
||||
Assignment,
|
||||
FunctionDeclaration,
|
||||
};
|
||||
|
||||
class BoundStatement{
|
||||
@@ -114,4 +115,32 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class BoundFunctionDeclarationStatement : public BoundStatement{
|
||||
BoundVariableKey* _key;
|
||||
BoundBlockStatement* _block;
|
||||
FunctionScriptType* _type;
|
||||
public:
|
||||
BoundFunctionDeclarationStatement(FunctionScriptType* type, BoundVariableKey* key, BoundBlockStatement* block){
|
||||
_key = key;
|
||||
_block = block;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
BoundStatementKind GetKind() final{
|
||||
return BoundStatementKind ::FunctionDeclaration;
|
||||
}
|
||||
|
||||
BoundVariableKey* GetKey(){
|
||||
return _key;
|
||||
}
|
||||
|
||||
BoundBlockStatement* GetBlock(){
|
||||
return _block;
|
||||
}
|
||||
|
||||
FunctionScriptType* GetType(){
|
||||
return _type;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PORYGONLANG_BOUNDSTATEMENT_HPP
|
||||
|
||||
@@ -32,6 +32,10 @@ public:
|
||||
int GetDeepestScope(){
|
||||
return _deepestScope;
|
||||
}
|
||||
|
||||
int GetCurrentScope(){
|
||||
return _currentScope;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user