Skip to content

Commit

Permalink
Expanded on the Filesystem module
Browse files Browse the repository at this point in the history
  • Loading branch information
mauro-balades committed Dec 20, 2023
1 parent 669fd43 commit 77b82a3
Show file tree
Hide file tree
Showing 29 changed files with 484 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/Debug/snowball",
"args": ["bench", "-O0"],
"args": ["test", "-O0"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
Expand Down
5 changes: 5 additions & 0 deletions runtime/libs/runtime.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

#include "runtime.h"
#include <errno.h>

void initialize_snowball(int flags) {
snowball::initialize_segfault_handler();
Expand All @@ -15,3 +16,7 @@ void error_log(std::ostringstream& oss, const char *message) {
oss << "\n\n\e[1;31merror\e[1;37m: " << message;
}
}

int snowball_errno() {
return errno;
}
1 change: 1 addition & 0 deletions runtime/libs/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ void error_log(std::ostringstream& oss, const char *message);
}

void initialize_snowball(int flags) __asm__("sn.runtime.initialize");
int snowball_errno() __asm__("sn.runtime.errno");

#endif // _SNOWBALL_RUNTIME_H_
6 changes: 6 additions & 0 deletions src/ast/syntax/nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,8 @@ struct VariableDecl : public AcceptorExtend<VariableDecl, Base>,
Expression::TypeRef* definedType = nullptr;
/// @brief If the variable is actually a constant expression.
bool isConstant = false;
/// @brief If the variable is external
bool isExtern = false;

