mirror of
https://github.com/janet-lang/janet
synced 2026-04-03 13:31:28 +00:00
Compare commits
12 Commits
issue-1692
...
socket-ext
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a5ff208a8 | ||
|
|
d35f189446 | ||
|
|
216c9799f5 | ||
|
|
5966017232 | ||
|
|
f80690e4c9 | ||
|
|
9bc308532f | ||
|
|
7a8d8444fe | ||
|
|
15cea60589 | ||
|
|
10954fe0d7 | ||
|
|
70fb13eb48 | ||
|
|
cb355815ee | ||
|
|
ddc7cc5ae4 |
@@ -2,6 +2,9 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Unreleased - ???
|
||||
- Use color in script output if color is being used in REPL output.
|
||||
- Fix `varfn` macros handling of extra metadata.
|
||||
- Add linting for unused bindings.
|
||||
- Add `janet_optuinteger` and `janet_optuinteger64` to the C API.
|
||||
- Add `cms` combinator to PEGs.
|
||||
- Add `thaw-keep-keys` as a variant of thaw
|
||||
|
||||
4
Makefile
4
Makefile
@@ -220,9 +220,9 @@ build/%.bin.o: src/%.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS) Makefile
|
||||
########################
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
SONAME=libjanet.1.40.dylib
|
||||
SONAME=libjanet.1.41.dylib
|
||||
else
|
||||
SONAME=libjanet.so.1.40
|
||||
SONAME=libjanet.so.1.41
|
||||
endif
|
||||
|
||||
ifeq ($(MINGW_COMPILER), clang)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
(broadcast name (string msg)))
|
||||
(print name " disconnected")))))
|
||||
|
||||
(defn main [& args]
|
||||
(defn main [&]
|
||||
(printf "STARTING SERVER...")
|
||||
(flush)
|
||||
(def my-server (net/listen "127.0.0.1" "8000"))
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
"Go to the next breakpoint."
|
||||
[&opt n]
|
||||
(var res nil)
|
||||
(for i 0 (or n 1)
|
||||
(repeat (or n 1)
|
||||
(set res (resume (.fiber))))
|
||||
res)
|
||||
|
||||
@@ -146,6 +146,6 @@
|
||||
"Execute the next n instructions."
|
||||
[&opt n]
|
||||
(var res nil)
|
||||
(for i 0 (or n 1)
|
||||
(repeat (or n 1)
|
||||
(set res (debug/step (.fiber))))
|
||||
res)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
(def counts (seq [_ :range [0 100]] 0))
|
||||
|
||||
(for i 0 1000000
|
||||
(repeat 1000000
|
||||
(let [x (math/random)
|
||||
intrange (math/floor (* 100 x))
|
||||
oldcount (counts intrange)]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(ev/give chan (math/random))
|
||||
(ev/give chan (math/random))
|
||||
(ev/sleep 0.5)
|
||||
(for i 0 10
|
||||
(repeat 10
|
||||
(print "giving to channel...")
|
||||
(ev/give chan (math/random))
|
||||
(ev/sleep 1))
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
project('janet', 'c',
|
||||
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
|
||||
version : '1.40.1')
|
||||
version : '1.41.0')
|
||||
|
||||
# Global settings
|
||||
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
|
||||
@@ -288,6 +288,7 @@ test_files = [
|
||||
'test/suite-io.janet',
|
||||
'test/suite-marsh.janet',
|
||||
'test/suite-math.janet',
|
||||
'test/suite-net.janet',
|
||||
'test/suite-os.janet',
|
||||
'test/suite-parse.janet',
|
||||
'test/suite-peg.janet',
|
||||
|
||||
@@ -2113,11 +2113,15 @@
|
||||
(array/concat anda unify)
|
||||
# Final binding
|
||||
(def defs (seq [[k v] :in (sort (pairs b2g))] ['def k (first v)]))
|
||||
(def unused-defs (seq [[k v] :in (sort (pairs b2g))] ['def k :unused (first v)]))
|
||||
# Predicates
|
||||
(unless (empty? preds)
|
||||
(def pred-join ~(do ,;defs (and ,;preds)))
|
||||
(def pred-join ~(do ,;unused-defs (and ,;preds)))
|
||||
(array/push anda pred-join))
|
||||
(emit-branch (tuple/slice anda) ['do ;defs expression]))
|
||||
# Use `unused-defs` instead of `defs` when we have predicates to avoid unused binding lint
|
||||
# e.g. (match x (n (even? n)) :yes :no) should not warn on unused binding `n`.
|
||||
# This is unfortunately not perfect since one programmer written binding is expanded for use in multiple places.
|
||||
(emit-branch (tuple/slice anda) ['do ;(if (next preds) unused-defs defs) expression]))
|
||||
|
||||
# Expand branches
|
||||
(def stack @[else])
|
||||
@@ -2399,6 +2403,7 @@
|
||||
(cond
|
||||
(keyword? m) (put metadata m true)
|
||||
(string? m) (put metadata :doc m)
|
||||
(dictionary? m) (merge-into metadata m)
|
||||
(error (string "invalid metadata " m))))
|
||||
(with-syms [entry old-entry f]
|
||||
~(let [,old-entry (,dyn ',name)]
|
||||
@@ -3089,7 +3094,7 @@
|
||||
(os/exit 1))
|
||||
(put env :exit true)
|
||||
(def buf @"")
|
||||
(with-dyns [*err* buf *err-color* false]
|
||||
(with-dyns [*err* buf]
|
||||
(bad-parse x y))
|
||||
(set exit-error (string/slice buf 0 -2)))
|
||||
(defn bc [&opt x y z a b]
|
||||
@@ -3098,7 +3103,7 @@
|
||||
(os/exit 1))
|
||||
(put env :exit true)
|
||||
(def buf @"")
|
||||
(with-dyns [*err* buf *err-color* false]
|
||||
(with-dyns [*err* buf]
|
||||
(bad-compile x nil z a b))
|
||||
(set exit-error (string/slice buf 0 -2))
|
||||
(set exit-fiber y))
|
||||
@@ -4672,6 +4677,17 @@
|
||||
"-lint-warn" "w"
|
||||
"-lint-error" "x"})
|
||||
|
||||
(defn- apply-color
|
||||
[colorize]
|
||||
(setdyn *pretty-format* (if colorize "%.20Q" "%.20q"))
|
||||
(setdyn *err-color* (if colorize true))
|
||||
(setdyn *doc-color* (if colorize true)))
|
||||
|
||||
(defn- getstdin [prompt buf _]
|
||||
(file/write stdout prompt)
|
||||
(file/flush stdout)
|
||||
(file/read stdin :line buf))
|
||||
|
||||
(defn cli-main
|
||||
`Entrance for the Janet CLI tool. Call this function with the command line
|
||||
arguments as an array or tuple of strings to invoke the CLI interface.`
|
||||
@@ -4685,11 +4701,7 @@
|
||||
(var raw-stdin false)
|
||||
(var handleopts true)
|
||||
(var exit-on-error true)
|
||||
(var colorize true)
|
||||
(var debug-flag false)
|
||||
(var compile-only false)
|
||||
(var warn-level nil)
|
||||
(var error-level nil)
|
||||
(var expect-image false)
|
||||
|
||||
(when-let [jp (getenv-alias "JANET_PATH")]
|
||||
@@ -4699,9 +4711,10 @@
|
||||
(module/add-syspath (get paths i)))
|
||||
(setdyn *syspath* (first paths)))
|
||||
(if-let [jprofile (getenv-alias "JANET_PROFILE")] (setdyn *profilepath* jprofile))
|
||||
(set colorize (and
|
||||
(not (getenv-alias "NO_COLOR"))
|
||||
(os/isatty stdout)))
|
||||
(apply-color
|
||||
(and
|
||||
(not (getenv-alias "NO_COLOR"))
|
||||
(os/isatty stdout)))
|
||||
|
||||
(defn- get-lint-level
|
||||
[i]
|
||||
@@ -4751,8 +4764,8 @@
|
||||
"q" (fn [&] (set quiet true) 1)
|
||||
"i" (fn [&] (set expect-image true) 1)
|
||||
"k" (fn [&] (set compile-only true) (set exit-on-error false) 1)
|
||||
"n" (fn [&] (set colorize false) 1)
|
||||
"N" (fn [&] (set colorize true) 1)
|
||||
"n" (fn [&] (apply-color false) 1)
|
||||
"N" (fn [&] (apply-color true) 1)
|
||||
"m" (fn [i &] (setdyn *syspath* (in args (+ i 1))) 2)
|
||||
"c" (fn c-switch [i &]
|
||||
(def path (in args (+ i 1)))
|
||||
@@ -4808,9 +4821,9 @@
|
||||
(compif (dyn 'bundle/list)
|
||||
(fn [i &] (each l (bundle/list) (print l)) (set no-file false) (if (= nil should-repl) (set should-repl false)) 1)
|
||||
(fn [i &] (eprint "--list not supported with reduced os") 1))
|
||||
"d" (fn [&] (set debug-flag true) 1)
|
||||
"w" (fn [i &] (set warn-level (get-lint-level i)) 2)
|
||||
"x" (fn [i &] (set error-level (get-lint-level i)) 2)
|
||||
"d" (fn [&] (setdyn *debug* true) (setdyn *redef* true) 1)
|
||||
"w" (fn [i &] (setdyn *lint-warn* (get-lint-level i)) 2)
|
||||
"x" (fn [i &] (setdyn *lint-error* (get-lint-level i)) 2)
|
||||
"R" (fn [&] (setdyn *profilepath* nil) 1)})
|
||||
|
||||
(defn- dohandler [n i &]
|
||||
@@ -4831,20 +4844,10 @@
|
||||
(do
|
||||
(def env (load-image (slurp arg)))
|
||||
(put env *args* subargs)
|
||||
(put env *lint-error* error-level)
|
||||
(put env *lint-warn* warn-level)
|
||||
(when debug-flag
|
||||
(put env *debug* true)
|
||||
(put env *redef* true))
|
||||
(run-main env subargs arg))
|
||||
(do
|
||||
(def env (make-env))
|
||||
(put env *args* subargs)
|
||||
(put env *lint-error* error-level)
|
||||
(put env *lint-warn* warn-level)
|
||||
(when debug-flag
|
||||
(put env *debug* true)
|
||||
(put env *redef* true))
|
||||
(if compile-only
|
||||
(flycheck arg :exit exit-on-error :env env)
|
||||
(do
|
||||
@@ -4864,21 +4867,9 @@
|
||||
(when-let [custom-prompt (get env *repl-prompt*)] (break (custom-prompt p)))
|
||||
(def [line] (parser/where p))
|
||||
(string "repl:" line ":" (parser/state p :delimiters) "> "))
|
||||
(defn getstdin [prompt buf _]
|
||||
(file/write stdout prompt)
|
||||
(file/flush stdout)
|
||||
(file/read stdin :line buf))
|
||||
(when debug-flag
|
||||
(put env *debug* true)
|
||||
(put env *redef* true))
|
||||
(def getter (if raw-stdin getstdin getline))
|
||||
(defn getchunk [buf p]
|
||||
(getter (getprompt p) buf env))
|
||||
(setdyn *pretty-format* (if colorize "%.20Q" "%.20q"))
|
||||
(setdyn *err-color* (if colorize true))
|
||||
(setdyn *doc-color* (if colorize true))
|
||||
(setdyn *lint-error* error-level)
|
||||
(setdyn *lint-warn* error-level)
|
||||
(when-let [profile.janet (dyn *profilepath*)]
|
||||
(dofile profile.janet :exit true :env env)
|
||||
(put env *current-file* nil))
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
#define JANETCONF_H
|
||||
|
||||
#define JANET_VERSION_MAJOR 1
|
||||
#define JANET_VERSION_MINOR 40
|
||||
#define JANET_VERSION_PATCH 1
|
||||
#define JANET_VERSION_EXTRA ""
|
||||
#define JANET_VERSION "1.40.1"
|
||||
#define JANET_VERSION_MINOR 41
|
||||
#define JANET_VERSION_PATCH 0
|
||||
#define JANET_VERSION_EXTRA "-dev"
|
||||
#define JANET_VERSION "1.41.0-dev"
|
||||
|
||||
/* #define JANET_BUILD "local" */
|
||||
|
||||
|
||||
@@ -98,6 +98,22 @@ void janetc_nameslot(JanetCompiler *c, const uint8_t *sym, JanetSlot s) {
|
||||
sp.sym2 = sym;
|
||||
sp.slot = s;
|
||||
sp.keep = 0;
|
||||
sp.referenced = sym[0] == '_'; /* Fake ref if symbol is _ to avoid lints */
|
||||
sp.slot.flags |= JANET_SLOT_NAMED;
|
||||
sp.birth_pc = cnt ? cnt - 1 : 0;
|
||||
sp.death_pc = UINT32_MAX;
|
||||
janet_v_push(c->scope->syms, sp);
|
||||
}
|
||||
|
||||
/* Same as janetc_nameslot, but don't have a lint for unused bindings. */
|
||||
void janetc_nameslot_no_unused(JanetCompiler *c, const uint8_t *sym, JanetSlot s) {
|
||||
SymPair sp;
|
||||
int32_t cnt = janet_v_count(c->buffer);
|
||||
sp.sym = sym;
|
||||
sp.sym2 = sym;
|
||||
sp.slot = s;
|
||||
sp.keep = 0;
|
||||
sp.referenced = 1;
|
||||
sp.slot.flags |= JANET_SLOT_NAMED;
|
||||
sp.birth_pc = cnt ? cnt - 1 : 0;
|
||||
sp.death_pc = UINT32_MAX;
|
||||
@@ -170,6 +186,10 @@ void janetc_popscope(JanetCompiler *c) {
|
||||
/* Keep upvalue slots and symbols for debugging. */
|
||||
for (int32_t i = 0; i < janet_v_count(oldscope->syms); i++) {
|
||||
SymPair pair = oldscope->syms[i];
|
||||
/* Check for unused symbols */
|
||||
if (pair.referenced == 0 && pair.sym) {
|
||||
janetc_lintf(c, JANET_C_LINT_STRICT, "binding %q is unused", janet_wrap_symbol(pair.sym));
|
||||
}
|
||||
/* The variable should not be lexically accessible */
|
||||
pair.sym = NULL;
|
||||
if (pair.death_pc == UINT32_MAX) {
|
||||
@@ -262,6 +282,7 @@ JanetSlot janetc_resolve(
|
||||
pair = scope->syms + i;
|
||||
if (pair->sym == sym) {
|
||||
ret = pair->slot;
|
||||
pair->referenced = 1;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
@@ -346,6 +367,7 @@ found:
|
||||
/* non-local scope needs to expose its environment */
|
||||
JanetScope *original_scope = scope;
|
||||
pair->keep = 1;
|
||||
pair->referenced = 1;
|
||||
while (scope && !(scope->flags & JANET_SCOPE_FUNCTION))
|
||||
scope = scope->parent;
|
||||
janet_assert(scope, "invalid scopes");
|
||||
@@ -516,7 +538,7 @@ void janetc_throwaway(JanetFopts opts, Janet x) {
|
||||
int32_t mapbufstart = janet_v_count(c->mapbuffer);
|
||||
janetc_scope(&unusedScope, c, JANET_SCOPE_UNUSED, "unusued");
|
||||
janetc_value(opts, x);
|
||||
janetc_lintf(c, JANET_C_LINT_STRICT, "dead code, consider removing %.2q", x);
|
||||
janetc_lintf(c, JANET_C_LINT_STRICT, "dead code, consider removing %.4q", x);
|
||||
janetc_popscope(c);
|
||||
if (c->buffer) {
|
||||
janet_v__cnt(c->buffer) = bufstart;
|
||||
@@ -974,6 +996,10 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
|
||||
SymPair pair = scope->syms[i];
|
||||
if (pair.sym2) {
|
||||
JanetSymbolMap jsm;
|
||||
/* Check for unused symbols */
|
||||
if (pair.referenced == 0 && pair.sym) {
|
||||
janetc_lintf(c, JANET_C_LINT_STRICT, "binding %q is unused", janet_wrap_symbol(pair.sym));
|
||||
}
|
||||
if (pair.death_pc == UINT32_MAX) {
|
||||
jsm.death_pc = def->bytecode_length;
|
||||
} else {
|
||||
|
||||
@@ -114,6 +114,7 @@ typedef struct SymPair {
|
||||
const uint8_t *sym;
|
||||
const uint8_t *sym2;
|
||||
int keep;
|
||||
int referenced; /* Has this value been used */
|
||||
uint32_t birth_pc;
|
||||
uint32_t death_pc;
|
||||
} SymPair;
|
||||
@@ -222,6 +223,7 @@ const JanetSpecial *janetc_special(const uint8_t *name);
|
||||
|
||||
void janetc_freeslot(JanetCompiler *c, JanetSlot s);
|
||||
void janetc_nameslot(JanetCompiler *c, const uint8_t *sym, JanetSlot s);
|
||||
void janetc_nameslot_no_unused(JanetCompiler *c, const uint8_t *sym, JanetSlot s);
|
||||
JanetSlot janetc_farslot(JanetCompiler *c);
|
||||
|
||||
/* Throw away some code after checking that it is well formed. */
|
||||
|
||||
@@ -120,6 +120,25 @@ static void janet_net_socknoblock(JSock s) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Allow specifying IPV6 vs. IPV4 (or unix domain socket) */
|
||||
static int net_get_address_family(Janet x) {
|
||||
if (janet_checktype(x, JANET_NIL)) {
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
if (janet_keyeq(x, "ipv4")) {
|
||||
return AF_INET;
|
||||
}
|
||||
if (janet_keyeq(x, "ipv6")) {
|
||||
return AF_INET6;
|
||||
}
|
||||
#ifndef JANET_WINDOWS
|
||||
if (janet_keyeq(x, "unix")) {
|
||||
return AF_UNIX;
|
||||
}
|
||||
#endif
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
|
||||
/* State machine for async connect */
|
||||
|
||||
void net_callback_connect(JanetFiber *fiber, JanetAsyncEvent event) {
|
||||
@@ -596,10 +615,11 @@ JANET_CORE_FN(cfun_net_connect,
|
||||
}
|
||||
|
||||
JANET_CORE_FN(cfun_net_socket,
|
||||
"(net/socket &opt type)",
|
||||
"(net/socket &opt type address-family)",
|
||||
"Creates a new unbound socket. Type is an optional keyword, "
|
||||
"either a :stream (usually tcp), or :datagram (usually udp). The default is :stream.") {
|
||||
janet_arity(argc, 0, 1);
|
||||
"either a :stream (usually tcp), or :datagram (usually udp). The default is :stream. "
|
||||
"`address-family` should be one of :ipv4 or :ipv6.") {
|
||||
janet_arity(argc, 0, 2);
|
||||
|
||||
int socktype = janet_get_sockettype(argv, argc, 0);
|
||||
|
||||
@@ -610,7 +630,14 @@ JANET_CORE_FN(cfun_net_socket,
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = socktype;
|
||||
#ifdef AI_NUMERICSERV
|
||||
hints.ai_flags = AI_NUMERICSERV; /* Explicitly prevent name resolution */
|
||||
#else
|
||||
hints.ai_flags = 0;
|
||||
#endif
|
||||
if (argc >= 2) {
|
||||
hints.ai_family = net_get_address_family(argv[1]);
|
||||
}
|
||||
int status = getaddrinfo(NULL, "0", &hints, &ai);
|
||||
if (status) {
|
||||
janet_panicf("could not get address info: %s", gai_strerror(status));
|
||||
@@ -1038,6 +1065,8 @@ static const struct sockopt_type sockopt_type_list[] = {
|
||||
#ifndef JANET_NO_IPV6
|
||||
{ "ipv6-join-group", IPPROTO_IPV6, IPV6_JOIN_GROUP, JANET_POINTER },
|
||||
{ "ipv6-leave-group", IPPROTO_IPV6, IPV6_LEAVE_GROUP, JANET_POINTER },
|
||||
{ "ipv6-multicast-hops", IPPROTO_IPV6, IPV6_MULTICAST_HOPS, JANET_NUMBER },
|
||||
{ "ipv6-unicast-hops", IPPROTO_IPV6, IPV6_UNICAST_HOPS, JANET_NUMBER },
|
||||
#endif
|
||||
{ NULL, 0, 0, JANET_POINTER }
|
||||
};
|
||||
@@ -1054,7 +1083,10 @@ JANET_CORE_FN(cfun_net_setsockopt,
|
||||
"- :ip-add-membership string\n"
|
||||
"- :ip-drop-membership string\n"
|
||||
"- :ipv6-join-group string\n"
|
||||
"- :ipv6-leave-group string\n") {
|
||||
"- :ipv6-leave-group string\n"
|
||||
"- :ipv6-multicast-hops number\n"
|
||||
"- :ipv6-unicast-hops number\n"
|
||||
) {
|
||||
janet_arity(argc, 3, 3);
|
||||
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
||||
janet_stream_flags(stream, JANET_STREAM_SOCKET);
|
||||
@@ -1073,6 +1105,7 @@ JANET_CORE_FN(cfun_net_setsockopt,
|
||||
}
|
||||
|
||||
union {
|
||||
unsigned char v_uchar;
|
||||
int v_int;
|
||||
struct ip_mreq v_mreq;
|
||||
#ifndef JANET_NO_IPV6
|
||||
@@ -1087,8 +1120,19 @@ JANET_CORE_FN(cfun_net_setsockopt,
|
||||
val.v_int = janet_getboolean(argv, 2);
|
||||
optlen = sizeof(val.v_int);
|
||||
} else if (st->type == JANET_NUMBER) {
|
||||
#ifdef JANET_BSD
|
||||
int v_int = janet_getinteger(argv, 2);
|
||||
if (st->optname == IP_MULTICAST_TTL) {
|
||||
val.v_uchar = v_int;
|
||||
optlen = sizeof(val.v_uchar);
|
||||
} else {
|
||||
val.v_int = v_int;
|
||||
optlen = sizeof(val.v_int);
|
||||
}
|
||||
#else
|
||||
val.v_int = janet_getinteger(argv, 2);
|
||||
optlen = sizeof(val.v_int);
|
||||
#endif
|
||||
} else if (st->optname == IP_ADD_MEMBERSHIP || st->optname == IP_DROP_MEMBERSHIP) {
|
||||
const char *addr = janet_getcstring(argv, 2);
|
||||
memset(&val.v_mreq, 0, sizeof val.v_mreq);
|
||||
|
||||
@@ -404,7 +404,7 @@ SlotHeadPair *dohead_destructure(JanetCompiler *c, SlotHeadPair *into, JanetFopt
|
||||
}
|
||||
|
||||
/* Def or var a symbol in a local scope */
|
||||
static int namelocal(JanetCompiler *c, const uint8_t *head, int32_t flags, JanetSlot ret) {
|
||||
static int namelocal(JanetCompiler *c, const uint8_t *head, int32_t flags, JanetSlot ret, int no_unused) {
|
||||
int isUnnamedRegister = !(ret.flags & JANET_SLOT_NAMED) &&
|
||||
ret.index > 0 &&
|
||||
ret.envindex >= 0;
|
||||
@@ -425,7 +425,11 @@ static int namelocal(JanetCompiler *c, const uint8_t *head, int32_t flags, Janet
|
||||
ret = localslot;
|
||||
}
|
||||
ret.flags |= flags;
|
||||
janetc_nameslot(c, head, ret);
|
||||
if ((c->scope->flags & JANET_SCOPE_TOP) || no_unused) {
|
||||
janetc_nameslot_no_unused(c, head, ret);
|
||||
} else {
|
||||
janetc_nameslot(c, head, ret);
|
||||
}
|
||||
return !isUnnamedRegister;
|
||||
}
|
||||
|
||||
@@ -460,7 +464,8 @@ static int varleaf(
|
||||
janetc_emit_ssu(c, JOP_PUT_INDEX, refslot, s, 0, 0);
|
||||
return 1;
|
||||
} else {
|
||||
return namelocal(c, sym, JANET_SLOT_MUTABLE, s);
|
||||
int no_unused = reftab && reftab->count && janet_truthy(janet_table_get(reftab, janet_ckeywordv("unused")));
|
||||
return namelocal(c, sym, JANET_SLOT_MUTABLE, s, no_unused);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,8 +474,6 @@ static void check_metadata_lint(JanetCompiler *c, JanetTable *attr_table) {
|
||||
/* A macro is a normal lint, other metadata is a strict lint */
|
||||
if (janet_truthy(janet_table_get(attr_table, janet_ckeywordv("macro")))) {
|
||||
janetc_lintf(c, JANET_C_LINT_NORMAL, "macro tag is ignored in inner scopes");
|
||||
} else {
|
||||
janetc_lintf(c, JANET_C_LINT_STRICT, "unused metadata %j in inner scope", janet_wrap_table(attr_table));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -533,7 +536,8 @@ static int defleaf(
|
||||
/* Add env entry to env */
|
||||
janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(entry));
|
||||
}
|
||||
return namelocal(c, sym, 0, s);
|
||||
int no_unused = tab && tab->count && janet_truthy(janet_table_get(tab, janet_ckeywordv("unused")));
|
||||
return namelocal(c, sym, 0, s, no_unused);
|
||||
}
|
||||
|
||||
static JanetSlot janetc_def(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
@@ -1114,7 +1118,7 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
JanetSlot slot = janetc_farslot(c);
|
||||
slot.flags = JANET_SLOT_NAMED | JANET_FUNCTION;
|
||||
janetc_emit_s(c, JOP_LOAD_SELF, slot, 1);
|
||||
janetc_nameslot(c, sym, slot);
|
||||
janetc_nameslot_no_unused(c, sym, slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Helper code for running tests
|
||||
|
||||
# Turn on strict linting by default in test suite.
|
||||
(put root-env *lint-warn* :strict)
|
||||
|
||||
(var num-tests-passed 0)
|
||||
(var num-tests-run 0)
|
||||
(var suite-name 0)
|
||||
@@ -7,7 +10,7 @@
|
||||
(var skip-count 0)
|
||||
(var skip-n 0)
|
||||
|
||||
(def is-verbose (os/getenv "VERBOSE"))
|
||||
(var is-verbose (os/getenv "VERBOSE"))
|
||||
|
||||
(defn- assert-no-tail
|
||||
"Override's the default assert with some nice error handling."
|
||||
@@ -19,7 +22,6 @@
|
||||
(break x))
|
||||
(default e "assert error")
|
||||
(when x (++ num-tests-passed))
|
||||
(def str (string e))
|
||||
(def stack (debug/stack (fiber/current)))
|
||||
(def frame (last stack))
|
||||
(def line-info (string/format "%s:%d"
|
||||
@@ -65,8 +67,8 @@
|
||||
(def e (gensym))
|
||||
(def f (gensym))
|
||||
(if is-verbose
|
||||
~(try (do ,;forms (,assert true ,msg)) ([,e ,f] (,assert false ,msg) (,debug/stacktrace ,f ,e "\e[31m✘\e[0m ")))
|
||||
~(try (do ,;forms (,assert true ,msg)) ([_] (,assert false ,msg)))))
|
||||
~(try (do ,;forms (as-macro ,assert true ,msg)) ([,e ,f] (as-macro ,assert false ,msg) (,debug/stacktrace ,f ,e "\e[31m✘\e[0m ")))
|
||||
~(try (do ,;forms (as-macro ,assert true ,msg)) ([_] (as-macro ,assert false ,msg)))))
|
||||
|
||||
(defn start-suite [&opt x]
|
||||
(default x (dyn :current-file))
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
(import ./helper :prefix "" :exit true)
|
||||
(start-suite)
|
||||
|
||||
(setdyn *lint-warn* :none)
|
||||
|
||||
# Assembly test
|
||||
# Fibonacci sequence, implemented with naive recursion.
|
||||
# a679f60
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
(import ./helper :prefix "" :exit true)
|
||||
(start-suite)
|
||||
|
||||
(setdyn *lint-warn* :none)
|
||||
|
||||
# Let
|
||||
# 807f981
|
||||
(assert (= (let [a 1 b 2] (+ a b)) 3) "simple let")
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
(defn myfun [x]
|
||||
(var a 10)
|
||||
(set a (do
|
||||
(def y x)
|
||||
(def _y x)
|
||||
(if x 8 9))))
|
||||
|
||||
(assert (= (myfun true) 8) "check do form regression")
|
||||
@@ -46,8 +46,10 @@
|
||||
# Edge case should cause old compilers to fail due to
|
||||
# if statement optimization
|
||||
# 17283241
|
||||
(setdyn *lint-warn* :relaxed)
|
||||
(var var-a 1)
|
||||
(var var-b (if false 2 (string "hello")))
|
||||
(setdyn *lint-warn* nil)
|
||||
|
||||
(assert (= var-b "hello") "regression 1")
|
||||
|
||||
|
||||
@@ -192,8 +192,10 @@
|
||||
(assert (deep-not= (thaw ds2) (thaw-keep-keys ds2)) "thaw vs. thaw-keep-keys 2")
|
||||
|
||||
# match
|
||||
(setdyn *lint-warn* :none)
|
||||
(assert (= :yes (match [1 2 3] [x y z w] :no1 [x y $] :no2 [x y z] :yes)) "match dollar suffix 1")
|
||||
(assert (= :yes (match [1 2 3] [x y z w] :no1 [x y z $] :yes [x y z] :no2)) "match dollar suffix 2")
|
||||
(setdyn *lint-warn* nil)
|
||||
|
||||
# Issue #1687
|
||||
(assert-no-error "def destructure splice works 1" (do (def [a] [;[1]]) a))
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
(import ./helper :prefix "" :exit true)
|
||||
(start-suite)
|
||||
|
||||
(setdyn *lint-warn* :none)
|
||||
|
||||
(def test-port (os/getenv "JANET_TEST_PORT" "8761"))
|
||||
(def test-host (os/getenv "JANET_TEST_HOST" "127.0.0.1"))
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
(import ./helper :prefix "" :exit true)
|
||||
(start-suite)
|
||||
|
||||
(def has-ffi (dyn 'ffi/native))
|
||||
(var has-ffi (dyn 'ffi/native))
|
||||
(def has-full-ffi
|
||||
(and has-ffi
|
||||
(when-let [entry (dyn 'ffi/calling-conventions)]
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
(assert true)
|
||||
|
||||
(def chan (ev/chan 1000))
|
||||
(def is-win (or (= :mingw (os/which)) (= :windows (os/which))))
|
||||
(def is-linux (= :linux (os/which)))
|
||||
(var is-win (or (= :mingw (os/which)) (= :windows (os/which))))
|
||||
(var is-linux (= :linux (os/which)))
|
||||
|
||||
# If not supported, exit early
|
||||
(def [supported msg] (protect (filewatch/new chan)))
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
(import ./helper :prefix "" :exit true)
|
||||
(start-suite)
|
||||
|
||||
# Disable linting warnings
|
||||
(setdyn *lint-warn* :none)
|
||||
|
||||
# some tests for bigint
|
||||
# 319575c
|
||||
(def i64 int/s64)
|
||||
|
||||
@@ -81,10 +81,12 @@
|
||||
"marshal nested fibers")
|
||||
|
||||
# issue #53 - f4908ebc4
|
||||
(setdyn *lint-warn* :none)
|
||||
(def issue-53-x
|
||||
(fiber/new
|
||||
(fn []
|
||||
(var y (fiber/new (fn [] (print "1") (yield) (print "2")))))))
|
||||
(setdyn *lint-warn* nil)
|
||||
|
||||
(check-image issue-53-x "issue 53 regression")
|
||||
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
[rng]
|
||||
(assert (all identity (seq [i :range [0 1000]]
|
||||
(<= (math/rng-int rng i) i))) "math/rng-int test")
|
||||
(assert (all identity (seq [i :range [0 1000]]
|
||||
(assert (all identity (seq [_ :range [0 1000]]
|
||||
(def x (math/rng-uniform rng))
|
||||
(and (>= x 0) (< x 1))))
|
||||
"math/rng-uniform test"))
|
||||
|
||||
(def seedrng (math/rng 123))
|
||||
(for i 0 75
|
||||
(for _ 0 75
|
||||
(test-rng (math/rng (:int seedrng))))
|
||||
|
||||
# 70328437f
|
||||
@@ -49,7 +49,7 @@
|
||||
# 027b2a8
|
||||
(defn assert-many [f n e]
|
||||
(var good true)
|
||||
(loop [i :range [0 n]]
|
||||
(loop [_ :range [0 n]]
|
||||
(if (not (f))
|
||||
(set good false)))
|
||||
(assert good e))
|
||||
|
||||
35
test/suite-net.janet
Normal file
35
test/suite-net.janet
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright (c) 2026 Calvin Rose & contributors
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
# Expand on ev testing with some extra network protocol testing.
|
||||
|
||||
(import ./helper :prefix "" :exit true)
|
||||
(start-suite)
|
||||
|
||||
# Smoke
|
||||
(assert true)
|
||||
|
||||
# Raw socket testing
|
||||
(def s (net/socket :datagram :ipv4))
|
||||
(assert-no-error "multicast ipv4" (net/setsockopt s :ip-multicast-ttl 255))
|
||||
#(def s6 (net/socket :datagram :ipv6))
|
||||
#(assert-no-error "multicast ipv6" (net/setsockopt s6 :ipv6-multicast-hops 255))
|
||||
|
||||
(end-suite)
|
||||
@@ -67,7 +67,7 @@
|
||||
(def str
|
||||
(if rewrite
|
||||
(peg/replace-all ~(* '(* (? "\r") "\n") (between 0 ,indent " "))
|
||||
(fn [mtch eol] eol) text)
|
||||
(fn [_mtch eol] eol) text)
|
||||
text))
|
||||
|
||||
(def first-eol (cond
|
||||
@@ -177,12 +177,12 @@
|
||||
(def p1 (parser/new))
|
||||
(parser/state p1)
|
||||
(parser/consume p1 step1)
|
||||
(loop [v :iterate (parser/produce p1)])
|
||||
(loop [_ :iterate (parser/produce p1)])
|
||||
(parser/state p1)
|
||||
(def p2 (parser/clone p1))
|
||||
(parser/state p2)
|
||||
(parser/consume p2 step2)
|
||||
(loop [v :iterate (parser/produce p2)])
|
||||
(loop [_ :iterate (parser/produce p2)])
|
||||
(parser/state p2)
|
||||
|
||||
# parser delimiter errors
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
(import ./helper :prefix "" :exit true)
|
||||
(start-suite)
|
||||
|
||||
# Disable linting warnings
|
||||
(setdyn *lint-warn* :none)
|
||||
|
||||
# Regression Test #137
|
||||
# affcb5b45
|
||||
(def [a b c] (range 10))
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
(import ./helper :prefix "" :exit true)
|
||||
(start-suite)
|
||||
|
||||
# Disable linting warnings
|
||||
(setdyn *lint-warn* :none)
|
||||
|
||||
# Set global variables to prevent some possible compiler optimizations
|
||||
# that defeat point of the test
|
||||
# 2771171
|
||||
|
||||
@@ -64,11 +64,11 @@
|
||||
# b9c0fc820
|
||||
(assert (= 1 ({:ok 1} :ok)) "calling struct")
|
||||
(assert (= 2 (@{:ok 2} :ok)) "calling table")
|
||||
(assert (= :bad (try ((identity @{:ok 2}) :ok :no) ([err] :bad)))
|
||||
(assert (= :bad (try ((identity @{:ok 2}) :ok :no) ([_err] :bad)))
|
||||
"calling table too many arguments")
|
||||
(assert (= :bad (try ((identity :ok) @{:ok 2} :no) ([err] :bad)))
|
||||
(assert (= :bad (try ((identity :ok) @{:ok 2} :no) ([_err] :bad)))
|
||||
"calling keyword too many arguments")
|
||||
(assert (= :oops (try ((+ 2 -1) 1) ([err] :oops)))
|
||||
(assert (= :oops (try ((+ 2 -1) 1) ([_err] :oops)))
|
||||
"calling number fails")
|
||||
|
||||
# Method test
|
||||
@@ -119,7 +119,7 @@
|
||||
(with-dyns []
|
||||
(ev/sleep 0)
|
||||
(error "oops")))
|
||||
([err] :caught))))
|
||||
([_err] :caught))))
|
||||
"regression #638"))
|
||||
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user