Merge pull request #35 from rafalgrodzinski/13-support-structs
Support structs
This commit is contained in:
@@ -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<u8, 32>
|
||||
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<u8> <- "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
|
||||
;
|
||||
@@ -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> statement) {
|
||||
case StatementKind::RAW_FUNCTION:
|
||||
buildRawFunction(dynamic_pointer_cast<StatementRawFunction>(statement));
|
||||
break;
|
||||
case StatementKind::BLOB:
|
||||
buildBlob(dynamic_pointer_cast<StatementBlob>(statement));
|
||||
break;
|
||||
case StatementKind::VARIABLE:
|
||||
buildVarDeclaration(dynamic_pointer_cast<StatementVariable>(statement));
|
||||
break;
|
||||
@@ -160,6 +164,24 @@ void ModuleBuilder::buildRawFunction(shared_ptr<StatementRawFunction> statement)
|
||||
return;
|
||||
}
|
||||
|
||||
void ModuleBuilder::buildBlob(shared_ptr<StatementBlob> statement) {
|
||||
llvm::StructType *structType = llvm::StructType::create(*context, statement->getIdentifier());
|
||||
|
||||
// Generate types for body
|
||||
vector<string> memberNames;
|
||||
vector<llvm::Type *> types;
|
||||
for (pair<string, shared_ptr<ValueType>> &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<StatementVariable> statement) {
|
||||
if (statement->getValueType()->getKind() == ValueTypeKind::DATA) {
|
||||
vector<llvm::Value *> values = valuesForExpression(statement->getExpression());
|
||||
@@ -177,37 +199,66 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> 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<StatementAssignment> 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<int> 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> expression
|
||||
return valueForUnary(dynamic_pointer_cast<ExpressionUnary>(expression));
|
||||
case ExpressionKind::IF_ELSE:
|
||||
return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression));
|
||||
case ExpressionKind::VAR:
|
||||
return valueForVar(dynamic_pointer_cast<ExpressionVariable>(expression));
|
||||
case ExpressionKind::VARIABLE:
|
||||
return valueForVariable(dynamic_pointer_cast<ExpressionVariable>(expression));
|
||||
case ExpressionKind::CALL:
|
||||
return valueForCall(dynamic_pointer_cast<ExpressionCall>(expression));
|
||||
default:
|
||||
@@ -384,6 +435,8 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> 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<ExpressionIfElse> expressi
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVariable> expression) {
|
||||
llvm::AllocaInst *alloca = getAlloca(expression->getName());
|
||||
llvm::Value *ModuleBuilder::valueForVariable(shared_ptr<ExpressionVariable> 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<int> 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<string> 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<Scope> scopes = this->scopes;
|
||||
|
||||
while (!scopes.empty()) {
|
||||
llvm::StructType *structType = scopes.top().structTypeMap[structName];
|
||||
if (structType != nullptr)
|
||||
return structType;
|
||||
scopes.pop();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
optional<int> ModuleBuilder::getMemberIndex(string structName, string memberName) {
|
||||
stack<Scope> scopes = this->scopes;
|
||||
|
||||
while (!scopes.empty()) {
|
||||
if (scopes.top().structMembersMap.contains(structName)) {
|
||||
vector<string> memberNames = scopes.top().structMembersMap[structName];
|
||||
for (int i=0; i<memberNames.size(); i++) {
|
||||
if (memberNames[i].compare(memberName) == 0)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
scopes.pop();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) {
|
||||
if (valueType == nullptr) {
|
||||
markError(0, 0, "Missing type");
|
||||
@@ -699,6 +810,8 @@ llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int
|
||||
count = valueType->getValueArg();
|
||||
return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count);
|
||||
}
|
||||
case ValueTypeKind::TYPE:
|
||||
return getStructType(valueType->getTypeName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<string, llvm::AllocaInst*> allocaMap;
|
||||
map<string, llvm::Function*> funMap;
|
||||
map<string, llvm::InlineAsm*> rawFunMap;
|
||||
map<string, llvm::StructType*> structTypeMap;
|
||||
map<string, vector<string>> structMembersMap;
|
||||
} Scope;
|
||||
|
||||
class ModuleBuilder {
|
||||
@@ -69,6 +72,7 @@ private:
|
||||
void buildStatement(shared_ptr<Statement> statement);
|
||||
void buildFunction(shared_ptr<StatementFunction> statement);
|
||||
void buildRawFunction(shared_ptr<StatementRawFunction> statement);
|
||||
void buildBlob(shared_ptr<StatementBlob> statement);
|
||||
void buildVarDeclaration(shared_ptr<StatementVariable> statement);
|
||||
void buildAssignment(shared_ptr<StatementAssignment> statement);
|
||||
void buildBlock(shared_ptr<StatementBlock> statement);
|
||||
@@ -89,7 +93,7 @@ private:
|
||||
llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
|
||||
llvm::Value *valueForUnary(shared_ptr<ExpressionUnary> expression);
|
||||
llvm::Value *valueForIfElse(shared_ptr<ExpressionIfElse> expression);
|
||||
llvm::Value *valueForVar(shared_ptr<ExpressionVariable> expression);
|
||||
llvm::Value *valueForVariable(shared_ptr<ExpressionVariable> expression);
|
||||
llvm::Value *valueForCall(shared_ptr<ExpressionCall> 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<string> memberNames);
|
||||
llvm::StructType *getStructType(string structName);
|
||||
optional<int> getMemberIndex(string structName, string memberName);
|
||||
|
||||
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0);
|
||||
|
||||
void markError(int line, int column, string message);
|
||||
|
||||
@@ -161,6 +161,10 @@ shared_ptr<Token> 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<Token> 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<Token> 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<Token> Lexer::match(TokenKind kind, string lexme, bool needsSeparator
|
||||
return token;
|
||||
}
|
||||
|
||||
shared_ptr<Token> 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> token = make_shared<Token>(TokenKind::REAL, lexme, currentLine, currentColumn);
|
||||
advanceWithToken(token);
|
||||
return token;
|
||||
}
|
||||
|
||||
shared_ptr<Token> Lexer::matchIntegerDec() {
|
||||
int nextIndex = currentIndex;
|
||||
|
||||
@@ -399,31 +432,6 @@ shared_ptr<Token> Lexer::matchIntegerChar() {
|
||||
return token;
|
||||
}
|
||||
|
||||
shared_ptr<Token> 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> token = make_shared<Token>(TokenKind::REAL, lexme, currentLine, currentColumn);
|
||||
advanceWithToken(token);
|
||||
return token;
|
||||
}
|
||||
|
||||
shared_ptr<Token> 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;
|
||||
|
||||
@@ -22,11 +22,11 @@ private:
|
||||
|
||||
shared_ptr<Token> nextToken();
|
||||
shared_ptr<Token> match(TokenKind kind, string lexme, bool needsSeparator);
|
||||
shared_ptr<Token> matchReal();
|
||||
shared_ptr<Token> matchIntegerDec();
|
||||
shared_ptr<Token> matchIntegerHex();
|
||||
shared_ptr<Token> matchIntegerBin();
|
||||
shared_ptr<Token> matchIntegerChar();
|
||||
shared_ptr<Token> matchReal();
|
||||
shared_ptr<Token> matchString();
|
||||
shared_ptr<Token> matchType();
|
||||
shared_ptr<Token> matchIdentifier();
|
||||
|
||||
@@ -47,11 +47,11 @@ vector<TokenKind> Token::tokensBinary = {
|
||||
|
||||
vector<TokenKind> Token::tokensLiteral = {
|
||||
TokenKind::BOOL,
|
||||
TokenKind::REAL,
|
||||
TokenKind::INTEGER_DEC,
|
||||
TokenKind::INTEGER_HEX,
|
||||
TokenKind::INTEGER_BIN,
|
||||
TokenKind::INTEGER_CHAR,
|
||||
TokenKind::REAL,
|
||||
TokenKind::STRING
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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> 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> 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> 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> statement) {
|
||||
return toString(dynamic_pointer_cast<StatementFunction>(statement));
|
||||
case StatementKind::RAW_FUNCTION:
|
||||
return toString(dynamic_pointer_cast<StatementRawFunction>(statement));
|
||||
case StatementKind::BLOB:
|
||||
return toString(dynamic_pointer_cast<StatementBlob>(statement));
|
||||
case StatementKind::BLOCK:
|
||||
return toString(dynamic_pointer_cast<StatementBlock>(statement));
|
||||
case StatementKind::ASSIGNMENT:
|
||||
@@ -264,7 +275,10 @@ string Logger::toString(shared_ptr<StatementMetaExternFunction> statement) {
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<StatementVariable> 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<StatementFunction> statement) {
|
||||
@@ -296,6 +310,16 @@ string Logger::toString(shared_ptr<StatementRawFunction> statement) {
|
||||
return text;
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<StatementBlob> statement) {
|
||||
string text;
|
||||
|
||||
text += format("BLOB(\"{}\"):\n", statement->getIdentifier());
|
||||
for (pair<string, shared_ptr<ValueType>> &variable : statement->getVariables())
|
||||
text += format("{}: {}\n", variable.first, toString(variable.second));
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<StatementBlock> statement) {
|
||||
string text;
|
||||
|
||||
@@ -309,7 +333,14 @@ string Logger::toString(shared_ptr<StatementBlock> statement) {
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<StatementAssignment> 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<StatementReturn> statement) {
|
||||
@@ -353,7 +384,7 @@ string Logger::toString(shared_ptr<Expression> expression) {
|
||||
return toString(dynamic_pointer_cast<ExpressionUnary>(expression));
|
||||
case ExpressionKind::IF_ELSE:
|
||||
return toString(dynamic_pointer_cast<ExpressionIfElse>(expression));
|
||||
case ExpressionKind::VAR:
|
||||
case ExpressionKind::VARIABLE:
|
||||
return toString(dynamic_pointer_cast<ExpressionVariable>(expression));
|
||||
case ExpressionKind::GROUPING:
|
||||
return toString(dynamic_pointer_cast<ExpressionGrouping>(expression));
|
||||
@@ -423,11 +454,14 @@ string Logger::toString(shared_ptr<ExpressionIfElse> expression) {
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<ExpressionVariable> 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<ExpressionGrouping> expression) {
|
||||
|
||||
@@ -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<StatementVariable> statement);
|
||||
static string toString(shared_ptr<StatementFunction> statement);
|
||||
static string toString(shared_ptr<StatementRawFunction> statement);
|
||||
static string toString(shared_ptr<StatementBlob> statement);
|
||||
static string toString(shared_ptr<StatementBlock> statement);
|
||||
static string toString(shared_ptr<StatementAssignment> statement);
|
||||
static string toString(shared_ptr<StatementReturn> statement);
|
||||
|
||||
@@ -15,7 +15,7 @@ enum class ExpressionKind {
|
||||
UNARY,
|
||||
BINARY,
|
||||
IF_ELSE,
|
||||
VAR,
|
||||
VARIABLE,
|
||||
CALL,
|
||||
BLOCK
|
||||
};
|
||||
|
||||
@@ -1,12 +1,43 @@
|
||||
#include "ExpressionVariable.h"
|
||||
|
||||
ExpressionVariable::ExpressionVariable(string name, shared_ptr<Expression> indexExpression):
|
||||
Expression(ExpressionKind::VAR, nullptr), name(name), indexExpression(indexExpression) { }
|
||||
shared_ptr<ExpressionVariable> ExpressionVariable::simple(string identifier) {
|
||||
shared_ptr<ExpressionVariable> expression = make_shared<ExpressionVariable>();
|
||||
expression->variableKind = ExpressionVariableKind::SIMPLE;
|
||||
expression->identifier = identifier;
|
||||
return expression;
|
||||
}
|
||||
|
||||
string ExpressionVariable::getName() {
|
||||
return name;
|
||||
shared_ptr<ExpressionVariable> ExpressionVariable::data(string identifier, shared_ptr<Expression> indexExpression) {
|
||||
shared_ptr<ExpressionVariable> expression = make_shared<ExpressionVariable>();
|
||||
expression->variableKind = ExpressionVariableKind::DATA;
|
||||
expression->identifier = identifier;
|
||||
expression->indexExpression = indexExpression;
|
||||
return expression;
|
||||
}
|
||||
|
||||
shared_ptr<ExpressionVariable> ExpressionVariable::blob(string identifier, string memberName) {
|
||||
shared_ptr<ExpressionVariable> expression = make_shared<ExpressionVariable>();
|
||||
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<Expression> ExpressionVariable::getIndexExpression() {
|
||||
return indexExpression;
|
||||
}
|
||||
|
||||
string ExpressionVariable::getMemberName() {
|
||||
return memberName;
|
||||
}
|
||||
@@ -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<Expression> indexExpression;
|
||||
string memberName;
|
||||
|
||||
public:
|
||||
ExpressionVariable(string name, shared_ptr<Expression> indexExpression);
|
||||
string getName();
|
||||
static shared_ptr<ExpressionVariable> simple(string identifer);
|
||||
static shared_ptr<ExpressionVariable> data(string identifier, shared_ptr<Expression> indexExpression);
|
||||
static shared_ptr<ExpressionVariable> blob(string identifier, string memberName);
|
||||
|
||||
ExpressionVariable();
|
||||
ExpressionVariableKind getVariableKind();
|
||||
string getIdentifier();
|
||||
shared_ptr<Expression> getIndexExpression();
|
||||
string getMemberName();
|
||||
};
|
||||
@@ -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<ParseeGroup> Parsee::getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
optional<ParseeGroup> 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;
|
||||
}
|
||||
@@ -2,10 +2,17 @@
|
||||
#define PARSEE_H
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#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<ParseeGroup> group;
|
||||
optional<ParseeGroup> 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<ParseeGroup> getGroup();
|
||||
optional<ParseeGroup> getRepeatedGroup();
|
||||
TokenKind getTokenKind();
|
||||
bool getIsRequired();
|
||||
bool getShouldReturn();
|
||||
bool getShouldFailOnNoMatch();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,19 +2,9 @@
|
||||
|
||||
#include "Parsee.h"
|
||||
|
||||
ParseeGroup::ParseeGroup(vector<Parsee> parsees, optional<ParseeGroup> repeatedGroup):
|
||||
parsees(parsees) {
|
||||
if (repeatedGroup) {
|
||||
this->repeatedGroup = *repeatedGroup;
|
||||
} else {
|
||||
this->repeatedGroup = {};
|
||||
}
|
||||
}
|
||||
ParseeGroup::ParseeGroup(vector<Parsee> parsees):
|
||||
parsees(parsees) { }
|
||||
|
||||
vector<Parsee> ParseeGroup::getParsees() {
|
||||
return parsees;
|
||||
}
|
||||
|
||||
optional<reference_wrapper<ParseeGroup>> ParseeGroup::getRepeatedGroup() {
|
||||
return repeatedGroup;
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
#define PARSEE_GROUP_H
|
||||
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
class Parsee;
|
||||
|
||||
@@ -11,12 +10,10 @@ using namespace std;
|
||||
class ParseeGroup {
|
||||
private:
|
||||
vector<Parsee> parsees;
|
||||
optional<reference_wrapper<ParseeGroup>> repeatedGroup;
|
||||
|
||||
public:
|
||||
ParseeGroup(vector<Parsee> parsees, optional<ParseeGroup> repeatedGroup);
|
||||
ParseeGroup(vector<Parsee> parsees);
|
||||
vector<Parsee> getParsees();
|
||||
optional<reference_wrapper<ParseeGroup>> getRepeatedGroup();
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,7 @@ private:
|
||||
shared_ptr<Statement> matchStatementVariable();
|
||||
shared_ptr<Statement> matchStatementFunction();
|
||||
shared_ptr<Statement> matchStatementRawFunction();
|
||||
shared_ptr<Statement> matchStatementBlob();
|
||||
|
||||
shared_ptr<Statement> matchStatementBlock(vector<TokenKind> terminalTokenKinds);
|
||||
shared_ptr<Statement> matchStatementAssignment();
|
||||
@@ -56,9 +57,11 @@ private:
|
||||
shared_ptr<Expression> matchExpressionBlock(vector<TokenKind> terminalTokenKinds);
|
||||
|
||||
ParseeResultsGroup parseeResultsGroupForParseeGroup(ParseeGroup group);
|
||||
optional<ParseeResult> tokenParseeResult(int index, TokenKind tokenKind);
|
||||
optional<ParseeResult> valueTypeParseeResult(int index);
|
||||
optional<ParseeResult> expressionParseeResult(int index);
|
||||
optional<pair<vector<ParseeResult>, int>> groupParseeResults(ParseeGroup group);
|
||||
optional<pair<vector<ParseeResult>, int>> repeatedGroupParseeResults(ParseeGroup group);
|
||||
optional<pair<vector<ParseeResult>, int>> tokenParseeResults(int index, TokenKind tokenKind);
|
||||
optional<pair<vector<ParseeResult>, int>> valueTypeParseeResults(int index);
|
||||
optional<pair<vector<ParseeResult>, int>> expressionParseeResults(int index);
|
||||
bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance);
|
||||
|
||||
void markError(optional<TokenKind> expectedTokenKind, optional<string> message);
|
||||
|
||||
@@ -14,7 +14,8 @@ enum class StatementKind {
|
||||
VARIABLE,
|
||||
ASSIGNMENT,
|
||||
REPEAT,
|
||||
META_EXTERN_FUNCTION
|
||||
META_EXTERN_FUNCTION,
|
||||
BLOB
|
||||
};
|
||||
|
||||
class Statement {
|
||||
|
||||
@@ -1,16 +1,50 @@
|
||||
#include "StatementAssignment.h"
|
||||
|
||||
StatementAssignment::StatementAssignment(string name, shared_ptr<Expression> indexExpression, shared_ptr<Expression> expression):
|
||||
Statement(StatementKind::ASSIGNMENT), name(name), indexExpression(indexExpression), expression(expression) { }
|
||||
shared_ptr<StatementAssignment> StatementAssignment::simple(string identifier, shared_ptr<Expression> valueExpression) {
|
||||
shared_ptr<StatementAssignment> statement = make_shared<StatementAssignment>();
|
||||
statement->assignmentKind = StatementAssignmentKind::SIMPLE;
|
||||
statement->identifier = identifier;
|
||||
statement->valueExpression = valueExpression;
|
||||
return statement;
|
||||
}
|
||||
|
||||
string StatementAssignment::getName() {
|
||||
return name;
|
||||
shared_ptr<StatementAssignment> StatementAssignment::data(string identifier, shared_ptr<Expression> indexExpression, shared_ptr<Expression> valueExpression) {
|
||||
shared_ptr<StatementAssignment> statement = make_shared<StatementAssignment>();
|
||||
statement->assignmentKind = StatementAssignmentKind::DATA;
|
||||
statement->identifier = identifier;
|
||||
statement->indexExpression = indexExpression;
|
||||
statement->valueExpression = valueExpression;
|
||||
return statement;
|
||||
}
|
||||
|
||||
shared_ptr<StatementAssignment> StatementAssignment::blob(string identifier, string memberName, shared_ptr<Expression> valueExpression) {
|
||||
shared_ptr<StatementAssignment> statement = make_shared<StatementAssignment>();
|
||||
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<Expression> StatementAssignment::getIndexExpression() {
|
||||
return indexExpression;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> StatementAssignment::getExpression() {
|
||||
return expression;
|
||||
string StatementAssignment::getMemberName() {
|
||||
return memberName;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> StatementAssignment::getValueExpression() {
|
||||
return valueExpression;
|
||||
}
|
||||
@@ -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<Expression> indexExpression;
|
||||
shared_ptr<Expression> expression;
|
||||
|
||||
string memberName;
|
||||
shared_ptr<Expression> valueExpression;
|
||||
|
||||
public:
|
||||
StatementAssignment(string name, shared_ptr<Expression> indexExpressio, shared_ptr<Expression> expression);
|
||||
string getName();
|
||||
static shared_ptr<StatementAssignment> simple(string identifier, shared_ptr<Expression> valueExpression);
|
||||
static shared_ptr<StatementAssignment> data(string identifier, shared_ptr<Expression> indexExpression, shared_ptr<Expression> valueExpression);
|
||||
static shared_ptr<StatementAssignment> blob(string identifier, string memberName, shared_ptr<Expression> valueExpression);
|
||||
|
||||
StatementAssignment();
|
||||
StatementAssignmentKind getAssignmentKind();
|
||||
string getIdentifier();
|
||||
shared_ptr<Expression> getIndexExpression();
|
||||
shared_ptr<Expression> getExpression();
|
||||
string getMemberName();
|
||||
shared_ptr<Expression> getValueExpression();
|
||||
};
|
||||
14
src/Parser/Statement/StatementBlob.cpp
Normal file
14
src/Parser/Statement/StatementBlob.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "StatementBlob.h"
|
||||
|
||||
#include "Parser/ValueType.h"
|
||||
|
||||
StatementBlob::StatementBlob(string identifier, vector<pair<string, shared_ptr<ValueType>>> variables):
|
||||
Statement(StatementKind::BLOB), identifier(identifier), variables(variables) { }
|
||||
|
||||
string StatementBlob::getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
vector<pair<string, shared_ptr<ValueType>>> StatementBlob::getVariables() {
|
||||
return variables;
|
||||
}
|
||||
19
src/Parser/Statement/StatementBlob.h
Normal file
19
src/Parser/Statement/StatementBlob.h
Normal file
@@ -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<pair<string, shared_ptr<ValueType>>> variables;
|
||||
|
||||
public:
|
||||
StatementBlob(string identifier, vector<pair<string, shared_ptr<ValueType>>> variables);
|
||||
string getIdentifier();
|
||||
vector<pair<string, shared_ptr<ValueType>>> getVariables();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -10,27 +10,38 @@ shared_ptr<ValueType> ValueType::S8 = make_shared<ValueType>(ValueTypeKind::S8,
|
||||
shared_ptr<ValueType> ValueType::S32 = make_shared<ValueType>(ValueTypeKind::S32, nullptr, 0);
|
||||
shared_ptr<ValueType> ValueType::R32 = make_shared<ValueType>(ValueTypeKind::R32, nullptr, 0);
|
||||
|
||||
ValueType::ValueType() { }
|
||||
|
||||
ValueType::ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg):
|
||||
kind(kind), subType(subType), valueArg(valueArg) { }
|
||||
|
||||
shared_ptr<ValueType> ValueType::type(string typeName) {
|
||||
shared_ptr<ValueType> valueType = make_shared<ValueType>();
|
||||
valueType->kind = ValueTypeKind::TYPE;
|
||||
valueType->typeName = typeName;
|
||||
return valueType;
|
||||
}
|
||||
|
||||
shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg) {
|
||||
switch (token->getKind()) {
|
||||
case TokenKind::TYPE: {
|
||||
string lexme = token->getLexme();
|
||||
if (lexme.compare("bool") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::BOOL, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0);
|
||||
else if (lexme.compare("u8") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::U8, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::U8, nullptr, 0);
|
||||
else if (lexme.compare("u32") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::U32, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::U32, nullptr, 0);
|
||||
else if (lexme.compare("s8") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::S8, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::S8, nullptr, 0);
|
||||
else if (lexme.compare("s32") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::S32, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::S32, nullptr, 0);
|
||||
else if (lexme.compare("r32") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::R32, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::R32, nullptr, 0);
|
||||
else if (lexme.compare("data") == 0)
|
||||
return make_shared<ValueType>(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> ValueType::getSubType() {
|
||||
|
||||
int ValueType::getValueArg() {
|
||||
return valueArg;
|
||||
}
|
||||
|
||||
string ValueType::getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
#define VALUE_TYPE_H
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
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<ValueType> subType;
|
||||
int valueArg;
|
||||
string typeName;
|
||||
|
||||
public:
|
||||
static shared_ptr<ValueType> NONE;
|
||||
@@ -34,10 +37,13 @@ public:
|
||||
static shared_ptr<ValueType> R32;
|
||||
static shared_ptr<ValueType> valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg);
|
||||
|
||||
ValueType();
|
||||
ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg);
|
||||
static shared_ptr<ValueType> type(string typeName);
|
||||
ValueTypeKind getKind();
|
||||
shared_ptr<ValueType> getSubType();
|
||||
int getValueArg();
|
||||
string getTypeName();
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user