Implements setting table values
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
996b5be496
commit
a9def6c539
|
@ -29,6 +29,7 @@ BoundStatement* Binder::BindStatement(const 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::IndexAssignment: return this -> BindIndexAssignmentStatement(statement);
|
||||
case ParsedStatementKind ::FunctionDeclaration: return this->BindFunctionDeclarationStatement(statement);
|
||||
case ParsedStatementKind::Return: return this -> BindReturnStatement(statement);
|
||||
case ParsedStatementKind::Conditional: return this -> BindConditionalStatement(statement);
|
||||
|
@ -70,6 +71,17 @@ BoundStatement* Binder::BindAssignmentStatement(const ParsedStatement *statement
|
|||
}
|
||||
}
|
||||
|
||||
BoundStatement *Binder::BindIndexAssignmentStatement(const ParsedStatement *statement) {
|
||||
auto s = (ParsedIndexAssignmentStatement*) statement;
|
||||
auto boundIndexExpression = this -> BindIndexExpression((IndexExpression*)s->GetIndexExpression());
|
||||
auto valueExpression = this -> BindExpression(s->GetValueExpression());
|
||||
if (boundIndexExpression->GetType()->operator!=(valueExpression->GetType().get())){
|
||||
this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidTableValueType, statement->GetStartPosition(), statement->GetLength());
|
||||
return new BoundBadStatement();
|
||||
}
|
||||
return new BoundIndexAssignmentStatement(boundIndexExpression, valueExpression);
|
||||
}
|
||||
|
||||
std::shared_ptr<ScriptType> ParseTypeIdentifier(HashedString s){
|
||||
switch (s.GetHash()){
|
||||
case HashedString::ConstHash("number"): return std::make_shared<NumericScriptType>(false, false);
|
||||
|
@ -442,3 +454,4 @@ BoundExpression *Binder::BindTableExpression(const ParsedTableExpression *expres
|
|||
|
||||
return new BoundTableExpression((BoundBlockStatement*)block, tableType, expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ class Binder {
|
|||
BoundStatement *BindBlockStatement(const ParsedStatement *statement);
|
||||
BoundStatement *BindExpressionStatement(const ParsedStatement *statement);
|
||||
BoundStatement *BindAssignmentStatement(const ParsedStatement *statement);
|
||||
BoundStatement *BindIndexAssignmentStatement(const ParsedStatement *statement);
|
||||
BoundStatement *BindFunctionDeclarationStatement(const ParsedStatement * statement);
|
||||
BoundStatement *BindReturnStatement(const ParsedStatement *statement);
|
||||
BoundStatement *BindConditionalStatement(const ParsedStatement *statement);
|
||||
|
|
|
@ -18,6 +18,7 @@ enum class BoundStatementKind{
|
|||
Block,
|
||||
Expression,
|
||||
Assignment,
|
||||
IndexAssignment,
|
||||
FunctionDeclaration,
|
||||
Return,
|
||||
Conditional,
|
||||
|
@ -124,6 +125,33 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class BoundIndexAssignmentStatement : public BoundStatement{
|
||||
const BoundExpression* _indexExpression;
|
||||
const BoundExpression* _valueExpression;
|
||||
public:
|
||||
BoundIndexAssignmentStatement(BoundExpression* index, BoundExpression* value)
|
||||
: _indexExpression(index), _valueExpression(value)
|
||||
{
|
||||
}
|
||||
|
||||
~BoundIndexAssignmentStatement() final{
|
||||
delete _indexExpression;
|
||||
delete _valueExpression;
|
||||
}
|
||||
|
||||
const BoundStatementKind GetKind() const final{
|
||||
return BoundStatementKind ::IndexAssignment;
|
||||
}
|
||||
|
||||
const BoundExpression* GetIndexExpression() const {
|
||||
return _indexExpression;
|
||||
}
|
||||
|
||||
const BoundExpression* GetValueExpression() const {
|
||||
return _valueExpression;
|
||||
}
|
||||
};
|
||||
|
||||
class BoundReturnStatement : public BoundStatement{
|
||||
const BoundExpression* _expression;
|
||||
public:
|
||||
|
|
|
@ -22,16 +22,16 @@ public:
|
|||
|
||||
virtual shared_ptr<EvalValue> Clone() = 0;
|
||||
|
||||
virtual long EvaluateInteger(){
|
||||
virtual long EvaluateInteger() const{
|
||||
throw EvaluationException("Can't evaluate this EvalValue as integer.");
|
||||
}
|
||||
virtual double EvaluateFloat(){
|
||||
virtual double EvaluateFloat() const{
|
||||
throw EvaluationException("Can't evaluate this EvalValue as float.");
|
||||
}
|
||||
virtual bool EvaluateBool(){
|
||||
virtual bool EvaluateBool() const{
|
||||
throw EvaluationException("Can't evaluate this EvalValue as bool.");
|
||||
}
|
||||
virtual std::string* EvaluateString(){
|
||||
virtual const std::string* EvaluateString() const {
|
||||
throw EvaluationException("Can't evaluate this EvalValue as string.");
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,10 @@ public:
|
|||
virtual shared_ptr<EvalValue> IndexValue(EvalValue* val){
|
||||
throw EvaluationException("Can't index this EvalValue");
|
||||
}
|
||||
|
||||
virtual void SetIndexValue(EvalValue *key, shared_ptr<EvalValue> value){
|
||||
throw EvaluationException("Can't index this EvalValue");
|
||||
}
|
||||
};
|
||||
|
||||
class BooleanEvalValue : public EvalValue{
|
||||
|
@ -58,7 +62,7 @@ public:
|
|||
return TypeClass ::Bool;
|
||||
}
|
||||
|
||||
bool EvaluateBool() final{
|
||||
bool EvaluateBool() const final{
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
long EvaluateInteger() final{
|
||||
long EvaluateInteger() const final{
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
double EvaluateFloat() final{
|
||||
double EvaluateFloat() const final{
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
return this->_hash == b->GetHashCode();
|
||||
};
|
||||
|
||||
string* EvaluateString() final{
|
||||
const string* EvaluateString() const final{
|
||||
return &_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,11 @@ public:
|
|||
auto hash = HashedString::ConstHash(val);
|
||||
return this -> _table -> at(hash);
|
||||
}
|
||||
|
||||
void SetIndexValue(EvalValue *key, shared_ptr<EvalValue> value) final{
|
||||
auto hash = key->GetHashCode();
|
||||
this -> _table->at(hash) = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ void Evaluator::EvaluateStatement(const 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::IndexAssignment:
|
||||
return this -> EvaluateIndexAssignmentStatement((BoundIndexAssignmentStatement*)statement);
|
||||
case BoundStatementKind ::FunctionDeclaration: return this->EvaluateFunctionDeclarationStatement((BoundFunctionDeclarationStatement*)statement);
|
||||
case BoundStatementKind::Return: return this -> EvaluateReturnStatement((BoundReturnStatement*)statement);
|
||||
case BoundStatementKind::Conditional: return this -> EvaluateConditionalStatement((BoundConditionalStatement*)statement);
|
||||
|
@ -58,6 +60,15 @@ void Evaluator::EvaluateAssignmentStatement(const BoundAssignmentStatement *stat
|
|||
}
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateIndexAssignmentStatement(const BoundIndexAssignmentStatement *statement) {
|
||||
auto indexExpression = statement -> GetIndexExpression();
|
||||
auto value = this -> EvaluateExpression(statement -> GetValueExpression());
|
||||
auto index = ((BoundIndexExpression*)indexExpression);
|
||||
auto table = this -> EvaluateExpression(index -> GetIndexableExpression());
|
||||
auto key = this -> EvaluateExpression(index->GetIndexExpression());
|
||||
table -> SetIndexValue(key.get(), value);
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement) {
|
||||
auto type = statement->GetType();
|
||||
auto key = statement->GetKey();
|
||||
|
@ -300,3 +311,4 @@ shared_ptr<EvalValue> Evaluator::EvaluateUserDataExpression(const BoundExpressio
|
|||
default: throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ class Evaluator {
|
|||
void EvaluateBlockStatement(const BoundBlockStatement *statement);
|
||||
void EvaluateExpressionStatement(const BoundExpressionStatement* statement);
|
||||
void EvaluateAssignmentStatement(const BoundAssignmentStatement* statement);
|
||||
void EvaluateIndexAssignmentStatement(const BoundIndexAssignmentStatement* statement);
|
||||
void EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement);
|
||||
void EvaluateReturnStatement(const BoundReturnStatement *statement);
|
||||
void EvaluateConditionalStatement(const BoundConditionalStatement *statement);
|
||||
|
|
|
@ -19,6 +19,7 @@ enum class ParsedStatementKind{
|
|||
Block,
|
||||
Expression,
|
||||
Assignment,
|
||||
IndexAssignment,
|
||||
FunctionDeclaration,
|
||||
Return,
|
||||
Conditional
|
||||
|
@ -180,6 +181,33 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class ParsedIndexAssignmentStatement : public ParsedStatement{
|
||||
const ParsedExpression* _indexExpression;
|
||||
const ParsedExpression* _valueExpression;
|
||||
public:
|
||||
ParsedIndexAssignmentStatement(ParsedExpression* indexExpression, ParsedExpression* valueExpression, unsigned int start,
|
||||
unsigned int length)
|
||||
: ParsedStatement(start, length),
|
||||
_indexExpression(indexExpression), _valueExpression(valueExpression){}
|
||||
|
||||
~ParsedIndexAssignmentStatement() final{
|
||||
delete _indexExpression;
|
||||
delete _valueExpression;
|
||||
}
|
||||
|
||||
const ParsedStatementKind GetKind() const final{
|
||||
return ParsedStatementKind ::IndexAssignment;
|
||||
}
|
||||
|
||||
const ParsedExpression* GetIndexExpression() const{
|
||||
return _indexExpression;
|
||||
}
|
||||
|
||||
const ParsedExpression* GetValueExpression() const{
|
||||
return _valueExpression;
|
||||
}
|
||||
};
|
||||
|
||||
class ParsedReturnStatement : public ParsedStatement{
|
||||
const ParsedExpression* _expression;
|
||||
public:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#include <utility>
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include "Parser.hpp"
|
||||
#include "ParsedStatements/ParsedStatement.hpp"
|
||||
|
@ -38,19 +36,23 @@ const IToken *Parser::Next() {
|
|||
ParsedStatement* Parser::ParseStatement(const IToken* current){
|
||||
auto currentKind = current->GetKind();
|
||||
switch (currentKind){
|
||||
case TokenKind ::LocalKeyword: return this -> ParseAssignment(current);
|
||||
case TokenKind ::LocalKeyword: return this->ParseVariableAssignment(current);
|
||||
case TokenKind ::FunctionKeyword: return this -> ParseFunctionDeclaration(current);
|
||||
case TokenKind ::ReturnKeyword: return this->ParseReturnStatement(current);
|
||||
case TokenKind ::IfKeyword: return this -> ParseIfStatement(current);
|
||||
default: break;
|
||||
}
|
||||
if (this->Peek()->GetKind() == TokenKind::AssignmentToken){
|
||||
return ParseAssignment(current);
|
||||
return ParseVariableAssignment(current);
|
||||
}
|
||||
return new ParsedExpressionStatement(this -> ParseExpression(current));
|
||||
auto expression = this -> ParseExpression(current);
|
||||
if (expression->GetKind() == ParsedExpressionKind::Indexer && this -> Peek()->GetKind() == TokenKind::AssignmentToken){
|
||||
return this -> ParseIndexAssignment(expression);
|
||||
}
|
||||
return new ParsedExpressionStatement(expression);
|
||||
}
|
||||
|
||||
ParsedStatement *Parser::ParseAssignment(const IToken *current) {
|
||||
ParsedStatement *Parser::ParseVariableAssignment(const IToken *current) {
|
||||
bool isLocal = false;
|
||||
const IToken* identifier;
|
||||
if (current -> GetKind() == TokenKind::LocalKeyword){
|
||||
|
@ -75,6 +77,14 @@ ParsedStatement *Parser::ParseAssignment(const IToken *current) {
|
|||
return new ParsedAssignmentStatement(isLocal, ((IdentifierToken*)identifier) -> GetValue(), expression, start, expression->GetEndPosition() - start);
|
||||
}
|
||||
|
||||
ParsedStatement *Parser::ParseIndexAssignment(ParsedExpression *indexer) {
|
||||
this -> Next(); // Consume assignment token
|
||||
auto valueExpression = this -> ParseExpression(this -> Next());
|
||||
auto start = indexer->GetStartPosition();
|
||||
return new ParsedIndexAssignmentStatement(indexer, valueExpression, start, valueExpression->GetEndPosition() - start);
|
||||
}
|
||||
|
||||
|
||||
ParsedStatement *Parser::ParseBlock(const vector<TokenKind>& endTokens, const vector<const ParsedStatement*>& openStatements) {
|
||||
auto statements = openStatements;
|
||||
auto start = this->_position;
|
||||
|
|
|
@ -27,7 +27,8 @@ class Parser {
|
|||
const IToken* Next();
|
||||
|
||||
ParsedStatement* ParseStatement(const IToken* current);
|
||||
ParsedStatement* ParseAssignment(const IToken* current);
|
||||
ParsedStatement* ParseVariableAssignment(const IToken *current);
|
||||
ParsedStatement* ParseIndexAssignment(ParsedExpression *indexer);
|
||||
ParsedStatement *ParseBlock(const vector<TokenKind>& endTokens, const vector<const ParsedStatement*>& openStatements = {});
|
||||
ParsedStatement* ParseFunctionDeclaration(const IToken* current);
|
||||
ParsedStatement *ParseReturnStatement(const IToken *current);
|
||||
|
|
|
@ -44,6 +44,12 @@ public:
|
|||
auto field = _userData->GetField(fieldId);
|
||||
return shared_ptr<EvalValue>(field->Get(_obj));
|
||||
}
|
||||
|
||||
void SetIndexValue(EvalValue *key, shared_ptr<EvalValue> value) final{
|
||||
auto fieldId = key->GetHashCode();
|
||||
auto field = _userData->GetField(fieldId);
|
||||
field -> Set(_obj, value.get());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -44,5 +44,22 @@ end
|
|||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "Sets UserData value", "[integration]" ) {
|
||||
UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::CreateData());
|
||||
Script* script = Script::Create(R"(
|
||||
function testFunc(testObject obj)
|
||||
obj["foo"] = 5000
|
||||
end
|
||||
)");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto obj = new UserDataTestObject();
|
||||
auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj);
|
||||
script->CallFunction("testFunc", {parameter});
|
||||
REQUIRE(obj->foo == 5000);
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue