1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-01 04:19:55 +00:00

Merge branch 'master' into armtest

This commit is contained in:
Calvin Rose 2023-06-24 10:40:35 -05:00
commit c2d77d6720
14 changed files with 104 additions and 29 deletions

View File

@ -1,7 +1,8 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## ??? - Unreleased ## 1.29.1 - 2023-06-19
- Add support for passing booleans to PEGs for "always" and "never" matching.
- Allow dictionary types for `take` and `drop` - Allow dictionary types for `take` and `drop`
- Fix bug with closing channels while other fibers were waiting on them - `ev/take`, `ev/give`, and `ev/select` will now return the correct (documented) value when another fiber closes the channel. - Fix bug with closing channels while other fibers were waiting on them - `ev/take`, `ev/give`, and `ev/select` will now return the correct (documented) value when another fiber closes the channel.
- Add `ffi/calling-conventions` to show all available calling conventions for FFI. - Add `ffi/calling-conventions` to show all available calling conventions for FFI.

View File

@ -195,9 +195,9 @@ build/%.bin.o: src/%.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS) Makefile
######################## ########################
ifeq ($(UNAME), Darwin) ifeq ($(UNAME), Darwin)
SONAME=libjanet.1.28.dylib SONAME=libjanet.1.29.dylib
else else
SONAME=libjanet.so.1.28 SONAME=libjanet.so.1.29
endif endif
build/c/shell.c: src/mainclient/shell.c build/c/shell.c: src/mainclient/shell.c

View File

@ -20,7 +20,7 @@
project('janet', 'c', project('janet', 'c',
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'], default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
version : '1.28.0') version : '1.29.1')
# Global settings # Global settings
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet') janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')

View File

