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

@@ -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){
}