Merge branch 'main' into 26-update-readme

This commit is contained in:
Rafał Grodziński
2025-08-01 12:45:51 +09:00
35 changed files with 1426 additions and 285 deletions

6
.gitignore vendored
View File

@@ -1,3 +1,8 @@
# ingnore files without extension
*
!*.*
!*/
.DS_Store .DS_Store
.vscode/settings.json .vscode/settings.json
@@ -7,3 +12,4 @@ build/
# brb build artifiacts # brb build artifiacts
*.o *.o
*.asm

2
.vscode/launch.json vendored
View File

@@ -6,7 +6,7 @@
"type": "lldb-dap", "type": "lldb-dap",
"request": "launch", "request": "launch",
"program": "${command:cmake.launchTargetPath}", "program": "${command:cmake.launchTargetPath}",
"args": ["-v", "${workspaceFolder}/samples/hello.brc"], "args": ["-v", "${workspaceFolder}/samples/test.brc"],
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"internalConsoleOptions": "openOnSessionStart", "internalConsoleOptions": "openOnSessionStart",
} }

9
.vscode/tasks.json vendored
View File

@@ -3,12 +3,17 @@
"tasks": [ "tasks": [
{ {
"label": "Build Bits Runner Builder (Debug)", "label": "Build Bits Runner Builder (Debug)",
"type": "cmake", "type": "shell",
"command": "build", "command": "cmake -B build && cmake --build build --config Debug",
"group": { "group": {
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true
} }
},
{
"label": "Clean",
"type": "shell",
"command": "rm -rf build *.o *.asm; find ./ -perm +100 -type f -maxdepth 1 -delete"
} }
] ]
} }

View File

@@ -1,6 +1,6 @@
@extern putchar fun: character sint32 -> sint32 @extern putchar fun: character u32 -> u32
fib fun: number sint32 -> sint32 fib fun: number u32 -> u32
ret if number < 2: ret if number < 2:
number number
else else
@@ -8,13 +8,13 @@ fib fun: number sint32 -> sint32
; ;
; ;
printNum fun: number sint32 printNum fun: number u32
biggest sint32 <- 10 biggest u32 <- 10
rep biggest <= number: biggest <- biggest * 10 rep biggest <= number: biggest <- biggest * 10
biggest <- biggest / 10 biggest <- biggest / 10
rep biggest > 0: rep biggest > 0:
digit sint32 <- number / biggest digit u32 <- number / biggest
putchar(digit + '0') putchar(digit + '0')
number <- number % biggest number <- number % biggest
biggest <- biggest / 10 biggest <- biggest / 10
@@ -22,9 +22,9 @@ printNum fun: number sint32
; ;
// Print first 20 fibonaci numbers // Print first 20 fibonaci numbers
main fun -> sint32 main fun -> u32
rep i sint32 <- 0, i < 20: rep i u32 <- 0, i < 20:
res sint32 <- fib(i) res u32 <- fib(i)
printNum(res) printNum(res)
putchar('\n') putchar('\n')
i <- i + 1 i <- i + 1

View File

@@ -1,9 +1,9 @@
@extern putchar fun: character sint32 -> sint32 @extern putchar fun: character u32 -> u32
main fun -> sint32 main fun -> u32
text data<sint32> <- "Hello, world!\n" text data<u32> <- "Hello, world!\n"
rep i sint32 <- 0, text[i] != 0: rep i u32 <- 0, text[i] != 0:
putchar(text[i]) putchar(text[i])
i <- i + 1 i <- i + 1
; ;

View File

