Skip to content

Commit

Permalink
Importing specific words from modules.
Browse files Browse the repository at this point in the history
Also, fixed so that imports don't evaluate in the current scope, because
that didn't make any sense
  • Loading branch information
cassowarii committed Jul 25, 2018
1 parent be4999a commit b08aded
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 16 deletions.
6 changes: 6 additions & 0 deletions alma.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,11 @@ typedef enum {
typedef struct AFunc {
AFuncType type;
ASymbol *sym; // we might want to print it at runtime
// this is sort of weird because functions might
// be known as different things due to imports
// or w/e, but this means they'll always show up
// as the thing they were first named...
// maybe something to change later
union {
int varindex; // if var_push, which var to push?
APrimitiveFunc primitive;
Expand Down Expand Up @@ -369,6 +374,7 @@ typedef struct AScopeEntry {
/* Struct representing a (possibly nested) lexical scope. */
typedef struct AScope {
struct AScope *parent;
struct AScope *libscope;
AScopeEntry *content;
} AScope;

Expand Down
49 changes: 33 additions & 16 deletions import.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ char *extract_mod_prefix(const char *path, int strip_ext) {
* (prefixing qualified declaration as appropriate.) */
ACompileStatus handle_import (AScope *scope, ASymbolTable *symtab,
AFuncRegistry *reg, AImportStmt *decl) {
AScope *module_scope = scope_new(scope);
AScope *module_scope = scope_new(scope->libscope);

int has_suffix = decl->just_string
|| !strcmp(decl->module + strlen(decl->module) - 5, ".alma");
Expand All @@ -151,31 +151,48 @@ ACompileStatus handle_import (AScope *scope, ASymbolTable *symtab,
"(ALMA_PATH is: %s)\n", filename, ALMA_PATH);
} else {
result = put_file_into_scope(file_loc, symtab, module_scope, reg);
free(file_loc);
}
free(filename);

if (result == compile_fail) {
return result;
}

/* Now that we have successfully compiled the module to import,
* we need to put it into our scope with optional prefix. */
char *prefix = extract_mod_prefix(decl->module, has_suffix);

/* Move all the functions from module scope into our scope,
* prefixing them with the module name. */
AScopeEntry *current, *tmp;
HASH_ITER(hh, module_scope->content, current, tmp) {
if (!current->imported) {
ASymbol *prefixed_name = prefix_symbol(symtab, prefix, ".", current->sym);
ACompileStatus stat = scope_import(scope, prefixed_name, current->func);
if (stat == compile_success && decl->interactive) {
printf(" => %s\n", prefixed_name->name);
if (decl->names) {
/* Iterate over the sequence of names, and import each of them
* unqualified into our scope. */
ANameNode *curr = decl->names->first;
while (curr) {
AScopeEntry *entry = scope_lookup(module_scope, curr->sym);
if (entry == NULL) {
fprintf(stderr, "Error: couldn't import ‘%s’ from %s: no such word defined.\n",
curr->sym->name, file_loc);
} else {
ACompileStatus stat = scope_import(scope, curr->sym, entry->func);
if (stat == compile_success && decl->interactive) {
printf(" => %s\n", curr->sym->name);
}
}
curr = curr->next;
}
} else {
/* Move all the (non-imported) functions from module scope into our scope,
* prefixing them with the module name. */
char *prefix = extract_mod_prefix(decl->module, has_suffix);
AScopeEntry *current, *tmp;
HASH_ITER(hh, module_scope->content, current, tmp) {
if (!current->imported) {
ASymbol *prefixed_name = prefix_symbol(symtab, prefix, ".", current->sym);
ACompileStatus stat = scope_import(scope, prefixed_name, current->func);
if (stat == compile_success && decl->interactive) {
printf(" => %s\n", prefixed_name->name);
}
}
}

free(prefix);
}
free(file_loc);

free(prefix);
return result;
}
9 changes: 9 additions & 0 deletions scope.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ AScope *scope_new(AScope *parent) {
AScope *newscope = malloc(sizeof(AScope));
newscope->parent = parent;
newscope->content = NULL;
if (parent == NULL) {
/* If parent is null, we're creating the scope for
* the library. So the library scope is this one! */
newscope->libscope = newscope;
} else {
/* Otherwise point at the library scope so we can
* use it to create new scopes for imports and whatnot. */
newscope->libscope = parent->libscope;
}
return newscope;
}

Expand Down

0 comments on commit b08aded

Please sign in to comment.