Make parsed statements constant during binding

This commit is contained in:
Deukhoofd 2019-06-13 18:14:59 +02:00
parent 601c4a3f89
commit 5910cbbfa9
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
8 changed files with 238 additions and 215 deletions

View File

@ -1,9 +1,11 @@
#include <memory>
#include "Binder.hpp" #include "Binder.hpp"
#include "../TableScriptType.hpp" #include "../TableScriptType.hpp"
#include "BoundExpressions/BoundTableExpression.hpp" #include "BoundExpressions/BoundTableExpression.hpp"
#include <memory> #include <memory>
BoundScriptStatement *Binder::Bind(Script* script, ParsedScriptStatement *s, BoundScope* scriptScope) { BoundScriptStatement *Binder::Bind(Script* script, const ParsedScriptStatement *s, BoundScope* scriptScope) {
auto binder = Binder(); auto binder = Binder();
binder._scriptData = script; binder._scriptData = script;
@ -20,7 +22,7 @@ Binder::~Binder() {
delete _scope; delete _scope;
} }
BoundStatement* Binder::BindStatement(ParsedStatement* statement){ BoundStatement* Binder::BindStatement(const ParsedStatement* statement){
switch (statement -> GetKind()) { switch (statement -> GetKind()) {
case ParsedStatementKind ::Script: throw; // This shouldn't happen. case ParsedStatementKind ::Script: throw; // This shouldn't happen.
case ParsedStatementKind ::Block: return this -> BindBlockStatement(statement); case ParsedStatementKind ::Block: return this -> BindBlockStatement(statement);
@ -34,7 +36,7 @@ BoundStatement* Binder::BindStatement(ParsedStatement* statement){
} }
} }
BoundStatement *Binder::BindBlockStatement(ParsedStatement *statement) { BoundStatement *Binder::BindBlockStatement(const ParsedStatement *statement) {
auto statements = ((ParsedBlockStatement*)statement)->GetStatements(); auto statements = ((ParsedBlockStatement*)statement)->GetStatements();
vector<BoundStatement*> boundStatements (statements->size()); vector<BoundStatement*> boundStatements (statements->size());
this->_scope->GoInnerScope(); this->_scope->GoInnerScope();
@ -45,12 +47,12 @@ BoundStatement *Binder::BindBlockStatement(ParsedStatement *statement) {
return new BoundBlockStatement(boundStatements); return new BoundBlockStatement(boundStatements);
} }
BoundStatement *Binder::BindExpressionStatement(ParsedStatement *statement) { BoundStatement *Binder::BindExpressionStatement(const ParsedStatement *statement) {
auto exp = ((ParsedExpressionStatement*)statement)->GetExpression(); auto exp = ((ParsedExpressionStatement*)statement)->GetExpression();
return new BoundExpressionStatement(this -> BindExpression(exp)); return new BoundExpressionStatement(this -> BindExpression(exp));
} }
BoundStatement* Binder::BindAssignmentStatement(ParsedStatement *statement){ BoundStatement* Binder::BindAssignmentStatement(const ParsedStatement *statement){
auto s = (ParsedAssignmentStatement*) statement; auto s = (ParsedAssignmentStatement*) statement;
auto boundExpression = this->BindExpression(s->GetExpression()); auto boundExpression = this->BindExpression(s->GetExpression());
VariableAssignment assignment = VariableAssignment assignment =
@ -76,16 +78,16 @@ std::shared_ptr<ScriptType> ParseTypeIdentifier(HashedString s){
} }
} }
BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statement) { BoundStatement *Binder::BindFunctionDeclarationStatement(const ParsedStatement *statement) {
auto functionStatement = (ParsedFunctionDeclarationStatement*) statement; auto functionStatement = (ParsedFunctionDeclarationStatement*) statement;
auto parameters = functionStatement->GetParameters(); auto parameters = functionStatement->GetParameters();
auto parameterTypes = vector<shared_ptr<ScriptType>>(parameters.size()); auto parameterTypes = vector<shared_ptr<ScriptType>>(parameters->size());
auto parameterKeys = vector<shared_ptr<BoundVariableKey>>(parameters.size()); auto parameterKeys = vector<shared_ptr<BoundVariableKey>>(parameters->size());
auto scopeIndex = this->_scope->GetCurrentScope(); auto scopeIndex = this->_scope->GetCurrentScope();
this->_scope->GoInnerScope(); this->_scope->GoInnerScope();
for (int i = 0; i < parameters.size(); i++){ for (int i = 0; i < parameters->size(); i++){
auto var = parameters[i]; auto var = parameters -> at(i);
auto parsedType = ParseTypeIdentifier(var->GetType()); auto parsedType = ParseTypeIdentifier(var->GetType());
parameterTypes.at(i) = parsedType; parameterTypes.at(i) = parsedType;
auto parameterAssignment = this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), parsedType); auto parameterAssignment = this->_scope->CreateExplicitLocal(var->GetIdentifier().GetHash(), parsedType);
@ -114,7 +116,7 @@ BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statem
return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock); return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock);
} }
BoundStatement *Binder::BindReturnStatement(ParsedStatement* statement){ BoundStatement *Binder::BindReturnStatement(const ParsedStatement* statement){
auto expression = ((ParsedReturnStatement*)statement)->GetExpression(); auto expression = ((ParsedReturnStatement*)statement)->GetExpression();
shared_ptr<ScriptType> currentReturnType; shared_ptr<ScriptType> currentReturnType;
if (this->_currentFunction == nullptr){ if (this->_currentFunction == nullptr){
@ -143,7 +145,7 @@ BoundStatement *Binder::BindReturnStatement(ParsedStatement* statement){
return new BoundReturnStatement(boundExpression); return new BoundReturnStatement(boundExpression);
} }
BoundStatement *Binder::BindConditionalStatement(ParsedStatement* statement) { BoundStatement *Binder::BindConditionalStatement(const ParsedStatement* statement) {
auto conditionalStatement = (ParsedConditionalStatement*)statement; auto conditionalStatement = (ParsedConditionalStatement*)statement;
auto boundCondition = this -> BindExpression(conditionalStatement -> GetCondition()); auto boundCondition = this -> BindExpression(conditionalStatement -> GetCondition());
if (boundCondition->GetType() -> GetClass() != TypeClass::Bool){ if (boundCondition->GetType() -> GetClass() != TypeClass::Bool){
@ -158,7 +160,7 @@ BoundStatement *Binder::BindConditionalStatement(ParsedStatement* statement) {
return new BoundConditionalStatement(boundCondition, boundBlock, elseStatement); return new BoundConditionalStatement(boundCondition, boundBlock, elseStatement);
} }
BoundExpression* Binder::BindExpression(ParsedExpression* expression){ BoundExpression* Binder::BindExpression(const ParsedExpression* expression){
switch (expression -> GetKind()){ switch (expression -> GetKind()){
case ParsedExpressionKind ::LiteralInteger: case ParsedExpressionKind ::LiteralInteger:
return new BoundLiteralIntegerExpression(((LiteralIntegerExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength()); return new BoundLiteralIntegerExpression(((LiteralIntegerExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength());
@ -193,7 +195,7 @@ BoundExpression* Binder::BindExpression(ParsedExpression* expression){
} }
} }
BoundExpression* Binder::BindVariableExpression(VariableExpression* expression){ BoundExpression* Binder::BindVariableExpression(const VariableExpression* expression){
auto key = expression->GetValue(); auto key = expression->GetValue();
auto scope = this->_scope->Exists(key.GetHash()); auto scope = this->_scope->Exists(key.GetHash());
if (scope == -1){ if (scope == -1){
@ -205,7 +207,7 @@ BoundExpression* Binder::BindVariableExpression(VariableExpression* expression){
return new BoundVariableExpression(new BoundVariableKey(key.GetHash(), scope, false), type, expression->GetStartPosition(), expression->GetLength()); return new BoundVariableExpression(new BoundVariableKey(key.GetHash(), scope, false), type, expression->GetStartPosition(), expression->GetLength());
} }
BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){ BoundExpression* Binder::BindBinaryOperator(const BinaryExpression* expression){
auto boundLeft = this -> BindExpression(expression->GetLeft()); auto boundLeft = this -> BindExpression(expression->GetLeft());
auto boundRight = this -> BindExpression(expression->GetRight()); auto boundRight = this -> BindExpression(expression->GetRight());
@ -326,7 +328,7 @@ BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength()); return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
} }
BoundExpression* Binder::BindUnaryOperator(UnaryExpression* expression){ BoundExpression* Binder::BindUnaryOperator(const UnaryExpression* expression){
auto operand = this -> BindExpression(expression->GetOperand()); auto operand = this -> BindExpression(expression->GetOperand());
auto operandType = operand -> GetType(); auto operandType = operand -> GetType();
switch (expression->GetOperatorKind()){ switch (expression->GetOperatorKind()){
@ -359,7 +361,7 @@ BoundExpression* Binder::BindUnaryOperator(UnaryExpression* expression){
} }
BoundExpression* Binder::BindFunctionCall(FunctionCallExpression* expression){ BoundExpression* Binder::BindFunctionCall(const FunctionCallExpression* expression){
auto functionExpression = BindExpression(expression->GetFunction()); auto functionExpression = BindExpression(expression->GetFunction());
auto type = functionExpression->GetType(); auto type = functionExpression->GetType();
if (type->GetClass() != TypeClass::Function){ if (type->GetClass() != TypeClass::Function){
@ -370,14 +372,14 @@ BoundExpression* Binder::BindFunctionCall(FunctionCallExpression* expression){
auto functionType = std::dynamic_pointer_cast<FunctionScriptType>(type); auto functionType = std::dynamic_pointer_cast<FunctionScriptType>(type);
auto parameterTypes = functionType->GetParameterTypes(); auto parameterTypes = functionType->GetParameterTypes();
auto givenParameters = expression->GetParameters(); auto givenParameters = expression->GetParameters();
if (parameterTypes.size() != givenParameters.size()){ if (parameterTypes.size() != givenParameters->size()){
this->_scriptData->Diagnostics->LogError(DiagnosticCode::ParameterCountMismatch, expression->GetStartPosition(), this->_scriptData->Diagnostics->LogError(DiagnosticCode::ParameterCountMismatch, expression->GetStartPosition(),
expression->GetLength()); expression->GetLength());
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength()); return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
} }
vector<BoundExpression*> boundParameters = vector<BoundExpression*>(givenParameters.size()); vector<BoundExpression*> boundParameters = vector<BoundExpression*>(givenParameters->size());
for (int i = 0; i < givenParameters.size(); i++){ for (int i = 0; i < givenParameters->size(); i++){
auto parameter = givenParameters[i]; auto parameter = givenParameters -> at(i);
auto boundParameter = this -> BindExpression(parameter); auto boundParameter = this -> BindExpression(parameter);
if (boundParameter->GetType().get()->operator!=(parameterTypes.at(i).get())){ if (boundParameter->GetType().get()->operator!=(parameterTypes.at(i).get())){
this->_scriptData->Diagnostics->LogError(DiagnosticCode::ParameterTypeMismatch, parameter->GetStartPosition(), this->_scriptData->Diagnostics->LogError(DiagnosticCode::ParameterTypeMismatch, parameter->GetStartPosition(),
@ -391,7 +393,7 @@ BoundExpression* Binder::BindFunctionCall(FunctionCallExpression* expression){
expression->GetStartPosition(), expression->GetLength()); expression->GetStartPosition(), expression->GetLength());
} }
BoundExpression *Binder::BindIndexExpression(IndexExpression *expression) { BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression) {
auto indexer = this->BindExpression(expression->GetIndexer()); auto indexer = this->BindExpression(expression->GetIndexer());
auto index = this->BindExpression(expression->GetIndex()); auto index = this->BindExpression(expression->GetIndex());
@ -404,15 +406,15 @@ BoundExpression *Binder::BindIndexExpression(IndexExpression *expression) {
return new BoundIndexExpression(indexer, index, resultType, expression->GetStartPosition(), expression->GetLength()); return new BoundIndexExpression(indexer, index, resultType, expression->GetStartPosition(), expression->GetLength());
} }
BoundExpression* Binder::BindNumericalTableExpression(ParsedNumericalTableExpression* expression){ BoundExpression* Binder::BindNumericalTableExpression(const ParsedNumericalTableExpression* expression){
auto expressions = expression->GetExpressions(); auto expressions = expression->GetExpressions();
auto boundExpressions = vector<BoundExpression*>(expressions.size()); auto boundExpressions = vector<BoundExpression*>(expressions-> size());
shared_ptr<ScriptType> valueType = nullptr; shared_ptr<ScriptType> valueType = nullptr;
if (!boundExpressions.empty()){ if (!boundExpressions.empty()){
boundExpressions[0] = this -> BindExpression(expressions[0]); boundExpressions[0] = this -> BindExpression(expressions -> at(0));
valueType = boundExpressions[0] -> GetType(); valueType = boundExpressions[0] -> GetType();
for (int i = 1; i < expressions.size(); i++){ for (int i = 1; i < expressions->size(); i++){
boundExpressions[i] = this -> BindExpression(expressions[i]); boundExpressions[i] = this -> BindExpression(expressions -> at(i));
if (boundExpressions[i] -> GetType().get()->operator!=(valueType.get())){ if (boundExpressions[i] -> GetType().get()->operator!=(valueType.get())){
this->_scriptData->Diagnostics->LogError(DiagnosticCode::InvalidTableValueType, boundExpressions[i]->GetStartPosition(), this->_scriptData->Diagnostics->LogError(DiagnosticCode::InvalidTableValueType, boundExpressions[i]->GetStartPosition(),
boundExpressions[i]->GetLength()); boundExpressions[i]->GetLength());
@ -426,7 +428,7 @@ BoundExpression* Binder::BindNumericalTableExpression(ParsedNumericalTableExpres
return new BoundNumericalTableExpression(boundExpressions, tableType, expression->GetStartPosition(), expression->GetLength()); return new BoundNumericalTableExpression(boundExpressions, tableType, expression->GetStartPosition(), expression->GetLength());
} }
BoundExpression *Binder::BindTableExpression(ParsedTableExpression *expression) { BoundExpression *Binder::BindTableExpression(const ParsedTableExpression *expression) {
auto tableScope = new unordered_map<int, BoundVariable*>(); auto tableScope = new unordered_map<int, BoundVariable*>();
auto innerScope = new BoundScope(tableScope); auto innerScope = new BoundScope(tableScope);
auto currentScope = this -> _scope; auto currentScope = this -> _scope;
@ -434,7 +436,7 @@ BoundExpression *Binder::BindTableExpression(ParsedTableExpression *expression)
auto block = this -> BindBlockStatement(expression -> GetBlock()); auto block = this -> BindBlockStatement(expression -> GetBlock());
this -> _scope = currentScope; this -> _scope = currentScope;
auto tableType = shared_ptr<TableScriptType>(new TableScriptType(tableScope, innerScope->GetLocalVariableCount())); auto tableType = std::make_shared<TableScriptType>(tableScope, innerScope->GetLocalVariableCount());
delete innerScope; delete innerScope;
return new BoundTableExpression((BoundBlockStatement*)block, tableType, expression->GetStartPosition(), expression->GetLength()); return new BoundTableExpression((BoundBlockStatement*)block, tableType, expression->GetStartPosition(), expression->GetLength());

View File

@ -16,24 +16,24 @@ class Binder {
~Binder(); ~Binder();
BoundStatement *BindStatement(ParsedStatement *statement); BoundStatement *BindStatement(const ParsedStatement *statement);
BoundStatement *BindBlockStatement(ParsedStatement *statement); BoundStatement *BindBlockStatement(const ParsedStatement *statement);
BoundStatement *BindExpressionStatement(ParsedStatement *statement); BoundStatement *BindExpressionStatement(const ParsedStatement *statement);
BoundStatement *BindAssignmentStatement(ParsedStatement *statement); BoundStatement *BindAssignmentStatement(const ParsedStatement *statement);
BoundStatement *BindFunctionDeclarationStatement(ParsedStatement * statement); BoundStatement *BindFunctionDeclarationStatement(const ParsedStatement * statement);
BoundStatement *BindReturnStatement(ParsedStatement *statement); BoundStatement *BindReturnStatement(const ParsedStatement *statement);
BoundStatement *BindConditionalStatement(ParsedStatement *statement); BoundStatement *BindConditionalStatement(const ParsedStatement *statement);
BoundExpression *BindExpression(ParsedExpression *expression); BoundExpression *BindExpression(const ParsedExpression *expression);
BoundExpression *BindVariableExpression(VariableExpression *expression); BoundExpression *BindVariableExpression(const VariableExpression *expression);
BoundExpression *BindBinaryOperator(BinaryExpression *expression); BoundExpression *BindBinaryOperator(const BinaryExpression *expression);
BoundExpression *BindUnaryOperator(UnaryExpression *expression); BoundExpression *BindUnaryOperator(const UnaryExpression *expression);
BoundExpression *BindFunctionCall(FunctionCallExpression *expression); BoundExpression *BindFunctionCall(const FunctionCallExpression *expression);
BoundExpression *BindIndexExpression(IndexExpression *expression); BoundExpression *BindIndexExpression(const IndexExpression *expression);
BoundExpression *BindNumericalTableExpression(ParsedNumericalTableExpression *expression); BoundExpression *BindNumericalTableExpression(const ParsedNumericalTableExpression *expression);
BoundExpression *BindTableExpression(ParsedTableExpression * expression); BoundExpression *BindTableExpression(const ParsedTableExpression * expression);
public: public:
static BoundScriptStatement* Bind(Script* script, ParsedScriptStatement* s, BoundScope* scriptScope); static BoundScriptStatement* Bind(Script* script, const ParsedScriptStatement* s, BoundScope* scriptScope);
}; };

View File

@ -1,3 +1,5 @@
#include <utility>
#ifndef PORYGONLANG_PARSEDEXPRESSION_HPP #ifndef PORYGONLANG_PARSEDEXPRESSION_HPP
#define PORYGONLANG_PARSEDEXPRESSION_HPP #define PORYGONLANG_PARSEDEXPRESSION_HPP
@ -28,26 +30,28 @@ enum class ParsedExpressionKind{
}; };
class ParsedExpression { class ParsedExpression {
unsigned int _position; const unsigned int _position;
unsigned int _length; const unsigned int _length;
public: public:
ParsedExpression(unsigned int position, unsigned int length){ ParsedExpression(unsigned int position, unsigned int length)
_position = position; : _position(position),
_length = length; _length(length)
{
} }
virtual ~ParsedExpression() = default; virtual ~ParsedExpression() = default;
virtual ParsedExpressionKind GetKind() = 0; virtual const ParsedExpressionKind GetKind() const = 0;
unsigned int GetStartPosition(){ const unsigned int GetStartPosition() const{
return _position; return _position;
} }
unsigned int GetEndPosition(){ const unsigned int GetEndPosition() const{
return _position + _length - 1; return _position + _length - 1;
} }
unsigned int GetLength(){ const unsigned int GetLength() const{
return _length; return _length;
} }
}; };
@ -56,75 +60,83 @@ class BadExpression : public ParsedExpression{
public: public:
BadExpression(unsigned int position, unsigned int length) : ParsedExpression(position, length){} BadExpression(unsigned int position, unsigned int length) : ParsedExpression(position, length){}
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final {
return ParsedExpressionKind::Bad; return ParsedExpressionKind::Bad;
} }
}; };
class LiteralIntegerExpression : public ParsedExpression{ class LiteralIntegerExpression : public ParsedExpression{
long _value; const long _value;
public: public:
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::LiteralInteger; return ParsedExpressionKind::LiteralInteger;
} }
explicit LiteralIntegerExpression(IntegerToken* token) : ParsedExpression(token -> GetStartPosition(), token -> GetLength()){ explicit LiteralIntegerExpression(IntegerToken* token)
_value = token->Value; : ParsedExpression(token -> GetStartPosition(), token -> GetLength()),
_value(token -> Value)
{
} }
long GetValue(){ const long GetValue() const{
return _value; return _value;
} }
}; };
class LiteralFloatExpression : public ParsedExpression{ class LiteralFloatExpression : public ParsedExpression{
double _value; const double _value;
public: public:
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::LiteralFloat; return ParsedExpressionKind::LiteralFloat;
} }
explicit LiteralFloatExpression(FloatToken* token) : ParsedExpression(token -> GetStartPosition(), token -> GetLength()){ explicit LiteralFloatExpression(FloatToken* token)
_value = token->Value; : ParsedExpression(token -> GetStartPosition(), token -> GetLength()),
_value(token -> Value)
{
} }
double GetValue(){ const double GetValue() const{
return _value; return _value;
} }
}; };
class LiteralStringExpression : public ParsedExpression{ class LiteralStringExpression : public ParsedExpression{
string _value; const string _value;
public: public:
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::LiteralString; return ParsedExpressionKind::LiteralString;
} }
explicit LiteralStringExpression(StringToken* token) : ParsedExpression(token -> GetStartPosition(), token -> GetLength()){ explicit LiteralStringExpression(StringToken* token)
_value = std::move(token->Value); : ParsedExpression(token -> GetStartPosition(), token -> GetLength()),
_value(std::move(token -> Value))
{
} }
string GetValue(){ const string& GetValue() const{
return _value; return _value;
} }
}; };
class LiteralBoolExpression : public ParsedExpression{ class LiteralBoolExpression : public ParsedExpression{
bool _value; const bool _value;
public: public:
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::LiteralBool; return ParsedExpressionKind::LiteralBool;
} }
explicit LiteralBoolExpression(IToken* token) : ParsedExpression(token -> GetStartPosition(), token -> GetLength()){ explicit LiteralBoolExpression(IToken* token)
_value = token -> GetKind() == TokenKind::TrueKeyword; : ParsedExpression(token -> GetStartPosition(), token -> GetLength()),
_value(token -> GetKind() == TokenKind::TrueKeyword)
{
} }
bool GetValue(){ const bool GetValue() const{
return _value; return _value;
} }
}; };
class VariableExpression : public ParsedExpression{ class VariableExpression : public ParsedExpression{
HashedString _value; const HashedString _value;
public: public:
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::Variable; return ParsedExpressionKind::Variable;
} }
explicit VariableExpression(IdentifierToken* token) : ParsedExpression(token -> GetStartPosition(), token -> GetLength()) explicit VariableExpression(IdentifierToken* token) : ParsedExpression(token -> GetStartPosition(), token -> GetLength())
@ -132,150 +144,153 @@ public:
{ {
} }
HashedString GetValue(){ const HashedString GetValue() const{
return _value; return _value;
} }
}; };
class ParenthesizedExpression : public ParsedExpression{ class ParenthesizedExpression : public ParsedExpression{
ParsedExpression* _expression; const ParsedExpression* _expression;
public: public:
~ParenthesizedExpression() override { ~ParenthesizedExpression() override {
delete _expression; delete _expression;
} }
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::Parenthesized; return ParsedExpressionKind::Parenthesized;
} }
explicit ParenthesizedExpression(ParsedExpression* innerExpression, unsigned int start, unsigned int length) explicit ParenthesizedExpression(ParsedExpression* innerExpression, unsigned int start, unsigned int length)
: ParsedExpression(start, length){ : ParsedExpression(start, length), _expression(innerExpression){
_expression = innerExpression;
} }
ParsedExpression* GetInnerExpression(){ const ParsedExpression* GetInnerExpression() const{
return _expression; return _expression;
} }
}; };
class UnaryExpression : public ParsedExpression{ class UnaryExpression : public ParsedExpression{
UnaryOperatorKind _kind; const UnaryOperatorKind _kind;
ParsedExpression* _operand; const ParsedExpression* _operand;
public: public:
~UnaryExpression() override { ~UnaryExpression() override {
delete _operand; delete _operand;
} }
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::Unary; return ParsedExpressionKind::Unary;
} }
UnaryExpression(UnaryOperatorKind kind, ParsedExpression* operand, unsigned int start, unsigned int length) UnaryExpression(UnaryOperatorKind kind, ParsedExpression* operand, unsigned int start, unsigned int length)
: ParsedExpression(start, length){ : ParsedExpression(start, length),
_kind = kind; _kind(kind), _operand(operand)
_operand = operand; {
} }
UnaryOperatorKind GetOperatorKind(){ const UnaryOperatorKind GetOperatorKind() const{
return _kind; return _kind;
} }
ParsedExpression* GetOperand(){ const ParsedExpression* GetOperand() const{
return _operand; return _operand;
} }
}; };
class BinaryExpression : public ParsedExpression{ class BinaryExpression : public ParsedExpression{
BinaryOperatorKind _kind; const BinaryOperatorKind _kind;
ParsedExpression* _left; const ParsedExpression* _left;
ParsedExpression* _right; const ParsedExpression* _right;
public: public:
~BinaryExpression() override { ~BinaryExpression() override {
delete _left; delete _left;
delete _right; delete _right;
} }
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::Binary; return ParsedExpressionKind::Binary;
} }
BinaryExpression(BinaryOperatorKind kind, ParsedExpression* left, ParsedExpression* right, unsigned int start, BinaryExpression(BinaryOperatorKind kind, ParsedExpression* left, ParsedExpression* right, unsigned int start,
unsigned int length) unsigned int length)
: ParsedExpression(start, length){ : ParsedExpression(start, length),
_kind = kind; _kind(kind), _left(left), _right(right)
_left = left; {
_right = right;
} }
BinaryOperatorKind GetOperatorKind(){ const BinaryOperatorKind GetOperatorKind() const{
return _kind; return _kind;
} }
ParsedExpression* GetLeft() { const ParsedExpression* GetLeft() const{
return _left; return _left;
} }
ParsedExpression* GetRight() { const ParsedExpression* GetRight() const{
return _right; return _right;
} }
}; };
class FunctionCallExpression : public ParsedExpression{ class FunctionCallExpression : public ParsedExpression{
std::unique_ptr<ParsedExpression> _function; const std::unique_ptr<ParsedExpression> _function;
vector<std::unique_ptr<ParsedExpression>> _parameters; const vector<const ParsedExpression*> _parameters;
public: public:
FunctionCallExpression(ParsedExpression* function, vector<ParsedExpression*> parameters, FunctionCallExpression(ParsedExpression* function, vector<const ParsedExpression*> parameters, unsigned int start, unsigned int length)
unsigned int start, unsigned int length) : ParsedExpression(start, length){ : ParsedExpression(start, length),
_function = std::unique_ptr<ParsedExpression>(function); _function(function), _parameters(std::move(parameters))
for (int i = 0; i < parameters.size(); i++){ {
_parameters.push_back(std::unique_ptr<ParsedExpression>(parameters[i])); }
~FunctionCallExpression() final{
for (auto p : _parameters){
delete p;
} }
} }
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::FunctionCall; return ParsedExpressionKind::FunctionCall;
} }
ParsedExpression* GetFunction(){ const ParsedExpression* GetFunction() const{
return _function.get(); return _function.get();
} }
vector<ParsedExpression*> GetParameters(){ const vector<const ParsedExpression*>* GetParameters() const{
auto par = vector<ParsedExpression*>(_parameters.size(), nullptr); return &_parameters;
for (int i = 0; i < _parameters.size(); i++){
par[i] = _parameters[i].get();
}
return par;
} }
}; };
class IndexExpression : public ParsedExpression{ class IndexExpression : public ParsedExpression{
std::unique_ptr<ParsedExpression> _indexerExpression; const ParsedExpression* _indexerExpression;
std::unique_ptr<ParsedExpression> _indexExpression; const ParsedExpression* _indexExpression;
public: public:
IndexExpression(ParsedExpression* indexer, ParsedExpression* index, unsigned int start, unsigned int length) IndexExpression(ParsedExpression* indexer, ParsedExpression* index, unsigned int start, unsigned int length)
:ParsedExpression(start, length){ :ParsedExpression(start, length),
_indexerExpression = std::unique_ptr<ParsedExpression>(indexer); _indexerExpression(indexer), _indexExpression(index)
_indexExpression = std::unique_ptr<ParsedExpression>(index); {
} }
ParsedExpressionKind GetKind() final{ ~IndexExpression() final{
delete _indexerExpression;
delete _indexExpression;
}
const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::Indexer; return ParsedExpressionKind::Indexer;
} }
ParsedExpression* GetIndexer(){ const ParsedExpression* GetIndexer() const{
return _indexerExpression.get(); return _indexerExpression;
} }
ParsedExpression* GetIndex(){ const ParsedExpression* GetIndex() const{
return _indexExpression.get(); return _indexExpression;
} }
}; };
class ParsedNumericalTableExpression : public ParsedExpression{ class ParsedNumericalTableExpression : public ParsedExpression{
vector<ParsedExpression*> _expressions; vector<const ParsedExpression*> _expressions;
public: public:
ParsedNumericalTableExpression(vector<ParsedExpression*> expressions, unsigned int start, unsigned int length) ParsedNumericalTableExpression(vector<const ParsedExpression*> expressions, unsigned int start, unsigned int length)
: ParsedExpression(start, length){ : ParsedExpression(start, length){
_expressions = std::move(expressions); _expressions = std::move(expressions);
} }
@ -286,11 +301,11 @@ public:
} }
} }
vector<ParsedExpression*> GetExpressions(){ const vector<const ParsedExpression*>* GetExpressions() const{
return _expressions; return &_expressions;
} }
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::NumericalTable; return ParsedExpressionKind::NumericalTable;
} }
}; };

View File

@ -6,22 +6,22 @@
#include "../ParsedStatements/ParsedStatement.hpp" #include "../ParsedStatements/ParsedStatement.hpp"
class ParsedTableExpression : public ParsedExpression{ class ParsedTableExpression : public ParsedExpression{
ParsedBlockStatement* _block; const ParsedBlockStatement* _block;
public: public:
ParsedTableExpression(ParsedBlockStatement* block, unsigned int start, unsigned int length) ParsedTableExpression(ParsedBlockStatement* block, unsigned int start, unsigned int length)
: ParsedExpression(start, length){ : ParsedExpression(start, length), _block(block)
_block = block; {
} }
~ParsedTableExpression() final{ ~ParsedTableExpression() final{
delete _block; delete _block;
} }
ParsedBlockStatement* GetBlock(){ const ParsedBlockStatement* GetBlock() const{
return _block; return _block;
} }
ParsedExpressionKind GetKind() final{ const ParsedExpressionKind GetKind() const final{
return ParsedExpressionKind::Table; return ParsedExpressionKind::Table;
} }
}; };

View File

@ -1,5 +1,7 @@
#include <utility> #include <utility>
#include <utility>
#ifndef PORYGONLANG_PARSEDSTATEMENT_HPP #ifndef PORYGONLANG_PARSEDSTATEMENT_HPP
#define PORYGONLANG_PARSEDSTATEMENT_HPP #define PORYGONLANG_PARSEDSTATEMENT_HPP
@ -23,25 +25,25 @@ enum class ParsedStatementKind{
}; };
class ParsedStatement { class ParsedStatement {
unsigned int _start; const unsigned int _start;
unsigned int _length; const unsigned int _length;
public: public:
ParsedStatement(unsigned int start, unsigned int length){ ParsedStatement(unsigned int start, unsigned int length)
_start = start; :_start(start), _length(length)
_length = length; {
} }
virtual ~ParsedStatement() = default; virtual ~ParsedStatement() = default;
virtual ParsedStatementKind GetKind() = 0; virtual const ParsedStatementKind GetKind() const = 0;
unsigned int GetStartPosition(){ const unsigned int GetStartPosition() const {
return _start; return _start;
} }
unsigned int GetLength(){ const unsigned int GetLength() const {
return _length; return _length;
} }
unsigned int GetEndPosition(){ const unsigned int GetEndPosition() const {
return _start + _length - 1; return _start + _length - 1;
} }
}; };
@ -49,20 +51,22 @@ public:
class ParsedBadStatement : public ParsedStatement{ class ParsedBadStatement : public ParsedStatement{
public: public:
ParsedBadStatement(unsigned int start, unsigned int length) : ParsedStatement(start, length){}; ParsedBadStatement(unsigned int start, unsigned int length) : ParsedStatement(start, length){};
ParsedStatementKind GetKind() final{ const ParsedStatementKind GetKind() const final{
return ParsedStatementKind ::Bad; return ParsedStatementKind ::Bad;
} }
}; };
class ParsedBlockStatement : public ParsedStatement{ class ParsedBlockStatement : public ParsedStatement{
std::vector<ParsedStatement*> _statements; const std::vector<const ParsedStatement*> _statements;
public: public:
explicit ParsedBlockStatement(std::vector<ParsedStatement*> statements) explicit ParsedBlockStatement(std::vector<const ParsedStatement*> statements)
: ParsedStatement(statements.front()->GetStartPosition(), statements.back()->GetEndPosition() - statements.front()->GetStartPosition()){ : ParsedStatement(statements.front()->GetStartPosition(), statements.back()->GetEndPosition() - statements.front()->GetStartPosition()),
_statements = std::move(statements); _statements(statements)
} {}
ParsedBlockStatement(std::vector<ParsedStatement*> statements, unsigned int start) : ParsedStatement(start, 0){
_statements = std::move(statements); ParsedBlockStatement(std::vector<const ParsedStatement*> statements, unsigned int start) : ParsedStatement(start, 0),
_statements(std::move(statements))
{
} }
@ -70,50 +74,52 @@ public:
for (auto s: _statements){ for (auto s: _statements){
delete s; delete s;
} }
_statements.clear();
} }
ParsedStatementKind GetKind() override{ const ParsedStatementKind GetKind() const override {
return ParsedStatementKind ::Block; return ParsedStatementKind ::Block;
} }
std::vector<ParsedStatement*>* GetStatements(){ const std::vector<const ParsedStatement*>* GetStatements() const{
return &_statements; return &_statements;
} }
}; };
class ParsedScriptStatement : public ParsedBlockStatement{ class ParsedScriptStatement : public ParsedBlockStatement{
public: public:
explicit ParsedScriptStatement(vector<ParsedStatement*> statements) : ParsedBlockStatement(move(statements)){} explicit ParsedScriptStatement(vector<const ParsedStatement*> statements) : ParsedBlockStatement(move(statements)){}
ParsedStatementKind GetKind() final{ const ParsedStatementKind GetKind() const final{
return ParsedStatementKind ::Script; return ParsedStatementKind ::Script;
} }
}; };
class ParsedExpressionStatement : public ParsedStatement{ class ParsedExpressionStatement : public ParsedStatement{
ParsedExpression* _expression; const ParsedExpression* _expression;
public: public:
explicit ParsedExpressionStatement(ParsedExpression* expression) : ParsedStatement(expression->GetStartPosition(), expression->GetLength()){ explicit ParsedExpressionStatement(ParsedExpression* expression)
_expression = expression; : ParsedStatement(expression->GetStartPosition(), expression->GetLength()),
_expression(expression)
{
} }
~ParsedExpressionStatement() override { ~ParsedExpressionStatement() override {
delete _expression; delete _expression;
} }
ParsedStatementKind GetKind() final{ const ParsedStatementKind GetKind() const final{
return ParsedStatementKind ::Expression; return ParsedStatementKind ::Expression;
} }
ParsedExpression* GetExpression(){ const ParsedExpression* GetExpression() const{
return _expression; return _expression;
} }
}; };
class ParsedFunctionDeclarationStatement : public ParsedStatement{ class ParsedFunctionDeclarationStatement : public ParsedStatement{
HashedString _identifier; const HashedString _identifier;
vector<TypedVariableIdentifier*> _parameters; const vector<TypedVariableIdentifier*> _parameters;
ParsedBlockStatement* _block; const ParsedBlockStatement* _block;
public: public:
ParsedFunctionDeclarationStatement(HashedString identifier, vector<TypedVariableIdentifier*> parameters, ParsedBlockStatement* block, ParsedFunctionDeclarationStatement(HashedString identifier, vector<TypedVariableIdentifier*> parameters, ParsedBlockStatement* block,
unsigned int start, unsigned int length) unsigned int start, unsigned int length)
@ -126,90 +132,90 @@ public:
delete _block; delete _block;
} }
ParsedStatementKind GetKind() final{ const ParsedStatementKind GetKind() const final{
return ParsedStatementKind ::FunctionDeclaration; return ParsedStatementKind ::FunctionDeclaration;
} }
HashedString GetIdentifier(){ const HashedString GetIdentifier() const{
return _identifier; return _identifier;
} }
vector<TypedVariableIdentifier*> GetParameters(){ const vector<TypedVariableIdentifier*>* GetParameters() const{
return _parameters; return &_parameters;
} }
ParsedBlockStatement* GetBlock(){ const ParsedBlockStatement* GetBlock() const{
return _block; return _block;
} }
}; };
class ParsedAssignmentStatement : public ParsedStatement{ class ParsedAssignmentStatement : public ParsedStatement{
bool _local; const bool _local;
HashedString _identifier; const HashedString _identifier;
ParsedExpression* _expression; const ParsedExpression* _expression;
public: public:
ParsedAssignmentStatement(bool local, std::string identifier, ParsedExpression* expression, unsigned int start, unsigned int length) ParsedAssignmentStatement(bool local, const std::string& identifier, ParsedExpression* expression, unsigned int start, unsigned int length)
: ParsedStatement(start, length), _identifier(HashedString(std::move(identifier))) : ParsedStatement(start, length), _local(local), _identifier(HashedString(identifier)), _expression(expression)
{ {
_local = local;
_expression = expression;
} }
~ParsedAssignmentStatement() final{ ~ParsedAssignmentStatement() final{
delete _expression; delete _expression;
} }
ParsedStatementKind GetKind() final{ const ParsedStatementKind GetKind() const final{
return ParsedStatementKind ::Assignment; return ParsedStatementKind ::Assignment;
} }
bool IsLocal(){ const bool IsLocal() const{
return _local; return _local;
} }
HashedString GetIdentifier(){ const HashedString GetIdentifier() const{
return _identifier; return _identifier;
} }
ParsedExpression* GetExpression(){ const ParsedExpression* GetExpression() const{
return _expression; return _expression;
} }
}; };
class ParsedReturnStatement : public ParsedStatement{ class ParsedReturnStatement : public ParsedStatement{
ParsedExpression* _expression; const ParsedExpression* _expression;
public: public:
ParsedReturnStatement(ParsedExpression* expression, unsigned int start, unsigned int length) : ParsedStatement(start, length){ ParsedReturnStatement(ParsedExpression* expression, unsigned int start, unsigned int length)
_expression = expression; : ParsedStatement(start, length),
_expression(expression)
{
} }
~ParsedReturnStatement() final{ ~ParsedReturnStatement() final{
delete _expression; delete _expression;
} }
ParsedStatementKind GetKind() final{ const ParsedStatementKind GetKind() const final{
return ParsedStatementKind ::Return; return ParsedStatementKind ::Return;
} }
ParsedExpression* GetExpression(){ const ParsedExpression* GetExpression() const{
return _expression; return _expression;
} }
}; };
class ParsedConditionalStatement : public ParsedStatement{ class ParsedConditionalStatement : public ParsedStatement{
ParsedExpression* _condition; const ParsedExpression* _condition;
ParsedStatement* _block; const ParsedStatement* _block;
// This can be either else if or else // This can be either else if or else
ParsedStatement* _elseStatement; const ParsedStatement* _elseStatement;
public: public:
ParsedConditionalStatement(ParsedExpression* condition, ParsedStatement* block, unsigned int start, unsigned int length) ParsedConditionalStatement(ParsedExpression* condition, ParsedStatement* block, unsigned int start, unsigned int length)
: ParsedStatement(start, length){ : ParsedStatement(start, length), _condition(condition), _block(block), _elseStatement(nullptr)
_condition = condition; {
_block = block;
_elseStatement = nullptr;
} }
ParsedConditionalStatement(ParsedExpression* condition, ParsedStatement* block, ParsedStatement* nextStatement, unsigned int start, unsigned int length) ParsedConditionalStatement(ParsedExpression* condition, ParsedStatement* block, ParsedStatement* nextStatement, unsigned int start, unsigned int length)
: ParsedStatement(start, length){ : ParsedStatement(start, length), _condition(condition), _block(block), _elseStatement(nextStatement)
{
_condition = condition; _condition = condition;
_block = block; _block = block;
_elseStatement = nextStatement; _elseStatement = nextStatement;
@ -221,19 +227,19 @@ public:
delete _elseStatement; delete _elseStatement;
} }
ParsedStatementKind GetKind() final{ const ParsedStatementKind GetKind() const final{
return ParsedStatementKind ::Conditional; return ParsedStatementKind ::Conditional;
} }
ParsedExpression* GetCondition(){ const ParsedExpression* GetCondition() const {
return _condition; return _condition;
} }
ParsedStatement* GetBlock(){ const ParsedStatement* GetBlock() const {
return _block; return _block;
} }
ParsedStatement* GetElseStatement(){ const ParsedStatement* GetElseStatement() const {
return _elseStatement; return _elseStatement;
} }
}; };