@@ -1,4 +1,6 @@
@extern putchar fun: character sint32 -> sint32 //@extern putchar fun: character sint32 -> sint32
// ./build/brb samples/test.brc -S -x86-asm-syntax=intel
/* /*
User type User type
@@ -18,8 +20,42 @@ i u32 <- 0, rep text[i] != 0:
// text data<u8> <- "Hello world!" // text data<u8> <- "Hello world!"
main fun -> sint32 /*addStuff asm<"+r, r">: num1 u32, num2 u32 -> u32
text data<sint32> <- "Hello string!\n" add $1, $0
;*/
/*normAdd fun: num1 sint32, num2 sint32 -> sint32
ret num1 + num2
;*/
/*rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32
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
num5 + num3
ret 0 ret 0
; ;

View File

@@ -11,9 +11,11 @@
#include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionCall.h"
#include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionIfElse.h"
#include "Parser/Expression/ExpressionBinary.h" #include "Parser/Expression/ExpressionBinary.h"
#include "Parser/Expression/ExpressionUnary.h"
#include "Parser/Expression/ExpressionBlock.h" #include "Parser/Expression/ExpressionBlock.h"
#include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementFunction.h"
#include "Parser/Statement/StatementRawFunction.h"
#include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementVariable.h"
#include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementAssignment.h"
#include "Parser/Statement/StatementReturn.h" #include "Parser/Statement/StatementReturn.h"
@@ -31,8 +33,11 @@ moduleName(moduleName), sourceFileName(sourceFileName), statements(statements) {
typeVoid = llvm::Type::getVoidTy(*context); typeVoid = llvm::Type::getVoidTy(*context);
typeBool = llvm::Type::getInt1Ty(*context); typeBool = llvm::Type::getInt1Ty(*context);
typeSint32 = llvm::Type::getInt32Ty(*context); typeU8 = llvm::Type::getInt8Ty(*context);
typeReal32 = llvm::Type::getFloatTy(*context); typeU32 = llvm::Type::getInt32Ty(*context);
typeS8 = llvm::Type::getInt8Ty(*context);
typeS32 = llvm::Type::getInt32Ty(*context);
typeR32 = llvm::Type::getFloatTy(*context);
} }
shared_ptr<llvm::Module> ModuleBuilder::getModule() { shared_ptr<llvm::Module> ModuleBuilder::getModule() {
@@ -40,6 +45,12 @@ shared_ptr<llvm::Module> ModuleBuilder::getModule() {
for (shared_ptr<Statement> &statement : statements) for (shared_ptr<Statement> &statement : statements)
buildStatement(statement); buildStatement(statement);
// verify module
string errorMessage;
llvm::raw_string_ostream llvmErrorMessage(errorMessage);
if (llvm::verifyModule(*module, &llvmErrorMessage))
markError(0, 0, errorMessage);
if (!errors.empty()) { if (!errors.empty()) {
for (shared_ptr<Error> &error : errors) for (shared_ptr<Error> &error : errors)
Logger::print(error); Logger::print(error);
@@ -52,7 +63,10 @@ shared_ptr<llvm::Module> ModuleBuilder::getModule() {
void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) { void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) {
switch (statement->getKind()) { switch (statement->getKind()) {
case StatementKind::FUNCTION: case StatementKind::FUNCTION:
buildFunctionDeclaration(dynamic_pointer_cast<StatementFunction>(statement)); buildFunction(dynamic_pointer_cast<StatementFunction>(statement));
break;
case StatementKind::RAW_FUNCTION:
buildRawFunction(dynamic_pointer_cast<StatementRawFunction>(statement));
break; break;
case StatementKind::VARIABLE: case StatementKind::VARIABLE:
buildVarDeclaration(dynamic_pointer_cast<StatementVariable>(statement)); buildVarDeclaration(dynamic_pointer_cast<StatementVariable>(statement));
@@ -80,15 +94,21 @@ void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) {
} }
} }
void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunction> statement) { void ModuleBuilder::buildFunction(shared_ptr<StatementFunction> statement) {
// get argument types // function types
vector<llvm::Type *> types; llvm::Type *returnType = typeForValueType(statement->getReturnValueType());
if (returnType == nullptr)
return;
vector<llvm::Type *> argTypes;
for (pair<string, shared_ptr<ValueType>> &arg : statement->getArguments()) { for (pair<string, shared_ptr<ValueType>> &arg : statement->getArguments()) {
types.push_back(typeForValueType(arg.second)); llvm::Type *argType = typeForValueType(arg.second);
if (argType == nullptr)
return;
argTypes.push_back(argType);
} }
// build function declaration // build function declaration
llvm::FunctionType *funType = llvm::FunctionType::get(typeForValueType(statement->getReturnValueType()), types, false); llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false);
llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get()); llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get());
if (!setFun(statement->getName(), fun)) if (!setFun(statement->getName(), fun))
return; return;
@@ -103,7 +123,7 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunction> state
int i=0; int i=0;
for (auto &arg : fun->args()) { for (auto &arg : fun->args()) {
string name = statement->getArguments()[i].first; string name = statement->getArguments()[i].first;
llvm::Type *type = types[i]; llvm::Type *type = argTypes[i];
arg.setName(name); arg.setName(name);
llvm::AllocaInst *alloca = builder->CreateAlloca(type, nullptr, name); llvm::AllocaInst *alloca = builder->CreateAlloca(type, nullptr, name);
@@ -126,6 +146,20 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunction> state
markError(0, 0, errorMessage); markError(0, 0, errorMessage);
} }
void ModuleBuilder::buildRawFunction(shared_ptr<StatementRawFunction> statement) {
// function types
llvm::Type *returnType = typeForValueType(statement->getReturnValueType());
vector<llvm::Type *> argTypes;
for (pair<string, shared_ptr<ValueType>> &arg : statement->getArguments())
argTypes.push_back(typeForValueType(arg.second));
// build function declaration & body
llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false);
llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), statement->getConstraints(), true, false, llvm::InlineAsm::AsmDialect::AD_Intel);
if (!setRawFun(statement->getName(), rawFun))
return;
}
void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement) { void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement) {
if (statement->getValueType()->getKind() == ValueTypeKind::DATA) { if (statement->getValueType()->getKind() == ValueTypeKind::DATA) {
vector<llvm::Value *> values = valuesForExpression(statement->getExpression()); vector<llvm::Value *> values = valuesForExpression(statement->getExpression());
@@ -145,6 +179,8 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement)
} }
} else { } else {
llvm::Value *value = valueForExpression(statement->getExpression()); llvm::Value *value = valueForExpression(statement->getExpression());
if (value == nullptr)
return;
llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType(), 0), nullptr, statement->getName()); llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType(), 0), nullptr, statement->getName());
if (!setAlloca(statement->getName(), alloca)) if (!setAlloca(statement->getName(), alloca))
@@ -244,7 +280,10 @@ void ModuleBuilder::buildMetaExternFunction(shared_ptr<StatementMetaExternFuncti
} }
// build function declaration // build function declaration
llvm::FunctionType *funType = llvm::FunctionType::get(typeForValueType(statement->getReturnValueType()), types, false); llvm::Type *returnType = typeForValueType(statement->getReturnValueType());
if (returnType == nullptr)
return;
llvm::FunctionType *funType = llvm::FunctionType::get(returnType, types, false);
llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get()); llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get());
if (!setFun(statement->getName(), fun)) if (!setFun(statement->getName(), fun))
return; return;
@@ -270,6 +309,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
return valueForExpression(dynamic_pointer_cast<ExpressionGrouping>(expression)->getExpression()); return valueForExpression(dynamic_pointer_cast<ExpressionGrouping>(expression)->getExpression());
case ExpressionKind::BINARY: case ExpressionKind::BINARY:
return valueForBinary(dynamic_pointer_cast<ExpressionBinary>(expression)); return valueForBinary(dynamic_pointer_cast<ExpressionBinary>(expression));
case ExpressionKind::UNARY:
return valueForUnary(dynamic_pointer_cast<ExpressionUnary>(expression));
case ExpressionKind::IF_ELSE: case ExpressionKind::IF_ELSE:
return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression)); return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression));
case ExpressionKind::VAR: case ExpressionKind::VAR:
@@ -301,10 +342,16 @@ llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expres
return llvm::UndefValue::get(typeVoid); return llvm::UndefValue::get(typeVoid);
case ValueTypeKind::BOOL: case ValueTypeKind::BOOL:
return llvm::ConstantInt::get(typeBool, expression->getBoolValue(), true); return llvm::ConstantInt::get(typeBool, expression->getBoolValue(), true);
case ValueTypeKind::SINT32: case ValueTypeKind::U8:
return llvm::ConstantInt::get(typeSint32, expression->getSint32Value(), true); return llvm::ConstantInt::get(typeU8, expression->getU8Value(), true);
case ValueTypeKind::REAL32: case ValueTypeKind::U32:
return llvm::ConstantInt::get(typeReal32, expression->getReal32Value(), true); return llvm::ConstantInt::get(typeU32, expression->getU32Value(), true);
case ValueTypeKind::S8:
return llvm::ConstantInt::get(typeS8, expression->getS8Value(), true);
case ValueTypeKind::S32:
return llvm::ConstantInt::get(typeS32, expression->getS32Value(), true);
case ValueTypeKind::R32:
return llvm::ConstantFP::get(typeR32, expression->getR32Value());
} }
} }
@@ -331,9 +378,11 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expressi
if (type == typeBool) { if (type == typeBool) {
return valueForBinaryBool(expression->getOperation(), leftValue, rightValue); return valueForBinaryBool(expression->getOperation(), leftValue, rightValue);
} else if (type == typeSint32 || type == typeVoid) { } else if (type == typeU8 || type == typeU32) {
return valueForBinaryInteger(expression->getOperation(), leftValue, rightValue); return valueForBinaryUnsignedInteger(expression->getOperation(), leftValue, rightValue);
} else if (type == typeReal32) { } else if (type == typeS8 || type == typeS32) {
return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue);
} else if (type == typeR32) {
return valueForBinaryReal(expression->getOperation(), leftValue, rightValue); return valueForBinaryReal(expression->getOperation(), leftValue, rightValue);
} }
@@ -348,12 +397,39 @@ llvm::Value *ModuleBuilder::valueForBinaryBool(ExpressionBinaryOperation operati
case ExpressionBinaryOperation::NOT_EQUAL: case ExpressionBinaryOperation::NOT_EQUAL:
return builder->CreateICmpNE(leftValue, rightValue); return builder->CreateICmpNE(leftValue, rightValue);
default: default:
markError(0, 0, "Unexpecgted operation for boolean operands"); markError(0, 0, "Unexpected operation for boolean operands");
return nullptr; return nullptr;
} }
} }
llvm::Value *ModuleBuilder::valueForBinaryInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) { llvm::Value *ModuleBuilder::valueForBinaryUnsignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) {
switch (operation) {
case ExpressionBinaryOperation::EQUAL:
return builder->CreateICmpEQ(leftValue, rightValue);
case ExpressionBinaryOperation::NOT_EQUAL:
return builder->CreateICmpNE(leftValue, rightValue);
case ExpressionBinaryOperation::LESS:
return builder->CreateICmpSLT(leftValue, rightValue);
case ExpressionBinaryOperation::LESS_EQUAL:
return builder->CreateICmpSLE(leftValue, rightValue);
case ExpressionBinaryOperation::GREATER:
return builder->CreateICmpSGT(leftValue, rightValue);
case ExpressionBinaryOperation::GREATER_EQUAL:
return builder->CreateICmpSGE(leftValue, rightValue);
case ExpressionBinaryOperation::ADD:
return builder->CreateNUWAdd(leftValue, rightValue);
case ExpressionBinaryOperation::SUB:
return builder->CreateNUWSub(leftValue, rightValue);
case ExpressionBinaryOperation::MUL:
return builder->CreateNUWMul(leftValue, rightValue);
case ExpressionBinaryOperation::DIV:
return builder->CreateUDiv(leftValue, rightValue);
case ExpressionBinaryOperation::MOD:
return builder->CreateURem(leftValue, rightValue);
}
}
llvm::Value *ModuleBuilder::valueForBinarySignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) {
switch (operation) { switch (operation) {
case ExpressionBinaryOperation::EQUAL: case ExpressionBinaryOperation::EQUAL:
return builder->CreateICmpEQ(leftValue, rightValue); return builder->CreateICmpEQ(leftValue, rightValue);
@@ -407,6 +483,26 @@ llvm::Value *ModuleBuilder::valueForBinaryReal(ExpressionBinaryOperation operati
} }
} }
llvm::Value *ModuleBuilder::valueForUnary(shared_ptr<ExpressionUnary> expression) {
llvm::Value *value = valueForExpression(expression->getExpression());
llvm::Type *type = value->getType();
// do nothing for plus
if (expression->getOperation() == ExpressionUnaryOperation::PLUS)
return value;
if (type == typeU8 || type == typeU32) {
return builder->CreateNeg(value);
} else if (type == typeS8 || type == typeS32) {
return builder->CreateNSWNeg(value);
} else if (type == typeR32) {
return builder->CreateFNeg(value);
}
markError(0, 0, "Unexpected operation");
return nullptr;
}
llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expression) { llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expression) {
shared_ptr<Expression> conditionExpression = expression->getCondition(); shared_ptr<Expression> conditionExpression = expression->getCondition();
@@ -481,8 +577,7 @@ llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVariable> expressio
llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) { llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) {
llvm::Function *fun = getFun(expression->getName()); llvm::Function *fun = getFun(expression->getName());
if (fun == nullptr) if (fun != nullptr) {
return nullptr;
llvm::FunctionType *funType = fun->getFunctionType(); llvm::FunctionType *funType = fun->getFunctionType();
vector<llvm::Value*> argValues; vector<llvm::Value*> argValues;
for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) { for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) {
@@ -492,6 +587,20 @@ llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression)
return builder->CreateCall(funType, fun, llvm::ArrayRef(argValues)); return builder->CreateCall(funType, fun, llvm::ArrayRef(argValues));
} }
llvm::InlineAsm *rawFun = getRawFun(expression->getName());
if (rawFun != nullptr) {
vector<llvm::Value *>argValues;
for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) {
llvm::Value *argValue = valueForExpression(argumentExpression);
argValues.push_back(argValue);
}
return builder->CreateCall(rawFun, llvm::ArrayRef(argValues));
}
markError(0, 0, format("Function \"{}\" not defined in scope", expression->getName()));
return nullptr;
}
bool ModuleBuilder::setAlloca(string name, llvm::AllocaInst *alloca) { bool ModuleBuilder::setAlloca(string name, llvm::AllocaInst *alloca) {
if (scopes.top().allocaMap[name] != nullptr) { if (scopes.top().allocaMap[name] != nullptr) {
markError(0, 0, format("Variable \"{}\" already defined", name)); markError(0, 0, format("Variable \"{}\" already defined", name));
@@ -518,7 +627,7 @@ llvm::AllocaInst* ModuleBuilder::getAlloca(string name) {
bool ModuleBuilder::setFun(string name, llvm::Function *fun) { bool ModuleBuilder::setFun(string name, llvm::Function *fun) {
if (scopes.top().funMap[name] != nullptr) { if (scopes.top().funMap[name] != nullptr) {
markError(0, 0, format("Function \"{}\" already defined", name)); markError(0, 0, format("Function \"{}\" already defined in scope", name));
return false; return false;
} }
@@ -536,27 +645,59 @@ llvm::Function* ModuleBuilder::getFun(string name) {
scopes.pop(); scopes.pop();
} }
markError(0, 0, format("Function \"{}\" not defined in scope", name)); return nullptr;
}
bool ModuleBuilder::setRawFun(string name, llvm::InlineAsm *rawFun) {
if (scopes.top().rawFunMap[name] != nullptr) {
markError(0, 0, format("Raw function \"{}\" already defined in scope", name));
return false;
}
scopes.top().rawFunMap[name] = rawFun;
return true;
}
llvm::InlineAsm *ModuleBuilder::getRawFun(string name) {
stack<Scope> scopes = this->scopes;
while (!scopes.empty()) {
llvm::InlineAsm *rawFun = scopes.top().rawFunMap[name];
if (rawFun != nullptr)
return rawFun;
scopes.pop();
}
return nullptr; return nullptr;
} }
llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) { llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) {
if (valueType == nullptr) {
markError(0, 0, "Missing type");
return nullptr;
}
switch (valueType->getKind()) { switch (valueType->getKind()) {
case ValueTypeKind::NONE: case ValueTypeKind::NONE:
return typeVoid; return typeVoid;
case ValueTypeKind::BOOL: case ValueTypeKind::BOOL:
return typeBool; return typeBool;
case ValueTypeKind::SINT32: case ValueTypeKind::U8:
return typeSint32; return typeU8;
case ValueTypeKind::REAL32: case ValueTypeKind::U32:
return typeReal32; return typeU32;
case ValueTypeKind::S8:
return typeS8;
case ValueTypeKind::S32:
return typeS32;
case ValueTypeKind::R32:
return typeR32;
case ValueTypeKind::DATA: { case ValueTypeKind::DATA: {
if (valueType->getSubType() == nullptr) if (valueType->getSubType() == nullptr)
return nullptr; return nullptr;
if (valueType->getValueArg() > 0) if (valueType->getValueArg() > 0)
count = valueType->getValueArg(); count = valueType->getValueArg();
return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count); return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count);
return nullptr;
} }
} }
} }

View File

@@ -10,6 +10,7 @@
#include <llvm/IR/Constants.h> #include <llvm/IR/Constants.h>
#include <llvm/Support/raw_ostream.h> #include <llvm/Support/raw_ostream.h>
#include <llvm/IR/Verifier.h> #include <llvm/IR/Verifier.h>
#include <llvm/IR/InlineAsm.h>
class Error; class Error;
class ValueType; class ValueType;
@@ -22,10 +23,12 @@ class ExpressionVariable;
class ExpressionCall; class ExpressionCall;
class ExpressionIfElse; class ExpressionIfElse;
class ExpressionBinary; class ExpressionBinary;
class ExpressionUnary;
enum class ExpressionBinaryOperation; enum class ExpressionBinaryOperation;
class Statement; class Statement;
class StatementFunction; class StatementFunction;
class StatementRawFunction;
class StatementVariable; class StatementVariable;
class StatementAssignment; class StatementAssignment;
class StatementReturn; class StatementReturn;
@@ -39,6 +42,7 @@ using namespace std;
typedef struct { typedef struct {
map<string, llvm::AllocaInst*> allocaMap; map<string, llvm::AllocaInst*> allocaMap;
map<string, llvm::Function*> funMap; map<string, llvm::Function*> funMap;
map<string, llvm::InlineAsm*> rawFunMap;
} Scope; } Scope;
class ModuleBuilder { class ModuleBuilder {
@@ -53,14 +57,18 @@ private:
llvm::Type *typeVoid; llvm::Type *typeVoid;
llvm::Type *typeBool; llvm::Type *typeBool;
llvm::IntegerType *typeSint32; llvm::IntegerType *typeU8;
llvm::Type *typeReal32; llvm::IntegerType *typeU32;
llvm::IntegerType *typeS8;
llvm::IntegerType *typeS32;
llvm::Type *typeR32;
vector<shared_ptr<Statement>> statements; vector<shared_ptr<Statement>> statements;
stack<Scope> scopes; stack<Scope> scopes;
void buildStatement(shared_ptr<Statement> statement); void buildStatement(shared_ptr<Statement> statement);
void buildFunctionDeclaration(shared_ptr<StatementFunction> statement); void buildFunction(shared_ptr<StatementFunction> statement);
void buildRawFunction(shared_ptr<StatementRawFunction> statement);
void buildVarDeclaration(shared_ptr<StatementVariable> statement); void buildVarDeclaration(shared_ptr<StatementVariable> statement);
void buildAssignment(shared_ptr<StatementAssignment> statement); void buildAssignment(shared_ptr<StatementAssignment> statement);
void buildBlock(shared_ptr<StatementBlock> statement); void buildBlock(shared_ptr<StatementBlock> statement);
@@ -76,8 +84,10 @@ private:
llvm::Value *valueForGrouping(shared_ptr<ExpressionGrouping> expression); llvm::Value *valueForGrouping(shared_ptr<ExpressionGrouping> expression);
llvm::Value *valueForBinary(shared_ptr<ExpressionBinary> expression); llvm::Value *valueForBinary(shared_ptr<ExpressionBinary> expression);
llvm::Value *valueForBinaryBool(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForBinaryBool(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
llvm::Value *valueForBinaryInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForBinaryUnsignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
llvm::Value *valueForBinarySignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); 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 *valueForIfElse(shared_ptr<ExpressionIfElse> expression);
llvm::Value *valueForVar(shared_ptr<ExpressionVariable> expression); llvm::Value *valueForVar(shared_ptr<ExpressionVariable> expression);
llvm::Value *valueForCall(shared_ptr<ExpressionCall> expression); llvm::Value *valueForCall(shared_ptr<ExpressionCall> expression);
@@ -88,6 +98,9 @@ private:
bool setFun(string name, llvm::Function *fun); bool setFun(string name, llvm::Function *fun);
llvm::Function *getFun(string name); llvm::Function *getFun(string name);
bool setRawFun(string name, llvm::InlineAsm *rawFun);
llvm::InlineAsm *getRawFun(string name);
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0); llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0);
void markError(int line, int column, string message); void markError(int line, int column, string message);

View File

@@ -12,6 +12,8 @@ vector<shared_ptr<Token>> Lexer::getTokens() {
currentIndex = 0; currentIndex = 0;
currentLine = 0; currentLine = 0;
currentColumn = 0; currentColumn = 0;
foundRawSourceStart = false;
isParsingRawSource = false;
tokens.clear(); tokens.clear();
errors.clear(); errors.clear();
@@ -117,6 +119,11 @@ shared_ptr<Token> Lexer::nextToken() {
return nextToken(); // gets rid of remaining white spaces without repeating the code return nextToken(); // gets rid of remaining white spaces without repeating the code
} }
// raw source
token = matchRawSourceLine();
if (token != nullptr)
return token;
// structural // structural
token = match(TokenKind::LEFT_PAREN, "(", false); token = match(TokenKind::LEFT_PAREN, "(", false);
if (token != nullptr) if (token != nullptr)
@@ -213,6 +220,12 @@ shared_ptr<Token> Lexer::nextToken() {
if (token != nullptr) if (token != nullptr)
return token; return token;
token = match(TokenKind::RAW_FUNCTION, "raw", true);
if (token != nullptr) {
foundRawSourceStart = true;
return token;
}
token = match(TokenKind::RETURN, "ret", true); token = match(TokenKind::RETURN, "ret", true);
if (token != nullptr) if (token != nullptr)
return token; return token;
@@ -271,8 +284,10 @@ shared_ptr<Token> Lexer::nextToken() {
// new line // new line
token = match(TokenKind::NEW_LINE, "\n", false); token = match(TokenKind::NEW_LINE, "\n", false);
if (token != nullptr) if (token != nullptr) {
tryStartingRawSourceParsing();
return token; return token;
}
// eof // eof
token = matchEnd(); token = matchEnd();
@@ -430,21 +445,6 @@ shared_ptr<Token> Lexer::matchString() {
return token; return token;
} }
shared_ptr<Token> Lexer::matchIdentifier() {
int nextIndex = currentIndex;
while (nextIndex < source.length() && isIdentifier(nextIndex))
nextIndex++;
if (nextIndex == currentIndex || !isSeparator(nextIndex))
return nullptr;
string lexme = source.substr(currentIndex, nextIndex - currentIndex);
shared_ptr<Token> token = make_shared<Token>(TokenKind::IDENTIFIER, lexme, currentLine, currentColumn);
advanceWithToken(token);
return token;
}
shared_ptr<Token> Lexer::matchType() { shared_ptr<Token> Lexer::matchType() {
int nextIndex = currentIndex; int nextIndex = currentIndex;
@@ -463,6 +463,52 @@ shared_ptr<Token> Lexer::matchType() {
return token; return token;
} }
shared_ptr<Token> Lexer::matchIdentifier() {
int nextIndex = currentIndex;
while (nextIndex < source.length() && isIdentifier(nextIndex))
nextIndex++;
if (nextIndex == currentIndex || !isSeparator(nextIndex))
return nullptr;
string lexme = source.substr(currentIndex, nextIndex - currentIndex);
shared_ptr<Token> token = make_shared<Token>(TokenKind::IDENTIFIER, lexme, currentLine, currentColumn);
advanceWithToken(token);
return token;
}
void Lexer::tryStartingRawSourceParsing() {
if (!foundRawSourceStart)
return;
if (!tokens.at(tokens.size() - 1)->isOfKind({TokenKind::COLON, TokenKind::COMMA, TokenKind::RIGHT_ARROW})) {
foundRawSourceStart = false;
isParsingRawSource = true;
}
}
shared_ptr<Token> Lexer::matchRawSourceLine() {
int nextIndex = currentIndex;
if (!isParsingRawSource)
return nullptr;
if (source.at(nextIndex) == ';') {
isParsingRawSource = false;
return nullptr;
}
while (source.at(nextIndex) != '\n')
nextIndex++;
string lexme = source.substr(currentIndex, nextIndex - currentIndex);
shared_ptr<Token> token = make_shared<Token>(TokenKind::RAW_SOURCE_LINE, lexme, currentLine, currentColumn);
advanceWithToken(token);
currentIndex++; // skip newline
return token;
}
shared_ptr<Token> Lexer::matchEnd() { shared_ptr<Token> Lexer::matchEnd() {
if (currentIndex >= source.length()) if (currentIndex >= source.length())
return make_shared<Token>(TokenKind::END, "", currentLine, currentColumn); return make_shared<Token>(TokenKind::END, "", currentLine, currentColumn);
@@ -530,11 +576,15 @@ bool Lexer::isSeparator(int index) {
} }
void Lexer::advanceWithToken(shared_ptr<Token> token) { void Lexer::advanceWithToken(shared_ptr<Token> token) {
if (token->getKind() == TokenKind::NEW_LINE) { switch (token->getKind()) {
case TokenKind::NEW_LINE:
case TokenKind::RAW_SOURCE_LINE:
currentLine++; currentLine++;
currentColumn = 0; currentColumn = 0;
} else { break;
default:
currentColumn += token->getLexme().length(); currentColumn += token->getLexme().length();
break;
} }
currentIndex += token->getLexme().length(); currentIndex += token->getLexme().length();
} }

View File

@@ -17,6 +17,8 @@ private:
int currentColumn; int currentColumn;
vector<shared_ptr<Token>> tokens; vector<shared_ptr<Token>> tokens;
vector<shared_ptr<Error>> errors; vector<shared_ptr<Error>> errors;
bool foundRawSourceStart;
bool isParsingRawSource;
shared_ptr<Token> nextToken(); shared_ptr<Token> nextToken();
shared_ptr<Token> match(TokenKind kind, string lexme, bool needsSeparator); shared_ptr<Token> match(TokenKind kind, string lexme, bool needsSeparator);
@@ -28,6 +30,8 @@ private:
shared_ptr<Token> matchString(); shared_ptr<Token> matchString();
shared_ptr<Token> matchType(); shared_ptr<Token> matchType();
shared_ptr<Token> matchIdentifier(); shared_ptr<Token> matchIdentifier();
void tryStartingRawSourceParsing();
shared_ptr<Token> matchRawSourceLine();
shared_ptr<Token> matchEnd(); shared_ptr<Token> matchEnd();
bool isWhiteSpace(int index); bool isWhiteSpace(int index);

View File

@@ -4,21 +4,30 @@ vector<TokenKind> Token::tokensEquality = {
TokenKind::EQUAL, TokenKind::EQUAL,
TokenKind::NOT_EQUAL TokenKind::NOT_EQUAL
}; };
vector<TokenKind> Token::tokensComparison = { vector<TokenKind> Token::tokensComparison = {
TokenKind::LESS, TokenKind::LESS,
TokenKind::LESS_EQUAL, TokenKind::LESS_EQUAL,
TokenKind::GREATER, TokenKind::GREATER,
TokenKind::GREATER_EQUAL TokenKind::GREATER_EQUAL
}; };
vector<TokenKind> Token::tokensTerm = { vector<TokenKind> Token::tokensTerm = {
TokenKind::PLUS, TokenKind::PLUS,
TokenKind::MINUS TokenKind::MINUS
}; };
vector<TokenKind> Token::tokensFactor = { vector<TokenKind> Token::tokensFactor = {
TokenKind::STAR, TokenKind::STAR,
TokenKind::SLASH, TokenKind::SLASH,
TokenKind::PERCENT TokenKind::PERCENT
}; };
vector<TokenKind> Token::tokensUnary = {
TokenKind::PLUS,
TokenKind::MINUS
};
vector<TokenKind> Token::tokensBinary = { vector<TokenKind> Token::tokensBinary = {
TokenKind::EQUAL, TokenKind::EQUAL,
TokenKind::NOT_EQUAL, TokenKind::NOT_EQUAL,
@@ -35,6 +44,7 @@ vector<TokenKind> Token::tokensBinary = {
TokenKind::SLASH, TokenKind::SLASH,
TokenKind::PERCENT TokenKind::PERCENT
}; };
vector<TokenKind> Token::tokensLiteral = { vector<TokenKind> Token::tokensLiteral = {
TokenKind::BOOL, TokenKind::BOOL,
TokenKind::INTEGER_DEC, TokenKind::INTEGER_DEC,

View File

@@ -30,6 +30,8 @@ enum class TokenKind {
RIGHT_ARROW, RIGHT_ARROW,
FUNCTION, FUNCTION,
RAW_FUNCTION,
RAW_SOURCE_LINE,
RETURN, RETURN,
REPEAT, REPEAT,
IF, IF,
@@ -63,6 +65,7 @@ public:
static vector<TokenKind> tokensComparison; static vector<TokenKind> tokensComparison;
static vector<TokenKind> tokensTerm; static vector<TokenKind> tokensTerm;
static vector<TokenKind> tokensFactor; static vector<TokenKind> tokensFactor;
static vector<TokenKind> tokensUnary;
static vector<TokenKind> tokensBinary; static vector<TokenKind> tokensBinary;
static vector<TokenKind> tokensLiteral; static vector<TokenKind> tokensLiteral;

View File

@@ -11,6 +11,7 @@
#include "Parser/Statement/StatementMetaExternFunction.h" #include "Parser/Statement/StatementMetaExternFunction.h"
#include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementVariable.h"
#include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementFunction.h"
#include "Parser/Statement/StatementRawFunction.h"
#include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementBlock.h"
#include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementAssignment.h"
#include "Parser/Statement/StatementReturn.h" #include "Parser/Statement/StatementReturn.h"
@@ -19,6 +20,7 @@
#include "Parser/Expression/Expression.h" #include "Parser/Expression/Expression.h"
#include "Parser/Expression/ExpressionBinary.h" #include "Parser/Expression/ExpressionBinary.h"
#include "Parser/Expression/ExpressionUnary.h"
#include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionIfElse.h"
#include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionVariable.h"
#include "Parser/Expression/ExpressionGrouping.h" #include "Parser/Expression/ExpressionGrouping.h"
@@ -97,6 +99,10 @@ string Logger::toString(shared_ptr<Token> token) {
return "ELSE"; return "ELSE";
case TokenKind::FUNCTION: case TokenKind::FUNCTION:
return "FUN"; return "FUN";
case TokenKind::RAW_FUNCTION:
return "RAW";
case TokenKind::RAW_SOURCE_LINE:
return format("RAW_SOURCE_LINE({})", token->getLexme());
case TokenKind::RETURN: case TokenKind::RETURN:
return "RET"; return "RET";
case TokenKind::REPEAT: case TokenKind::REPEAT:
@@ -179,6 +185,8 @@ string Logger::toString(TokenKind tokenKind) {
return "ELSE"; return "ELSE";
case TokenKind::FUNCTION: case TokenKind::FUNCTION:
return "FUN"; return "FUN";
case TokenKind::RAW_FUNCTION:
return "RAW";
case TokenKind::RETURN: case TokenKind::RETURN:
return "RET"; return "RET";
case TokenKind::REPEAT: case TokenKind::REPEAT:
@@ -195,15 +203,24 @@ string Logger::toString(TokenKind tokenKind) {
} }
string Logger::toString(shared_ptr<ValueType> valueType) { string Logger::toString(shared_ptr<ValueType> valueType) {
if (valueType == nullptr)
return "{INVALID}";
switch (valueType->getKind()) { switch (valueType->getKind()) {
case ValueTypeKind::NONE: case ValueTypeKind::NONE:
return "NONE"; return "NONE";
case ValueTypeKind::BOOL: case ValueTypeKind::BOOL:
return "BOOL"; return "BOOL";
case ValueTypeKind::SINT32: case ValueTypeKind::U8:
return "SINT32"; return "U8";
case ValueTypeKind::REAL32: case ValueTypeKind::U32:
return "REAL32"; return "U32";
case ValueTypeKind::S8:
return "S8";
case ValueTypeKind::S32:
return "S32";
case ValueTypeKind::R32:
return "R32";
case ValueTypeKind::DATA: case ValueTypeKind::DATA:
return "[]"; return "[]";
} }
@@ -217,6 +234,8 @@ string Logger::toString(shared_ptr<Statement> statement) {
return toString(dynamic_pointer_cast<StatementVariable>(statement)); return toString(dynamic_pointer_cast<StatementVariable>(statement));
case StatementKind::FUNCTION: case StatementKind::FUNCTION:
return toString(dynamic_pointer_cast<StatementFunction>(statement)); return toString(dynamic_pointer_cast<StatementFunction>(statement));
case StatementKind::RAW_FUNCTION:
return toString(dynamic_pointer_cast<StatementRawFunction>(statement));
case StatementKind::BLOCK: case StatementKind::BLOCK:
return toString(dynamic_pointer_cast<StatementBlock>(statement)); return toString(dynamic_pointer_cast<StatementBlock>(statement));
case StatementKind::ASSIGNMENT: case StatementKind::ASSIGNMENT:
@@ -262,6 +281,21 @@ string Logger::toString(shared_ptr<StatementFunction> statement) {
return text; return text;
} }
string Logger::toString(shared_ptr<StatementRawFunction> statement) {
string text;
string argsString;
for (int i = 0; i < statement->getArguments().size(); i++) {
auto arg = statement->getArguments().at(i);
argsString += format("ARG({}, {})", arg.first, toString(arg.second));
}
text += format("RAW(\"{}\"|{}|{}):\n", statement->getName(), argsString, toString(statement->getReturnValueType()));
text += statement->getRawSource();
return text;
}
string Logger::toString(shared_ptr<StatementBlock> statement) { string Logger::toString(shared_ptr<StatementBlock> statement) {
string text; string text;
@@ -315,6 +349,8 @@ string Logger::toString(shared_ptr<Expression> expression) {
switch (expression->getKind()) { switch (expression->getKind()) {
case ExpressionKind::BINARY: case ExpressionKind::BINARY:
return toString(dynamic_pointer_cast<ExpressionBinary>(expression)); return toString(dynamic_pointer_cast<ExpressionBinary>(expression));
case ExpressionKind::UNARY:
return toString(dynamic_pointer_cast<ExpressionUnary>(expression));
case ExpressionKind::IF_ELSE: case ExpressionKind::IF_ELSE:
return toString(dynamic_pointer_cast<ExpressionIfElse>(expression)); return toString(dynamic_pointer_cast<ExpressionIfElse>(expression));
case ExpressionKind::VAR: case ExpressionKind::VAR:
@@ -361,6 +397,17 @@ string Logger::toString(shared_ptr<ExpressionBinary> expression) {
} }
} }
string Logger::toString(shared_ptr<ExpressionUnary> expression) {
switch (expression->getOperation()) {
case ExpressionUnaryOperation::PLUS:
return "+" + toString(expression->getExpression());
case ExpressionUnaryOperation::MINUS:
return "-" + toString(expression->getExpression());
case ExpressionUnaryOperation::INVALID:
return "{INVALID}";
}
}
string Logger::toString(shared_ptr<ExpressionIfElse> expression) { string Logger::toString(shared_ptr<ExpressionIfElse> expression) {
string text; string text;
@@ -396,10 +443,16 @@ string Logger::toString(shared_ptr<ExpressionLiteral> expression) {
return "NONE"; return "NONE";
case ValueTypeKind::BOOL: case ValueTypeKind::BOOL:
return expression->getBoolValue() ? "true" : "false"; return expression->getBoolValue() ? "true" : "false";
case ValueTypeKind::SINT32: case ValueTypeKind::U8:
return to_string(expression->getSint32Value()); return to_string(expression->getU8Value());
case ValueTypeKind::REAL32: case ValueTypeKind::U32:
return to_string(expression->getReal32Value()); return to_string(expression->getU32Value());
case ValueTypeKind::S8:
return to_string(expression->getS8Value());
case ValueTypeKind::S32:
return to_string(expression->getS32Value());
case ValueTypeKind::R32:
return to_string(expression->getR32Value());
default: default:
return "?"; return "?";
} }
@@ -458,7 +511,7 @@ void Logger::print(shared_ptr<Error> error) {
switch (error->getKind()) { switch (error->getKind()) {
case ErrorKind::LEXER_ERROR: { case ErrorKind::LEXER_ERROR: {
string lexme = error->getLexme() ? *(error->getLexme()) : ""; string lexme = error->getLexme() ? *(error->getLexme()) : "";
message = format("Unexpected token \"{}\" at line: {}, column: {}", lexme, error->getLine() + 1, error->getColumn() + 1); message = format("At line {}, column {}: Unexpected token \"{}\"", error->getLine() + 1, error->getColumn() + 1, lexme);
break; break;
} }
case ErrorKind::PARSER_ERROR: { case ErrorKind::PARSER_ERROR: {
@@ -468,13 +521,13 @@ void Logger::print(shared_ptr<Error> error) {
if (expectedTokenKind) { if (expectedTokenKind) {
message = format( message = format(
"Expected token {} but instead found \"{}\" at line: {}, column: {}", "At line {}, column {}: Expected token {} but found {} instead",
toString(*expectedTokenKind), token->getLexme(), token->getLine() + 1, token->getColumn() + 1 token->getLine() + 1, token->getColumn() + 1, toString(*expectedTokenKind), toString(token)
); );
} else { } else {
message = format( message = format(
"Unexpected token \"{}\" found at line: {}, column: {}", "At line {}, column {}: Unexpected token \"{}\" found",
token->getLexme(), token->getLine() + 1, token->getColumn() + 1 token->getLine() + 1, token->getColumn() + 1, toString(token)
); );
} }
if (errorMessage) if (errorMessage)
@@ -483,7 +536,7 @@ void Logger::print(shared_ptr<Error> error) {
} }
case ErrorKind::BUILDER_ERROR: { case ErrorKind::BUILDER_ERROR: {
string errorMessage = error->getMessage() ? *(error->getMessage()) : ""; string errorMessage = error->getMessage() ? *(error->getMessage()) : "";
message = format("Error at line {}, column {}: {}", error->getLine(), error->getColumn(), errorMessage); message = format("At line {}, column {}: {}", error->getLine(), error->getColumn(), errorMessage);
break; break;
} }
} }

View File

@@ -11,6 +11,7 @@ class Statement;
class StatementMetaExternFunction; class StatementMetaExternFunction;
class StatementVariable; class StatementVariable;
class StatementFunction; class StatementFunction;
class StatementRawFunction;
class StatementBlock; class StatementBlock;
class StatementAssignment; class StatementAssignment;
class StatementReturn; class StatementReturn;
@@ -19,6 +20,7 @@ class StatementExpression;
class Expression; class Expression;
class ExpressionBinary; class ExpressionBinary;
class ExpressionUnary;
class ExpressionIfElse; class ExpressionIfElse;
class ExpressionVariable; class ExpressionVariable;
class ExpressionGrouping; class ExpressionGrouping;
@@ -41,6 +43,7 @@ private:
static string toString(shared_ptr<StatementMetaExternFunction> statement); static string toString(shared_ptr<StatementMetaExternFunction> statement);
static string toString(shared_ptr<StatementVariable> statement); static string toString(shared_ptr<StatementVariable> statement);
static string toString(shared_ptr<StatementFunction> statement); static string toString(shared_ptr<StatementFunction> statement);
static string toString(shared_ptr<StatementRawFunction> statement);
static string toString(shared_ptr<StatementBlock> statement); static string toString(shared_ptr<StatementBlock> statement);
static string toString(shared_ptr<StatementAssignment> statement); static string toString(shared_ptr<StatementAssignment> statement);
static string toString(shared_ptr<StatementReturn> statement); static string toString(shared_ptr<StatementReturn> statement);
@@ -49,6 +52,7 @@ private:
static string toString(shared_ptr<Expression> expression); static string toString(shared_ptr<Expression> expression);
static string toString(shared_ptr<ExpressionBinary> expression); static string toString(shared_ptr<ExpressionBinary> expression);
static string toString(shared_ptr<ExpressionUnary> expression);
static string toString(shared_ptr<ExpressionIfElse> expression); static string toString(shared_ptr<ExpressionIfElse> expression);
static string toString(shared_ptr<ExpressionVariable> expression); static string toString(shared_ptr<ExpressionVariable> expression);
static string toString(shared_ptr<ExpressionGrouping> expression); static string toString(shared_ptr<ExpressionGrouping> expression);

View File

@@ -12,6 +12,7 @@ enum class ExpressionKind {
LITERAL, LITERAL,
ARRAY_LITERAL, ARRAY_LITERAL,
GROUPING, GROUPING,
UNARY,
BINARY, BINARY,
IF_ELSE, IF_ELSE,
VAR, VAR,

View File

@@ -1,4 +1,7 @@
#include "Parser/Expression/Expression.h" #ifndef EXPRESSION_BINARY_H
#define EXPRESSION_BINARY_H
#include "Expression.h"
enum class ExpressionBinaryOperation { enum class ExpressionBinaryOperation {
EQUAL, EQUAL,
@@ -27,3 +30,5 @@ public:
shared_ptr<Expression> getLeft(); shared_ptr<Expression> getLeft();
shared_ptr<Expression> getRight(); shared_ptr<Expression> getRight();
}; };
#endif

View File

@@ -15,14 +15,14 @@ shared_ptr<ExpressionLiteral> ExpressionLiteral::expressionLiteralForToken(share
case TokenKind::INTEGER_DEC: { case TokenKind::INTEGER_DEC: {
string numString = token->getLexme(); string numString = token->getLexme();
erase(numString, '_'); erase(numString, '_');
expression->sint32Value = stoi(numString, nullptr, 10); expression->s32Value = stoi(numString, nullptr, 10);
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
break; break;
} }
case TokenKind::INTEGER_HEX: { case TokenKind::INTEGER_HEX: {
string numString = token->getLexme(); string numString = token->getLexme();
erase(numString, '_'); erase(numString, '_');
expression->sint32Value = stoi(numString, nullptr, 16); expression->u32Value = stoul(numString, nullptr, 16);
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
break; break;
} }
@@ -30,7 +30,7 @@ shared_ptr<ExpressionLiteral> ExpressionLiteral::expressionLiteralForToken(share
string numString = token->getLexme(); string numString = token->getLexme();
erase(numString, '_'); erase(numString, '_');
numString = numString.substr(2, numString.size()-1); numString = numString.substr(2, numString.size()-1);
expression->sint32Value = stoi(numString, nullptr, 2); expression->u32Value = stoul(numString, nullptr, 2);
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
break; break;
} }
@@ -41,13 +41,14 @@ shared_ptr<ExpressionLiteral> ExpressionLiteral::expressionLiteralForToken(share
return nullptr; return nullptr;
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
expression->sint32Value = *charValue; expression->u32Value = *charValue;
return expression; return expression;
} }
case TokenKind::REAL: case TokenKind::REAL: {
expression->real32Value = stof(token->getLexme()); expression->r32Value = stof(token->getLexme());
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
break; break;
}
default: default:
return nullptr; return nullptr;
} }
@@ -62,10 +63,22 @@ bool ExpressionLiteral::getBoolValue() {
return boolValue; return boolValue;
} }
int32_t ExpressionLiteral::getSint32Value() { uint8_t ExpressionLiteral::getU8Value() {
return sint32Value; return u8Value;
} }
float ExpressionLiteral::getReal32Value() { uint32_t ExpressionLiteral::getU32Value() {
return real32Value; return u32Value;
}
int8_t ExpressionLiteral::getS8Value() {
return s8Value;
}
int32_t ExpressionLiteral::getS32Value() {
return s32Value;
}
float ExpressionLiteral::getR32Value() {
return r32Value;
} }

View File

@@ -6,16 +6,22 @@
class ExpressionLiteral: public Expression { class ExpressionLiteral: public Expression {
private: private:
bool boolValue; bool boolValue;
int32_t sint32Value; uint8_t u8Value;
float real32Value; uint32_t u32Value;
int8_t s8Value;
int32_t s32Value;
float r32Value;
public: public:
static shared_ptr<ExpressionLiteral> expressionLiteralForToken(shared_ptr<Token> token); static shared_ptr<ExpressionLiteral> expressionLiteralForToken(shared_ptr<Token> token);
ExpressionLiteral(); ExpressionLiteral();
bool getBoolValue(); bool getBoolValue();
int32_t getSint32Value(); uint8_t getU8Value();
float getReal32Value(); uint32_t getU32Value();
int8_t getS8Value();
int32_t getS32Value();
float getR32Value();
}; };
#endif #endif

View File

@@ -0,0 +1,29 @@
#include "ExpressionUnary.h"
#include "Lexer/Token.h"
ExpressionUnary::ExpressionUnary(shared_ptr<Token> token, shared_ptr<Expression> expression):
Expression(ExpressionKind::UNARY, nullptr), expression(expression) {
switch (token->getKind()) {
case TokenKind::PLUS:
operation = ExpressionUnaryOperation::PLUS;
valueType = expression->getValueType();
break;
case TokenKind::MINUS:
operation = ExpressionUnaryOperation::MINUS;
valueType = expression->getValueType();
break;
default:
operation = ExpressionUnaryOperation::INVALID;
valueType = nullptr;
break;
}
}
ExpressionUnaryOperation ExpressionUnary::getOperation() {
return operation;
}
shared_ptr<Expression> ExpressionUnary::getExpression() {
return expression;
}

View File

@@ -0,0 +1,23 @@
#ifndef EXPRESSION_UNARY_H
#define EXPRESSION_UNARY_H
#include "Expression.h"
enum class ExpressionUnaryOperation {
PLUS,
MINUS,
INVALID
};
class ExpressionUnary: public Expression {
private:
ExpressionUnaryOperation operation;
shared_ptr<Expression> expression;
public:
ExpressionUnary(shared_ptr<Token> token, shared_ptr<Expression> expression);
ExpressionUnaryOperation getOperation();
shared_ptr<Expression> getExpression();
};
#endif

View File

@@ -0,0 +1,44 @@
#include "Parsee.h"
Parsee Parsee::tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn) {
Parsee parsee;
parsee.kind = ParseeKind::TOKEN;
parsee.tokenKind = tokenKind;
parsee.isRequired = isRequired;
parsee.shouldReturn = shouldReturn;
return parsee;
}
Parsee Parsee::valueTypeParsee(bool isRequired) {
Parsee parsee;
parsee.kind = ParseeKind::VALUE_TYPE;
parsee.isRequired = isRequired;
parsee.shouldReturn = true;
return parsee;
}
Parsee Parsee::expressionParsee(bool isRequired) {
Parsee parsee;
parsee.kind = ParseeKind::EXPRESSION;
parsee.isRequired = isRequired;
parsee.shouldReturn = true;
return parsee;
}
Parsee::Parsee() { }
ParseeKind Parsee::getKind() {
return kind;
}
TokenKind Parsee::getTokenKind() {
return tokenKind;
}
bool Parsee::getIsRequired() {
return isRequired;
}
bool Parsee::getShouldReturn() {
return shouldReturn;
}

View File

@@ -0,0 +1,33 @@
#ifndef PARSEE_H
#define PARSEE_H
#include <memory>
enum class TokenKind;
enum class ParseeKind {
TOKEN,
VALUE_TYPE,
EXPRESSION
};
class Parsee {
private:
ParseeKind kind;
TokenKind tokenKind;
bool isRequired;
bool shouldReturn;
Parsee();
public:
static Parsee tokenParsee(TokenKind tokenKind, bool isRequired, bool shouldReturn);
static Parsee valueTypeParsee(bool isRequired);
static Parsee expressionParsee(bool isRequired);
ParseeKind getKind();
TokenKind getTokenKind();
bool getIsRequired();
bool getShouldReturn();
};
#endif

View File

@@ -0,0 +1,20 @@
#include "ParseeGroup.h"
#include "Parsee.h"
ParseeGroup::ParseeGroup(vector<Parsee> parsees, optional<ParseeGroup> repeatedGroup):
parsees(parsees) {
if (repeatedGroup) {
this->repeatedGroup = *repeatedGroup;
} else {
this->repeatedGroup = {};
}
}
vector<Parsee> ParseeGroup::getParsees() {
return parsees;
}
optional<reference_wrapper<ParseeGroup>> ParseeGroup::getRepeatedGroup() {
return repeatedGroup;
}

View File

@@ -0,0 +1,22 @@
#ifndef PARSEE_GROUP_H
#define PARSEE_GROUP_H
#include <vector>
#include <optional>
class Parsee;
using namespace std;
class ParseeGroup {
private:
vector<Parsee> parsees;
optional<reference_wrapper<ParseeGroup>> repeatedGroup;
public:
ParseeGroup(vector<Parsee> parsees, optional<ParseeGroup> repeatedGroup);
vector<Parsee> getParsees();
optional<reference_wrapper<ParseeGroup>> getRepeatedGroup();
};
#endif

View File

@@ -0,0 +1,51 @@
#include "ParseeResult.h"
#include "Lexer/Token.h"
#include "Parser/ValueType.h"
ParseeResult ParseeResult::tokenResult(shared_ptr<Token> token) {
ParseeResult parseeResult;
parseeResult.kind = ParseeResultKind::TOKEN;
parseeResult.token = token;
parseeResult.tokensCount = 1;
return parseeResult;
}
ParseeResult ParseeResult::valueTypeResult(shared_ptr<ValueType> valueType, int tokensCount) {
ParseeResult parseeResult;
parseeResult.kind = ParseeResultKind::VALUE_TYPE;
parseeResult.valueType = valueType;
parseeResult.tokensCount = tokensCount;
return parseeResult;
}
ParseeResult ParseeResult::expressionResult(shared_ptr<Expression> expression, int tokensCount) {
ParseeResult result;
result.kind = ParseeResultKind::EXPRESSION;
result.expression = expression;
result.tokensCount = tokensCount;
return result;
}
ParseeResult::ParseeResult() { }
ParseeResultKind ParseeResult::getKind() {
return kind;
}
shared_ptr<Token> ParseeResult::getToken() {
return token;
}
shared_ptr<ValueType> ParseeResult::getValueType() {
return valueType;
}
shared_ptr<Expression> ParseeResult::getExpression() {
return expression;
}
int ParseeResult::getTokensCount() {
return tokensCount;
}

View File

@@ -0,0 +1,39 @@
#ifndef PARSEE_RESULT_H
#define PARSEE_RESULT_H
#include <memory>
class Token;
class ValueType;
class Expression;
using namespace std;
enum class ParseeResultKind {
TOKEN,
VALUE_TYPE,
EXPRESSION
};
class ParseeResult {
private:
ParseeResultKind kind;
shared_ptr<Token> token;
shared_ptr<ValueType> valueType;
shared_ptr<Expression> expression;
int tokensCount;
ParseeResult();
public:
static ParseeResult tokenResult(shared_ptr<Token> token);
static ParseeResult valueTypeResult(shared_ptr<ValueType> valueType, int tokensCount);
static ParseeResult expressionResult(shared_ptr<Expression> expression, int tokensCount);
ParseeResultKind getKind();
shared_ptr<Token> getToken();
shared_ptr<ValueType> getValueType();
shared_ptr<Expression> getExpression();
int getTokensCount();
};
#endif

View File

@@ -0,0 +1,30 @@
#include "ParseeResultsGroup.h"
#include "ParseeResult.h"
ParseeResultsGroup ParseeResultsGroup::success(vector<ParseeResult> results) {
ParseeResultsGroup resultsGroup;
resultsGroup.kind = ParseeResultsGroupKind::SUCCESS;
resultsGroup.results = results;
return resultsGroup;
}
ParseeResultsGroup ParseeResultsGroup::noMatch() {
ParseeResultsGroup resultsGroup;
resultsGroup.kind = ParseeResultsGroupKind::NO_MATCH;
return resultsGroup;
}
ParseeResultsGroup ParseeResultsGroup::failure() {
ParseeResultsGroup resultsGroup;
resultsGroup.kind = ParseeResultsGroupKind::FAILURE;
return resultsGroup;
}
ParseeResultsGroupKind ParseeResultsGroup::getKind() {
return kind;
}
vector<ParseeResult> ParseeResultsGroup::getResults() {
return results;
}

View File

@@ -0,0 +1,30 @@
#ifndef PARSEE_RESULTS_GROUP_H
#define PARSEE_RESULTS_GROUP_H
#include <vector>
class ParseeResult;
using namespace std;
enum class ParseeResultsGroupKind {
SUCCESS,
NO_MATCH,
FAILURE
};
class ParseeResultsGroup {
private:
ParseeResultsGroupKind kind;
vector<ParseeResult> results;
public:
static ParseeResultsGroup success(vector<ParseeResult> results);
static ParseeResultsGroup noMatch();
static ParseeResultsGroup failure();
ParseeResultsGroupKind getKind();
vector<ParseeResult> getResults();
};
#endif

View File

@@ -12,10 +12,12 @@
#include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionVariable.h"
#include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionCall.h"
#include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionIfElse.h"
#include "Parser/Expression/ExpressionUnary.h"
#include "Parser/Expression/ExpressionBinary.h" #include "Parser/Expression/ExpressionBinary.h"
#include "Parser/Expression/ExpressionBlock.h" #include "Parser/Expression/ExpressionBlock.h"
#include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementFunction.h"
#include "Parser/Statement/StatementRawFunction.h"
#include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementVariable.h"
#include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementAssignment.h"
#include "Parser/Statement/StatementReturn.h" #include "Parser/Statement/StatementReturn.h"
@@ -24,6 +26,11 @@
#include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementBlock.h"
#include "Parser/Statement/StatementRepeat.h" #include "Parser/Statement/StatementRepeat.h"
#include "Parsee/Parsee.h"
#include "Parsee/ParseeGroup.h"
#include "Parsee/ParseeResult.h"
#include "Parsee/ParseeResultsGroup.h"
Parser::Parser(vector<shared_ptr<Token>> tokens) : Parser::Parser(vector<shared_ptr<Token>> tokens) :
tokens(tokens) { } tokens(tokens) { }
@@ -61,6 +68,10 @@ shared_ptr<Statement> Parser::nextStatement() {
if (statement != nullptr || errors.size() > errorsCount) if (statement != nullptr || errors.size() > errorsCount)
return statement; return statement;
statement = matchStatementRawFunction();
if (statement != nullptr || errors.size() > errorsCount)
return statement;
statement = matchStatementVariable(); statement = matchStatementVariable();
if (statement != nullptr || errors.size() > errorsCount) if (statement != nullptr || errors.size() > errorsCount)
return statement; return statement;
@@ -102,112 +113,207 @@ shared_ptr<Statement> Parser::nextInBlockStatement() {
} }
shared_ptr<Statement> Parser::matchStatementMetaExternFunction() { shared_ptr<Statement> Parser::matchStatementMetaExternFunction() {
if (!tryMatchingTokenKinds({TokenKind::M_EXTERN, TokenKind::IDENTIFIER, TokenKind::FUNCTION}, true, false)) ParseeResultsGroup resultsGroup;
return nullptr;
string name; string identifier;
vector<pair<string, shared_ptr<ValueType>>> arguments; vector<pair<string, shared_ptr<ValueType>>> arguments;
shared_ptr<ValueType> returnType = ValueType::NONE; shared_ptr<ValueType> returnType = ValueType::NONE;
currentIndex++; // skip meta // identifier
shared_ptr<Token> identifierToken = tokens.at(currentIndex++); resultsGroup = parseeResultsGroupForParseeGroup(
currentIndex++; // skip fun 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 // arguments
if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { resultsGroup = parseeResultsGroupForParseeGroup(
do { ParseeGroup(
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line {
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) { Parsee::tokenParsee(TokenKind::COLON, true, false),
markError({}, "Expected function argument"); Parsee::tokenParsee(TokenKind::NEW_LINE, false, false),
return nullptr; 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<resultsGroup.getResults().size(); i+=2) {
pair<string, shared_ptr<ValueType>> arg;
arg.first = resultsGroup.getResults().at(i).getToken()->getLexme();
arg.second = resultsGroup.getResults().at(i+1).getValueType();
arguments.push_back(arg);
} }
shared_ptr<Token> identifierToken = tokens.at(currentIndex++); break;
//shared_ptr<Token> argumentTypeToken = tokens.at(currentIndex++); case ParseeResultsGroupKind::NO_MATCH:
shared_ptr<ValueType> argumentType = matchValueType(); break;
if (argumentType == nullptr) { case ParseeResultsGroupKind::FAILURE:
markError(TokenKind::TYPE, {});
return nullptr; return nullptr;
} }
arguments.push_back(pair<string, shared_ptr<ValueType>>(identifierToken->getLexme(), argumentType)); // return type
} while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)); resultsGroup = parseeResultsGroupForParseeGroup(
} ParseeGroup(
{
Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false),
Parsee::tokenParsee(TokenKind::NEW_LINE, false, false),
Parsee::valueTypeParsee(true)
},
{}
)
);
// Return type switch (resultsGroup.getKind()) {
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) { case ParseeResultsGroupKind::SUCCESS:
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line returnType = resultsGroup.getResults().at(0).getValueType();
break;
//shared_ptr<Token> returnTypeToken = tokens.at(currentIndex); case ParseeResultsGroupKind::NO_MATCH:
returnType = matchValueType(); break;
if (returnType == nullptr) { case ParseeResultsGroupKind::FAILURE:
markError(TokenKind::TYPE, {});
return nullptr; return nullptr;
} }
}
return make_shared<StatementMetaExternFunction>(identifierToken->getLexme(), arguments, returnType); return make_shared<StatementMetaExternFunction>(identifier, arguments, returnType);
} }
shared_ptr<Statement> Parser::matchStatementVariable() { shared_ptr<Statement> Parser::matchStatementVariable() {
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup(
ParseeGroup(
{
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true),
Parsee::valueTypeParsee(true),
Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false),
Parsee::expressionParsee(true)
},
{}
)
);
if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS)
return nullptr; return nullptr;
shared_ptr<Token> identifierToken = tokens.at(currentIndex++); string identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
shared_ptr<ValueType> valueType = matchValueType(); shared_ptr<ValueType> valueType = resultsGroup.getResults().at(1).getValueType();
shared_ptr<Expression> expression = resultsGroup.getResults().at(2).getExpression();
// Expect left arrow return make_shared<StatementVariable>(identifier, valueType, expression);
if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true)) {
markError(TokenKind::LEFT_ARROW, {});
return nullptr;
}
shared_ptr<Expression> expression = nextExpression();
if (expression == nullptr)
return nullptr;
return make_shared<StatementVariable>(identifierToken->getLexme(), valueType, expression);
} }
shared_ptr<Statement> Parser::matchStatementFunction() { shared_ptr<Statement> Parser::matchStatementFunction() {
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::FUNCTION}, true, false)) bool hasError = false;
return nullptr; ParseeResultsGroup resultsGroup;
string name; string name;
vector<pair<string, shared_ptr<ValueType>>> arguments; vector<pair<string, shared_ptr<ValueType>>> arguments;
shared_ptr<ValueType> returnType = ValueType::NONE; shared_ptr<ValueType> returnType = ValueType::NONE;
shared_ptr<Statement> statementBlock; shared_ptr<Statement> statementBlock;
// name // identifier
name = tokens.at(currentIndex++)->getLexme(); resultsGroup = parseeResultsGroupForParseeGroup(
currentIndex++; // skip fun ParseeGroup(
{
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true),
Parsee::tokenParsee(TokenKind::FUNCTION, true, false)
},
{}
)
);
switch (resultsGroup.getKind()) {
case ParseeResultsGroupKind::SUCCESS:
name = resultsGroup.getResults().at(0).getToken()->getLexme();
break;
case ParseeResultsGroupKind::NO_MATCH:
return nullptr;
case ParseeResultsGroupKind::FAILURE:
hasError = true;
break;
}
// arguments // arguments
if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { if (!hasError) {
do { resultsGroup = parseeResultsGroupForParseeGroup(
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line ParseeGroup(
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false)) { {
markError({}, "Expected function argument"); Parsee::tokenParsee(TokenKind::COLON, true, false),
return nullptr; 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<resultsGroup.getResults().size(); i+=2) {
pair<string, shared_ptr<ValueType>> arg;
arg.first = resultsGroup.getResults().at(i).getToken()->getLexme();
arg.second = resultsGroup.getResults().at(i+1).getValueType();
arguments.push_back(arg);
} }
shared_ptr<Token> identifierToken = tokens.at(currentIndex++); break;
shared_ptr<ValueType> argumentType = matchValueType(); case ParseeResultsGroupKind::NO_MATCH:
if (argumentType == nullptr) { break;
markError(TokenKind::TYPE, {}); case ParseeResultsGroupKind::FAILURE:
return nullptr; hasError = true;
break;
} }
arguments.push_back(pair<string, shared_ptr<ValueType>>(identifierToken->getLexme(), argumentType));
} while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true));
} }
// return type // return type
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) { if (!hasError) {
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line resultsGroup = parseeResultsGroupForParseeGroup(
ParseeGroup(
{
Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false),
Parsee::tokenParsee(TokenKind::NEW_LINE, false, false),
Parsee::valueTypeParsee(true)
},
{}
)
);
returnType = matchValueType(); switch (resultsGroup.getKind()) {
if (returnType == nullptr) { case ParseeResultsGroupKind::SUCCESS:
markError(TokenKind::TYPE, {}); returnType = resultsGroup.getResults().at(0).getValueType();
return nullptr; break;
case ParseeResultsGroupKind::NO_MATCH:
break;
case ParseeResultsGroupKind::FAILURE:
hasError = true;
break;
} }
} }
@@ -218,10 +324,11 @@ shared_ptr<Statement> Parser::matchStatementFunction() {
} }
// block // block
statementBlock = matchStatementBlock({TokenKind::SEMICOLON}); statementBlock = matchStatementBlock({TokenKind::SEMICOLON, TokenKind::END});
if (statementBlock == nullptr) if (statementBlock == nullptr)
return nullptr; return nullptr;
// closing semicolon
if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) { if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) {
markError(TokenKind::SEMICOLON, {}); markError(TokenKind::SEMICOLON, {});
return nullptr; return nullptr;
@@ -230,6 +337,155 @@ shared_ptr<Statement> Parser::matchStatementFunction() {
return make_shared<StatementFunction>(name, arguments, returnType, dynamic_pointer_cast<StatementBlock>(statementBlock)); return make_shared<StatementFunction>(name, arguments, returnType, dynamic_pointer_cast<StatementBlock>(statementBlock));
} }
shared_ptr<Statement> Parser::matchStatementRawFunction() {
bool hasError = false;
ParseeResultsGroup resultsGroup;
string name;
string constraints;
vector<pair<string, shared_ptr<ValueType>>> arguments;
shared_ptr<ValueType> returnType = ValueType::NONE;
string rawSource;
// identifier
resultsGroup = parseeResultsGroupForParseeGroup(
ParseeGroup(
{
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true),
Parsee::tokenParsee(TokenKind::RAW_FUNCTION, true, false)
},
{}
)
);
switch (resultsGroup.getKind()) {
case ParseeResultsGroupKind::SUCCESS:
name = resultsGroup.getResults().at(0).getToken()->getLexme();
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<resultsGroup.getResults().size(); i+=2) {
pair<string, shared_ptr<ValueType>> 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())
rawSource += "\n";
rawSource += tokens.at(currentIndex++)->getLexme();
// Consume optional new line (for example because of a comment)
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
}
if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) {
markError(TokenKind::SEMICOLON, {});
return nullptr;
}
return make_shared<StatementRawFunction>(name, constraints, arguments, returnType, rawSource);
}
shared_ptr<Statement> Parser::matchStatementBlock(vector<TokenKind> terminalTokenKinds) { shared_ptr<Statement> Parser::matchStatementBlock(vector<TokenKind> terminalTokenKinds) {
vector<shared_ptr<Statement>> statements; vector<shared_ptr<Statement>> statements;
@@ -251,43 +507,89 @@ shared_ptr<Statement> Parser::matchStatementBlock(vector<TokenKind> terminalToke
shared_ptr<Statement> Parser::matchStatementAssignment() { shared_ptr<Statement> Parser::matchStatementAssignment() {
int startIndex = currentIndex; int startIndex = currentIndex;
ParseeResultsGroup resultsGroup;
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, false)) string identifier;
return nullptr;
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
shared_ptr<Expression> indexExpression; shared_ptr<Expression> indexExpression;
shared_ptr<Expression> expression;
if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) { // identifier
indexExpression = nextExpression(); resultsGroup = parseeResultsGroupForParseeGroup(
if (indexExpression == nullptr) ParseeGroup(
{
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true),
},
{}
)
);
if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS)
return nullptr; return nullptr;
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) { identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
markError(TokenKind::RIGHT_SQUARE_BRACKET, {});
// index expression
resultsGroup = parseeResultsGroupForParseeGroup(
ParseeGroup(
{
Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false),
Parsee::expressionParsee(true),
Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false),
},
{}
)
);
switch (resultsGroup.getKind()) {
case ParseeResultsGroupKind::SUCCESS:
indexExpression = resultsGroup.getResults().at(0).getExpression();
break;
case ParseeResultsGroupKind::NO_MATCH:
break;
case ParseeResultsGroupKind::FAILURE:
return nullptr; return nullptr;
} }
}
// assignment requires left arrow, otherwise abort // expression
if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true)) { resultsGroup = parseeResultsGroupForParseeGroup(
ParseeGroup(
{
Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false),
Parsee::expressionParsee(true)
},
{}
)
);
switch (resultsGroup.getKind()) {
case ParseeResultsGroupKind::SUCCESS:
expression = resultsGroup.getResults().at(0).getExpression();
break;
case ParseeResultsGroupKind::NO_MATCH:
currentIndex = startIndex; currentIndex = startIndex;
return nullptr; return nullptr;
case ParseeResultsGroupKind::FAILURE:
return nullptr;
} }
shared_ptr<Expression> expression = nextExpression(); return make_shared<StatementAssignment>(identifier, indexExpression, expression);
if (expression == nullptr)
return nullptr;
return make_shared<StatementAssignment>(identifierToken->getLexme(), indexExpression, expression);
} }
shared_ptr<Statement> Parser::matchStatementReturn() { shared_ptr<Statement> Parser::matchStatementReturn() {
if (!tryMatchingTokenKinds({TokenKind::RETURN}, true, true)) ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup(
ParseeGroup(
{
Parsee::tokenParsee(TokenKind::RETURN, true, false),
Parsee::expressionParsee(false)
},
{}
)
);
if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS)
return nullptr; return nullptr;
shared_ptr<Expression> expression = nextExpression(); shared_ptr<Expression> expression = !resultsGroup.getResults().empty() ? resultsGroup.getResults().at(0).getExpression() : nullptr;
if (expression == nullptr)
return nullptr;
return make_shared<StatementReturn>(expression); return make_shared<StatementReturn>(expression);
} }
@@ -385,7 +687,6 @@ shared_ptr<Expression> Parser::nextExpression() {
if (expression != nullptr || errors.size() > errorsCount) if (expression != nullptr || errors.size() > errorsCount)
return expression; return expression;
markError({}, {});
return nullptr; return nullptr;
} }
@@ -423,7 +724,7 @@ shared_ptr<Expression> Parser::matchTerm() {
} }
shared_ptr<Expression> Parser::matchFactor() { shared_ptr<Expression> Parser::matchFactor() {
shared_ptr<Expression> expression = matchPrimary(); shared_ptr<Expression> expression = matchUnary();
if (expression == nullptr) if (expression == nullptr)
return nullptr; return nullptr;
@@ -433,6 +734,19 @@ shared_ptr<Expression> Parser::matchFactor() {
return expression; return expression;
} }
shared_ptr<Expression> Parser::matchUnary() {
shared_ptr<Token> token = tokens.at(currentIndex);
if (tryMatchingTokenKinds(Token::tokensUnary, false, true)) {
shared_ptr<Expression> expression = matchPrimary();
if (expression == nullptr)
return nullptr;
return make_shared<ExpressionUnary>(token, expression);
}
return matchPrimary();
}
shared_ptr<Expression> Parser::matchPrimary() { shared_ptr<Expression> Parser::matchPrimary() {
shared_ptr<Expression> expression; shared_ptr<Expression> expression;
int errorsCount = errors.size(); int errorsCount = errors.size();
@@ -621,6 +935,7 @@ shared_ptr<Expression> Parser::matchExpressionBinary(shared_ptr<Expression> left
} }
if (right == nullptr) { if (right == nullptr) {
markError({}, "Expected expression");
return nullptr; return nullptr;
} else { } else {
return make_shared<ExpressionBinary>(token, left, right); return make_shared<ExpressionBinary>(token, left, right);
@@ -651,44 +966,130 @@ shared_ptr<Expression> Parser::matchExpressionBlock(vector<TokenKind> terminalTo
return make_shared<ExpressionBlock>(statements); return make_shared<ExpressionBlock>(statements);
} }
shared_ptr<ValueType> Parser::matchValueType() { ParseeResultsGroup Parser::parseeResultsGroupForParseeGroup(ParseeGroup group) {
if (!tryMatchingTokenKinds({TokenKind::TYPE}, true, false)) int errorsCount = errors.size();
return nullptr; int startIndex = currentIndex;
shared_ptr<Token> typeToken = tokens.at(currentIndex++); vector<ParseeResult> results;
bool mustFulfill = false;
for (Parsee &parsee : group.getParsees()) {
optional<ParseeResult> result;
switch (parsee.getKind()) {
case ParseeKind::TOKEN:
result = tokenParseeResult(currentIndex, parsee.getTokenKind());
break;
case ParseeKind::VALUE_TYPE:
result = valueTypeParseeResult(currentIndex);
break;
case ParseeKind::EXPRESSION:
result = expressionParseeResult(currentIndex);
break;
}
// generated an error?
if (errors.size() > errorsCount)
return ParseeResultsGroup::failure();
// if doesn't match on optional group
if (!result && parsee.getIsRequired() && !mustFulfill) {
currentIndex = startIndex;
//return vector<ParseeResult>();
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;
// invalid sequence detected?
if (!result && parsee.getIsRequired() && mustFulfill) {
markError(parsee.getTokenKind(), {});
//return {};
return ParseeResultsGroup::failure();
}
// got to the next token if we got a match
if (result)
currentIndex += (*result).getTokensCount();
}
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);
}
optional<ParseeResult> Parser::tokenParseeResult(int index, TokenKind tokenKind) {
shared_ptr<Token> token = tokens.at(index);
if (token->isOfKind({tokenKind}))
return ParseeResult::tokenResult(token);
return {};
}
optional<ParseeResult> Parser::valueTypeParseeResult(int index) {
int startIndex = index;
if (!tokens.at(index)->isOfKind({TokenKind::TYPE}))
return {};
shared_ptr<Token> typeToken = tokens.at(index++);
shared_ptr<ValueType> subType; shared_ptr<ValueType> subType;
int valueArg = 0; int typeArg = 0;
if (tryMatchingTokenKinds({TokenKind::LESS}, true, true)) { if (tokens.at(index)->isOfKind({TokenKind::LESS})) {
if (!tryMatchingTokenKinds({TokenKind::TYPE}, true, false)) { index++;
markError(TokenKind::TYPE, {}); optional<ParseeResult> subResult = valueTypeParseeResult(index);
return nullptr; if (!subResult)
} return {};
subType = matchValueType(); subType = (*subResult).getValueType();
if (subType == nullptr) index += (*subResult).getTokensCount();
return subType;
if (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) { if (tokens.at(index)->isOfKind({TokenKind::COMMA})) {
if (!tryMatchingTokenKinds({TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, TokenKind::INTEGER_BIN, TokenKind::INTEGER_CHAR}, false, false)) { index++;
markError({}, "Expected integer literal");
return nullptr; if (!tokens.at(index)->isOfKind({TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, TokenKind::INTEGER_BIN, TokenKind::INTEGER_CHAR}))
} return {};
int storedIndex = currentIndex;
currentIndex = index;
shared_ptr<Expression> expressionValue = matchExpressionLiteral(); shared_ptr<Expression> expressionValue = matchExpressionLiteral();
if (expressionValue == nullptr) { typeArg = dynamic_pointer_cast<ExpressionLiteral>(expressionValue)->getU32Value();
markError({}, "Expected integer literal"); currentIndex = storedIndex;
return nullptr; index++;
} }
valueArg = dynamic_pointer_cast<ExpressionLiteral>(expressionValue)->getSint32Value(); if (!tokens.at(index)->isOfKind({TokenKind::GREATER}))
return {};
index++;
} }
shared_ptr<ValueType> valueType = ValueType::valueTypeForToken(typeToken, subType, typeArg);
if (!tryMatchingTokenKinds({TokenKind::GREATER}, true, true)) { return ParseeResult::valueTypeResult(valueType, index - startIndex);
markError(TokenKind::GREATER, {});
return nullptr;
}
} }
return ValueType::valueTypeForToken(typeToken, subType, valueArg); optional<ParseeResult> Parser::expressionParseeResult(int index) {
int startIndex = currentIndex;
int errorsCount = errors.size();
shared_ptr<Expression> expression = nextExpression();
if (errors.size() > errorsCount)
return {};
int tokensCount = currentIndex - startIndex;
currentIndex = startIndex;
return ParseeResult::expressionResult(expression, tokensCount);
} }
bool Parser::tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance) { bool Parser::tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance) {

View File

@@ -12,6 +12,10 @@ class ValueType;
class Expression; class Expression;
class Statement; class Statement;
class ParseeGroup;
class ParseeResult;
class ParseeResultsGroup;
using namespace std; using namespace std;
class Parser { class Parser {
@@ -26,6 +30,7 @@ private:
shared_ptr<Statement> matchStatementMetaExternFunction(); shared_ptr<Statement> matchStatementMetaExternFunction();
shared_ptr<Statement> matchStatementVariable(); shared_ptr<Statement> matchStatementVariable();
shared_ptr<Statement> matchStatementFunction(); shared_ptr<Statement> matchStatementFunction();
shared_ptr<Statement> matchStatementRawFunction();
shared_ptr<Statement> matchStatementBlock(vector<TokenKind> terminalTokenKinds); shared_ptr<Statement> matchStatementBlock(vector<TokenKind> terminalTokenKinds);
shared_ptr<Statement> matchStatementAssignment(); shared_ptr<Statement> matchStatementAssignment();
@@ -38,7 +43,8 @@ private:
shared_ptr<Expression> matchComparison(); // <, <=, >, >= shared_ptr<Expression> matchComparison(); // <, <=, >, >=
shared_ptr<Expression> matchTerm(); // +, - shared_ptr<Expression> matchTerm(); // +, -
shared_ptr<Expression> matchFactor(); // *, /, % shared_ptr<Expression> matchFactor(); // *, /, %
shared_ptr<Expression> matchPrimary(); // integer, () shared_ptr<Expression> matchUnary(); // +, -
shared_ptr<Expression> matchPrimary(); // literal, ()
shared_ptr<Expression> matchExpressionGrouping(); shared_ptr<Expression> matchExpressionGrouping();
shared_ptr<Expression> matchExpressionLiteral(); shared_ptr<Expression> matchExpressionLiteral();
@@ -49,8 +55,10 @@ private:
shared_ptr<Expression> matchExpressionBinary(shared_ptr<Expression> left); shared_ptr<Expression> matchExpressionBinary(shared_ptr<Expression> left);
shared_ptr<Expression> matchExpressionBlock(vector<TokenKind> terminalTokenKinds); shared_ptr<Expression> matchExpressionBlock(vector<TokenKind> terminalTokenKinds);
shared_ptr<ValueType> matchValueType(); ParseeResultsGroup parseeResultsGroupForParseeGroup(ParseeGroup group);
optional<ParseeResult> tokenParseeResult(int index, TokenKind tokenKind);
optional<ParseeResult> valueTypeParseeResult(int index);
optional<ParseeResult> expressionParseeResult(int index);
bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance); bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance);
void markError(optional<TokenKind> expectedTokenKind, optional<string> message); void markError(optional<TokenKind> expectedTokenKind, optional<string> message);

View File

@@ -10,6 +10,7 @@ enum class StatementKind {
BLOCK, BLOCK,
RETURN, RETURN,
FUNCTION, FUNCTION,
RAW_FUNCTION,
VARIABLE, VARIABLE,
ASSIGNMENT, ASSIGNMENT,
REPEAT, REPEAT,

View File

@@ -0,0 +1,24 @@
#include "StatementRawFunction.h"
StatementRawFunction::StatementRawFunction(string name, string constraints, vector<pair<string, shared_ptr<ValueType>>> arguments, shared_ptr<ValueType> returnValueType, string rawSource):
Statement(StatementKind::RAW_FUNCTION), name(name), constraints(constraints), arguments(arguments), returnValueType(returnValueType), rawSource(rawSource) { }
string StatementRawFunction::getName() {
return name;
}
string StatementRawFunction::getConstraints() {
return constraints;
}
vector<pair<string, shared_ptr<ValueType>>> StatementRawFunction::getArguments() {
return arguments;
}
shared_ptr<ValueType> StatementRawFunction::getReturnValueType() {
return returnValueType;
}
string StatementRawFunction::getRawSource() {
return rawSource;
}

View File

@@ -0,0 +1,20 @@
#include "Parser/Statement/Statement.h"
class ValueType;
class StatementRawFunction: public Statement {
private:
string name;
string constraints;
vector<pair<string, shared_ptr<ValueType>>> arguments;
shared_ptr<ValueType> returnValueType;
string rawSource;
public:
StatementRawFunction(string name, string constraints, vector<pair<string, shared_ptr<ValueType>>> arguments, shared_ptr<ValueType> returnValueType, string rawSource);
string getName();
string getConstraints();
vector<pair<string, shared_ptr<ValueType>>> getArguments();
shared_ptr<ValueType> getReturnValueType();
string getRawSource();
};

View File

@@ -4,8 +4,11 @@
shared_ptr<ValueType> ValueType::NONE = make_shared<ValueType>(ValueTypeKind::NONE, nullptr, 0); shared_ptr<ValueType> ValueType::NONE = make_shared<ValueType>(ValueTypeKind::NONE, nullptr, 0);
shared_ptr<ValueType> ValueType::BOOL = make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0); shared_ptr<ValueType> ValueType::BOOL = make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0);
shared_ptr<ValueType> ValueType::SINT32 = make_shared<ValueType>(ValueTypeKind::SINT32, nullptr, 0); shared_ptr<ValueType> ValueType::U8 = make_shared<ValueType>(ValueTypeKind::U8, nullptr, 0);
shared_ptr<ValueType> ValueType::REAL32 = make_shared<ValueType>(ValueTypeKind::REAL32, nullptr, 0); shared_ptr<ValueType> ValueType::U32 = make_shared<ValueType>(ValueTypeKind::U32, nullptr, 0);
shared_ptr<ValueType> ValueType::S8 = make_shared<ValueType>(ValueTypeKind::S8, nullptr, 0);
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(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg): ValueType::ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg):
kind(kind), subType(subType), valueArg(valueArg) { } kind(kind), subType(subType), valueArg(valueArg) { }
@@ -16,10 +19,16 @@ shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token, shar
string lexme = token->getLexme(); string lexme = token->getLexme();
if (lexme.compare("bool") == 0) if (lexme.compare("bool") == 0)
return make_shared<ValueType>(ValueTypeKind::BOOL, subType, valueArg); return make_shared<ValueType>(ValueTypeKind::BOOL, subType, valueArg);
else if (lexme.compare("sint32") == 0) else if (lexme.compare("u8") == 0)
return make_shared<ValueType>(ValueTypeKind::SINT32, subType, valueArg); return make_shared<ValueType>(ValueTypeKind::U8, subType, valueArg);
else if (lexme.compare("real32") == 0) else if (lexme.compare("u32") == 0)
return make_shared<ValueType>(ValueTypeKind::REAL32, subType, valueArg); return make_shared<ValueType>(ValueTypeKind::U32, subType, valueArg);
else if (lexme.compare("s8") == 0)
return make_shared<ValueType>(ValueTypeKind::S8, subType, valueArg);
else if (lexme.compare("s32") == 0)
return make_shared<ValueType>(ValueTypeKind::S32, subType, valueArg);
else if (lexme.compare("r32") == 0)
return make_shared<ValueType>(ValueTypeKind::R32, subType, valueArg);
else if (lexme.compare("data") == 0) else if (lexme.compare("data") == 0)
return make_shared<ValueType>(ValueTypeKind::DATA, subType, valueArg); return make_shared<ValueType>(ValueTypeKind::DATA, subType, valueArg);
else else
@@ -28,12 +37,13 @@ shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token, shar
case TokenKind::BOOL: case TokenKind::BOOL:
return make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0); return make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0);
case TokenKind::INTEGER_DEC: case TokenKind::INTEGER_DEC:
return make_shared<ValueType>(ValueTypeKind::S32, nullptr, 0);
case TokenKind::INTEGER_HEX: case TokenKind::INTEGER_HEX:
case TokenKind::INTEGER_BIN: case TokenKind::INTEGER_BIN:
case TokenKind::INTEGER_CHAR: case TokenKind::INTEGER_CHAR:
return make_shared<ValueType>(ValueTypeKind::SINT32, nullptr, 0); return make_shared<ValueType>(ValueTypeKind::U32, nullptr, 0);
case TokenKind::REAL: case TokenKind::REAL:
return make_shared<ValueType>(ValueTypeKind::REAL32, nullptr, 0); return make_shared<ValueType>(ValueTypeKind::R32, nullptr, 0);
default: default:
return nullptr; return nullptr;
} }

View File

@@ -10,8 +10,11 @@ using namespace std;
enum class ValueTypeKind { enum class ValueTypeKind {
NONE, NONE,
BOOL, BOOL,
SINT32, U8,
REAL32, U32,
S8,
S32,
R32,
DATA DATA
}; };
@@ -24,8 +27,11 @@ private:
public: public:
static shared_ptr<ValueType> NONE; static shared_ptr<ValueType> NONE;
static shared_ptr<ValueType> BOOL; static shared_ptr<ValueType> BOOL;
static shared_ptr<ValueType> SINT32; static shared_ptr<ValueType> U8;
static shared_ptr<ValueType> REAL32; static shared_ptr<ValueType> U32;
static shared_ptr<ValueType> S8;
static shared_ptr<ValueType> S32;
static shared_ptr<ValueType> R32;
static shared_ptr<ValueType> valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg); static shared_ptr<ValueType> valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg);
ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg); ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg);