Skip to content

Commit

Permalink
Added custom selected imports (finally)
Browse files Browse the repository at this point in the history
  • Loading branch information
mauro-balades committed Jan 24, 2024
1 parent 35351ac commit f1e192f
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 36 deletions.
3 changes: 3 additions & 0 deletions src/ast/syntax/nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ struct Index : public AcceptorExtend<Index, Base> {
auto getBase() { return base; }
/// @return Get respective base value
auto getIdentifier() { return identifier; }
/// @brief Set a new identifier to the index
/// @note This shoudn't be used unless you know what you're doing
void unsafeSetidentifier(Identifier* id) { identifier = id; }

ACCEPT()
};
Expand Down
23 changes: 8 additions & 15 deletions src/ast/visitor/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,42 +50,35 @@ class ASTContext {
// Create a global scope for primitive types
addScope();
}

~ASTContext() noexcept = default;

/**
* @brief Insert an item into the current stack
*
* @param name Identifier for the item
* @param item Item to be stored
*/
virtual void addItem(const std::string& name, Item item) {
void addItem(const std::string& name, Item item) {
DEBUG_SYMTABLE(1, FMT(" Adding to scope: %s", name.c_str()).c_str())
auto f = stack.front();
auto val = f.find(name);

if (val != f.end()) {
E<VARIABLE_ERROR>(item, FMT("Value for '%s' is already defiend!", item->toString().c_str()));
}

if (val != f.end())
E<BUG>(item, FMT("Item '%s' is already defined!", name.c_str()));
stack.front().insert(std::make_pair(name, item));
}

/**
* @brief Get the Item from the stack
*
* @param name Item to search for
* @return {item or nullptr, if found}
*/
virtual std::pair<Item, bool> getItem(const std::string name) const {
std::pair<Item, bool> getItem(const std::string name) const {
for (auto s : stack) {
auto [val, found] = getInScope(name, s);
if (found) {
DEBUG_SYMTABLE(1, FMT("[symtable]: Successfully fetched %s", name.c_str()).c_str())
return {val, true};
}
}

DEBUG_SYMTABLE(1, FMT("[symtable]: Coudn't fetch '%s'", name.c_str()).c_str())
return {std::shared_ptr<T>(nullptr), false};
}
Expand All @@ -96,7 +89,7 @@ class ASTContext {
* @param s scope where search is performed
* @return {item or nullptr, if found}
*/
virtual std::pair<Item, bool> getInScope(const std::string name, Scope s) const {
std::pair<Item, bool> getInScope(const std::string name, Scope s) const {
auto val = s.find(name);
if (val != s.end()) { return {val->second, true}; }

Expand All @@ -108,13 +101,13 @@ class ASTContext {
* @param name Item to search for
* @return {item or nullptr, if found}
*/
virtual std::pair<Item, bool> getInCurrentScope(const std::string name) const {
std::pair<Item, bool> getInCurrentScope(const std::string name) const {
return getInScope(name, currentScope());
}
/// @return the current scope the programm is into
virtual Scope currentScope() const { return stack.front(); }
Scope currentScope() const { return stack.front(); }
/// @brief Create a new scope and append it.
virtual void addScope() {
void addScope() {
DEBUG_SYMTABLE(0, "Creating new scope")

Scope newScope{};
Expand Down
1 change: 0 additions & 1 deletion src/parser/parseImportStatement.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ Syntax::Statement::ImportStmt* Parser::parseImportStatement() {
}

consume<TokenType::BRACKET_RCURLY>("'}'");
createError<TODO>("variable imports");
break;
} else {
prev();
Expand Down
23 changes: 14 additions & 9 deletions src/visitors/TransformItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ namespace transform {
// from the stack. It can either represent a
// value, a function or a type.
class Item : public DBGObject {
// Using a type definition incase we need to
// change it.
using ValuePtr = std::shared_ptr<ir::Value>;
using FunctionPtr = std::shared_ptr<ir::Func>;
using TypePtr = types::Type*;

using MacroPtr = MacroInstance*;
using ASTAlias = Node*;

// This value is the actual value gotten from
// the stack.
Expand Down Expand Up @@ -75,6 +73,10 @@ class Item : public DBGObject {
// be either user-defined or it can be imported from
// another file.
MacroPtr macro = nullptr;
// AST Alias stored inside this item. The alias can
// be either user-defined or it can be imported from
// another file.
ASTAlias astAlias = nullptr;

public:
// The type used to represent what this
Expand All @@ -85,7 +87,8 @@ class Item : public DBGObject {
FUNC,
VALUE,
MODULE,
MACRO
MACRO,
AST_ALIAS,
} type;

// Constructors and destructors for the
Expand All @@ -97,13 +100,15 @@ class Item : public DBGObject {
Item(std::shared_ptr<ir::Module> m) : module(m), type(MODULE){};
Item(TypePtr val) : type(TYPE), tyVal(val){};
Item(MacroPtr m) : macro(m), type(MACRO){};
Item(ASTAlias a) : astAlias(a), type(AST_ALIAS){};

// Utility functions to identify the item
bool isType() { return type == TYPE; }
bool isFunc() { return type == FUNC; }
bool isVal() { return type == VALUE; }
bool isModule() { return type == MODULE; }
bool isMacro() { return type == MACRO; }
bool isAlias() { return type == AST_ALIAS; }

/// @return The module stored inside this item
auto getModule() const {
Expand Down Expand Up @@ -135,11 +140,11 @@ class Item : public DBGObject {
assert(type == FUNC);
functions.push_front(fn);
}

std::string toString() { /*TODO:*/
assert(false);
return "<TODO: transform item name>";
};
/// @return The AST alias stored inside this item
auto getASTAlias() const {
assert(type == AST_ALIAS);
return astAlias;
}
};

} // namespace transform
Expand Down
7 changes: 7 additions & 0 deletions src/visitors/Transformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,13 @@ class Transformer : public AcceptorExtend<Transformer, Visitor> {
* @note It will return a nullptr if the type is not a pointer.
*/
std::string getBuiltinTypeUUID(types::Type* ty, const std::string& name, types::Type* original = nullptr);
/**
* @brief It creates AST aliases for imported modules.
* @param mod The module to create the aliases from.
* @param import The import statement to create the aliases from.
* @param exportName The name to export the module as.
*/
void createModuleAliases(std::shared_ptr<ir::Module> mod, Statement::ImportStmt* import, const std::string& exportName);
/**
* @brief It generates a a new types::Type instance from a
* Statement::Base pointer.
Expand Down
26 changes: 26 additions & 0 deletions src/visitors/transform/utils/createModuleAliases.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

#include "../../Transformer.h"

using namespace snowball::utils;
using namespace snowball::Syntax;

namespace snowball {
namespace Syntax {

void Transformer::createModuleAliases(std::shared_ptr<ir::Module> mod, Statement::ImportStmt* import, const std::string& exportName) {
auto aliases = import->getVariables();
if (aliases.size() == 0) return;

auto baseIdentifier = N<Expression::Identifier>(exportName);
baseIdentifier->setDBGInfo(import->getDBGInfo());
for (auto [alias, identifier] : aliases) {
auto aliasIdentifier = N<Expression::Identifier>(alias);
auto moduleIndex = N<Expression::Index>(baseIdentifier, aliasIdentifier, true);
moduleIndex->setDBGInfo(import->getDBGInfo());
auto item = std::make_shared<transform::Item>(moduleIndex);
ctx->addItem(identifier, item);
}
}

} // namespace Syntax
} // namespace snowball
15 changes: 15 additions & 0 deletions src/visitors/transform/utils/transformIdentifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ Transformer::StoreType Transformer::getFromIdentifier(
.help = "If you want to use a macro as a value, you can use the '@' symbol before \nand "
"identifier to use a function-like macro."}
);
} else if (item->isAlias()) {
if (auto x = utils::cast<Expression::Index>(item->getASTAlias())) {
if (generics.size() > 0) {
auto clone = N<Expression::Index>(*x);
clone->unsafeSetidentifier(N<Expression::GenericIdentifier>(clone->getIdentifier()->getIdentifier(), generics));
x = clone;
}
auto [r, _] = getFromIndex(x->getDBGInfo(), x, x->isStatic);
auto [val, ty, funcs, overloads, mod, _canPrivate] = r;
return {val, ty, funcs, overloads, mod};
} else if (auto x = utils::cast<Expression::Identifier>(item->getASTAlias())) {
return getFromIdentifier(dbgInfo, x->getIdentifier(), generics, p_uuid);
} else {
assert(false && "BUG: Unhandled alias type!");
}
} else {
assert(false && "BUG: Unhandled value type!");
}
Expand Down
4 changes: 2 additions & 2 deletions src/visitors/transform/utils/transformTypeExtension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void Transformer::transformTypeExtension(Statement::DefinedTypeDef* node, std::s
E<SYNTAX_ERROR>(
node,
"Cant extend a type alias!",
{.info = FMT("'%s' is a type alias!", item->toString().c_str()),
{.info = FMT("'%s' is a type alias!", name.c_str()),
.note = "Only types can be extended!",
.help = "Remove the 'extends' keyword from this class."}
);
Expand Down Expand Up @@ -52,7 +52,7 @@ void Transformer::transformTypeExtension(Statement::DefinedTypeDef* node, std::s
E<SYNTAX_ERROR>(
node,
"Cant extend a non-type!",
{.info = FMT("'%s' is not a type!", item->toString().c_str()),
{.info = FMT("'%s' is not a type!", name.c_str()),
.note = "Only types can be extended!",
.help = "Remove the 'extends' keyword from this class."}
);
Expand Down
1 change: 1 addition & 0 deletions src/visitors/transform/visits/Statement/ImportStmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ SN_TRANSFORMER_VISIT(Statement::ImportStmt) {
ctx->addItem(exportName, item);
importedModule = mod;
}
createModuleAliases(importedModule, p_node, exportName);

if (p_node->hasAttribute(Attributes::MACROS)) {
auto args = p_node->getAttributeArgs(Attributes::MACROS);
Expand Down
8 changes: 2 additions & 6 deletions stdlib/env.sn
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import std::c_bindings;
import std::ptr;
import std::map;
import std::opt;
import std::map::{Map};
import std::opt::{Option};

@use_macro(assert)
import std::asserts;

// TODO: remove these once we have propepr import selectors
type Map<K, V> = map::Map<K, V>;
type Option<T> = opt::Option<T>;

/**
* @brief Returns the error message for the last error that occurred.
* @param code The error code to get the message for.
Expand Down
5 changes: 2 additions & 3 deletions tests/main.sn
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,13 @@ import pkg::time;

////import std::io::{{ println }};

import std::io;
import std::opt;
import std::tuples;
import std::env as os_env;

import std::rand as random;

//import std::io::{ println };
import std::io::{ println };

//import std::json as std_json;

Expand All @@ -55,5 +54,5 @@ public func main() i32 {
//vec.push(false);
//io::println(std_json::serialize(vec));
let a = (-10.0);
io::println(a as f64);
println(a as f64);
}

0 comments on commit f1e192f

Please sign in to comment.