View File

@ -1,3 +1,5 @@
#include <utility>
#include <algorithm> #include <algorithm>
#include "Parser.hpp" #include "Parser.hpp"
@ -9,7 +11,7 @@
ParsedScriptStatement* Parser::Parse() { ParsedScriptStatement* Parser::Parse() {
vector<ParsedStatement*> statements; vector<const ParsedStatement*> statements;
while (this->_position < this->_tokens.size()){ while (this->_position < this->_tokens.size()){
auto next = this -> Next(); auto next = this -> Next();
if (next->GetKind() == TokenKind::EndOfFile){ if (next->GetKind() == TokenKind::EndOfFile){
@ -73,8 +75,8 @@ ParsedStatement *Parser::ParseAssignment(IToken *current) {
return new ParsedAssignmentStatement(isLocal, ((IdentifierToken*)identifier) -> Value, expression, start, expression->GetEndPosition() - start); return new ParsedAssignmentStatement(isLocal, ((IdentifierToken*)identifier) -> Value, expression, start, expression->GetEndPosition() - start);
} }
ParsedStatement *Parser::ParseBlock(const vector<TokenKind>& endTokens) { ParsedStatement *Parser::ParseBlock(const vector<TokenKind>& endTokens, const vector<const ParsedStatement*>& openStatements) {
vector<ParsedStatement*> statements; auto statements = openStatements;
auto start = this->_position; auto start = this->_position;
while (this->_position < this->_tokens.size()){ while (this->_position < this->_tokens.size()){
auto next = this -> Next(); auto next = this -> Next();
@ -331,7 +333,7 @@ ParsedExpression *Parser::ParseParenthesizedExpression(IToken *current) {
ParsedExpression *Parser::ParseFunctionCallExpression(ParsedExpression* functionExpression) { ParsedExpression *Parser::ParseFunctionCallExpression(ParsedExpression* functionExpression) {
this -> Next(); // consume the open parenthesis this -> Next(); // consume the open parenthesis
vector<ParsedExpression*> parameters; vector<const ParsedExpression*> parameters;
auto peeked = this -> Peek(); auto peeked = this -> Peek();
auto peekedKind = peeked->GetKind(); auto peekedKind = peeked->GetKind();
if (peekedKind == TokenKind::CloseParenthesis){ if (peekedKind == TokenKind::CloseParenthesis){
@ -379,7 +381,7 @@ ParsedExpression* Parser::ParseTableExpression(IToken* current){
if (firstItem->GetKind() == ParsedStatementKind::Expression && if (firstItem->GetKind() == ParsedStatementKind::Expression &&
(this->Peek()->GetKind() == TokenKind::CommaToken )){ (this->Peek()->GetKind() == TokenKind::CommaToken )){
auto expr = ((ParsedExpressionStatement*)firstItem)->GetExpression(); auto expr = ((ParsedExpressionStatement*)firstItem)->GetExpression();
auto expressions = vector<ParsedExpression*>{expr}; auto expressions = vector<const ParsedExpression*>{expr};
auto n = this -> Next(); // consume the comma auto n = this -> Next(); // consume the comma
bool hasErrors = false; bool hasErrors = false;
while (n->GetKind() != TokenKind::CloseCurlyBracket){ while (n->GetKind() != TokenKind::CloseCurlyBracket){
@ -398,9 +400,7 @@ ParsedExpression* Parser::ParseTableExpression(IToken* current){
} }
// Otherwise we have a more complex table, which can be defined by a block // Otherwise we have a more complex table, which can be defined by a block
else { else {
auto block = (ParsedBlockStatement*)this -> ParseBlock({TokenKind ::CloseCurlyBracket}); auto block = (ParsedBlockStatement*)this -> ParseBlock({TokenKind ::CloseCurlyBracket}, {firstItem});
auto statements = block->GetStatements();
statements->insert(statements->begin(), firstItem);
auto closeToken = this -> PeekAt(-1); auto closeToken = this -> PeekAt(-1);
return new ParsedTableExpression(block, start, closeToken->GetEndPosition() - start); return new ParsedTableExpression(block, start, closeToken->GetEndPosition() - start);
} }

View File

@ -27,7 +27,7 @@ class Parser {
ParsedStatement* ParseStatement(IToken* current); ParsedStatement* ParseStatement(IToken* current);
ParsedStatement* ParseAssignment(IToken* current); ParsedStatement* ParseAssignment(IToken* current);
ParsedStatement *ParseBlock(const vector<TokenKind>& endTokens); ParsedStatement *ParseBlock(const vector<TokenKind>& endTokens, const vector<const ParsedStatement*>& openStatements = {});
ParsedStatement* ParseFunctionDeclaration(IToken* current); ParsedStatement* ParseFunctionDeclaration(IToken* current);
ParsedStatement *ParseReturnStatement(IToken *current); ParsedStatement *ParseReturnStatement(IToken *current);
ParsedStatement *ParseIfStatement(IToken *current); ParsedStatement *ParseIfStatement(IToken *current);
@ -41,8 +41,8 @@ class Parser {
ParsedExpression *ParseIndexExpression(ParsedExpression *indexingExpression); ParsedExpression *ParseIndexExpression(ParsedExpression *indexingExpression);
public: public:
ParsedScriptStatement* Parse(); ParsedScriptStatement* Parse();
explicit Parser(vector<IToken*> tokens, Script* scriptData){ explicit Parser(const vector<IToken*>& tokens, Script* scriptData){
_tokens = std::move(tokens); _tokens = tokens;
_position = 0; _position = 0;
ScriptData = scriptData; ScriptData = scriptData;
} }

View File

@ -216,10 +216,10 @@ TEST_CASE( "Parse function declaration", "[parser]" ){
auto functionDeclaration = (ParsedFunctionDeclarationStatement*)firstStatement; auto functionDeclaration = (ParsedFunctionDeclarationStatement*)firstStatement;
REQUIRE(functionDeclaration->GetIdentifier() == HashedString("foo")); REQUIRE(functionDeclaration->GetIdentifier() == HashedString("foo"));
auto parameters = functionDeclaration->GetParameters(); auto parameters = functionDeclaration->GetParameters();
CHECK(parameters[0]->GetType() == HashedString("number")); CHECK(parameters -> at(0) ->GetType() == HashedString("number"));
CHECK(parameters[0]->GetIdentifier() == HashedString("bar")); CHECK(parameters -> at(0) ->GetIdentifier() == HashedString("bar"));
CHECK(parameters[1]->GetType() == HashedString("number")); CHECK(parameters -> at(1) ->GetType() == HashedString("number"));
CHECK(parameters[1]->GetIdentifier() == HashedString("par")); CHECK(parameters -> at(1) ->GetIdentifier() == HashedString("par"));
} }