1
0
mirror of https://github.com/janet-lang/janet synced 2026-04-03 13:31:28 +00:00

Compare commits

..

12 Commits

Author SHA1 Message Date
Calvin Rose
0a5ff208a8 Disable ipv6 for now in main test. 2026-01-12 08:00:11 -06:00
Calvin Rose
d35f189446 Turn strict linting back on. 2026-01-12 07:57:41 -06:00
Calvin Rose
216c9799f5 Some more work on socket testing and allow setting ipv4 vs. ipv6 on raw
sockets.
2026-01-12 07:41:14 -06:00
Peter Rippe
5966017232 use u_char for IP_MULTICAST_TTL sockopt on BSD 2026-01-12 06:06:27 -06:00
Calvin Rose
f80690e4c9 Version bump for wip 1.41.x 2026-01-10 15:40:04 -06:00
Calvin Rose
9bc308532f Make varfn correctly handle verbose metadata.
The macro would previously choke on `(varfn abc {:abc 123} ...)` due
to mishandling of structs and tables as metadata. This caused issues
when running `janet -d` with spork.
2026-01-10 14:04:48 -06:00
Calvin Rose
7a8d8444fe Simplify dynamic binding setup in cli-main.
Instead of manually putting bindings into environment tables, just use
`setdyn` to set the bindings based on the command line flags. This
results in easier to understand behavior and prevents "swallowing" of
options. For example, linting and debug flags should be set in the
root-env by default so that they are used in all loaded modules.
2026-01-10 13:37:42 -06:00
Calvin Rose
15cea60589 Revert "Reworking coloring logic for repl and CLI interface."
This reverts commit 10954fe0d7.
2026-01-10 13:20:02 -06:00
Calvin Rose
10954fe0d7 Reworking coloring logic for repl and CLI interface. 2026-01-10 13:15:46 -06:00
Calvin Rose
70fb13eb48 Fix -w flag with repl. 2026-01-10 12:35:41 -06:00
Calvin Rose
cb355815ee Turn on strict linting in test suite. 2026-01-10 08:37:09 -06:00
Calvin Rose
ddc7cc5ae4 Warn on unused bindings (strict lint).
This does create a lot of warnings, especially in the test suite, but
should improve code and point out real issues.

To disable individual messages, either disable linting, add the metadata :unused to a
binding, or add the prefix "_" to a symbol.
2026-01-10 07:59:11 -06:00
29 changed files with 209 additions and 80 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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"))

View File

@@ -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)

View File

@@ -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)]

View File

@@ -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))

View File

@@ -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',

View File

@@ -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))

View File

@@ -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" */

View File

@@ -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 {

View File

@@ -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. */

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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))

View 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

View File

@@ -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")

View File

@@ -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")

View File

@@ -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))

View File

@@ -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"))

View File

@@ -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)]

View File

@@ -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)))

View File

@@ -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)

View File

@@ -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")

View File

@@ -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
View 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)

View File

@@ -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

View File

@@ -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))

View File

@@ -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

View File

@@ -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"))
#