Merge pull request #35 from rafalgrodzinski/13-support-structs

Support structs
This commit is contained in:
Rafał
2025-08-12 13:17:35 +09:00
committed by GitHub
25 changed files with 950 additions and 561 deletions

View File

@@ -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
;

View File

@@ -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());
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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
};

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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);

View File

@@ -15,7 +15,7 @@ enum class ExpressionKind {
UNARY,
BINARY,
IF_ELSE,
VAR,
VARIABLE,
CALL,
BLOCK
};

View File

@@ -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;
}

View File

@@ -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();
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);

View File

@@ -14,7 +14,8 @@ enum class StatementKind {
VARIABLE,
ASSIGNMENT,
REPEAT,
META_EXTERN_FUNCTION
META_EXTERN_FUNCTION,
BLOB
};
class Statement {

View File

@@ -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;
}

View File

@@ -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();
};

View 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;
}

View 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

View File

@@ -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;
}

View File

@@ -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