diff --git a/samples/test.brc b/samples/test.brc index baa3e8f..7e1eaf1 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -1,61 +1,21 @@ -//@extern putchar fun: character sint32 -> sint32 +//@extern putchar fun: character u32 -> u32 -// ./build/brb samples/test.brc -S -x86-asm-syntax=intel - -/* -User type - name data - age u32 - successRatio r32 - isActive bool +User blob + num1 s32 + num2 u8 ; -*/ -/* -i u32 <- 0, rep text[i] != 0: - putchar(text[i]) - i++ -; -*/ - -// text data <- "Hello world!" - -/*addStuff asm<"+r, r">: num1 u32, num2 u32 -> u32 - add $1, $0 -;*/ - -/*normAdd fun: num1 sint32, num2 sint32 -> sint32 - ret num1 + num2 -;*/ - -/*rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 +/*rawAdd raw<"=r,r,r">: num1 u32, num2 u32 -> u32 add $1, $2 mov $0, $1 ;*/ -/*rawAdd raw: num1 sint32, num2 sint32 -> sint32 - add $1, $2 - mov $0, $1 -;*/ - -/*printChar raw - .global REGISTER - .text - .REGISTER: - .byte "Hello", 0xa0 - .long RegisterTable - //push 0x21 - -;*/ - main fun -> u32 - num1 u8 <- 42 - num2 s8 <- 3 - +15 - num3 u32 <- 1234123 - num4 s32 <- -345345 - num5 r32 <- -42.58 + us User + us.num1 <- 5 + us.num2 <- 4 - num5 + num3 + num3 s32 <- us.num1 + 13 ret 0 ; \ No newline at end of file diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 4fdd0d8..723671e 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -16,6 +16,7 @@ #include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementRawFunction.h" +#include "Parser/Statement/StatementBlob.h" #include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementReturn.h" @@ -68,6 +69,9 @@ void ModuleBuilder::buildStatement(shared_ptr statement) { case StatementKind::RAW_FUNCTION: buildRawFunction(dynamic_pointer_cast(statement)); break; + case StatementKind::BLOB: + buildBlob(dynamic_pointer_cast(statement)); + break; case StatementKind::VARIABLE: buildVarDeclaration(dynamic_pointer_cast(statement)); break; @@ -160,6 +164,24 @@ void ModuleBuilder::buildRawFunction(shared_ptr statement) return; } +void ModuleBuilder::buildBlob(shared_ptr statement) { + llvm::StructType *structType = llvm::StructType::create(*context, statement->getIdentifier()); + + // Generate types for body + vector memberNames; + vector types; + for (pair> &variable: statement->getVariables()) { + memberNames.push_back(variable.first); + llvm::Type *type = typeForValueType(variable.second); + if (type == nullptr) + return; + types.push_back(type); + } + structType->setBody(types, false); + if (!registerStruct(statement->getIdentifier(), structType, memberNames)) + return; +} + void ModuleBuilder::buildVarDeclaration(shared_ptr statement) { if (statement->getValueType()->getKind() == ValueTypeKind::DATA) { vector values = valuesForExpression(statement->getExpression()); @@ -177,37 +199,66 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr statement) builder->CreateStore(values[i], elementPtr); } - } else { - llvm::Value *value = valueForExpression(statement->getExpression()); - if (value == nullptr) + } else if (statement->getValueType()->getKind() == ValueTypeKind::TYPE) { + llvm::StructType *type = (llvm::StructType *)typeForValueType(statement->getValueType(), 0); + llvm::AllocaInst *alloca = builder->CreateAlloca(type, nullptr, statement->getName()); + if (!setAlloca(statement->getName(), alloca)) return; + } else { llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType(), 0), nullptr, statement->getName()); if (!setAlloca(statement->getName(), alloca)) return; - builder->CreateStore(value, alloca); + + // set initial value + if (statement->getExpression() != nullptr) { + llvm::Value *value = nullptr; + value = valueForExpression(statement->getExpression()); + if (value == nullptr) + return; + builder->CreateStore(value, alloca); + } } } void ModuleBuilder::buildAssignment(shared_ptr statement) { - llvm::AllocaInst *alloca = getAlloca(statement->getName()); + llvm::AllocaInst *alloca = getAlloca(statement->getIdentifier()); if (alloca == nullptr) return; - llvm::Value *value = valueForExpression(statement->getExpression()); + llvm::Value *value = valueForExpression(statement->getValueExpression()); - if (statement->getIndexExpression()) { - llvm::Value *indexValue = valueForExpression(statement->getIndexExpression()); - llvm::Value *index[] = { - builder->getInt32(0), - indexValue - }; - llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType(); - llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getName())); + switch (statement->getAssignmentKind()) { + case StatementAssignmentKind::SIMPLE: { + builder->CreateStore(value, alloca); + break; + } + case StatementAssignmentKind::DATA: { + llvm::Value *indexValue = valueForExpression(statement->getIndexExpression()); + llvm::Value *index[] = { + builder->getInt32(0), + indexValue + }; + llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType(); + llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getIdentifier())); - builder->CreateStore(value, elementPtr); - } else { - builder->CreateStore(value, alloca); + builder->CreateStore(value, elementPtr); + break; + } + case StatementAssignmentKind::BLOB: { + llvm::StructType *structType = (llvm::StructType *)alloca->getAllocatedType(); + string structName = string(structType->getName()); + optional memberIndex = getMemberIndex(structName, statement->getMemberName()); + if (!memberIndex) + return; + llvm::Value *index[] = { + builder->getInt32(0), + builder->getInt32(*memberIndex) + }; + llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index, format("{}.{}", statement->getIdentifier(), statement->getMemberName())); + builder->CreateStore(value, elementPtr); + break; + } } } @@ -313,8 +364,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression return valueForUnary(dynamic_pointer_cast(expression)); case ExpressionKind::IF_ELSE: return valueForIfElse(dynamic_pointer_cast(expression)); - case ExpressionKind::VAR: - return valueForVar(dynamic_pointer_cast(expression)); + case ExpressionKind::VARIABLE: + return valueForVariable(dynamic_pointer_cast(expression)); case ExpressionKind::CALL: return valueForCall(dynamic_pointer_cast(expression)); default: @@ -384,6 +435,8 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr expressi return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue); } else if (type == typeR32) { return valueForBinaryReal(expression->getOperation(), leftValue, rightValue); + } else { // FIXME (we have missing value types) + return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue); } markError(0, 0, "Unexpected operation"); @@ -555,23 +608,39 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi } } -llvm::Value *ModuleBuilder::valueForVar(shared_ptr expression) { - llvm::AllocaInst *alloca = getAlloca(expression->getName()); +llvm::Value *ModuleBuilder::valueForVariable(shared_ptr expression) { + llvm::AllocaInst *alloca = getAlloca(expression->getIdentifier()); if (alloca == nullptr) return nullptr; - if (expression->getIndexExpression()) { - llvm::Value *indexValue = valueForExpression(expression->getIndexExpression()); - llvm::Value *index[] = { - builder->getInt32(0), - indexValue - }; - llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType(); - llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", expression->getName())); + switch (expression->getVariableKind()) { + case ExpressionVariableKind::SIMPLE: { + return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getIdentifier()); + } + case ExpressionVariableKind::DATA: { + llvm::Value *indexValue = valueForExpression(expression->getIndexExpression()); + llvm::Value *index[] = { + builder->getInt32(0), + indexValue + }; + llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType(); + llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", expression->getIdentifier())); - return builder->CreateLoad(type->getArrayElementType(), elementPtr); - } else { - return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName()); + return builder->CreateLoad(type->getArrayElementType(), elementPtr); + } + case ExpressionVariableKind::BLOB: { + llvm::StructType *structType = (llvm::StructType *)alloca->getAllocatedType(); + string structName = string(structType->getName()); + optional memberIndex = getMemberIndex(structName, expression->getMemberName()); + if (!memberIndex) + return nullptr; + llvm::Value *index[] = { + builder->getInt32(0), + builder->getInt32(*memberIndex) + }; + llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index, format("{}.{}", expression->getIdentifier(), expression->getMemberName())); + return builder->CreateLoad(structType->getElementType(*memberIndex), elementPtr); + } } } @@ -671,6 +740,48 @@ llvm::InlineAsm *ModuleBuilder::getRawFun(string name) { return nullptr; } +bool ModuleBuilder::registerStruct(string structName, llvm::StructType *structType, vector memberNames) { + if (scopes.top().structTypeMap[structName] != nullptr) { + markError(0, 0, format("Blob \"{}\" already defined in scope",structName)); + return false; + } + + scopes.top().structTypeMap[structName] = structType; + scopes.top().structMembersMap[structName] = memberNames; + + return true; +} + +llvm::StructType *ModuleBuilder::getStructType(string structName) { + stack scopes = this->scopes; + + while (!scopes.empty()) { + llvm::StructType *structType = scopes.top().structTypeMap[structName]; + if (structType != nullptr) + return structType; + scopes.pop(); + } + + return nullptr; +} + +optional ModuleBuilder::getMemberIndex(string structName, string memberName) { + stack scopes = this->scopes; + + while (!scopes.empty()) { + if (scopes.top().structMembersMap.contains(structName)) { + vector memberNames = scopes.top().structMembersMap[structName]; + for (int i=0; i valueType, int count) { if (valueType == nullptr) { markError(0, 0, "Missing type"); @@ -699,6 +810,8 @@ llvm::Type *ModuleBuilder::typeForValueType(shared_ptr valueType, int count = valueType->getValueArg(); return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count); } + case ValueTypeKind::TYPE: + return getStructType(valueType->getTypeName()); } } diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index 872b4ad..43d3eb7 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -29,6 +29,7 @@ enum class ExpressionBinaryOperation; class Statement; class StatementFunction; class StatementRawFunction; +class StatementBlob; class StatementVariable; class StatementAssignment; class StatementReturn; @@ -43,6 +44,8 @@ typedef struct { map allocaMap; map funMap; map rawFunMap; + map structTypeMap; + map> structMembersMap; } Scope; class ModuleBuilder { @@ -69,6 +72,7 @@ private: void buildStatement(shared_ptr statement); void buildFunction(shared_ptr statement); void buildRawFunction(shared_ptr statement); + void buildBlob(shared_ptr statement); void buildVarDeclaration(shared_ptr statement); void buildAssignment(shared_ptr statement); void buildBlock(shared_ptr statement); @@ -89,7 +93,7 @@ private: llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForUnary(shared_ptr expression); llvm::Value *valueForIfElse(shared_ptr expression); - llvm::Value *valueForVar(shared_ptr expression); + llvm::Value *valueForVariable(shared_ptr expression); llvm::Value *valueForCall(shared_ptr expression); bool setAlloca(string name, llvm::AllocaInst *alloca); @@ -101,6 +105,10 @@ private: bool setRawFun(string name, llvm::InlineAsm *rawFun); llvm::InlineAsm *getRawFun(string name); + bool registerStruct(string structName, llvm::StructType *structType, vector memberNames); + llvm::StructType *getStructType(string structName); + optional getMemberIndex(string structName, string memberName); + llvm::Type *typeForValueType(shared_ptr valueType, int count = 0); void markError(int line, int column, string message); diff --git a/src/Lexer/Lexer.cpp b/src/Lexer/Lexer.cpp index 0706245..843cb4f 100644 --- a/src/Lexer/Lexer.cpp +++ b/src/Lexer/Lexer.cpp @@ -161,6 +161,10 @@ shared_ptr Lexer::nextToken() { if (token != nullptr) return token; + token = match(TokenKind::DOT, ".", false); + if (token != nullptr) + return token; + // arithmetic token = match(TokenKind::PLUS, "+", false); if (token != nullptr) @@ -208,14 +212,6 @@ shared_ptr Lexer::nextToken() { return token; // keywords - token = match(TokenKind::IF, "if", true); - if (token != nullptr) - return token; - - token = match(TokenKind::ELSE, "else", true); - if (token != nullptr) - return token; - token = match(TokenKind::FUNCTION, "fun", true); if (token != nullptr) return token; @@ -225,12 +221,24 @@ shared_ptr Lexer::nextToken() { foundRawSourceStart = true; return token; } + + token = match(TokenKind::BLOB, "blob", true); + if (token != nullptr) + return token; token = match(TokenKind::RETURN, "ret", true); if (token != nullptr) return token; token = match(TokenKind::REPEAT, "rep", true); + if (token != nullptr) + return token; + + token = match(TokenKind::IF, "if", true); + if (token != nullptr) + return token; + + token = match(TokenKind::ELSE, "else", true); if (token != nullptr) return token; @@ -313,6 +321,31 @@ shared_ptr Lexer::match(TokenKind kind, string lexme, bool needsSeparator return token; } +shared_ptr Lexer::matchReal() { + int nextIndex = currentIndex; + + while (nextIndex < source.length() && isDecDigit(nextIndex)) + nextIndex++; + + if (nextIndex >= source.length() || source.at(nextIndex) != '.') + return nullptr; + else + nextIndex++; + + while (nextIndex < source.length() && isDecDigit(nextIndex)) + nextIndex++; + + if (!isSeparator(nextIndex)) { + markError(); + return nullptr; + } + + string lexme = source.substr(currentIndex, nextIndex - currentIndex); + shared_ptr token = make_shared(TokenKind::REAL, lexme, currentLine, currentColumn); + advanceWithToken(token); + return token; +} + shared_ptr Lexer::matchIntegerDec() { int nextIndex = currentIndex; @@ -399,31 +432,6 @@ shared_ptr Lexer::matchIntegerChar() { return token; } -shared_ptr Lexer::matchReal() { - int nextIndex = currentIndex; - - while (nextIndex < source.length() && isDecDigit(nextIndex)) - nextIndex++; - - if (nextIndex >= source.length() || source.at(nextIndex) != '.') - return nullptr; - else - nextIndex++; - - while (nextIndex < source.length() && isDecDigit(nextIndex)) - nextIndex++; - - if (!isSeparator(nextIndex)) { - markError(); - return nullptr; - } - - string lexme = source.substr(currentIndex, nextIndex - currentIndex); - shared_ptr token = make_shared(TokenKind::REAL, lexme, currentLine, currentColumn); - advanceWithToken(token); - return token; -} - shared_ptr Lexer::matchString() { int nextIndex = currentIndex; @@ -569,6 +577,7 @@ bool Lexer::isSeparator(int index) { case ' ': case '\t': case '\n': + case '.': return true; default: return false; diff --git a/src/Lexer/Lexer.h b/src/Lexer/Lexer.h index 805ad50..7c36882 100644 --- a/src/Lexer/Lexer.h +++ b/src/Lexer/Lexer.h @@ -22,11 +22,11 @@ private: shared_ptr nextToken(); shared_ptr match(TokenKind kind, string lexme, bool needsSeparator); + shared_ptr matchReal(); shared_ptr matchIntegerDec(); shared_ptr matchIntegerHex(); shared_ptr matchIntegerBin(); shared_ptr matchIntegerChar(); - shared_ptr matchReal(); shared_ptr matchString(); shared_ptr matchType(); shared_ptr matchIdentifier(); diff --git a/src/Lexer/Token.cpp b/src/Lexer/Token.cpp index 2adddfe..57e5626 100644 --- a/src/Lexer/Token.cpp +++ b/src/Lexer/Token.cpp @@ -47,11 +47,11 @@ vector Token::tokensBinary = { vector Token::tokensLiteral = { TokenKind::BOOL, + TokenKind::REAL, TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, TokenKind::INTEGER_BIN, TokenKind::INTEGER_CHAR, - TokenKind::REAL, TokenKind::STRING }; diff --git a/src/Lexer/Token.h b/src/Lexer/Token.h index 4b1ab57..e7b5b75 100644 --- a/src/Lexer/Token.h +++ b/src/Lexer/Token.h @@ -28,24 +28,26 @@ enum class TokenKind { SEMICOLON, LEFT_ARROW, RIGHT_ARROW, + DOT, FUNCTION, RAW_FUNCTION, RAW_SOURCE_LINE, + BLOB, RETURN, REPEAT, IF, ELSE, BOOL, + REAL, INTEGER_DEC, INTEGER_HEX, INTEGER_BIN, INTEGER_CHAR, - REAL, STRING, - IDENTIFIER, TYPE, + IDENTIFIER, M_EXTERN, diff --git a/src/Logger.cpp b/src/Logger.cpp index d5ca83d..196f552 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -12,6 +12,7 @@ #include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementRawFunction.h" +#include "Parser/Statement/StatementBlob.h" #include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementReturn.h" @@ -73,6 +74,8 @@ string Logger::toString(shared_ptr token) { return "←"; case TokenKind::RIGHT_ARROW: return "→"; + case TokenKind::DOT: + return "."; case TokenKind::BOOL: return "BOOL(" + token->getLexme() + ")"; @@ -93,20 +96,22 @@ string Logger::toString(shared_ptr token) { case TokenKind::TYPE: return "TYPE(" + token->getLexme() + ")"; - case TokenKind::IF: - return "IF"; - case TokenKind::ELSE: - return "ELSE"; case TokenKind::FUNCTION: return "FUN"; case TokenKind::RAW_FUNCTION: return "RAW"; case TokenKind::RAW_SOURCE_LINE: return format("RAW_SOURCE_LINE({})", token->getLexme()); + case TokenKind::BLOB: + return "BLOB"; case TokenKind::RETURN: return "RET"; case TokenKind::REPEAT: return "REP"; + case TokenKind::IF: + return "IF"; + case TokenKind::ELSE: + return "ELSE"; case TokenKind::M_EXTERN: return "@EXTERN"; @@ -162,6 +167,8 @@ string Logger::toString(TokenKind tokenKind) { return "←"; case TokenKind::RIGHT_ARROW: return "→"; + case TokenKind::DOT: + return "."; case TokenKind::BOOL: return "LITERAL(BOOLEAN)"; @@ -223,6 +230,8 @@ string Logger::toString(shared_ptr valueType) { return "R32"; case ValueTypeKind::DATA: return "[]"; + case ValueTypeKind::TYPE: + return format("TYPE({})", valueType->getTypeName()); } } @@ -236,6 +245,8 @@ string Logger::toString(shared_ptr statement) { return toString(dynamic_pointer_cast(statement)); case StatementKind::RAW_FUNCTION: return toString(dynamic_pointer_cast(statement)); + case StatementKind::BLOB: + return toString(dynamic_pointer_cast(statement)); case StatementKind::BLOCK: return toString(dynamic_pointer_cast(statement)); case StatementKind::ASSIGNMENT: @@ -264,7 +275,10 @@ string Logger::toString(shared_ptr statement) { } string Logger::toString(shared_ptr statement) { - return format("{}({}|{})", statement->getName(), toString(statement->getValueType()), toString(statement->getExpression())); + if (statement->getExpression() != nullptr) + return format("{}({}|{})", statement->getName(), toString(statement->getValueType()), toString(statement->getExpression())); + else + return format("{}({})", statement->getName(), toString(statement->getValueType())); } string Logger::toString(shared_ptr statement) { @@ -296,6 +310,16 @@ string Logger::toString(shared_ptr statement) { return text; } +string Logger::toString(shared_ptr statement) { + string text; + + text += format("BLOB(\"{}\"):\n", statement->getIdentifier()); + for (pair> &variable : statement->getVariables()) + text += format("{}: {}\n", variable.first, toString(variable.second)); + + return text; +} + string Logger::toString(shared_ptr statement) { string text; @@ -309,7 +333,14 @@ string Logger::toString(shared_ptr statement) { } string Logger::toString(shared_ptr statement) { - return format("{} <- {}", statement->getName(), toString(statement->getExpression())); + switch (statement->getAssignmentKind()) { + case StatementAssignmentKind::SIMPLE: + return format("{} <- {}", statement->getIdentifier(), toString(statement->getValueExpression())); + case StatementAssignmentKind::DATA: + return format("{}[{}] <- {}", statement->getIdentifier(), toString(statement->getIndexExpression()), toString(statement->getValueExpression())); + case StatementAssignmentKind::BLOB: + return format("{}.{} <- {}", statement->getIdentifier(), statement->getMemberName(), toString(statement->getValueExpression())); + } } string Logger::toString(shared_ptr statement) { @@ -353,7 +384,7 @@ string Logger::toString(shared_ptr expression) { return toString(dynamic_pointer_cast(expression)); case ExpressionKind::IF_ELSE: return toString(dynamic_pointer_cast(expression)); - case ExpressionKind::VAR: + case ExpressionKind::VARIABLE: return toString(dynamic_pointer_cast(expression)); case ExpressionKind::GROUPING: return toString(dynamic_pointer_cast(expression)); @@ -423,11 +454,14 @@ string Logger::toString(shared_ptr expression) { } string Logger::toString(shared_ptr expression) { - string text = format("VAR({}", expression->getName()); - if (expression->getIndexExpression() != nullptr) - text += format("|{}", toString(expression->getIndexExpression())); - text += ")"; - return text; + switch (expression->getVariableKind()) { + case ExpressionVariableKind::SIMPLE: + return format("VAR({})", expression->getIdentifier()); + case ExpressionVariableKind::DATA: + return format("VAR({}|{})", expression->getIdentifier(), toString(expression->getIndexExpression())); + case ExpressionVariableKind::BLOB: + return format("VAR({}.{})", expression->getIdentifier(), expression->getMemberName()); + } } string Logger::toString(shared_ptr expression) { diff --git a/src/Logger.h b/src/Logger.h index 72e6746..5ebcd86 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -12,6 +12,7 @@ class StatementMetaExternFunction; class StatementVariable; class StatementFunction; class StatementRawFunction; +class StatementBlob; class StatementBlock; class StatementAssignment; class StatementReturn; @@ -44,6 +45,7 @@ private: static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); + static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); diff --git a/src/Parser/Expression/Expression.h b/src/Parser/Expression/Expression.h index a335052..9fc4f46 100644 --- a/src/Parser/Expression/Expression.h +++ b/src/Parser/Expression/Expression.h @@ -15,7 +15,7 @@ enum class ExpressionKind { UNARY, BINARY, IF_ELSE, - VAR, + VARIABLE, CALL, BLOCK }; diff --git a/src/Parser/Expression/ExpressionVariable.cpp b/src/Parser/Expression/ExpressionVariable.cpp index 61a03e2..242fa89 100644 --- a/src/Parser/Expression/ExpressionVariable.cpp +++ b/src/Parser/Expression/ExpressionVariable.cpp @@ -1,12 +1,43 @@ #include "ExpressionVariable.h" -ExpressionVariable::ExpressionVariable(string name, shared_ptr indexExpression): -Expression(ExpressionKind::VAR, nullptr), name(name), indexExpression(indexExpression) { } +shared_ptr ExpressionVariable::simple(string identifier) { + shared_ptr expression = make_shared(); + expression->variableKind = ExpressionVariableKind::SIMPLE; + expression->identifier = identifier; + return expression; +} -string ExpressionVariable::getName() { - return name; +shared_ptr ExpressionVariable::data(string identifier, shared_ptr indexExpression) { + shared_ptr expression = make_shared(); + expression->variableKind = ExpressionVariableKind::DATA; + expression->identifier = identifier; + expression->indexExpression = indexExpression; + return expression; +} + +shared_ptr ExpressionVariable::blob(string identifier, string memberName) { + shared_ptr expression = make_shared(); + expression->variableKind = ExpressionVariableKind::BLOB; + expression->identifier = identifier; + expression->memberName = memberName; + return expression; +} + +ExpressionVariable::ExpressionVariable(): +Expression(ExpressionKind::VARIABLE, nullptr) { } + +ExpressionVariableKind ExpressionVariable::getVariableKind() { + return variableKind; +} + +string ExpressionVariable::getIdentifier() { + return identifier; } shared_ptr ExpressionVariable::getIndexExpression() { return indexExpression; } + +string ExpressionVariable::getMemberName() { + return memberName; +} \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionVariable.h b/src/Parser/Expression/ExpressionVariable.h index 5835d9a..99c9868 100644 --- a/src/Parser/Expression/ExpressionVariable.h +++ b/src/Parser/Expression/ExpressionVariable.h @@ -1,12 +1,26 @@ #include "Parser/Expression/Expression.h" +enum class ExpressionVariableKind { + SIMPLE, + DATA, + BLOB +}; + class ExpressionVariable: public Expression { private: - string name; + ExpressionVariableKind variableKind; + string identifier; shared_ptr indexExpression; + string memberName; public: - ExpressionVariable(string name, shared_ptr indexExpression); - string getName(); + static shared_ptr simple(string identifer); + static shared_ptr data(string identifier, shared_ptr indexExpression); + static shared_ptr blob(string identifier, string memberName); + + ExpressionVariable(); + ExpressionVariableKind getVariableKind(); + string getIdentifier(); shared_ptr getIndexExpression(); + string getMemberName(); }; \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.cpp b/src/Parser/Parsee/Parsee.cpp index 3ec80d9..55ebf35 100644 --- a/src/Parser/Parsee/Parsee.cpp +++ b/src/Parser/Parsee/Parsee.cpp @@ -1,32 +1,65 @@ #include "Parsee.h" -Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn) { +#include "ParseeGroup.h" + +Parsee Parsee::groupParsee(ParseeGroup group, bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch) { + Parsee parsee; + parsee.kind = ParseeKind::GROUP; + parsee.group = group; + parsee.isRequired = isRequired; + parsee.shouldReturn = shouldReturn; + parsee.shouldFailOnNoMatch = shouldFailOnNoMatch; + return parsee; +} + +Parsee Parsee::repeatedGroupParsee(ParseeGroup repeatedGroup, bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch) { + Parsee parsee; + parsee.kind = ParseeKind::REPEATED_GROUP; + parsee.repeatedGroup = repeatedGroup; + parsee.isRequired = isRequired; + parsee.shouldReturn = shouldReturn; + parsee.shouldFailOnNoMatch = shouldFailOnNoMatch; + return parsee; +} + +Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch) { Parsee parsee; parsee.kind = ParseeKind::TOKEN; parsee.tokenKind = tokenKind; parsee.isRequired = isRequired; parsee.shouldReturn = shouldReturn; + parsee.shouldFailOnNoMatch = shouldFailOnNoMatch; return parsee; } -Parsee Parsee::valueTypeParsee(bool isRequired) { +Parsee Parsee::valueTypeParsee(bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch) { Parsee parsee; parsee.kind = ParseeKind::VALUE_TYPE; parsee.isRequired = isRequired; - parsee.shouldReturn = true; + parsee.shouldReturn = shouldReturn; + parsee.shouldFailOnNoMatch = shouldFailOnNoMatch; return parsee; } -Parsee Parsee::expressionParsee(bool isRequired) { +Parsee Parsee::expressionParsee(bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch) { Parsee parsee; parsee.kind = ParseeKind::EXPRESSION; parsee.isRequired = isRequired; - parsee.shouldReturn = true; + parsee.shouldReturn = shouldReturn; + parsee.shouldFailOnNoMatch = shouldFailOnNoMatch; return parsee; } Parsee::Parsee() { } +optional Parsee::getGroup() { + return group; +} + +optional Parsee::getRepeatedGroup() { + return repeatedGroup; +} + ParseeKind Parsee::getKind() { return kind; } @@ -41,4 +74,8 @@ bool Parsee::getIsRequired() { bool Parsee::getShouldReturn() { return shouldReturn; +} + +bool Parsee::getShouldFailOnNoMatch() { + return shouldFailOnNoMatch; } \ No newline at end of file diff --git a/src/Parser/Parsee/Parsee.h b/src/Parser/Parsee/Parsee.h index 6dfdf0e..d194867 100644 --- a/src/Parser/Parsee/Parsee.h +++ b/src/Parser/Parsee/Parsee.h @@ -2,10 +2,17 @@ #define PARSEE_H #include +#include + +#include "ParseeGroup.h" enum class TokenKind; +using namespace std; + enum class ParseeKind { + GROUP, + REPEATED_GROUP, TOKEN, VALUE_TYPE, EXPRESSION @@ -14,20 +21,28 @@ enum class ParseeKind { class Parsee { private: ParseeKind kind; + optional group; + optional repeatedGroup; TokenKind tokenKind; bool isRequired; bool shouldReturn; + bool shouldFailOnNoMatch; Parsee(); public: - static Parsee tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn); - static Parsee valueTypeParsee(bool isRequired); - static Parsee expressionParsee(bool isRequired); + static Parsee groupParsee(ParseeGroup group, bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch); + static Parsee repeatedGroupParsee(ParseeGroup repeatedGroup, bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch); + static Parsee tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch); + static Parsee valueTypeParsee(bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch); + static Parsee expressionParsee(bool isRequired, bool shouldReturn, bool shouldFailOnNoMatch); ParseeKind getKind(); + optional getGroup(); + optional getRepeatedGroup(); TokenKind getTokenKind(); bool getIsRequired(); bool getShouldReturn(); + bool getShouldFailOnNoMatch(); }; #endif \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeGroup.cpp b/src/Parser/Parsee/ParseeGroup.cpp index ead5352..401c4f9 100644 --- a/src/Parser/Parsee/ParseeGroup.cpp +++ b/src/Parser/Parsee/ParseeGroup.cpp @@ -2,19 +2,9 @@ #include "Parsee.h" -ParseeGroup::ParseeGroup(vector parsees, optional repeatedGroup): -parsees(parsees) { - if (repeatedGroup) { - this->repeatedGroup = *repeatedGroup; - } else { - this->repeatedGroup = {}; - } - } +ParseeGroup::ParseeGroup(vector parsees): +parsees(parsees) { } vector ParseeGroup::getParsees() { return parsees; } - -optional> ParseeGroup::getRepeatedGroup() { - return repeatedGroup; -} \ No newline at end of file diff --git a/src/Parser/Parsee/ParseeGroup.h b/src/Parser/Parsee/ParseeGroup.h index 4e4cc82..0f26087 100644 --- a/src/Parser/Parsee/ParseeGroup.h +++ b/src/Parser/Parsee/ParseeGroup.h @@ -2,7 +2,6 @@ #define PARSEE_GROUP_H #include -#include class Parsee; @@ -11,12 +10,10 @@ using namespace std; class ParseeGroup { private: vector parsees; - optional> repeatedGroup; public: - ParseeGroup(vector parsees, optional repeatedGroup); + ParseeGroup(vector parsees); vector getParsees(); - optional> getRepeatedGroup(); }; #endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index bdf291f..2720985 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -18,6 +18,7 @@ #include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementRawFunction.h" +#include "Parser/Statement/StatementBlob.h" #include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementReturn.h" @@ -80,6 +81,10 @@ shared_ptr Parser::nextStatement() { if (statement != nullptr || errors.size() > errorsCount) return statement; + statement = matchStatementBlob(); + if (statement != nullptr || errors.size() > errorsCount) + return statement; + markError({}, {}); return nullptr; } @@ -113,89 +118,70 @@ shared_ptr Parser::nextInBlockStatement() { } shared_ptr Parser::matchStatementMetaExternFunction() { - ParseeResultsGroup resultsGroup; - string identifier; vector>> arguments; shared_ptr returnType = ValueType::NONE; - // identifier - resultsGroup = parseeResultsGroupForParseeGroup( + ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { - Parsee::tokenParsee(TokenKind::M_EXTERN, true, false), - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::tokenParsee(TokenKind::FUNCTION, true, false) - }, - {} - ) - ); - - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); - break; - case ParseeResultsGroupKind::NO_MATCH: - case ParseeResultsGroupKind::FAILURE: - return nullptr; - } - - // arguments - resultsGroup = parseeResultsGroupForParseeGroup( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::COLON, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(true) - }, - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::COMMA, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(true) - }, - {} - ) - ) - ); - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - for (int i=0; i> arg; - arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); - arg.second = resultsGroup.getResults().at(i+1).getValueType(); - arguments.push_back(arg); + // identifier + Parsee::tokenParsee(TokenKind::M_EXTERN, true, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + Parsee::tokenParsee(TokenKind::FUNCTION, true, false, false), + // arguments + Parsee::groupParsee( + ParseeGroup( + { + // first argument + Parsee::tokenParsee(TokenKind::COLON, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true), + Parsee::valueTypeParsee(true, true, true), + // additional arguments + Parsee::repeatedGroupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::COMMA, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true), + Parsee::valueTypeParsee(true, true, true) + } + ), false, true, false + ) + } + ), false, true, false + ), + // return type + Parsee::groupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::valueTypeParsee(true, true, true) + } + ), false, true, false + ) } - break; - case ParseeResultsGroupKind::NO_MATCH: - break; - case ParseeResultsGroupKind::FAILURE: - return nullptr; - } - - // return type - resultsGroup = parseeResultsGroupForParseeGroup( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::valueTypeParsee(true) - }, - {} ) ); - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - returnType = resultsGroup.getResults().at(0).getValueType(); - break; - case ParseeResultsGroupKind::NO_MATCH: - break; - case ParseeResultsGroupKind::FAILURE: - return nullptr; + if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) + return nullptr; + + int i = 0; + // identifier + identifier = resultsGroup.getResults().at(i++).getToken()->getLexme(); + // arguments + while (i < resultsGroup.getResults().size()-1 && resultsGroup.getResults().at(i).getKind() == ParseeResultKind::TOKEN) { + pair> argument; + argument.first = resultsGroup.getResults().at(i++).getToken()->getLexme(); + argument.second = resultsGroup.getResults().at(i++).getValueType(); + arguments.push_back(argument); } + // return type + if (i < resultsGroup.getResults().size()) + returnType = resultsGroup.getResults().at(i).getValueType(); return make_shared(identifier, arguments, returnType); } @@ -204,12 +190,17 @@ shared_ptr Parser::matchStatementVariable() { ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(true), - Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), - Parsee::expressionParsee(true) - }, - {} + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + Parsee::valueTypeParsee(true, true, false), + Parsee::groupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false), + Parsee::expressionParsee(true, true, true) + } + ), false, true, false + ) + } ) ); @@ -218,111 +209,85 @@ shared_ptr Parser::matchStatementVariable() { string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); shared_ptr valueType = resultsGroup.getResults().at(1).getValueType(); - shared_ptr expression = resultsGroup.getResults().at(2).getExpression(); + shared_ptr expression = resultsGroup.getResults().size() > 2 ? resultsGroup.getResults().at(2).getExpression() : nullptr; return make_shared(identifier, valueType, expression); } shared_ptr Parser::matchStatementFunction() { - bool hasError = false; - ParseeResultsGroup resultsGroup; - - string name; + string identifier; vector>> arguments; shared_ptr returnType = ValueType::NONE; shared_ptr statementBlock; - // identifier - resultsGroup = parseeResultsGroupForParseeGroup( + ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::tokenParsee(TokenKind::FUNCTION, true, false) - }, - {} + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + Parsee::tokenParsee(TokenKind::FUNCTION, true, false, false), + // arguments + Parsee::groupParsee( + ParseeGroup( + { + // first argument + Parsee::tokenParsee(TokenKind::COLON, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true), + Parsee::valueTypeParsee(true, true, true), + // additional arguments + Parsee::repeatedGroupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::COMMA, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true), + Parsee::valueTypeParsee(true, true, true) + } + ), false, true, false + ) + } + ), false, true, false + ), + // return type + Parsee::groupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::valueTypeParsee(true, true, true) + } + ), false, true, false + ), + // new line + Parsee::tokenParsee(TokenKind::NEW_LINE, true, false, true) + } ) ); switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - name = resultsGroup.getResults().at(0).getToken()->getLexme(); + case ParseeResultsGroupKind::SUCCESS: { + int i = 0; + // identifier + identifier = resultsGroup.getResults().at(i++).getToken()->getLexme(); + // arguments + while (i < resultsGroup.getResults().size()-1 && resultsGroup.getResults().at(i).getKind() == ParseeResultKind::TOKEN) { + pair> argument; + argument.first = resultsGroup.getResults().at(i++).getToken()->getLexme(); + argument.second = resultsGroup.getResults().at(i++).getValueType(); + arguments.push_back(argument); + } + // return type + if (i < resultsGroup.getResults().size()) + returnType = resultsGroup.getResults().at(i).getValueType(); + } break; case ParseeResultsGroupKind::NO_MATCH: return nullptr; case ParseeResultsGroupKind::FAILURE: - hasError = true; break; } - // arguments - if (!hasError) { - resultsGroup = parseeResultsGroupForParseeGroup( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::COLON, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(true) - }, - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::COMMA, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(true) - }, - {} - ) - ) - ); - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - for (int i=0; i> arg; - arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); - arg.second = resultsGroup.getResults().at(i+1).getValueType(); - arguments.push_back(arg); - } - break; - case ParseeResultsGroupKind::NO_MATCH: - break; - case ParseeResultsGroupKind::FAILURE: - hasError = true; - break; - } - } - - // return type - if (!hasError) { - resultsGroup = parseeResultsGroupForParseeGroup( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::valueTypeParsee(true) - }, - {} - ) - ); - - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - returnType = resultsGroup.getResults().at(0).getValueType(); - break; - case ParseeResultsGroupKind::NO_MATCH: - break; - case ParseeResultsGroupKind::FAILURE: - hasError = true; - break; - } - } - - // consume new line - if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { - markError(TokenKind::NEW_LINE, {}); - return nullptr; - } - // block statementBlock = matchStatementBlock({TokenKind::SEMICOLON, TokenKind::END}); if (statementBlock == nullptr) @@ -334,140 +299,99 @@ shared_ptr Parser::matchStatementFunction() { return nullptr; } - return make_shared(name, arguments, returnType, dynamic_pointer_cast(statementBlock)); + return make_shared(identifier, arguments, returnType, dynamic_pointer_cast(statementBlock)); } shared_ptr Parser::matchStatementRawFunction() { - bool hasError = false; - ParseeResultsGroup resultsGroup; - - string name; + string identifier; string constraints; vector>> arguments; shared_ptr returnType = ValueType::NONE; string rawSource; - // identifier - resultsGroup = parseeResultsGroupForParseeGroup( + ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::tokenParsee(TokenKind::RAW_FUNCTION, true, false) - }, - {} + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + Parsee::tokenParsee(TokenKind::RAW_FUNCTION, true, false, false), + // constraints + Parsee::groupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::LESS, true, false, true), + Parsee::tokenParsee(TokenKind::STRING, true, true, true), + Parsee::tokenParsee(TokenKind::GREATER, true, false, true) + } + ), true, true, true + ), + // arguments + Parsee::groupParsee( + ParseeGroup( + { + // first argument + Parsee::tokenParsee(TokenKind::COLON, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true), + Parsee::valueTypeParsee(true, true, true), + // additional arguments + Parsee::repeatedGroupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::COMMA, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true), + Parsee::valueTypeParsee(true, true, true) + } + ), false, true, false + ) + } + ), false, true, false + ), + // return type + Parsee::groupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::valueTypeParsee(true, true, true) + } + ), false, true, false + ), + // new line + Parsee::tokenParsee(TokenKind::NEW_LINE, true, false, true) + } ) ); switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - name = resultsGroup.getResults().at(0).getToken()->getLexme(); + case ParseeResultsGroupKind::SUCCESS: { + int i = 0; + // identifier + identifier = resultsGroup.getResults().at(i++).getToken()->getLexme(); + // constraints + constraints = resultsGroup.getResults().at(i++).getToken()->getLexme(); + // remove enclosing quotes + if (constraints.length() >= 2) + constraints = constraints.substr(1, constraints.length() - 2); + // arguments + while (i < resultsGroup.getResults().size()-1 && resultsGroup.getResults().at(i).getKind() == ParseeResultKind::TOKEN) { + pair> argument; + argument.first = resultsGroup.getResults().at(i++).getToken()->getLexme(); + argument.second = resultsGroup.getResults().at(i++).getValueType(); + arguments.push_back(argument); + } + // return type + if (i < resultsGroup.getResults().size()) + returnType = resultsGroup.getResults().at(i).getValueType(); + } break; case ParseeResultsGroupKind::NO_MATCH: return nullptr; - break; case ParseeResultsGroupKind::FAILURE: - hasError = true; break; } - // constraints - if (!hasError) { - resultsGroup = parseeResultsGroupForParseeGroup( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::LESS, true, false), - Parsee::tokenParsee(TokenKind::STRING, true, true), - Parsee::tokenParsee(TokenKind::GREATER, true, false) - }, - {} - ) - ); - - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - constraints = resultsGroup.getResults().at(0).getToken()->getLexme(); - // remove enclosing quotes - if (constraints.length() >= 2) - constraints = constraints.substr(1, constraints.length() - 2); - break; - case ParseeResultsGroupKind::NO_MATCH: - return nullptr; - break; - case ParseeResultsGroupKind::FAILURE: - hasError = true; - break; - } - } - - // arguments - if (!hasError) { - resultsGroup = parseeResultsGroupForParseeGroup( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::COLON, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(true) - }, - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::COMMA, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(true) - }, - {} - ) - ) - ); - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - for (int i=0; i> arg; - arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); - arg.second = resultsGroup.getResults().at(i+1).getValueType(); - arguments.push_back(arg); - } - break; - case ParseeResultsGroupKind::NO_MATCH: - break; - case ParseeResultsGroupKind::FAILURE: - hasError = true; - break; - } - } - - // return type - if (!hasError) { - resultsGroup = parseeResultsGroupForParseeGroup( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false), - Parsee::tokenParsee(TokenKind::NEW_LINE, false, false), - Parsee::valueTypeParsee(true) - }, - {} - ) - ); - - switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - returnType = resultsGroup.getResults().at(0).getValueType(); - break; - case ParseeResultsGroupKind::NO_MATCH: - break; - case ParseeResultsGroupKind::FAILURE: - hasError = true; - break; - } - } - - // consume new line - if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { - markError(TokenKind::NEW_LINE, {}); - return nullptr; - } - // source while (tryMatchingTokenKinds({TokenKind::RAW_SOURCE_LINE}, true, false)) { if (!rawSource.empty()) @@ -478,12 +402,58 @@ shared_ptr Parser::matchStatementRawFunction() { tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); } + // closing semicolon if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) { markError(TokenKind::SEMICOLON, {}); return nullptr; } - return make_shared(name, constraints, arguments, returnType, rawSource); + return make_shared(identifier, constraints, arguments, returnType, rawSource); +} + +shared_ptr Parser::matchStatementBlob() { + ParseeResultsGroup resultsGroup; + + string identifier; + vector>> variables; + + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + Parsee::tokenParsee(TokenKind::BLOB, true, false, false), + Parsee::tokenParsee(TokenKind::NEW_LINE, true, false, true), + Parsee::repeatedGroupParsee( + ParseeGroup( + { + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + Parsee::valueTypeParsee(true, true, true), + Parsee::tokenParsee(TokenKind::NEW_LINE, true, false, true) + } + ), false, true, false + ), + Parsee::tokenParsee(TokenKind::SEMICOLON, true, false, true) + } + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: + identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + for (int i=1; i> arg; + arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); + arg.second = resultsGroup.getResults().at(i+1).getValueType(); + variables.push_back(arg); + } + break; + case ParseeResultsGroupKind::NO_MATCH: + case ParseeResultsGroupKind::FAILURE: + return nullptr; + break; + } + + return make_shared(identifier, variables); } shared_ptr Parser::matchStatementBlock(vector terminalTokenKinds) { @@ -506,83 +476,102 @@ shared_ptr Parser::matchStatementBlock(vector terminalToke } shared_ptr Parser::matchStatementAssignment() { - int startIndex = currentIndex; ParseeResultsGroup resultsGroup; - string identifier; - shared_ptr indexExpression; - shared_ptr expression; - - // identifier + // simple resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - }, - {} - ) - ); - - if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) - return nullptr; - - identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); - - // index expression - resultsGroup = parseeResultsGroupForParseeGroup( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false), - Parsee::expressionParsee(true), - Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false), - }, - {} + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + // expression + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false), + Parsee::expressionParsee(true, true, true) + } ) ); switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - indexExpression = resultsGroup.getResults().at(0).getExpression(); - break; + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + shared_ptr valueExpression = resultsGroup.getResults().at(1).getExpression(); + return StatementAssignment::simple(identifier, valueExpression); + } case ParseeResultsGroupKind::NO_MATCH: break; case ParseeResultsGroupKind::FAILURE: return nullptr; } - // expression + // data resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { - Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false), - Parsee::expressionParsee(true) - }, - {} + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + // index expression + Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false, false), + Parsee::expressionParsee(true, true, true), + Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false, true), + // expression + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false), + Parsee::expressionParsee(true, true, true) + } ) ); switch (resultsGroup.getKind()) { - case ParseeResultsGroupKind::SUCCESS: - expression = resultsGroup.getResults().at(0).getExpression(); - break; + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + shared_ptr indexExpression = resultsGroup.getResults().at(1).getExpression(); + shared_ptr valueExpression = resultsGroup.getResults().at(2).getExpression(); + return StatementAssignment::data(identifier, indexExpression, valueExpression); + } case ParseeResultsGroupKind::NO_MATCH: - currentIndex = startIndex; - return nullptr; + break; case ParseeResultsGroupKind::FAILURE: return nullptr; } - return make_shared(identifier, indexExpression, expression); + // blob + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + // member name + Parsee::tokenParsee(TokenKind::DOT, true, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true), + // expression + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false), + Parsee::expressionParsee(true, true, true) + } + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + string memberName = resultsGroup.getResults().at(1).getToken()->getLexme(); + shared_ptr valueExpression = resultsGroup.getResults().at(2).getExpression(); + return StatementAssignment::blob(identifier, memberName, valueExpression); + } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + return nullptr; } shared_ptr Parser::matchStatementReturn() { ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { - Parsee::tokenParsee(TokenKind::RETURN, true, false), - Parsee::expressionParsee(false) - }, - {} + Parsee::tokenParsee(TokenKind::RETURN, true, false, false), + Parsee::expressionParsee(false, true, false) + } ) ); @@ -824,23 +813,81 @@ shared_ptr Parser::matchExpressionArrayLiteral() { } shared_ptr Parser::matchExpressionVariable() { - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, false)) - return nullptr; - shared_ptr idToken = tokens.at(currentIndex++); - shared_ptr indexExpression; + ParseeResultsGroup resultsGroup; - if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) { - indexExpression = nextExpression(); - if (indexExpression == nullptr) - return nullptr; + // data + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + // index expression + Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false, false), + Parsee::expressionParsee(true, true, true), + Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false, true) + } + ) + ); - if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) { - markError(TokenKind::RIGHT_SQUARE_BRACKET, {}); - return nullptr; + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + shared_ptr indexExpression = resultsGroup.getResults().at(1).getExpression(); + return ExpressionVariable::data(identifier, indexExpression); } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; } - - return make_shared(idToken->getLexme(), indexExpression); + + // blob + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + // member name + Parsee::tokenParsee(TokenKind::DOT, true, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true) + } + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + string memberName = resultsGroup.getResults().at(1).getToken()->getLexme(); + return ExpressionVariable::blob(identifier, memberName); + } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + // simple + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false) + } + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + return ExpressionVariable::simple(identifier); + } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + return nullptr; } shared_ptr Parser::matchExpressionCall() { @@ -969,20 +1016,25 @@ shared_ptr Parser::matchExpressionBlock(vector terminalTo ParseeResultsGroup Parser::parseeResultsGroupForParseeGroup(ParseeGroup group) { int errorsCount = errors.size(); int startIndex = currentIndex; - vector results; - bool mustFulfill = false; + vector parseeResults; for (Parsee &parsee : group.getParsees()) { - optional result; + optional, int>> subResults; switch (parsee.getKind()) { + case ParseeKind::GROUP: + subResults = groupParseeResults(*parsee.getGroup()); + break; + case ParseeKind::REPEATED_GROUP: + subResults = repeatedGroupParseeResults(*parsee.getRepeatedGroup()); + break; case ParseeKind::TOKEN: - result = tokenParseeResult(currentIndex, parsee.getTokenKind()); + subResults = tokenParseeResults(currentIndex, parsee.getTokenKind()); break; case ParseeKind::VALUE_TYPE: - result = valueTypeParseeResult(currentIndex); + subResults = valueTypeParseeResults(currentIndex); break; case ParseeKind::EXPRESSION: - result = expressionParseeResult(currentIndex); + subResults = expressionParseeResults(currentIndex); break; } @@ -990,56 +1042,75 @@ ParseeResultsGroup Parser::parseeResultsGroupForParseeGroup(ParseeGroup group) { if (errors.size() > errorsCount) return ParseeResultsGroup::failure(); - // if doesn't match on optional group - if (!result && parsee.getIsRequired() && !mustFulfill) { + // if doesn't match a required but non-failing parsee + if (!subResults && parsee.getIsRequired() && !parsee.getShouldFailOnNoMatch()) { currentIndex = startIndex; - //return vector(); return ParseeResultsGroup::noMatch(); } - // return matching token? - if (result && parsee.getShouldReturn()) - results.push_back(*result); - - // decide if we're decoding the expected sequence - if (!parsee.getIsRequired() && currentIndex > startIndex) - mustFulfill = true; + // should return a matching result? + if (subResults && parsee.getShouldReturn()) { + for (ParseeResult &subResult : (*subResults).first) + parseeResults.push_back(subResult); + } // invalid sequence detected? - if (!result && parsee.getIsRequired() && mustFulfill) { + if (!subResults && parsee.getShouldFailOnNoMatch()) { markError(parsee.getTokenKind(), {}); - //return {}; return ParseeResultsGroup::failure(); } // got to the next token if we got a match - if (result) - currentIndex += (*result).getTokensCount(); + if (subResults) + currentIndex += (*subResults).second; } - if (group.getRepeatedGroup()) { - ParseeResultsGroup subResultsGroup; - do { - subResultsGroup = parseeResultsGroupForParseeGroup(*group.getRepeatedGroup()); - if (subResultsGroup.getKind() == ParseeResultsGroupKind::FAILURE) - return ParseeResultsGroup::failure(); - - for (ParseeResult &subResult : subResultsGroup.getResults()) - results.push_back(subResult); - } while (subResultsGroup.getKind() == ParseeResultsGroupKind::SUCCESS); - } - - return ParseeResultsGroup::success(results); + return ParseeResultsGroup::success(parseeResults); } -optional Parser::tokenParseeResult(int index, TokenKind tokenKind) { +optional, int>> Parser::groupParseeResults(ParseeGroup group) { + int startIndex = currentIndex; + vector results; + + ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup(group); + if (resultsGroup.getKind() == ParseeResultsGroupKind::FAILURE) + return {}; + + for (ParseeResult &result : resultsGroup.getResults()) + results.push_back(result); + + int tokensCount = currentIndex - startIndex; + currentIndex = startIndex; + return pair(results, tokensCount); +} + +optional, int>> Parser::repeatedGroupParseeResults(ParseeGroup group) { + int startIndex = currentIndex; + vector results; + + ParseeResultsGroup resultsGroup; + do { + resultsGroup = parseeResultsGroupForParseeGroup(group); + if (resultsGroup.getKind() == ParseeResultsGroupKind::FAILURE) + return {}; + + for (ParseeResult &result : resultsGroup.getResults()) + results.push_back(result); + } while (resultsGroup.getKind() == ParseeResultsGroupKind::SUCCESS); + + int tokensCount = currentIndex - startIndex; + currentIndex = startIndex; + return pair(results, tokensCount); +} + +optional, int>> Parser::tokenParseeResults(int index, TokenKind tokenKind) { shared_ptr token = tokens.at(index); if (token->isOfKind({tokenKind})) - return ParseeResult::tokenResult(token); + return pair(vector({ParseeResult::tokenResult(token)}), 1); return {}; } -optional Parser::valueTypeParseeResult(int index) { +optional, int>> Parser::valueTypeParseeResults(int index) { int startIndex = index; if (!tokens.at(index)->isOfKind({TokenKind::TYPE})) @@ -1051,11 +1122,11 @@ optional Parser::valueTypeParseeResult(int index) { if (tokens.at(index)->isOfKind({TokenKind::LESS})) { index++; - optional subResult = valueTypeParseeResult(index); - if (!subResult) + optional, int>> subResults = valueTypeParseeResults(index); + if (!subResults || (*subResults).first.empty()) return {}; - subType = (*subResult).getValueType(); - index += (*subResult).getTokensCount(); + subType = (*subResults).first[0].getValueType(); + index += (*subResults).second; if (tokens.at(index)->isOfKind({TokenKind::COMMA})) { index++; @@ -1077,10 +1148,10 @@ optional Parser::valueTypeParseeResult(int index) { } shared_ptr valueType = ValueType::valueTypeForToken(typeToken, subType, typeArg); - return ParseeResult::valueTypeResult(valueType, index - startIndex); + return pair(vector({ParseeResult::valueTypeResult(valueType, index - startIndex)}), index - startIndex); } -optional Parser::expressionParseeResult(int index) { +optional, int>> Parser::expressionParseeResults(int index) { int startIndex = currentIndex; int errorsCount = errors.size(); shared_ptr expression = nextExpression(); @@ -1089,7 +1160,7 @@ optional Parser::expressionParseeResult(int index) { int tokensCount = currentIndex - startIndex; currentIndex = startIndex; - return ParseeResult::expressionResult(expression, tokensCount); + return pair(vector({ParseeResult::expressionResult(expression, tokensCount)}), tokensCount); } bool Parser::tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance) { diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 0e27960..5c5f176 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -31,6 +31,7 @@ private: shared_ptr matchStatementVariable(); shared_ptr matchStatementFunction(); shared_ptr matchStatementRawFunction(); + shared_ptr matchStatementBlob(); shared_ptr matchStatementBlock(vector terminalTokenKinds); shared_ptr matchStatementAssignment(); @@ -56,9 +57,11 @@ private: shared_ptr matchExpressionBlock(vector terminalTokenKinds); ParseeResultsGroup parseeResultsGroupForParseeGroup(ParseeGroup group); - optional tokenParseeResult(int index, TokenKind tokenKind); - optional valueTypeParseeResult(int index); - optional expressionParseeResult(int index); + optional, int>> groupParseeResults(ParseeGroup group); + optional, int>> repeatedGroupParseeResults(ParseeGroup group); + optional, int>> tokenParseeResults(int index, TokenKind tokenKind); + optional, int>> valueTypeParseeResults(int index); + optional, int>> expressionParseeResults(int index); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); void markError(optional expectedTokenKind, optional message); diff --git a/src/Parser/Statement/Statement.h b/src/Parser/Statement/Statement.h index 963a9c5..e13b25a 100644 --- a/src/Parser/Statement/Statement.h +++ b/src/Parser/Statement/Statement.h @@ -14,7 +14,8 @@ enum class StatementKind { VARIABLE, ASSIGNMENT, REPEAT, - META_EXTERN_FUNCTION + META_EXTERN_FUNCTION, + BLOB }; class Statement { diff --git a/src/Parser/Statement/StatementAssignment.cpp b/src/Parser/Statement/StatementAssignment.cpp index ae0d24f..5dfeee0 100644 --- a/src/Parser/Statement/StatementAssignment.cpp +++ b/src/Parser/Statement/StatementAssignment.cpp @@ -1,16 +1,50 @@ #include "StatementAssignment.h" -StatementAssignment::StatementAssignment(string name, shared_ptr indexExpression, shared_ptr expression): -Statement(StatementKind::ASSIGNMENT), name(name), indexExpression(indexExpression), expression(expression) { } +shared_ptr StatementAssignment::simple(string identifier, shared_ptr valueExpression) { + shared_ptr statement = make_shared(); + statement->assignmentKind = StatementAssignmentKind::SIMPLE; + statement->identifier = identifier; + statement->valueExpression = valueExpression; + return statement; +} -string StatementAssignment::getName() { - return name; +shared_ptr StatementAssignment::data(string identifier, shared_ptr indexExpression, shared_ptr valueExpression) { + shared_ptr statement = make_shared(); + statement->assignmentKind = StatementAssignmentKind::DATA; + statement->identifier = identifier; + statement->indexExpression = indexExpression; + statement->valueExpression = valueExpression; + return statement; +} + +shared_ptr StatementAssignment::blob(string identifier, string memberName, shared_ptr valueExpression) { + shared_ptr statement = make_shared(); + statement->assignmentKind = StatementAssignmentKind::BLOB; + statement->identifier = identifier; + statement->memberName = memberName; + statement->valueExpression = valueExpression; + return statement; +} + +StatementAssignment::StatementAssignment(): +Statement(StatementKind::ASSIGNMENT) { } + +StatementAssignmentKind StatementAssignment::getAssignmentKind() { + return assignmentKind; +} + +string StatementAssignment::getIdentifier() { + return identifier; } shared_ptr StatementAssignment::getIndexExpression() { return indexExpression; } -shared_ptr StatementAssignment::getExpression() { - return expression; +string StatementAssignment::getMemberName() { + return memberName; +} + +shared_ptr StatementAssignment::getValueExpression() { + return valueExpression; } \ No newline at end of file diff --git a/src/Parser/Statement/StatementAssignment.h b/src/Parser/Statement/StatementAssignment.h index 0bb7f63..9b639ca 100644 --- a/src/Parser/Statement/StatementAssignment.h +++ b/src/Parser/Statement/StatementAssignment.h @@ -2,15 +2,29 @@ class Expression; +enum class StatementAssignmentKind { + SIMPLE, + DATA, + BLOB +}; + class StatementAssignment: public Statement { private: - string name; + StatementAssignmentKind assignmentKind; + string identifier; shared_ptr indexExpression; - shared_ptr expression; - + string memberName; + shared_ptr valueExpression; + public: - StatementAssignment(string name, shared_ptr indexExpressio, shared_ptr expression); - string getName(); + static shared_ptr simple(string identifier, shared_ptr valueExpression); + static shared_ptr data(string identifier, shared_ptr indexExpression, shared_ptr valueExpression); + static shared_ptr blob(string identifier, string memberName, shared_ptr valueExpression); + + StatementAssignment(); + StatementAssignmentKind getAssignmentKind(); + string getIdentifier(); shared_ptr getIndexExpression(); - shared_ptr getExpression(); + string getMemberName(); + shared_ptr getValueExpression(); }; \ No newline at end of file diff --git a/src/Parser/Statement/StatementBlob.cpp b/src/Parser/Statement/StatementBlob.cpp new file mode 100644 index 0000000..c0a9479 --- /dev/null +++ b/src/Parser/Statement/StatementBlob.cpp @@ -0,0 +1,14 @@ +#include "StatementBlob.h" + +#include "Parser/ValueType.h" + +StatementBlob::StatementBlob(string identifier, vector>> variables): +Statement(StatementKind::BLOB), identifier(identifier), variables(variables) { } + +string StatementBlob::getIdentifier() { + return identifier; +} + +vector>> StatementBlob::getVariables() { + return variables; +} \ No newline at end of file diff --git a/src/Parser/Statement/StatementBlob.h b/src/Parser/Statement/StatementBlob.h new file mode 100644 index 0000000..2f1851b --- /dev/null +++ b/src/Parser/Statement/StatementBlob.h @@ -0,0 +1,19 @@ +#ifndef STATEMENT_TYPE_H +#define STATEMENT_TYPE_H + +#include "Statement.h" + +class ValueType; + +class StatementBlob: public Statement { +private: + string identifier; + vector>> variables; + +public: + StatementBlob(string identifier, vector>> variables); + string getIdentifier(); + vector>> getVariables(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/ValueType.cpp b/src/Parser/ValueType.cpp index 566342b..77bc8d1 100644 --- a/src/Parser/ValueType.cpp +++ b/src/Parser/ValueType.cpp @@ -10,27 +10,38 @@ shared_ptr ValueType::S8 = make_shared(ValueTypeKind::S8, shared_ptr ValueType::S32 = make_shared(ValueTypeKind::S32, nullptr, 0); shared_ptr ValueType::R32 = make_shared(ValueTypeKind::R32, nullptr, 0); +ValueType::ValueType() { } + ValueType::ValueType(ValueTypeKind kind, shared_ptr subType, int valueArg): kind(kind), subType(subType), valueArg(valueArg) { } +shared_ptr ValueType::type(string typeName) { + shared_ptr valueType = make_shared(); + valueType->kind = ValueTypeKind::TYPE; + valueType->typeName = typeName; + return valueType; +} + shared_ptr ValueType::valueTypeForToken(shared_ptr token, shared_ptr subType, int valueArg) { switch (token->getKind()) { case TokenKind::TYPE: { string lexme = token->getLexme(); if (lexme.compare("bool") == 0) - return make_shared(ValueTypeKind::BOOL, subType, valueArg); + return make_shared(ValueTypeKind::BOOL, nullptr, 0); else if (lexme.compare("u8") == 0) - return make_shared(ValueTypeKind::U8, subType, valueArg); + return make_shared(ValueTypeKind::U8, nullptr, 0); else if (lexme.compare("u32") == 0) - return make_shared(ValueTypeKind::U32, subType, valueArg); + return make_shared(ValueTypeKind::U32, nullptr, 0); else if (lexme.compare("s8") == 0) - return make_shared(ValueTypeKind::S8, subType, valueArg); + return make_shared(ValueTypeKind::S8, nullptr, 0); else if (lexme.compare("s32") == 0) - return make_shared(ValueTypeKind::S32, subType, valueArg); + return make_shared(ValueTypeKind::S32, nullptr, 0); else if (lexme.compare("r32") == 0) - return make_shared(ValueTypeKind::R32, subType, valueArg); + return make_shared(ValueTypeKind::R32, nullptr, 0); else if (lexme.compare("data") == 0) return make_shared(ValueTypeKind::DATA, subType, valueArg); + else if (lexme.compare("type") != 0) + return ValueType::type(token->getLexme()); else return nullptr; } @@ -59,4 +70,8 @@ shared_ptr ValueType::getSubType() { int ValueType::getValueArg() { return valueArg; +} + +string ValueType::getTypeName() { + return typeName; } \ No newline at end of file diff --git a/src/Parser/ValueType.h b/src/Parser/ValueType.h index 2b77f2f..6ce36ad 100644 --- a/src/Parser/ValueType.h +++ b/src/Parser/ValueType.h @@ -2,6 +2,7 @@ #define VALUE_TYPE_H #include +#include class Token; @@ -15,7 +16,8 @@ enum class ValueTypeKind { S8, S32, R32, - DATA + DATA, + TYPE }; class ValueType { @@ -23,6 +25,7 @@ private: ValueTypeKind kind; shared_ptr subType; int valueArg; + string typeName; public: static shared_ptr NONE; @@ -34,10 +37,13 @@ public: static shared_ptr R32; static shared_ptr valueTypeForToken(shared_ptr token, shared_ptr subType, int valueArg); + ValueType(); ValueType(ValueTypeKind kind, shared_ptr subType, int valueArg); + static shared_ptr type(string typeName); ValueTypeKind getKind(); shared_ptr getSubType(); int getValueArg(); + string getTypeName(); }; #endif \ No newline at end of file