Fix import macro to not coerce everything to string.

This commit is contained in:
Calvin Rose 2020-08-27 07:46:00 -05:00
parent 5dda83dc73
commit a31e079f93
5 changed files with 27 additions and 10 deletions

View File

@ -2,6 +2,8 @@
All notable changes to this project will be documented in this file.
## Unreleased - ???
- Add `:n` flag to `file/open` to raise an error if file cannot be opened.
- Fix import macro to not try and coerce everything to a string.
- Allow passing a second argument to `disasm`.
- Add `cancel`. Resumes a fiber but makes it immediately error at the yield point.
- Allow multi-line paste into built in repl.

View File

@ -2475,7 +2475,8 @@
to be called. Dynamic bindings will NOT be imported. Use :fresh to bypass the
module cache."
[path & args]
(def argm (map |(if (keyword? $) $ (string $)) args))
(def ps (partition 2 args))
(def argm (mapcat (fn [[k v]] [k (if (= k :as) (string v) v)]) ps))
(tuple import* (string path) ;argm))
(defmacro use

View File

@ -56,8 +56,8 @@ static int32_t checkflags(const uint8_t *str) {
int32_t flags = 0;
int32_t i;
int32_t len = janet_string_length(str);
if (!len || len > 3)
janet_panic("file mode must have a length between 1 and 3");
if (!len || len > 10)
janet_panic("file mode must have a length between 1 and 10");
switch (*str) {
default:
janet_panicf("invalid flag %c, expected w, a, or r", *str);
@ -75,7 +75,7 @@ static int32_t checkflags(const uint8_t *str) {
for (i = 1; i < len; i++) {
switch (str[i]) {
default:
janet_panicf("invalid flag %c, expected + or b", str[i]);
janet_panicf("invalid flag %c, expected +, b, or n", str[i]);
break;
case '+':
if (flags & JANET_FILE_UPDATE) return -1;
@ -85,6 +85,10 @@ static int32_t checkflags(const uint8_t *str) {
if (flags & JANET_FILE_BINARY) return -1;
flags |= JANET_FILE_BINARY;
break;
case 'n':
if (flags & JANET_FILE_NONIL) return -1;
flags |= JANET_FILE_NONIL;
break;
}
}
return flags;
@ -112,11 +116,11 @@ static Janet cfun_io_popen(int32_t argc, Janet *argv) {
int32_t flags;
if (argc == 2) {
fmode = janet_getkeyword(argv, 1);
if (janet_string_length(fmode) != 1 ||
!(fmode[0] == 'r' || fmode[0] == 'w')) {
janet_panicf("invalid file mode :%S, expected :r or :w", fmode);
flags = JANET_FILE_PIPED | checkflags(fmode);
if (flags & (JANET_FILE_UPDATE | JANET_FILE_BINARY | JANET_FILE_APPEND)) {
janet_panicf("invalid popen file mode :%S, expected :r or :w", fmode);
}
flags = JANET_FILE_PIPED | (fmode[0] == 'r' ? JANET_FILE_READ : JANET_FILE_WRITE);
fmode = (const uint8_t *)((fmode[0] == 'r') ? "r" : "w");
} else {
fmode = (const uint8_t *)"r";
flags = JANET_FILE_PIPED | JANET_FILE_READ;
@ -126,6 +130,8 @@ static Janet cfun_io_popen(int32_t argc, Janet *argv) {
#endif
FILE *f = popen((const char *)fname, (const char *)fmode);
if (!f) {
if (flags & JANET_FILE_NONIL)
janet_panicf("failed to popen %s: %s", fname, strerror(errno));
return janet_wrap_nil();
}
return janet_makefile(f, flags);
@ -155,7 +161,9 @@ static Janet cfun_io_fopen(int32_t argc, Janet *argv) {
flags = JANET_FILE_READ;
}
FILE *f = fopen((const char *)fname, (const char *)fmode);
return f ? janet_makefile(f, flags) : janet_wrap_nil();
return f ? janet_makefile(f, flags)
: (flags & JANET_FILE_NONIL) ? (janet_panicf("failed to open file %s: %s", fname, strerror(errno)), janet_wrap_nil())
: janet_wrap_nil();
}
/* Read up to n bytes into buffer. */
@ -720,7 +728,8 @@ static const JanetReg io_cfuns[] = {
"\tw - allow writing to the file\n"
"\ta - append to the file\n"
"\tb - open the file in binary mode (rather than text mode)\n"
"\t+ - append to the file instead of overwriting it")
"\t+ - append to the file instead of overwriting it\n"
"\tn - error if the file cannot be opened instead of returning nil")
},
{
"file/close", cfun_io_fclose,

View File

@ -1540,6 +1540,7 @@ extern JANET_API const JanetAbstractType janet_file_type;
#define JANET_FILE_BINARY 64
#define JANET_FILE_SERIALIZABLE 128
#define JANET_FILE_PIPED 256
#define JANET_FILE_NONIL 512
JANET_API Janet janet_makefile(FILE *f, int32_t flags);
JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int32_t *flags);

View File

@ -57,4 +57,8 @@
(assert (= nil (curenv 1000000)) "curenv 3")
(assert (= root-env (curenv 1)) "curenv 4")
# Import macro test
(assert-no-error "import macro 1" (macex '(import a :as b :fresh maybe)))
(assert (deep= ~(,import* "a" :as "b" :fresh maybe) (macex '(import a :as b :fresh maybe))) "import macro 2")
(end-suite)