public:
VariableDecl(
Expand All @@ -628,6 +630,10 @@ struct VariableDecl : public AcceptorExtend<VariableDecl, Base>,
bool isInitialized();
/// @brief If the variable is actually declared as a constant
bool isContantDecl();
/// @brief If the variable is declared as an extern variable
bool isExternDecl();
/// @brief Set the variable as an extern variable
void setExternDecl(bool e = true);

// Set an acceptance call
ACCEPT()
Expand Down
2 changes: 2 additions & 0 deletions src/ast/syntax/stmts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ bool VariableDecl::isContantDecl() { return isConstant; }
std::string VariableDecl::getName() const { return name; }
Expression::Base* VariableDecl::getValue() { return value; }
bool VariableDecl::isMutable() { return _mutable; }
bool VariableDecl::isExternDecl() { return isExtern; }
void VariableDecl::setExternDecl(bool e) { isExtern = e; }
Expression::TypeRef* VariableDecl::getDefinedType() { return definedType; }
void VariableDecl::setDefinedType(Expression::TypeRef* t) { definedType = t; }
Return::Return(Expression::Base* value) : value(value){};
Expand Down
16 changes: 15 additions & 1 deletion src/builder/llvm/addGlobalVariable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,23 @@ void LLVMBuilder::addGlobalVariable(std::shared_ptr<ir::VariableDeclaration> var
auto srcInfo = var->getDBGInfo();
auto file = dbg.getFile(var->getSourceInfo()->getPath());
auto debugVar = dbg.builder->createGlobalVariableExpression(
dbg.unit, var->getIdentifier(), var->getIdentifier(), file, srcInfo->line, getDIType(var->getType()), false
dbg.unit, var->getIdentifier(), var->getIdentifier(), file, srcInfo->line, getDIType(var->getType()), var->isExternDecl()
);

if (var->isExternDecl()) {
auto gvar = new llvm::GlobalVariable(
/*Module=*/*module,
/*Type=*/ty,
/*isConstant=*/!var->getVariable()->isMutable(),
/*Linkage=*/llvm::GlobalValue::ExternalLinkage,
/*Initializer=*/nullptr,
/*Name=*/var->getIdentifier()
);
ctx->addSymbol(var->getId(), gvar);
gvar->addDebugInfo(debugVar);
return;
}

if (utils::dyn_cast<ir::ConstantValue>(var->getValue())) {
auto c = build(var->getValue().get());
auto gvar = new llvm::GlobalVariable(
Expand Down
4 changes: 3 additions & 1 deletion src/builder/llvm/buildOperator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ bool LLVMBuilder::buildOperator(ir::Call* call) {
//OPERATOR_INSTANCE(BIT_AND_EQ, CreateAnd)
OPERATOR_INSTANCE(BIT_XOR, CreateXor)
//OPERATOR_INSTANCE(BIT_XOR_EQ, CreateXor)
OPERATOR_UINSTANCE(BIT_NOT, CreateNot)

SIGNED_DEPENDANT(LT, CreateICmpSLT, CreateICmpULT)
SIGNED_DEPENDANT(GT, CreateICmpSGT, CreateICmpUGT)
Expand Down Expand Up @@ -158,7 +159,7 @@ bool LLVMBuilder::buildOperator(ir::Call* call) {
break;
}

default: assert(false);
default: assert(false && "Unknown operator");
}

return true;
Expand All @@ -181,6 +182,7 @@ bool LLVMBuilder::buildOperator(ir::Call* call) {
OPERATOR_INSTANCE(BIT_AND, CreateAnd)
//OPERATOR_INSTANCE(BIT_AND_EQ, CreateAnd)
OPERATOR_INSTANCE(BIT_XOR, CreateXor)
OPERATOR_UINSTANCE(BIT_NOT, CreateNot)
//OPERATOR_INSTANCE(BIT_XOR_EQ, CreateXor)
OPERATOR_INSTANCE(LT, CreateFCmpOLT)
OPERATOR_INSTANCE(GT, CreateFCmpOGT)
Expand Down
4 changes: 2 additions & 2 deletions src/ir/builder/IRBuilder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ SharedValue<Call> IRBuilder::createCall(DBGSourceInfo* dbgInfo, SharedValue<> ca
return N<Call>(dbgInfo, callee, args);
}
SharedValue<VariableDeclaration> IRBuilder::createVariableDeclaration(
DBGSourceInfo* dbgInfo, std::shared_ptr<ir::Variable> variable, SharedValue<> value
DBGSourceInfo* dbgInfo, std::shared_ptr<ir::Variable> variable, SharedValue<> value, bool isExtern
) {
auto decl = N<VariableDeclaration>(dbgInfo, variable, value);
auto decl = N<VariableDeclaration>(dbgInfo, variable, value, isExtern);
if (value != nullptr) setType(decl, value->getType());
return decl;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ir/builder/IRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class IRBuilder : public AcceptorExtend<IRBuilder, ModuleHolder> {
);
/// @brief Create a new type
SharedValue<VariableDeclaration> createVariableDeclaration(
DBGSourceInfo* dbgInfo, std::shared_ptr<ir::Variable> variable, SharedValue<> value
DBGSourceInfo* dbgInfo, std::shared_ptr<ir::Variable> variable, SharedValue<> value, bool isExtern = false
);
/// @brief Create a extraction node from a value
SharedValue<ValueExtract> createValueExtract(DBGSourceInfo* dbgInfo, SharedValue<> value);
Expand Down
8 changes: 6 additions & 2 deletions src/ir/values/VariableDeclaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,25 @@ class VariableDeclaration : public IdMixin, public AcceptorExtend<Variable, Valu
std::shared_ptr<ir::Variable> variable;
// Value stored into the current variable
std::shared_ptr<Value> value;
// If the variable has been externally declared
bool external = false;

protected:
friend Argument;

public:
// Create a new variable declaration
VariableDeclaration(std::shared_ptr<ir::Variable> variable, std::shared_ptr<Value> value)
: variable(variable), value(value) {};
VariableDeclaration(std::shared_ptr<ir::Variable> variable, std::shared_ptr<Value> value, bool external = false)
: variable(variable), value(value), external(external) {}

/// @return Variable value
auto& getVariable() const { return variable; }
/// @return Variable identifier
std::string getIdentifier() const { return variable->getIdentifier(); }
/// @return respective value stored into the current variable
auto getValue() const { return value; }
/// @return if the variable has been externally declared
bool isExternDecl() const { return external; }

// Set a visit handler for the generators
SN_GENERATOR_VISITS
Expand Down
12 changes: 11 additions & 1 deletion src/lexer/lexer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -479,12 +479,14 @@ void Lexer::tokenize() {
INT,
FLOAT,
BIN,
HEX
HEX,
OCT
};
_ReadMode mode = INT;
if (GET_CHAR(0) == '0') {
if (GET_CHAR(1) == 'b' || GET_CHAR(1) == 'B') mode = BIN;
if (GET_CHAR(1) == 'x' || GET_CHAR(1) == 'X') mode = HEX;
if (GET_CHAR(1) == 'o' || GET_CHAR(1) == 'O') mode = OCT;
}
bool isRange = false;
EAT_CHAR(1);
Expand Down Expand Up @@ -518,6 +520,14 @@ void Lexer::tokenize() {
EAT_CHAR(1);
}
} break;
case OCT: {
num += GET_CHAR(0);
EAT_CHAR(1); // eat 'o';
while (GET_CHAR(0) >= '0' && GET_CHAR(0) <= '7') {
num += GET_CHAR(0);
EAT_CHAR(1);
}
} break;

default: lexer_error(Error::BUG, FMT("Unreachable number mode \"%i\"", mode), num.size());
}
Expand Down
11 changes: 9 additions & 2 deletions src/parser/parseConstant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ Syntax::Statement::VariableDecl* Parser::parseConstant() {

next();
bool isPublic = false;
bool isExternal = false;
if (is<TokenType::KWORD_PUBLIC, TokenType::KWORD_PRIVATE>(peek(-3, true))) {
isPublic = is<TokenType::KWORD_PUBLIC>(peek(-3, true));
} else if (is<TokenType::KWORD_EXTERN>(peek(-3, true))) {
isExternal = true;
isPublic = is<TokenType::KWORD_PUBLIC>(peek(-4, true));
}
auto token = assert_tok<TokenType::IDENTIFIER>("an identifier");
next(); // consume identifier
Expand All @@ -28,8 +32,10 @@ Syntax::Statement::VariableDecl* Parser::parseConstant() {
consume<TokenType::SYM_COLLON>("':' for a type declaration");
typeDef = parseType();
Syntax::Expression::Base* value = nullptr;
assert_tok<TokenType::OP_EQ>("'=' for a variable declaration");
value = parseExpr(false);
if (!isExternal) {
assert_tok<TokenType::OP_EQ>("'=' for a variable declaration");
value = parseExpr(false);
}
if (is<TokenType::SYM_SEMI_COLLON>(peek(0, true))) next();
auto v = Syntax::N<Syntax::Statement::VariableDecl>(name, value, false, true);
v->setDefinedType(typeDef);
Expand All @@ -38,6 +44,7 @@ Syntax::Statement::VariableDecl* Parser::parseConstant() {
auto info = new DBGSourceInfo(m_source_info, token.get_pos(), token.get_width());
v->setDBGInfo(info);
v->setComment(comment);
v->setExternDecl(isExternal);

for (auto [n, a] : attributes) { v->addAttribute(n, a); }

Expand Down
6 changes: 3 additions & 3 deletions src/parser/parseGlobal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ Parser::NodeVec Parser::parseGlobal(TokenType terminator) {

case TokenType::KWORD_EXTERN: {
auto pk = peek();
if (!is<TokenType::KWORD_FUNC>(pk) && !is<TokenType::KWORD_UNSAFE>(pk)) {
createError<SYNTAX_ERROR>("expected 'func' keyword after an "
"extern function declaration");
if (!is<TokenType::KWORD_FUNC>(pk) && !is<TokenType::KWORD_CONST>(pk) && !is<TokenType::KWORD_UNSAFE>(pk)) {
createError<SYNTAX_ERROR>("expected 'func' or 'const' keyword after an "
"external symbol declaration");
}

break;
Expand Down
19 changes: 10 additions & 9 deletions src/visitors/TypeChecker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,16 @@ VISIT(Call) {

VISIT(VariableDeclaration) {
auto val = p_node->getValue();
val->visit(this);

cantBeVoid(
p_node,
val->getType(),
FMT("Value used for variable '%s' has a value with 'void' "
"type!",
p_node->getIdentifier().c_str())
);
if (val) {
val->visit(this);
cantBeVoid(
p_node,
val->getType(),
FMT("Value used for variable '%s' has a value with 'void' "
"type!",
p_node->getIdentifier().c_str())
);
}
}

VISIT(Throw) {
Expand Down
4 changes: 2 additions & 2 deletions src/visitors/transform/utils/initializePerModuleMacros.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ void Transformer::initializePerModuleMacros() {
ctx->addItem("include_str", includeStringMacroItem);

auto envMacro = N<Macro>(
"env",
"env_var",
std::vector<std::tuple<std::string, Macro::ArguementType, Node*>>{
{"name", Macro::ArguementType::CONSTANT_STRING, nullptr}},
nullptr
);
auto envInstance = new transform::MacroInstance(envMacro, ctx->module);
auto envMacroItem = std::make_shared<transform::Item>(envInstance);
ctx->addItem("env", envMacroItem);
ctx->addItem("env_var", envMacroItem);
}

} // namespace Syntax
Expand Down
2 changes: 2 additions & 0 deletions src/visitors/transform/visits/Expression/ConstantValue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ SN_TRANSFORMER_VISIT(Expression::ConstantValue) {
n = std::stoll(str, nullptr, 16);
} else if (utils::startsWith(str, "0b") || utils::startsWith(str, "0B")) {
n = std::stoul(str.substr(2, (size_t) (str.size() - 2)), nullptr, 2);
} else if (utils::startsWith(str, "0o") || utils::startsWith(str, "0O")) {
n = std::stoul(str.substr(2, (size_t) (str.size() - 2)), nullptr, 8);
} else {
// TODO: big numbers!
n = std::stoll(str); // We asume the number is correct
Expand Down
20 changes: 18 additions & 2 deletions src/visitors/transform/visits/Statement/VariableDecl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ SN_TRANSFORMER_VISIT(Statement::VariableDecl) {
definedType->setMutable(isMutable);
}

if (p_node->isExternDecl()) {
if (std::find(ctx->exported.begin(), ctx->exported.end(), p_node->getName()) != ctx->exported.end()) {
E<VARIABLE_ERROR>(
p_node->getDBGInfo(),
"External symbol already exists!",
{.info = "This function name is already exported as unmangled.",
.note = "This symbols is exported on another location with the "
"'external' attribute.",
.help = "Try renaming the variable or removing the 'external' "
"attribute."}
);
} else {
ctx->exported.push_back(p_node->getName());
}
}

if (ctx->getInScope(variableName, ctx->currentScope()).second) {
E<VARIABLE_ERROR>(
p_node,
Expand All @@ -34,7 +50,7 @@ SN_TRANSFORMER_VISIT(Statement::VariableDecl) {
// TODO: it should always be declared
if (p_node->isInitialized()) {
auto val = trans(variableValue);
auto varDecl = getBuilder().createVariableDeclaration(p_node->getDBGInfo(), var, val);
auto varDecl = getBuilder().createVariableDeclaration(p_node->getDBGInfo(), var, val, p_node->isExternDecl());
varDecl->setId(var->getId());
getBuilder().setType(varDecl, val->getType());
if (auto f = ctx->getCurrentFunction().get()) {
Expand Down Expand Up @@ -65,7 +81,7 @@ SN_TRANSFORMER_VISIT(Statement::VariableDecl) {

this->value = varDecl;
} else {
auto varDecl = getBuilder().createVariableDeclaration(p_node->getDBGInfo(), var, nullptr);
auto varDecl = getBuilder().createVariableDeclaration(p_node->getDBGInfo(), var, nullptr, p_node->isExternDecl());
varDecl->setId(var->getId());
getBuilder().setType(varDecl, definedType);
if (auto f = ctx->getCurrentFunction().get()) {
Expand Down
Loading

0 comments on commit 77b82a3

Please sign in to comment.