More work on binder, implements basic literal expressions

This commit is contained in:
Deukhoofd 2019-05-21 20:59:26 +02:00
parent 2fe6f570ec
commit 80998eab14
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
7 changed files with 251 additions and 3 deletions

View File

@ -2,5 +2,48 @@
#include "Binder.hpp"
BoundScriptStatement *Binder::Bind(ParsedScriptStatement *s) {
return nullptr;
auto binder = Binder();
auto statements = s->GetStatements();
vector<BoundStatement*> boundStatements (statements.size());
for (int i = 0; i < statements.size(); i++){
boundStatements[i] = binder.BindStatement(statements[i]);
}
return new BoundScriptStatement(boundStatements);
}
BoundStatement* Binder::BindStatement(ParsedStatement* statement){
switch (statement -> GetKind()) {
case ParsedStatementKind ::Script: throw; // This shouldn't happen.
case ParsedStatementKind ::Block: return this -> BindBlockStatement(statement);
case ParsedStatementKind ::Expression: return this -> BindExpressionStatement(statement);
}
}
BoundStatement *Binder::BindBlockStatement(ParsedStatement *statement) {
auto statements = ((ParsedBlockStatement*)statement)->GetStatements();
vector<BoundStatement*> boundStatements (statements.size());
for (int i = 0; i < statements.size(); i++){
boundStatements[i] = this -> BindStatement(statements[i]);
}
return new BoundBlockStatement(boundStatements);
}
BoundStatement *Binder::BindExpressionStatement(ParsedStatement *statement) {
auto exp = ((ParsedExpressionStatement*)statement)->GetExpression();
return new BoundExpressionStatement(this -> BindExpression(exp));
}
BoundExpression* Binder::BindExpression(ParsedExpression* expression){
switch (expression -> GetKind()){
case ParsedExpressionKind ::LiteralInteger:
return new BoundLiteralIntegerExpression(((LiteralIntegerExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength());
case ParsedExpressionKind ::LiteralFloat:
return new BoundLiteralFloatExpression(((LiteralFloatExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength());
case ParsedExpressionKind ::LiteralBool:
return new BoundLiteralBoolExpression(((LiteralBoolExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength());
case ParsedExpressionKind ::Bad:
return new BoundBadExpression(expression->GetStartPosition(), expression-> GetLength());
}
}

View File

@ -1,13 +1,19 @@
#ifndef PORYGONLANG_BINDER_HPP
#define PORYGONLANG_BINDER_HPP
#include "../Parser/ParsedStatements/ParsedScriptStatement.hpp"
#include "../Parser/ParsedStatements/ParsedStatement.hpp"
#include "BoundStatements/BoundStatement.hpp"
class Binder {
BoundStatement *BindStatement(ParsedStatement *statement);
BoundStatement *BindBlockStatement(ParsedStatement *statement);
public:
static BoundScriptStatement* Bind(ParsedScriptStatement* s);
BoundExpression *BindExpression(ParsedExpression *expression);
BoundStatement *BindExpressionStatement(ParsedStatement *statement);
};

View File

@ -0,0 +1,133 @@
#include <utility>
#ifndef PORYGONLANG_BOUNDEXPRESSION_HPP
#define PORYGONLANG_BOUNDEXPRESSION_HPP
#include <string>
#include "../../ScriptType.hpp"
using namespace std;
enum class BoundExpressionKind{
Bad,
LiteralInteger,
LiteralFloat,
LiteralString,
LiteralBool,
Unary,
Binary,
Parenthesized,
};
class BoundExpression{
unsigned int _start;
unsigned int _length;
ScriptType* _type;
public:
BoundExpression(unsigned int start, unsigned int length, ScriptType* type){
_start = start;
_length = length;
_type = type;
}
virtual ~BoundExpression(){
delete _type;
};
virtual BoundExpressionKind GetKind() = 0;
virtual ScriptType* GetType(){
return _type;
};
unsigned int GetStartPosition(){
return _start;
}
unsigned int GetLength(){
return _length;
}
};
class BoundBadExpression : public BoundExpression{
public:
BoundBadExpression(unsigned int start, unsigned int length) : BoundExpression(start, length, new ScriptType(TypeClass::Error)){}
BoundExpressionKind GetKind() final{
return BoundExpressionKind ::Bad;
}
};
class BoundLiteralIntegerExpression : public BoundExpression{
long _value;
public:
BoundLiteralIntegerExpression(long value, unsigned int start, unsigned int length)
: BoundExpression(start, length, new NumericScriptType(true, false)){
_value = value;
}
BoundExpressionKind GetKind() final{
return BoundExpressionKind ::LiteralInteger;
}
long GetValue(){
return _value;
}
};
class BoundLiteralFloatExpression : public BoundExpression{
double _value;
public:
BoundLiteralFloatExpression(double value, unsigned int start, unsigned int length)
: BoundExpression(start, length, new NumericScriptType(true, true)){
_value = value;
}
BoundExpressionKind GetKind() final{
return BoundExpressionKind ::LiteralFloat;
}
double GetValue(){
return _value;
}
};
class BoundLiteralStringExpression : public BoundExpression{
string _value;
public:
BoundLiteralStringExpression(string value, unsigned int start, unsigned int length)
: BoundExpression(start, length, new ScriptType(TypeClass::String)){
_value = std::move(value);
}
BoundExpressionKind GetKind() final{
return BoundExpressionKind ::LiteralString;
}
string GetValue(){
return _value;
}
};
class BoundLiteralBoolExpression : public BoundExpression{
bool _value;
public:
BoundLiteralBoolExpression(bool value, unsigned int start, unsigned int length)
: BoundExpression(start, length, new ScriptType(TypeClass::Bool)){
_value = value;
}
BoundExpressionKind GetKind() final{
return BoundExpressionKind ::LiteralBool;
}
bool GetValue(){
return _value;
}
};
#endif //PORYGONLANG_BOUNDEXPRESSION_HPP

View File

@ -5,11 +5,14 @@
#define PORYGONLANG_BOUNDSTATEMENT_HPP
#include <vector>
#include "../BoundExpressions/BoundExpression.hpp"
using namespace std;
enum class BoundStatementKind{
Script,
Block,
Expression,
};
class BoundStatement{
@ -46,4 +49,19 @@ public:
}
};
class BoundExpressionStatement : public BoundStatement{
BoundExpression* _expression;
public:
explicit BoundExpressionStatement(BoundExpression* expression){
_expression = expression;
}
~BoundExpressionStatement() final{
delete _expression;
}
BoundStatementKind GetKind() final{
return BoundStatementKind ::Expression;
}
};
#endif //PORYGONLANG_BOUNDSTATEMENT_HPP

View File

@ -4,6 +4,7 @@
#include "Script.hpp"
#include "Parser/Lexer.hpp"
#include "Parser/Parser.hpp"
#include "Binder/Binder.hpp"
Script Script::Create(string script) {
auto s = Script();
@ -13,6 +14,7 @@ Script Script::Create(string script) {
Script::~Script() {
delete this -> Diagnostics;
delete this -> BoundScript;
}
void Script::Parse(string script) {
@ -24,5 +26,9 @@ void Script::Parse(string script) {
delete token;
}
lexResult.clear();
if (!Diagnostics->HasErrors()){
this->BoundScript = Binder::Bind(parseResult);
}
delete parseResult;
}

View File

@ -6,6 +6,7 @@
#include <string>
#include "Diagnostics/Diagnostics.hpp"
#include "Binder/BoundStatements/BoundStatement.hpp"
using namespace std;
@ -15,6 +16,7 @@ class Script {
};
void Parse(string script);
BoundScriptStatement* BoundScript;
public:
static Script Create(string script);
Diagnostics* Diagnostics;

40
src/ScriptType.hpp Normal file
View File

@ -0,0 +1,40 @@
#ifndef PORYGONLANG_SCRIPTTYPE_HPP
#define PORYGONLANG_SCRIPTTYPE_HPP
enum class TypeClass{
Error,
Nil,
Number,
Bool,
String,
Function,
UserData,
Table,
};
class ScriptType{
TypeClass _class;
public:
explicit ScriptType(TypeClass c){
_class = c;
}
explicit virtual operator TypeClass(){
return _class;
}
};
class NumericScriptType : public ScriptType{
// Are we aware of whether this is a float or not?
bool _awareOfFloat;
// Is this value a float?
bool _isFloat;
public:
explicit NumericScriptType(bool floatAware, bool isFloat) : ScriptType(TypeClass::Number){
_awareOfFloat = floatAware;
_isFloat = isFloat;
}
};
#endif //PORYGONLANG_SCRIPTTYPE_HPP