@ -668,14 +668,20 @@
(def len (length bindings)) (def len (length bindings))
(if (= 0 len) (error "expected at least 1 binding")) (if (= 0 len) (error "expected at least 1 binding"))
(if (odd? len) (error "expected an even number of bindings")) (if (odd? len) (error "expected an even number of bindings"))
(def res (gensym))
(defn aux [i] (defn aux [i]
(if (>= i len) (if (>= i len)
tru ~(do (set ,res ,tru) true)
(do (do
(def bl (in bindings i)) (def bl (in bindings i))
(def br (in bindings (+ 1 i))) (def br (in bindings (+ 1 i)))
(tuple 'if (tuple 'def bl br) (aux (+ 2 i)) fal)))) (if (symbol? bl)
(aux 0)) ~(if (def ,bl ,br) ,(aux (+ 2 i)))
~(if (def ,(def sym (gensym)) ,br)
(do (def ,bl ,sym) ,(aux (+ 2 i))))))))
~(do
(var ,res nil)
(if ,(aux 0) ,res ,fal)))
(defmacro when-let (defmacro when-let
"Same as `(if-let bindings (do ;body))`." "Same as `(if-let bindings (do ;body))`."

View File

@ -4,10 +4,10 @@
#define JANETCONF_H #define JANETCONF_H
#define JANET_VERSION_MAJOR 1 #define JANET_VERSION_MAJOR 1
#define JANET_VERSION_MINOR 28 #define JANET_VERSION_MINOR 29
#define JANET_VERSION_PATCH 0 #define JANET_VERSION_PATCH 1
#define JANET_VERSION_EXTRA "-dev" #define JANET_VERSION_EXTRA ""
#define JANET_VERSION "1.28.0-dev" #define JANET_VERSION "1.29.1"
/* #define JANET_BUILD "local" */ /* #define JANET_BUILD "local" */

View File

@ -273,6 +273,14 @@ int32_t janet_getinteger(const Janet *argv, int32_t n) {
return janet_unwrap_integer(x); return janet_unwrap_integer(x);
} }
uint32_t janet_getuinteger(const Janet *argv, int32_t n) {
Janet x = argv[n];
if (!janet_checkuint(x)) {
janet_panicf("bad slot #%d, expected 32 bit signed integer, got %v", n, x);
}
return janet_unwrap_integer(x);
}
int64_t janet_getinteger64(const Janet *argv, int32_t n) { int64_t janet_getinteger64(const Janet *argv, int32_t n) {
#ifdef JANET_INT_TYPES #ifdef JANET_INT_TYPES
return janet_unwrap_s64(argv[n]); return janet_unwrap_s64(argv[n]);
@ -290,7 +298,7 @@ uint64_t janet_getuinteger64(const Janet *argv, int32_t n) {
return janet_unwrap_u64(argv[n]); return janet_unwrap_u64(argv[n]);
#else #else
Janet x = argv[n]; Janet x = argv[n];
if (!janet_checkint64(x)) { if (!janet_checkuint64(x)) {
janet_panicf("bad slot #%d, expected 64 bit unsigned integer, got %v", n, x); janet_panicf("bad slot #%d, expected 64 bit unsigned integer, got %v", n, x);
} }
return (uint64_t) janet_unwrap_number(x); return (uint64_t) janet_unwrap_number(x);

View File

@ -746,12 +746,14 @@ static int macroexpand1(
int lock = janet_gclock(); int lock = janet_gclock();
Janet mf_kw = janet_ckeywordv("macro-form"); Janet mf_kw = janet_ckeywordv("macro-form");
janet_table_put(c->env, mf_kw, x); janet_table_put(c->env, mf_kw, x);
Janet ml_kw = janet_ckeywordv("macro-lints");
if (c->lints) {
janet_table_put(c->env, ml_kw, janet_wrap_array(c->lints));
}
Janet tempOut; Janet tempOut;
JanetSignal status = janet_continue(fiberp, janet_wrap_nil(), &tempOut); JanetSignal status = janet_continue(fiberp, janet_wrap_nil(), &tempOut);
janet_table_put(c->env, mf_kw, janet_wrap_nil()); janet_table_put(c->env, mf_kw, janet_wrap_nil());
if (c->lints) { janet_table_put(c->env, ml_kw, janet_wrap_nil());
janet_table_put(c->env, janet_ckeywordv("macro-lints"), janet_wrap_array(c->lints));
}
janet_gcunlock(lock); janet_gcunlock(lock);
if (status != JANET_SIGNAL_OK) { if (status != JANET_SIGNAL_OK) {
const uint8_t *es = janet_formatc("(macro) %V", tempOut); const uint8_t *es = janet_formatc("(macro) %V", tempOut);

View File

@ -1145,6 +1145,7 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
posix_spawn_file_actions_addclose(&actions, pipe_in); posix_spawn_file_actions_addclose(&actions, pipe_in);
} else if (new_in != JANET_HANDLE_NONE && new_in != 0) { } else if (new_in != JANET_HANDLE_NONE && new_in != 0) {
posix_spawn_file_actions_adddup2(&actions, new_in, 0); posix_spawn_file_actions_adddup2(&actions, new_in, 0);
if (new_in != new_out && new_in != new_err)
posix_spawn_file_actions_addclose(&actions, new_in); posix_spawn_file_actions_addclose(&actions, new_in);
} }
if (pipe_out != JANET_HANDLE_NONE) { if (pipe_out != JANET_HANDLE_NONE) {
@ -1152,6 +1153,7 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
posix_spawn_file_actions_addclose(&actions, pipe_out); posix_spawn_file_actions_addclose(&actions, pipe_out);
} else if (new_out != JANET_HANDLE_NONE && new_out != 1) { } else if (new_out != JANET_HANDLE_NONE && new_out != 1) {
posix_spawn_file_actions_adddup2(&actions, new_out, 1); posix_spawn_file_actions_adddup2(&actions, new_out, 1);
if (new_out != new_err)
posix_spawn_file_actions_addclose(&actions, new_out); posix_spawn_file_actions_addclose(&actions, new_out);
} }
if (pipe_err != JANET_HANDLE_NONE) { if (pipe_err != JANET_HANDLE_NONE) {
@ -1437,11 +1439,11 @@ JANET_CORE_FN(os_isatty,
FILE *f = (argc == 1) ? janet_getfile(argv, 0, NULL) : stdout; FILE *f = (argc == 1) ? janet_getfile(argv, 0, NULL) : stdout;
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
int fd = _fileno(f); int fd = _fileno(f);
if (fd == -1) janet_panicv(janet_ev_lasterr()); if (fd == -1) janet_panic("not a valid stream");
return janet_wrap_boolean(_isatty(fd)); return janet_wrap_boolean(_isatty(fd));
#else #else
int fd = fileno(f); int fd = fileno(f);
if (fd == -1) janet_panicv(janet_ev_lasterr()); if (fd == -1) janet_panic(strerror(errno));
return janet_wrap_boolean(isatty(fd)); return janet_wrap_boolean(isatty(fd));
#endif #endif
} }

View File

@ -1261,6 +1261,13 @@ static uint32_t peg_compile1(Builder *b, Janet peg) {
default: default:
peg_panic(b, "unexpected peg source"); peg_panic(b, "unexpected peg source");
return 0; return 0;
case JANET_BOOLEAN: {
int n = janet_unwrap_boolean(peg);
Reserve r = reserve(b, 2);
emit_1(r, n ? RULE_NCHAR : RULE_NOTNCHAR, 0);
break;
}
case JANET_NUMBER: { case JANET_NUMBER: {
int32_t n = peg_getinteger(b, peg); int32_t n = peg_getinteger(b, peg);
Reserve r = reserve(b, 2); Reserve r = reserve(b, 2);

View File

@ -805,6 +805,13 @@ int janet_checkint(Janet x) {
return janet_checkintrange(dval); return janet_checkintrange(dval);
} }
int janet_checkuint(Janet x) {
if (!janet_checktype(x, JANET_NUMBER))
return 0;
double dval = janet_unwrap_number(x);
return janet_checkuintrange(dval);
}
int janet_checkint64(Janet x) { int janet_checkint64(Janet x) {
if (!janet_checktype(x, JANET_NUMBER)) if (!janet_checktype(x, JANET_NUMBER))
return 0; return 0;
@ -816,7 +823,7 @@ int janet_checkuint64(Janet x) {
if (!janet_checktype(x, JANET_NUMBER)) if (!janet_checktype(x, JANET_NUMBER))
return 0; return 0;
double dval = janet_unwrap_number(x); double dval = janet_unwrap_number(x);
return dval >= 0 && dval <= JANET_INTMAX_DOUBLE && dval == (uint64_t) dval; return janet_checkuint64range(dval);
} }
int janet_checksize(Janet x) { int janet_checksize(Janet x) {

View File

@ -147,8 +147,8 @@
stack[A] = janet_mcall(#op, 2, _argv);\ stack[A] = janet_mcall(#op, 2, _argv);\
vm_checkgc_pcnext();\ vm_checkgc_pcnext();\
} else {\ } else {\
type1 x1 = (type1) janet_unwrap_integer(op1);\ type1 x1 = (type1) janet_unwrap_number(op1);\
stack[A] = janet_wrap_integer(x1 op CS);\ stack[A] = janet_wrap_number((type1) (x1 op CS));\
vm_pcnext();\ vm_pcnext();\
}\ }\
} }
@ -175,9 +175,9 @@
Janet op1 = stack[B];\ Janet op1 = stack[B];\
Janet op2 = stack[C];\ Janet op2 = stack[C];\
if (janet_checktype(op1, JANET_NUMBER) && janet_checktype(op2, JANET_NUMBER)) {\ if (janet_checktype(op1, JANET_NUMBER) && janet_checktype(op2, JANET_NUMBER)) {\
type1 x1 = (type1) janet_unwrap_integer(op1);\ type1 x1 = (type1) janet_unwrap_number(op1);\
int32_t x2 = janet_unwrap_integer(op2);\ int32_t x2 = janet_unwrap_integer(op2);\
stack[A] = janet_wrap_integer(x1 op x2);\ stack[A] = janet_wrap_number((type1) (x1 op x2));\
vm_pcnext();\ vm_pcnext();\
} else {\ } else {\
vm_commit();\ vm_commit();\
@ -980,7 +980,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
if (func->gc.flags & JANET_FUNCFLAG_TRACE) { if (func->gc.flags & JANET_FUNCFLAG_TRACE) {
vm_do_trace(func, fiber->stacktop - fiber->stackstart, fiber->data + fiber->stackstart); vm_do_trace(func, fiber->stacktop - fiber->stackstart, fiber->data + fiber->stackstart);
} }
janet_stack_frame(stack)->pc = pc; vm_commit();
if (janet_fiber_funcframe(fiber, func)) { if (janet_fiber_funcframe(fiber, func)) {
int32_t n = fiber->stacktop - fiber->stackstart; int32_t n = fiber->stacktop - fiber->stackstart;
janet_panicf("%v called with %d argument%s, expected %d", janet_panicf("%v called with %d argument%s, expected %d",

View File

@ -868,12 +868,15 @@ JANET_API Janet janet_nanbox32_from_tagp(uint32_t tag, void *pointer);
#endif #endif
JANET_API int janet_checkint(Janet x); JANET_API int janet_checkint(Janet x);
JANET_API int janet_checkuint(Janet x);
JANET_API int janet_checkint64(Janet x); JANET_API int janet_checkint64(Janet x);
JANET_API int janet_checkuint64(Janet x); JANET_API int janet_checkuint64(Janet x);
JANET_API int janet_checksize(Janet x); JANET_API int janet_checksize(Janet x);
JANET_API JanetAbstract janet_checkabstract(Janet x, const JanetAbstractType *at); JANET_API JanetAbstract janet_checkabstract(Janet x, const JanetAbstractType *at);
#define janet_checkintrange(x) ((x) >= INT32_MIN && (x) <= INT32_MAX && (x) == (int32_t)(x)) #define janet_checkintrange(x) ((x) >= INT32_MIN && (x) <= INT32_MAX && (x) == (int32_t)(x))
#define janet_checkuintrange(x) ((x) >= 0 && (x) <= UINT32_MAX && (x) == (uint32_t)(x))
#define janet_checkint64range(x) ((x) >= JANET_INTMIN_DOUBLE && (x) <= JANET_INTMAX_DOUBLE && (x) == (int64_t)(x)) #define janet_checkint64range(x) ((x) >= JANET_INTMIN_DOUBLE && (x) <= JANET_INTMAX_DOUBLE && (x) == (int64_t)(x))
#define janet_checkuint64range(x) ((x) >= 0 && (x) <= JANET_INTMAX_DOUBLE && (x) == (uint64_t)(x))
#define janet_unwrap_integer(x) ((int32_t) janet_unwrap_number(x)) #define janet_unwrap_integer(x) ((int32_t) janet_unwrap_number(x))
#define janet_wrap_integer(x) janet_wrap_number((int32_t)(x)) #define janet_wrap_integer(x) janet_wrap_number((int32_t)(x))

View File

@ -129,6 +129,13 @@
(assert (= (if-let [a my-array k (next a 5)] :t :f) :f) "if-let 4") (assert (= (if-let [a my-array k (next a 5)] :t :f) :f) "if-let 4")
(assert (= (if-let [[a b] my-array] a) 1) "if-let 5") (assert (= (if-let [[a b] my-array] a) 1) "if-let 5")
(assert (= (if-let [{:a a :b b} {:a 1 :b 2}] b) 2) "if-let 6") (assert (= (if-let [{:a a :b b} {:a 1 :b 2}] b) 2) "if-let 6")
(assert (= (if-let [[a b] nil] :t :f) :f) "if-let 7")
# #1191
(var cnt 0)
(defmacro upcnt [] (++ cnt))
(assert (= (if-let [a true b true c true] nil (upcnt)) nil) "issue #1191")
(assert (= cnt 1) "issue #1191")
(assert (= 14 (sum (map inc @[1 2 3 4]))) "sum map") (assert (= 14 (sum (map inc @[1 2 3 4]))) "sum map")
(def myfun (juxt + - * /)) (def myfun (juxt + - * /))
@ -879,5 +886,22 @@
(assert (= (thunk) 1) "delay 3") (assert (= (thunk) 1) "delay 3")
(assert (= counter 1) "delay 4") (assert (= counter 1) "delay 4")
(end-suite) # maclintf
(def env (table/clone (curenv)))
((compile '(defmacro foo [] (maclintf :strict "oops")) env :anonymous))
(def lints @[])
(compile (tuple/setmap '(foo) 1 2) env :anonymous lints)
(assert (deep= lints @[[:strict 1 2 "oops"]]) "maclintf 1")
(def env (table/clone (curenv)))
((compile '(defmacro foo [& body] (maclintf :strict "foo-oops") ~(do ,;body)) env :anonymous))
((compile '(defmacro bar [] (maclintf :strict "bar-oops")) env :anonymous))
(def lints @[])
# Compile (foo (bar)), but with explicit source map values
(def bar-invoke (tuple/setmap '(bar) 3 4))
(compile (tuple/setmap ~(foo ,bar-invoke) 1 2) env :anonymous lints)
(assert (deep= lints @[[:strict 1 2 "foo-oops"]
[:strict 3 4 "bar-oops"]])
"maclintf 2")
(end-suite)

View File

@ -94,9 +94,9 @@
(assert (= (length buf) 2) "cryptorand appends to buffer")) (assert (= (length buf) 2) "cryptorand appends to buffer"))
# 80db68210 # 80db68210
(assert-no-error (os/clock :realtime) "realtime clock") (assert-no-error "realtime clock" (os/clock :realtime))
(assert-no-error (os/clock :cputime) "cputime clock") (assert-no-error "cputime clock" (os/clock :cputime))
(assert-no-error (os/clock :monotonic) "monotonic clock") (assert-no-error "monotonic clock" (os/clock :monotonic))
(def before (os/clock :monotonic)) (def before (os/clock :monotonic))
(def after (os/clock :monotonic)) (def after (os/clock :monotonic))
@ -129,5 +129,20 @@
(string/format "(os/exit %d)" i)] :p)) (string/format "(os/exit %d)" i)] :p))
(string "os/execute " i))) (string "os/execute " i)))
# os/execute IO redirection
(assert-no-error "IO redirection"
(defn devnull []
(def os (os/which))
(def path (if (or (= os :mingw) (= os :windows))
"NUL"
"/dev/null"))
(os/open path :w))
(with [dn (devnull)]
(os/execute [(dyn :executable)
"-e"
"(print :foo) (eprint :bar)"]
:px
{:out dn :err dn})))
(end-suite) (end-suite)