From 348a5bc0a9f7d3557fdf9ad9a9882e6c2098f6c3 Mon Sep 17 00:00:00 2001 From: sogaiu <983021772@users.noreply.github.com> Date: Thu, 6 Jul 2023 13:26:03 +0900 Subject: [PATCH 01/19] Add source view to .ppasm output --- src/boot/boot.janet | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 74f6384d..93be8b88 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -3520,6 +3520,24 @@ (when-let [constants (dasm :constants)] (eprintf " constants: %.4q" constants)) (eprintf " slots: %.4q\n" (frame :slots)) + (when-let [src-path (in dasm :source)] + (when (and (fexists src-path) + sourcemap) + (defn dump + [src cur] + (def offset 5) + (def beg (max 1 (- cur offset))) + (def lines (array/concat @[""] (string/split "\n" src))) + (def end (min (+ cur offset) (length lines))) + (def digits (inc (math/floor (math/log10 end)))) + (def fmt-str (string "%" digits "d: %s")) + (for i beg end + (eprin " ") # breakpoint someday? + (eprin (if (= i cur) "> " " ")) + (eprintf fmt-str i (get lines i)))) + (let [[sl _] (sourcemap pc)] + (dump (slurp src-path) sl) + (eprint)))) (def padding (string/repeat " " 20)) (loop [i :range [0 (length bytecode)] :let [instr (bytecode i)]] From 5a5e70b0010ec538ac13c5e6a6a18528131fe78c Mon Sep 17 00:00:00 2001 From: sogaiu <983021772@users.noreply.github.com> Date: Sat, 8 Jul 2023 17:54:00 +0900 Subject: [PATCH 02/19] Update and ascii-sort string escapes in peg --- test/suite-peg.janet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/suite-peg.janet b/test/suite-peg.janet index 44236900..a237c853 100644 --- a/test/suite-peg.janet +++ b/test/suite-peg.janet @@ -367,7 +367,7 @@ (set "!$%&*+-./:@^_|")) :token (some :symchars) :hex (range "09" "af" "AF") - :escape (* "\\" (+ (set "ntrvzf0e\"\\") + :escape (* "\\" (+ (set `"'0?\abefnrtvz`) (* "x" :hex :hex) (error (constant "bad hex escape")))) :comment (/ '(* "#" (any (if-not (+ "\n" -1) 1))) (constant :comment)) From b5d3c8725335d18c69e84c4a01adb7ef27a5d473 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 9 Jul 2023 21:28:08 -0500 Subject: [PATCH 03/19] Add new opcode subtract immediate. --- src/core/asm.c | 1 + src/core/bytecode.c | 2 ++ src/core/cfuns.c | 2 +- src/core/vm.c | 5 ++++- src/include/janet.h | 1 + 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/asm.c b/src/core/asm.c index e5712cc1..14fa28c0 100644 --- a/src/core/asm.c +++ b/src/core/asm.c @@ -138,6 +138,7 @@ static const JanetInstructionDef janet_ops[] = { {"sru", JOP_SHIFT_RIGHT_UNSIGNED}, {"sruim", JOP_SHIFT_RIGHT_UNSIGNED_IMMEDIATE}, {"sub", JOP_SUBTRACT}, + {"subim", JOP_SUBTRACT_IMMEDIATE}, {"tcall", JOP_TAILCALL}, {"tchck", JOP_TYPECHECK} }; diff --git a/src/core/bytecode.c b/src/core/bytecode.c index 821bf42d..e0b25cfd 100644 --- a/src/core/bytecode.c +++ b/src/core/bytecode.c @@ -37,6 +37,7 @@ enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT] = { JINT_0, /* JOP_RETURN_NIL, */ JINT_SSI, /* JOP_ADD_IMMEDIATE, */ JINT_SSS, /* JOP_ADD, */ + JINT_SSI, /* JOP_SUBTRACT_IMMEDIATE, */ JINT_SSS, /* JOP_SUBTRACT, */ JINT_SSI, /* JOP_MULTIPLY_IMMEDIATE, */ JINT_SSS, /* JOP_MULTIPLY, */ @@ -251,6 +252,7 @@ void janet_bytecode_movopt(JanetFuncDef *def) { case JOP_SIGNAL: /* Write A, Read B */ case JOP_ADD_IMMEDIATE: + case JOP_SUBTRACT_IMMEDIATE: case JOP_MULTIPLY_IMMEDIATE: case JOP_DIVIDE_IMMEDIATE: case JOP_SHIFT_LEFT_IMMEDIATE: diff --git a/src/core/cfuns.c b/src/core/cfuns.c index be61da80..13c86dec 100644 --- a/src/core/cfuns.c +++ b/src/core/cfuns.c @@ -260,7 +260,7 @@ static JanetSlot do_add(JanetFopts opts, JanetSlot *args) { return opreduce(opts, args, JOP_ADD, JOP_ADD_IMMEDIATE, janet_wrap_integer(0), janet_wrap_integer(0)); } static JanetSlot do_sub(JanetFopts opts, JanetSlot *args) { - return opreduce(opts, args, JOP_SUBTRACT, -JOP_ADD_IMMEDIATE, janet_wrap_integer(0), janet_wrap_integer(0)); + return opreduce(opts, args, JOP_SUBTRACT, JOP_SUBTRACT_IMMEDIATE, janet_wrap_integer(0), janet_wrap_integer(0)); } static JanetSlot do_mul(JanetFopts opts, JanetSlot *args) { return opreduce(opts, args, JOP_MULTIPLY, JOP_MULTIPLY_IMMEDIATE, janet_wrap_integer(1), janet_wrap_integer(1)); diff --git a/src/core/vm.c b/src/core/vm.c index 132d8c09..5e881772 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -347,6 +347,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { &&label_JOP_RETURN_NIL, &&label_JOP_ADD_IMMEDIATE, &&label_JOP_ADD, + &&label_JOP_SUBTRACT_IMMEDIATE, &&label_JOP_SUBTRACT, &&label_JOP_MULTIPLY_IMMEDIATE, &&label_JOP_MULTIPLY, @@ -593,7 +594,6 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { &&label_unknown_op, &&label_unknown_op, &&label_unknown_op, - &&label_unknown_op, &&label_unknown_op }; #endif @@ -683,6 +683,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { VM_OP(JOP_ADD) vm_binop(+); + VM_OP(JOP_SUBTRACT_IMMEDIATE) + vm_binop_immediate(-); + VM_OP(JOP_SUBTRACT) vm_binop(-); diff --git a/src/include/janet.h b/src/include/janet.h index ada92277..e59318f1 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1262,6 +1262,7 @@ enum JanetOpCode { JOP_RETURN_NIL, JOP_ADD_IMMEDIATE, JOP_ADD, + JOP_SUBTRACT_IMMEDIATE, JOP_SUBTRACT, JOP_MULTIPLY_IMMEDIATE, JOP_MULTIPLY, From 3b6371e03dec52f4dc165788392a59b03399cd51 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 9 Jul 2023 21:56:41 -0500 Subject: [PATCH 04/19] Add test case for issue #1217 --- test/suite-inttypes.janet | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/suite-inttypes.janet b/test/suite-inttypes.janet index 9ee7c6fe..e55181c9 100644 --- a/test/suite-inttypes.janet +++ b/test/suite-inttypes.janet @@ -281,4 +281,7 @@ (assert (= (int/s64 "0x7FFF_FFFF_FFFF_FFFF") (- (int/s64 "-0x8000_0000_0000_0000") 1)) "int types wrap around") +# Issue #1217 +(assert (= (- (int/u64 "0xFFFFFFFF") 1) (int/u64 "0xFFFFFFFE")) "u64 subtract") + (end-suite) From f3bda1536de4e61d288ba6b4dd65d1cdd5880f72 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 9 Jul 2023 22:02:10 -0500 Subject: [PATCH 05/19] Remove some dead code in cfuns.c --- src/core/cfuns.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/cfuns.c b/src/core/cfuns.c index 13c86dec..4d355ca1 100644 --- a/src/core/cfuns.c +++ b/src/core/cfuns.c @@ -121,8 +121,6 @@ static JanetSlot opreduce( JanetCompiler *c = opts.compiler; int32_t i, len; int8_t imm = 0; - int neg = opim < 0; - if (opim < 0) opim = -opim; len = janet_v_count(args); JanetSlot t; if (len == 0) { @@ -139,13 +137,13 @@ static JanetSlot opreduce( } t = janetc_gettarget(opts); if (opim && can_slot_be_imm(args[1], &imm)) { - janetc_emit_ssi(c, opim, t, args[0], neg ? -imm : imm, 1); + janetc_emit_ssi(c, opim, t, args[0], imm, 1); } else { janetc_emit_sss(c, op, t, args[0], args[1], 1); } for (i = 2; i < len; i++) { if (opim && can_slot_be_imm(args[i], &imm)) { - janetc_emit_ssi(c, opim, t, t, neg ? -imm : imm, 1); + janetc_emit_ssi(c, opim, t, t, imm, 1); } else { janetc_emit_sss(c, op, t, t, args[i], 1); } From 8183cc5a8dc6fa7beeddb434ed26db966bf8aee5 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 9 Jul 2023 22:25:20 -0500 Subject: [PATCH 06/19] Disallow converting negative numbers to int/u64 The wrap-around rule doesn't make sense once subtraction is properly fixed. --- src/core/inttypes.c | 16 ++++++---------- test/suite-inttypes.janet | 7 ++++--- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/core/inttypes.c b/src/core/inttypes.c index 78c39fe0..6e5e54b4 100644 --- a/src/core/inttypes.c +++ b/src/core/inttypes.c @@ -118,10 +118,9 @@ int64_t janet_unwrap_s64(Janet x) { default: break; case JANET_NUMBER : { - double dbl = janet_unwrap_number(x); - if (fabs(dbl) <= MAX_INT_IN_DBL) - return (int64_t)dbl; - break; + double d = janet_unwrap_number(x); + if (!janet_checkint64range(d)) break; + return (int64_t) d; } case JANET_STRING: { int64_t value; @@ -147,12 +146,9 @@ uint64_t janet_unwrap_u64(Janet x) { default: break; case JANET_NUMBER : { - double dbl = janet_unwrap_number(x); - /* Allow negative values to be cast to "wrap around". - * This let's addition and subtraction work as expected. */ - if (fabs(dbl) <= MAX_INT_IN_DBL) - return (uint64_t)dbl; - break; + double d = janet_unwrap_number(x); + if (!janet_checkuint64range(d)) break; + return (uint64_t) d; } case JANET_STRING: { uint64_t value; diff --git a/test/suite-inttypes.janet b/test/suite-inttypes.janet index e55181c9..af76aa43 100644 --- a/test/suite-inttypes.janet +++ b/test/suite-inttypes.janet @@ -196,7 +196,8 @@ (assert-error "division by zero" (op (int 7) (int 0))))) (each int [int/s64 int/u64] - (loop [x :in [-5 -3 0 3 5]] + (loop [x :in [-5 -3 0 3 5] :when (or (pos? x) (= int int/s64))] + # skip check when comparing negative values with unsigned integers. (assert (= (int x) (mod (int x) 0)) (string int " mod 0")) (assert (= (int x) (mod x (int 0))) (string int " mod 0")) (assert (= (int x) (mod (int x) (int 0))) (string int " mod 0")))) @@ -267,12 +268,12 @@ # compare u64/i64 (assert (= (compare (u64 1) (i64 2)) -1) "compare 7") (assert (= (compare (u64 1) (i64 -1)) +1) "compare 8") -(assert (= (compare (u64 -1) (i64 -1)) +1) "compare 9") +(assert (= (compare (u64 0) (i64 -1)) +1) "compare 9") # compare i64/u64 (assert (= (compare (i64 1) (u64 2)) -1) "compare 10") (assert (= (compare (i64 -1) (u64 1)) -1) "compare 11") -(assert (= (compare (i64 -1) (u64 -1)) -1) "compare 12") +(assert (= (compare (i64 -1) (u64 0)) -1) "compare 12") # off by 1 error in inttypes # a3e812b86 From 4efcff33bd7fc5e4a6a696f2f087f16cc99be903 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Thu, 13 Jul 2023 19:58:38 -0500 Subject: [PATCH 07/19] Update inttypes. --- src/core/inttypes.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/inttypes.c b/src/core/inttypes.c index 6e5e54b4..c3281bc3 100644 --- a/src/core/inttypes.c +++ b/src/core/inttypes.c @@ -303,8 +303,8 @@ static int compare_double_double(double x, double y) { static int compare_int64_double(int64_t x, double y) { if (isnan(y)) { - return 0; // clojure and python do this - } else if ((y > (- ((double) MAX_INT_IN_DBL))) && (y < ((double) MAX_INT_IN_DBL))) { + return 0; + } else if ((y > JANET_INTMIN_DOUBLE) && (y < JANET_INTMAX_DOUBLE)) { double dx = (double) x; return compare_double_double(dx, y); } else if (y > ((double) INT64_MAX)) { @@ -319,10 +319,10 @@ static int compare_int64_double(int64_t x, double y) { static int compare_uint64_double(uint64_t x, double y) { if (isnan(y)) { - return 0; // clojure and python do this + return 0; } else if (y < 0) { return 1; - } else if ((y >= 0) && (y < ((double) MAX_INT_IN_DBL))) { + } else if ((y >= 0) && (y < JANET_INTMAX_DOUBLE)) { double dx = (double) x; return compare_double_double(dx, y); } else if (y > ((double) UINT64_MAX)) { @@ -335,8 +335,9 @@ static int compare_uint64_double(uint64_t x, double y) { static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) { janet_fixarity(argc, 2); - if (janet_is_int(argv[0]) != JANET_INT_S64) + if (janet_is_int(argv[0]) != JANET_INT_S64) { janet_panic("compare method requires int/s64 as first argument"); + } int64_t x = janet_unwrap_s64(argv[0]); switch (janet_type(argv[1])) { default: @@ -351,7 +352,6 @@ static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) { int64_t y = *(int64_t *)abst; return janet_wrap_number((x < y) ? -1 : (x > y ? 1 : 0)); } else if (janet_abstract_type(abst) == &janet_u64_type) { - // comparing signed to unsigned -- be careful! uint64_t y = *(uint64_t *)abst; if (x < 0) { return janet_wrap_number(-1); @@ -370,8 +370,9 @@ static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) { static Janet cfun_it_u64_compare(int32_t argc, Janet *argv) { janet_fixarity(argc, 2); - if (janet_is_int(argv[0]) != JANET_INT_U64) // is this needed? + if (janet_is_int(argv[0]) != JANET_INT_U64) { janet_panic("compare method requires int/u64 as first argument"); + } uint64_t x = janet_unwrap_u64(argv[0]); switch (janet_type(argv[1])) { default: @@ -386,7 +387,6 @@ static Janet cfun_it_u64_compare(int32_t argc, Janet *argv) { uint64_t y = *(uint64_t *)abst; return janet_wrap_number((x < y) ? -1 : (x > y ? 1 : 0)); } else if (janet_abstract_type(abst) == &janet_s64_type) { - // comparing unsigned to signed -- be careful! int64_t y = *(int64_t *)abst; if (y < 0) { return janet_wrap_number(1); From bdefd3ba1ec833771458cce77e3e0366564ee731 Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Fri, 14 Jul 2023 17:34:55 +0700 Subject: [PATCH 08/19] update final array index to be -1 --- src/core/array.c | 8 ++++---- test/suite-array.janet | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/array.c b/src/core/array.c index fe818225..eb5d37d2 100644 --- a/src/core/array.c +++ b/src/core/array.c @@ -211,7 +211,7 @@ JANET_CORE_FN(cfun_array_slice, "Takes a slice of array or tuple from `start` to `end`. The range is half open, " "[start, end). Indexes can also be negative, indicating indexing from the " "end of the array. By default, `start` is 0 and `end` is the length of the array. " - "Note that index -1 is synonymous with index `(length arrtup)` to allow a full " + "Note that if the range is negative, it is taken as (start, end] to allow a full " "negative slice range. Returns a new array.") { JanetView view = janet_getindexed(argv, 0); JanetRange range = janet_getslice(argc, argv); @@ -259,8 +259,8 @@ JANET_CORE_FN(cfun_array_insert, "(array/insert arr at & xs)", "Insert all `xs` into array `arr` at index `at`. `at` should be an integer between " "0 and the length of the array. A negative value for `at` will index backwards from " - "the end of the array, such that inserting at -1 appends to the array. " - "Returns the array.") { + "the end of the array, inserting after the index such that inserting at -1 appends to " + "the array. Returns the array.") { size_t chunksize, restsize; janet_arity(argc, 2, -1); JanetArray *array = janet_getarray(argv, 0); @@ -297,7 +297,7 @@ JANET_CORE_FN(cfun_array_remove, int32_t at = janet_getinteger(argv, 1); int32_t n = 1; if (at < 0) { - at = array->count + at + 1; + at = array->count + at; } if (at < 0 || at > array->count) janet_panicf("removal index %d out of range [0,%d]", at, array->count); diff --git a/test/suite-array.janet b/test/suite-array.janet index 3773b2ef..0b02ab1e 100644 --- a/test/suite-array.janet +++ b/test/suite-array.janet @@ -44,7 +44,7 @@ (assert (deep= (array/remove @[1 2 3 4 5] 2) @[1 2 4 5]) "array/remove 1") (assert (deep= (array/remove @[1 2 3 4 5] 2 2) @[1 2 5]) "array/remove 2") (assert (deep= (array/remove @[1 2 3 4 5] 2 200) @[1 2]) "array/remove 3") -(assert (deep= (array/remove @[1 2 3 4 5] -3 200) @[1 2 3]) "array/remove 4") +(assert (deep= (array/remove @[1 2 3 4 5] -2 200) @[1 2 3]) "array/remove 4") # array/peek From 989f0726e33c81612eb37f49bcd25c7978cec4a6 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Fri, 14 Jul 2023 10:06:20 -0500 Subject: [PATCH 09/19] Make encoding of immediate values capture full range. --- src/core/cfuns.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/cfuns.c b/src/core/cfuns.c index 4d355ca1..46ecfeb0 100644 --- a/src/core/cfuns.c +++ b/src/core/cfuns.c @@ -99,7 +99,7 @@ static JanetSlot opfunction( static int can_be_imm(Janet x, int8_t *out) { if (!janet_checkint(x)) return 0; int32_t integer = janet_unwrap_integer(x); - if (integer > 127 || integer < -127) return 0; + if (integer > INT8_MAX || integer < INT8_MIN) return 0; *out = (int8_t) integer; return 1; } From c2e55b54869adafd59464900fd1b2d21600587df Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Sat, 15 Jul 2023 00:52:12 +0700 Subject: [PATCH 10/19] update docstrings for `string/slice` and `tuple/slice` --- src/core/string.c | 5 +++-- src/core/tuple.c | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/string.c b/src/core/string.c index d7baf86b..81149243 100644 --- a/src/core/string.c +++ b/src/core/string.c @@ -175,8 +175,9 @@ JANET_CORE_FN(cfun_string_slice, "Returns a substring from a byte sequence. The substring is from " "index `start` inclusive to index `end`, exclusive. All indexing " "is from 0. `start` and `end` can also be negative to indicate indexing " - "from the end of the string. Note that index -1 is synonymous with " - "index `(length bytes)` to allow a full negative slice range. ") { + "from the end of the string. Note that if `start` is negative it is " + "exclusive, and if `end` is negative it is inclusive, to allow a full " + "negative slice range.") { JanetByteView view = janet_getbytes(argv, 0); JanetRange range = janet_getslice(argc, argv); return janet_stringv(view.bytes + range.start, range.end - range.start); diff --git a/src/core/tuple.c b/src/core/tuple.c index 1c51efc2..bf6d09e6 100644 --- a/src/core/tuple.c +++ b/src/core/tuple.c @@ -69,9 +69,9 @@ JANET_CORE_FN(cfun_tuple_slice, "inclusive to index `end` exclusive. If `start` or `end` are not provided, " "they default to 0 and the length of `arrtup`, respectively. " "`start` and `end` can also be negative to indicate indexing " - "from the end of the input. Note that index -1 is synonymous with " - "index `(length arrtup)` to allow a full negative slice range. " - "Returns the new tuple.") { + "from the end of the input. Note that if `start` is negative it is " + "exclusive, and if `end` is negative it is inclusive, to allow a full " + "negative slice range. Returns the new tuple.") { JanetView view = janet_getindexed(argv, 0); JanetRange range = janet_getslice(argc, argv); return janet_wrap_tuple(janet_tuple_n(view.items + range.start, range.end - range.start)); From 738fe24e6df174ef84c8570327aeb430a400e274 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Fri, 14 Jul 2023 20:04:10 -0500 Subject: [PATCH 11/19] Allow buffer/blit to take explicit nils for default args. Also small changes for range checking code. --- src/core/buffer.c | 8 +++++--- src/core/capi.c | 36 ++++++++++++++++++------------------ src/include/janet.h | 2 ++ test/suite-buffer.janet | 1 + 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/core/buffer.c b/src/core/buffer.c index 5e1f76f9..07770964 100644 --- a/src/core/buffer.c +++ b/src/core/buffer.c @@ -462,13 +462,15 @@ JANET_CORE_FN(cfun_buffer_blit, int same_buf = src.bytes == dest->data; int32_t offset_dest = 0; int32_t offset_src = 0; - if (argc > 2) + if (argc > 2 && !janet_checktype(argv[2], JANET_NIL)) offset_dest = janet_gethalfrange(argv, 2, dest->count, "dest-start"); - if (argc > 3) + if (argc > 3 && !janet_checktype(argv[3], JANET_NIL)) offset_src = janet_gethalfrange(argv, 3, src.len, "src-start"); int32_t length_src; if (argc > 4) { - int32_t src_end = janet_gethalfrange(argv, 4, src.len, "src-end"); + int32_t src_end = src.len; + if (!janet_checktype(argv[4], JANET_NIL)) + src_end = janet_gethalfrange(argv, 4, src.len, "src-end"); length_src = src_end - offset_src; if (length_src < 0) length_src = 0; } else { diff --git a/src/core/capi.c b/src/core/capi.c index a89b4685..d8ee2d39 100644 --- a/src/core/capi.c +++ b/src/core/capi.c @@ -342,6 +342,20 @@ int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const c return not_raw; } +int32_t janet_getstartrange(const Janet *argv, int32_t argc, int32_t n, int32_t length) { + if (n >= argc || janet_checktype(argv[n], JANET_NIL)) { + return 0; + } + return janet_gethalfrange(argv, n, length, "start"); +} + +int32_t janet_getendrange(const Janet *argv, int32_t argc, int32_t n, int32_t length) { + if (n >= argc || janet_checktype(argv[n], JANET_NIL)) { + return length; + } + return janet_gethalfrange(argv, n, length, "end"); +} + int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which) { int32_t raw = janet_getinteger(argv, n); int32_t not_raw = raw; @@ -394,24 +408,10 @@ JanetRange janet_getslice(int32_t argc, const Janet *argv) { janet_arity(argc, 1, 3); JanetRange range; int32_t length = janet_length(argv[0]); - if (argc == 1) { - range.start = 0; - range.end = length; - } else if (argc == 2) { - range.start = janet_checktype(argv[1], JANET_NIL) - ? 0 - : janet_gethalfrange(argv, 1, length, "start"); - range.end = length; - } else { - range.start = janet_checktype(argv[1], JANET_NIL) - ? 0 - : janet_gethalfrange(argv, 1, length, "start"); - range.end = janet_checktype(argv[2], JANET_NIL) - ? length - : janet_gethalfrange(argv, 2, length, "end"); - if (range.end < range.start) - range.end = range.start; - } + range.start = janet_getstartrange(argv, argc, 1, length); + range.end = janet_getendrange(argv, argc, 2, length); + if (range.end < range.start) + range.end = range.start; return range; } diff --git a/src/include/janet.h b/src/include/janet.h index e59318f1..34863070 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1997,6 +1997,8 @@ JANET_API JanetDictView janet_getdictionary(const Janet *argv, int32_t n); JANET_API void *janet_getabstract(const Janet *argv, int32_t n, const JanetAbstractType *at); JANET_API JanetRange janet_getslice(int32_t argc, const Janet *argv); JANET_API int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const char *which); +JANET_API int32_t janet_getstartrange(const Janet *argv, int32_t argc, int32_t n, int32_t length); +JANET_API int32_t janet_getendrange(const Janet *argv, int32_t argc, int32_t n, int32_t length); JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which); JANET_API uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags); diff --git a/test/suite-buffer.janet b/test/suite-buffer.janet index 8feb4c1c..681ad29e 100644 --- a/test/suite-buffer.janet +++ b/test/suite-buffer.janet @@ -103,6 +103,7 @@ (assert (deep= @"bcde" (buffer/blit @"" a -1 1 5)) "buffer/blit 3") (assert (deep= @"cde" (buffer/blit @"" a -1 2 5)) "buffer/blit 4") (assert (deep= @"de" (buffer/blit @"" a -1 3 5)) "buffer/blit 5") +(assert (deep= @"de" (buffer/blit @"" a nil 3 5)) "buffer/blit 6") # buffer/push-at # c55d93512 From f9233ef90bb7f17f1136b30f5764eae39ba297c4 Mon Sep 17 00:00:00 2001 From: sogaiu <983021772@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:39:20 +0900 Subject: [PATCH 12/19] Add fopen reference to file/open docstring --- src/core/io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/io.c b/src/core/io.c index d9a8626a..3af158cf 100644 --- a/src/core/io.c +++ b/src/core/io.c @@ -143,7 +143,8 @@ JANET_CORE_FN(cfun_io_fopen, "Following one of the initial flags, 0 or more of the following flags can be appended:\n\n" "* b - open the file in binary mode (rather than text mode)\n\n" "* + - append to the file instead of overwriting it\n\n" - "* n - error if the file cannot be opened instead of returning nil") { + "* n - error if the file cannot be opened instead of returning nil\n\n" + "See fopen (, C99) for further details.") { janet_arity(argc, 1, 2); const uint8_t *fname = janet_getstring(argv, 0); const uint8_t *fmode; From 080b37cb3128c1cc5a3912476892c2444930fc71 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Tue, 25 Jul 2023 17:51:07 -0500 Subject: [PATCH 13/19] Update CHANGELOG. --- CHANGELOG.md | 1 + Makefile | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e55dbb3..a1f84cc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ All notable changes to this project will be documented in this file. ## Unreleased - ??? +- Change indexing of `array/remove` to start from -1 at the end instead of -2. - Add new string escape sequences `\\a`, `\\b`, `\\?`, and `\\'`. - Fix bug with marshalling channels - Add `div` for floored division diff --git a/Makefile b/Makefile index c6be5487..b1d72830 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ SONAME_SETTER=-Wl,-soname, # For cross compilation HOSTCC?=$(CC) HOSTAR?=$(AR) -CFLAGS?=-O2 -g +CFLAGS?=-O2 LDFLAGS?=-rdynamic RUN:=$(RUN) @@ -364,7 +364,7 @@ build/janet.tmLanguage: tools/tm_lang_gen.janet $(JANET_TARGET) $(RUN) $(JANET_TARGET) $< > $@ compile-commands: - # Requires pip install copmiledb + # Requires pip install compiledb compiledb make clean: From 08f0e55d8f1933597c0b944650265619c4761b6f Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Thu, 27 Jul 2023 21:37:26 -0500 Subject: [PATCH 14/19] Add strip in release process instead of local builds - Address #1233 --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b1d72830..7f78ceee 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,8 @@ SONAME_SETTER=-Wl,-soname, # For cross compilation HOSTCC?=$(CC) HOSTAR?=$(AR) -CFLAGS?=-O2 +# Symbols are (optionally) removed later, keep -g as default! +CFLAGS?=-O2 -g LDFLAGS?=-rdynamic RUN:=$(RUN) @@ -266,6 +267,7 @@ build/janet-%.tar.gz: $(JANET_TARGET) \ README.md build/c/janet.c build/c/shell.c mkdir -p build/$(JANET_DIST_DIR)/bin cp $(JANET_TARGET) build/$(JANET_DIST_DIR)/bin/ + strip -x -S 'build/$(JANET_DIST_DIR)/bin/$(JANET_TARGET)' mkdir -p build/$(JANET_DIST_DIR)/include cp build/janet.h build/$(JANET_DIST_DIR)/include/ mkdir -p build/$(JANET_DIST_DIR)/lib/ From 4ff81a5a25cb3e398bd7cd1d76283e1e2b503820 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Thu, 27 Jul 2023 21:37:26 -0500 Subject: [PATCH 15/19] Add strip in release process instead of local builds - Address #1233 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7f78ceee..c7140d25 100644 --- a/Makefile +++ b/Makefile @@ -267,7 +267,7 @@ build/janet-%.tar.gz: $(JANET_TARGET) \ README.md build/c/janet.c build/c/shell.c mkdir -p build/$(JANET_DIST_DIR)/bin cp $(JANET_TARGET) build/$(JANET_DIST_DIR)/bin/ - strip -x -S 'build/$(JANET_DIST_DIR)/bin/$(JANET_TARGET)' + strip -x -S 'build/$(JANET_DIST_DIR)/bin/janet' mkdir -p build/$(JANET_DIST_DIR)/include cp build/janet.h build/$(JANET_DIST_DIR)/include/ mkdir -p build/$(JANET_DIST_DIR)/lib/ From 61712bae9c96450987d2c02f12251b50cac0285d Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Tue, 1 Aug 2023 23:00:54 +0700 Subject: [PATCH 16/19] speed up range creation --- src/boot/boot.janet | 24 ------------------------ src/core/corelib.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 93be8b88..46432619 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -1007,30 +1007,6 @@ (map-template :keep res pred ind inds) res) -(defn range - `Create an array of values [start, end) with a given step. - With one argument, returns a range [0, end). With two arguments, returns - a range [start, end). With three, returns a range with optional step size.` - [& args] - (case (length args) - 1 (do - (def [n] args) - (def arr (array/new n)) - (forv i 0 n (put arr i i)) - arr) - 2 (do - (def [n m] args) - (def arr (array/new (- m n))) - (forv i n m (put arr (- i n) i)) - arr) - 3 (do - (def [n m s] args) - (cond - (zero? s) @[] - (neg? s) (seq [i :down [n m (- s)]] i) - (seq [i :range [n m s]] i))) - (error "expected 1 to 3 arguments to range"))) - (defn find-index ``Find the index of indexed type for which `pred` is true. Returns `dflt` if not found.`` [pred ind &opt dflt] diff --git a/src/core/corelib.c b/src/core/corelib.c index 56b1d41e..bfcfa181 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -426,6 +426,39 @@ JANET_CORE_FN(janet_core_slice, } } +JANET_CORE_FN(janet_core_range, + "(range & args)", + "Create an array of values [start, end) with a given step. " + "With one argument, returns a range [0, end). With two arguments, returns " + "a range [start, end). With three, returns a range with optional step size.") { + janet_arity(argc, 1, 3); + int32_t start = 0, stop = 0, step = 1, count = 0; + switch (argc) { + case 1: + stop = janet_getinteger(argv, 0); + count = stop; + break; + case 2: + start = janet_getinteger(argv, 0); + stop = janet_getinteger(argv, 1); + count = stop - start; + break; + case 3: + start = janet_getinteger(argv, 0); + stop = janet_getinteger(argv, 1); + step = janet_getinteger(argv, 2); + count = (step > 0) ? (stop - start - 1) / step + 1 : + ((step < 0) ? (stop - start + 1) / step + 1 : 0); + break; + } + JanetArray *array = janet_array(count); + for (int32_t i = 0; i < count; i++) { + array->data[i] = janet_wrap_number(start + i * step); + } + array->count = count; + return janet_wrap_array(array); +} + JANET_CORE_FN(janet_core_table, "(table & kvs)", "Creates a new table from a variadic number of keys and values. " @@ -1024,6 +1057,7 @@ static void janet_load_libs(JanetTable *env) { JANET_CORE_REG("int?", janet_core_check_int), JANET_CORE_REG("nat?", janet_core_check_nat), JANET_CORE_REG("slice", janet_core_slice), + JANET_CORE_REG("range", janet_core_range), JANET_CORE_REG("signal", janet_core_signal), JANET_CORE_REG("memcmp", janet_core_memcmp), JANET_CORE_REG("getproto", janet_core_getproto), From d8b45ecd6104a82ba1b54b0ed3f17f5d14d6156a Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Thu, 3 Aug 2023 20:39:32 +0700 Subject: [PATCH 17/19] better test coverage --- test/suite-boot.janet | 7 ------- test/suite-corelib.janet | 12 ++++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/test/suite-boot.janet b/test/suite-boot.janet index dca18bb9..c907731a 100644 --- a/test/suite-boot.janet +++ b/test/suite-boot.janet @@ -362,14 +362,7 @@ (assert (= false (and false false)) "and 1") (assert (= false (or false false)) "or 1") -# Range -# a982f351d -(assert (deep= (range 10) @[0 1 2 3 4 5 6 7 8 9]) "range 1 argument") -(assert (deep= (range 5 10) @[5 6 7 8 9]) "range 2 arguments") -(assert (deep= (range 5 10 2) @[5 7 9]) "range 3 arguments") # 11cd1279d -(assert (= (length (range 10)) 10) "(range 10)") -(assert (= (length (range 1 10)) 9) "(range 1 10)") (assert (deep= @{:a 1 :b 2 :c 3} (zipcoll '[:a :b :c] '[1 2 3])) "zipcoll") # bc8be266f diff --git a/test/suite-corelib.janet b/test/suite-corelib.janet index 213a33f4..ea03b548 100644 --- a/test/suite-corelib.janet +++ b/test/suite-corelib.janet @@ -159,5 +159,17 @@ (assert-error "invalid offset-a: 1" (memcmp "a" "b" 1 1 0)) (assert-error "invalid offset-b: 1" (memcmp "a" "b" 1 0 1)) +# Range +# a982f351d +(assert (deep= (range 10) @[0 1 2 3 4 5 6 7 8 9]) "(range 10)") +(assert (deep= (range 5 10) @[5 6 7 8 9]) "(range 5 10)") +(assert (deep= (range 0 16 4) @[0 4 8 12]) "(range 0 16 4)") +(assert (deep= (range 0 17 4) @[0 4 8 12 16]) "(range 0 17 4)") +(assert (deep= (range 16 0 -4) @[16 12 8 4]) "(range 16 0 -4)") +(assert (deep= (range 17 0 -4) @[17 13 9 5 1]) "(range 17 0 -4)") + +(assert (= (length (range 10)) 10) "(range 10)") +(assert (= (length (range 1 10)) 9) "(range 1 10)") + (end-suite) From 8a70fb95b54982a181b68fde8a4457b5c9e64e55 Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Thu, 3 Aug 2023 21:48:59 +0700 Subject: [PATCH 18/19] slight refactoring --- src/core/corelib.c | 31 ++++++++++++++----------------- test/suite-corelib.janet | 1 + 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/core/corelib.c b/src/core/corelib.c index bfcfa181..0241f7d1 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -433,24 +433,21 @@ JANET_CORE_FN(janet_core_range, "a range [start, end). With three, returns a range with optional step size.") { janet_arity(argc, 1, 3); int32_t start = 0, stop = 0, step = 1, count = 0; - switch (argc) { - case 1: - stop = janet_getinteger(argv, 0); - count = stop; - break; - case 2: - start = janet_getinteger(argv, 0); - stop = janet_getinteger(argv, 1); - count = stop - start; - break; - case 3: - start = janet_getinteger(argv, 0); - stop = janet_getinteger(argv, 1); - step = janet_getinteger(argv, 2); - count = (step > 0) ? (stop - start - 1) / step + 1 : - ((step < 0) ? (stop - start + 1) / step + 1 : 0); - break; + if (argc == 3) { + start = janet_getinteger(argv, 0); + stop = janet_getinteger(argv, 1); + step = janet_getinteger(argv, 2); + count = (step > 0) ? (stop - start - 1) / step + 1 : + ((step < 0) ? (stop - start + 1) / step + 1 : 0); + } else if (argc == 2) { + start = janet_getinteger(argv, 0); + stop = janet_getinteger(argv, 1); + count = stop - start; + } else { + stop = janet_getinteger(argv, 0); + count = stop; } + count = (count > 0) ? count : 0; JanetArray *array = janet_array(count); for (int32_t i = 0; i < count; i++) { array->data[i] = janet_wrap_number(start + i * step); diff --git a/test/suite-corelib.janet b/test/suite-corelib.janet index ea03b548..5107c555 100644 --- a/test/suite-corelib.janet +++ b/test/suite-corelib.janet @@ -169,6 +169,7 @@ (assert (deep= (range 17 0 -4) @[17 13 9 5 1]) "(range 17 0 -4)") (assert (= (length (range 10)) 10) "(range 10)") +(assert (= (length (range -10)) 0) "(range -10)") (assert (= (length (range 1 10)) 9) "(range 1 10)") (end-suite) From ecc4d80a5ac342422c151a2704ec586a7e2fc3fa Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sat, 5 Aug 2023 18:58:04 -0500 Subject: [PATCH 19/19] Prepare for 1.30.0 release. --- CHANGELOG.md | 2 +- Makefile | 4 ++-- meson.build | 2 +- src/conf/janetconf.h | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1f84cc5..f3877890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog All notable changes to this project will be documented in this file. -## Unreleased - ??? +## 1.30.0 - 2023-08-05 - Change indexing of `array/remove` to start from -1 at the end instead of -2. - Add new string escape sequences `\\a`, `\\b`, `\\?`, and `\\'`. - Fix bug with marshalling channels diff --git a/Makefile b/Makefile index c7140d25..b624cbd5 100644 --- a/Makefile +++ b/Makefile @@ -196,9 +196,9 @@ build/%.bin.o: src/%.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS) Makefile ######################## ifeq ($(UNAME), Darwin) -SONAME=libjanet.1.29.dylib +SONAME=libjanet.1.30.dylib else -SONAME=libjanet.so.1.29 +SONAME=libjanet.so.1.30 endif build/c/shell.c: src/mainclient/shell.c diff --git a/meson.build b/meson.build index f0bcd709..8c3ebf4d 100644 --- a/meson.build +++ b/meson.build @@ -20,7 +20,7 @@ project('janet', 'c', default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'], - version : '1.29.1') + version : '1.30.0') # Global settings janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet') diff --git a/src/conf/janetconf.h b/src/conf/janetconf.h index d4786eb3..36c3fd10 100644 --- a/src/conf/janetconf.h +++ b/src/conf/janetconf.h @@ -4,10 +4,10 @@ #define JANETCONF_H #define JANET_VERSION_MAJOR 1 -#define JANET_VERSION_MINOR 29 -#define JANET_VERSION_PATCH 1 +#define JANET_VERSION_MINOR 30 +#define JANET_VERSION_PATCH 0 #define JANET_VERSION_EXTRA "" -#define JANET_VERSION "1.29.1" +#define JANET_VERSION "1.30.0" /* #define JANET_BUILD "local" */