Skip to content

Commit df9f37d

Browse files
gh-190: Make module ops use STR.
Closes #190.
1 parent 77a6210 commit df9f37d

105 files changed

Lines changed: 177 additions & 172 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/SPECIFICATION.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@
851851

852852
Operators registered with the module-restriction flag (for example `PREFIX_EXTENSION_MODULE_RESTRICTED`) MUST be exposed only under the extending module's namespace. Importing that module MUST expose the extension namespace qualifier under the importing module's qualified name. `PREFIX_EXTENSION_ASMODULE` by itself MUST NOT restrict an operator to the extending module's namespace or cause that qualified exposure. Extension side effects outside operator registration (for example process-global hooks or host-side state) remain global.
853853
854-
- `BOOL IMPORT(MODULE name)` or `BOOL IMPORT(MODULE name, SYMBOL alias)` = MUST load the named module, execute it in its own top-level environment on first import, cache that environment, and expose its bindings under the module name or the supplied alias. The implementation MUST search the referring source directory first, then bundled library locations as described in [8.2](#82-extensions-and-extend), [10](#10-standard-library), and the language's module-search rules. Re-importing an already loaded module MUST reuse the cached module namespace rather than re-executing the module.
854+
- `BOOL IMPORT(STR module)` or `BOOL IMPORT(STR module, STR alias)` = MUST load the named module, execute it in its own top-level environment on first import, cache that environment, and expose its bindings under the module name or the supplied alias. The implementation MUST search the referring source directory first, then bundled library locations as described in [8.2](#82-extensions-and-extend), [10](#10-standard-library), and the language's module-search rules. Re-importing an already loaded module MUST reuse the cached module namespace rather than re-executing the module.
855855
856856
Prefix package namespaces MUST use `..` as the package separator. The canonical form is `package..subpackage..module`. When `IMPORT(pkg)` is used and a package directory named `pkg` exists, the interpreter MUST prefer package resolution and attempt to load `pkg/init.pre`. If that package directory exists but contains no `init.pre`, the import MUST raise a runtime error. When `IMPORT(pkg..mod)` is used, the interpreter MUST resolve to `pkg/mod.pre`. If both a package directory and a same-named module file exist in the same search location, the package MUST take precedence.
857857
@@ -861,9 +861,9 @@
861861
862862
Module import MUST NOT implicitly load companion extension pointer files. Runtime extensions for module code MUST be loaded explicitly via `EXTEND` inside the module. On success, `IMPORT` MUST return `FALSE`.
863863
864-
- `BOOL IMPORT_PATH(STR path)` or `BOOL IMPORT_PATH(STR path, SYMBOL alias)` = MUST load a module from an explicit filesystem path and expose it under `alias` or, if omitted, under a basename-derived module name. The argument MUST at minimum accept an absolute path to a `.pre` source file. The module's basename, excluding the `.pre` suffix, MUST be used as the default qualified module name when no alias is supplied. The loaded module MUST otherwise obey the same isolation, caching, and exposure rules as `IMPORT`. Runtime extensions for that module MUST be loaded explicitly via `EXTEND`. On success, `IMPORT_PATH` MUST return `FALSE`.
864+
- `BOOL IMPORT_PATH(STR path)` or `BOOL IMPORT_PATH(STR path, STR alias)` = MUST load a module from an explicit filesystem path and expose it under `alias` or, if omitted, under a basename-derived module name. The argument MUST at minimum accept an absolute path to a `.pre` source file. The module's basename, excluding the `.pre` suffix, MUST be used as the default qualified module name when no alias is supplied. The loaded module MUST otherwise obey the same isolation, caching, and exposure rules as `IMPORT`. Runtime extensions for that module MUST be loaded explicitly via `EXTEND`. On success, `IMPORT_PATH` MUST return `FALSE`.
865865
866-
- `BOOL EXPORT(SYMBOL symbol, MODULE module)` = MUST copy the caller's current binding for `symbol` into the namespace of the already imported module designated by `module`, making the exported binding available through that module's qualified namespace. `EXPORT` MUST return `FALSE` on success and MUST raise a runtime error if `module` is not currently imported.
866+
- `BOOL EXPORT(STR symbol, STR module)` = MUST copy the caller's current binding for `symbol` into the namespace of the already imported module designated by `module`, making the exported binding available through that module's qualified namespace. `EXPORT` MUST return `FALSE` on success and MUST raise a runtime error if `module` is not currently imported.
867867
868868
---
869869

lib/std/image/init.pre

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ EXTEND(EXTENSION: win32)
88

99
EXTEND(EXTENSION: image)
1010

11-
IMPORT(path)
11+
IMPORT("path")
1212

1313
FUNC TNS LOAD(STR img_path){
1414
STR ext = path.EXTNAME(img_path)

src/builtins.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6955,10 +6955,10 @@ static Value builtin_import_path(Interpreter *interp, Value *args, int argc, Exp
69556955
const char *alias = NULL;
69566956
char *alias_dup = NULL;
69576957
if (argc >= 2) {
6958-
if (arg_nodes[1]->type != EXPR_IDENT) {
6959-
RUNTIME_ERROR(interp, "IMPORT_PATH second argument must be an identifier (alias)", line, col);
6958+
if (args[1].type != VAL_STR) {
6959+
RUNTIME_ERROR(interp, "IMPORT_PATH second argument must be STR (alias)", line, col);
69606960
}
6961-
alias = arg_nodes[1]->as.ident;
6961+
alias = args[1].as.s ? args[1].as.s : "";
69626962
} else {
69636963
// Derive alias from basename of path (strip directories and extension)
69646964
const char *p = inpath + strlen(inpath);
@@ -8514,12 +8514,15 @@ static Value builtin_permafreeze(Interpreter *interp, Value *args, int argc, Exp
85148514
}
85158515

85168516
static Value builtin_export(Interpreter *interp, Value *args, int argc, Expr **arg_nodes, Env *env, int line, int col) {
8517-
(void)args;
8518-
if (argc != 2 || arg_nodes[0]->type != EXPR_IDENT || arg_nodes[1]->type != EXPR_IDENT) {
8519-
RUNTIME_ERROR(interp, "EXPORT expects two identifiers", line, col);
8517+
(void)arg_nodes;
8518+
if (argc != 2) {
8519+
RUNTIME_ERROR(interp, "EXPORT expects two STR arguments (symbol, module)", line, col);
85208520
}
8521-
const char *sym = arg_nodes[0]->as.ident;
8522-
const char *module = arg_nodes[1]->as.ident;
8521+
if (args[0].type != VAL_STR || args[1].type != VAL_STR) {
8522+
RUNTIME_ERROR(interp, "EXPORT expects STR symbol and STR module", line, col);
8523+
}
8524+
const char *sym = args[0].as.s ? args[0].as.s : "";
8525+
const char *module = args[1].as.s ? args[1].as.s : "";
85238526

85248527
// Find the symbol in caller environment
85258528
EnvEntry *entry = env_get_entry(env, sym);
@@ -9974,18 +9977,21 @@ static int module_export_bindings(Interpreter *interp, Env *caller_env, Env *mod
99749977

99759978
// Stubs for operations requiring TNS/MAP/THD
99769979
static Value builtin_import(Interpreter *interp, Value *args, int argc, Expr **arg_nodes, Env *env, int line, int col) {
9977-
(void)args;
9978-
(void)argc;
9979-
if (argc < 1 || arg_nodes[0]->type != EXPR_IDENT) {
9980-
RUNTIME_ERROR(interp, "IMPORT expects a module identifier", line, col);
9980+
(void)arg_nodes;
9981+
(void)env;
9982+
if (argc < 1) {
9983+
RUNTIME_ERROR(interp, "IMPORT expects a module name STR", line, col);
99819984
}
9982-
const char *modname = arg_nodes[0]->as.ident;
9985+
if (args[0].type != VAL_STR) {
9986+
RUNTIME_ERROR(interp, "IMPORT first argument must be STR", line, col);
9987+
}
9988+
const char *modname = args[0].as.s ? args[0].as.s : "";
99839989
const char *alias = NULL;
99849990
if (argc >= 2) {
9985-
if (arg_nodes[1]->type != EXPR_IDENT) {
9986-
RUNTIME_ERROR(interp, "IMPORT second argument must be an identifier (alias)", line, col);
9991+
if (args[1].type != VAL_STR) {
9992+
RUNTIME_ERROR(interp, "IMPORT second argument must be STR (alias)", line, col);
99879993
}
9988-
alias = arg_nodes[1]->as.ident;
9994+
alias = args[1].as.s ? args[1].as.s : "";
99899995
} else {
99909996
alias = modname;
99919997
}

src/interpreter.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,11 +1410,10 @@ Value eval_expr(Interpreter *interp, Expr *expr, Env *env) {
14101410
// EXTEND(EXTENSION: name) passes the symbolic extension specifier.
14111411
continue;
14121412
}
1413-
if (((strcmp(func_name, "DEL") == 0 || strcmp(func_name, "EXIST") == 0 ||
1414-
strcmp(func_name, "IMPORT") == 0 || strcmp(func_name, "ASSIGN") == 0) &&
1415-
i == 0) ||
1416-
((strcmp(func_name, "IMPORT") == 0 || strcmp(func_name, "IMPORT_PATH") == 0) && i == 1)) {
1417-
// leave as null placeholder
1413+
if ((strcmp(func_name, "DEL") == 0 || strcmp(func_name, "EXIST") == 0 ||
1414+
strcmp(func_name, "ASSIGN") == 0) &&
1415+
i == 0) {
1416+
// leave as null placeholder for identifier-like targets
14181417
continue;
14191418
}
14201419
args[i] = eval_expr(interp, arg_expr, env);

tests/cases/failing/deletefile-arity-two.pre

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
IMPORT(path)
1+
IMPORT("path")
22

33
STR p = path.TEMPFILE("temp.txt")
44
WRITEFILE("Prefix", p)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
IMPORT(path)
1+
IMPORT("path")
22

33
DELETEFILE(JOIN(path.script_dir, "/nonexistent.txt"))
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
IMPORT(path)
1+
IMPORT("path")
22

33
EXISTFILE(path.script_dir, "/plain.txt")
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
INT value = 0d1
2-
EXPORT(value, helper, extra)
2+
EXPORT(value, "helper", extra)
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
IMPORT(path)
1+
IMPORT("path")
22

33
STR tests_dir = path.BASEPATH(path.BASEPATH(path.script_dir))
44
STR helper_path = JOIN(tests_dir, "/helpers/export_target.pre")
55

6-
REFUTE(IMPORT_PATH(helper_path, helper))
6+
REFUTE(IMPORT_PATH(helper_path, "helper"))
77

88
INT value
9-
EXPORT(value, helper)
9+
EXPORT("value", "helper")
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
IMPORT(path)
1+
IMPORT("path")
22

33
STR tests_dir = path.BASEPATH(path.BASEPATH(path.script_dir))
44
STR helper_path = JOIN(tests_dir, "/helpers/export_target.pre")
55

6-
REFUTE(IMPORT_PATH(helper_path, helper))
6+
REFUTE(IMPORT_PATH(helper_path, "helper"))
77

88
INT value = 0d1
99
DEL(value)
10-
EXPORT(value, helper)
10+
EXPORT("value", "helper")

0 commit comments

Comments
 (0)