mirror of
https://github.com/janet-lang/janet
synced 2025-04-28 05:33:18 +00:00
Merge branch 'master' into net
This commit is contained in:
commit
90b3730a0a
@ -1,12 +0,0 @@
|
|||||||
image: freebsd/latest
|
|
||||||
sources:
|
|
||||||
- https://git.sr.ht/~bakpakin/janet
|
|
||||||
packages:
|
|
||||||
- gmake
|
|
||||||
tasks:
|
|
||||||
- build: |
|
|
||||||
cd janet
|
|
||||||
gmake
|
|
||||||
gmake test
|
|
||||||
sudo gmake install
|
|
||||||
gmake test-install
|
|
@ -1,12 +0,0 @@
|
|||||||
image: openbsd/6.5
|
|
||||||
sources:
|
|
||||||
- https://git.sr.ht/~bakpakin/janet
|
|
||||||
packages:
|
|
||||||
- gmake
|
|
||||||
tasks:
|
|
||||||
- build: |
|
|
||||||
cd janet
|
|
||||||
gmake
|
|
||||||
gmake test
|
|
||||||
doas gmake install
|
|
||||||
gmake test-install
|
|
12
.builds/freebsd.yml
Normal file
12
.builds/freebsd.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
image: freebsd/12.x
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~bakpakin/janet
|
||||||
|
packages:
|
||||||
|
- gmake
|
||||||
|
tasks:
|
||||||
|
- build: |
|
||||||
|
cd janet
|
||||||
|
gmake
|
||||||
|
gmake test
|
||||||
|
sudo gmake install
|
||||||
|
gmake test-install
|
12
.builds/openbsd.yml
Normal file
12
.builds/openbsd.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
image: openbsd/latest
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~bakpakin/janet
|
||||||
|
packages:
|
||||||
|
- gmake
|
||||||
|
tasks:
|
||||||
|
- build: |
|
||||||
|
cd janet
|
||||||
|
gmake
|
||||||
|
gmake test
|
||||||
|
doas gmake install
|
||||||
|
gmake test-install
|
@ -2,6 +2,11 @@
|
|||||||
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
|
## Unreleased
|
||||||
|
- Allow `_` in the `match` macro to match anything without creating a binding
|
||||||
|
or doing unification.
|
||||||
|
- Add `:range-to` and `:down-to` verbs in the `loop` macro.
|
||||||
|
- Fix `and` and `or` macros returning nil instead of false in some cases.
|
||||||
|
- Allow matching successfully against nil values in the `match` macro.
|
||||||
- Improve `janet_formatc` and `janet_panicf` formatters to be more like `string/format`.
|
- Improve `janet_formatc` and `janet_panicf` formatters to be more like `string/format`.
|
||||||
This makes it easier to make nice error messages from C.
|
This makes it easier to make nice error messages from C.
|
||||||
- Add `signal`
|
- Add `signal`
|
||||||
@ -12,6 +17,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Correct arity for `marshal`
|
- Correct arity for `marshal`
|
||||||
- Add `flush` and `eflush`
|
- Add `flush` and `eflush`
|
||||||
- Add `prompt` and `return` on top of signal for user friendly delimited continuations.
|
- Add `prompt` and `return` on top of signal for user friendly delimited continuations.
|
||||||
|
- Fix possible segfault with malformed pegs.
|
||||||
|
|
||||||
## 1.7.0 - 2020-02-01
|
## 1.7.0 - 2020-02-01
|
||||||
- Remove `file/fileno` and `file/fdopen`.
|
- Remove `file/fileno` and `file/fdopen`.
|
||||||
|
49
README.md
49
README.md
@ -14,7 +14,7 @@ The language also supports bridging to native code written in C, meta-programmin
|
|||||||
|
|
||||||
There is a repl for trying out the language, as well as the ability
|
There is a repl for trying out the language, as well as the ability
|
||||||
to run script files. This client program is separate from the core runtime, so
|
to run script files. This client program is separate from the core runtime, so
|
||||||
janet could be embedded into other programs. Try janet in your browser at
|
janet can be embedded into other programs. Try janet in your browser at
|
||||||
[https://janet-lang.org](https://janet-lang.org).
|
[https://janet-lang.org](https://janet-lang.org).
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@ -61,7 +61,9 @@ documentation for symbols in the core library. For example,
|
|||||||
Shows documentation for the doc macro.
|
Shows documentation for the doc macro.
|
||||||
|
|
||||||
To get a list of all bindings in the default
|
To get a list of all bindings in the default
|
||||||
environment, use the `(all-bindings)` function.
|
environment, use the `(all-bindings)` function. You
|
||||||
|
can also use the `(doc)` macro with no arguments if you are in the repl
|
||||||
|
to show bound symbols.
|
||||||
|
|
||||||
## Source
|
## Source
|
||||||
|
|
||||||
@ -122,7 +124,7 @@ is maybe more convenient and flexible for integrating into existing pipelines.
|
|||||||
Meson also provides much better IDE integration than Make or batch files, as well as support
|
Meson also provides much better IDE integration than Make or batch files, as well as support
|
||||||
for cross compilation.
|
for cross compilation.
|
||||||
|
|
||||||
For the impatient, building with Meson is as simple as follows. The options provided to
|
For the impatient, building with Meson is as follows. The options provided to
|
||||||
`meson setup` below emulate Janet's Makefile.
|
`meson setup` below emulate Janet's Makefile.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@ -152,7 +154,7 @@ Emacs, and Atom will have syntax packages for the Janet language, though.
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
See [the Introduction](https://janet-lang.org/introduction.html) for more details. If you just want
|
See [the Introduction](https://janet-lang.org/introduction.html) for more details. If you just want
|
||||||
to try out the language, you don't need to install anything. You can also simply move the `janet` executable wherever you want on your system and run it.
|
to try out the language, you don't need to install anything. You can also move the `janet` executable wherever you want on your system and run it.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -163,35 +165,38 @@ If you are looking to explore, you can print a list of all available macros, fun
|
|||||||
by entering the command `(all-bindings)` into the repl.
|
by entering the command `(all-bindings)` into the repl.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./janet
|
$ janet
|
||||||
Janet 0.0.0 alpha Copyright (C) 2017-2018 Calvin Rose
|
Janet 1.7.1-dev-951e10f Copyright (C) 2017-2020 Calvin Rose
|
||||||
janet:1:> (+ 1 2 3)
|
janet:1:> (+ 1 2 3)
|
||||||
6
|
6
|
||||||
janet:2:> (print "Hello, World!")
|
janet:2:> (print "Hello, World!")
|
||||||
Hello, World!
|
Hello, World!
|
||||||
nil
|
nil
|
||||||
janet:3:> (os/exit)
|
janet:3:> (os/exit)
|
||||||
$ ./janet -h
|
$ janet -h
|
||||||
usage: ./janet [options] scripts...
|
usage: build/janet [options] script args...
|
||||||
Options are:
|
Options are:
|
||||||
-h Show this help
|
-h : Show this help
|
||||||
-v Print the version string
|
-v : Print the version string
|
||||||
-s Use raw stdin instead of getline like functionality
|
-s : Use raw stdin instead of getline like functionality
|
||||||
-e Execute a string of janet
|
-e code : Execute a string of janet
|
||||||
-r Enter the repl after running all scripts
|
-r : Enter the repl after running all scripts
|
||||||
-p Keep on executing if there is a top level error (persistent)
|
-p : Keep on executing if there is a top level error (persistent)
|
||||||
-- Stop handling option
|
-q : Hide prompt, logo, and repl output (quiet)
|
||||||
$
|
-k : Compile scripts but do not execute (flycheck)
|
||||||
|
-m syspath : Set system path for loading global modules
|
||||||
|
-c source output : Compile janet source code into an image
|
||||||
|
-n : Disable ANSI color output in the repl
|
||||||
|
-l path : Execute code in a file before running the main script
|
||||||
|
-- : Stop handling options
|
||||||
```
|
```
|
||||||
|
|
||||||
If installed, you can also run `man janet` to get usage information.
|
If installed, you can also run `man janet` and `man jpm` to get usage information.
|
||||||
|
|
||||||
## Embedding
|
## Embedding
|
||||||
|
|
||||||
The C API for Janet is not yet documented but coming soon.
|
Janet can be embedded in a host program very easily. The normal build
|
||||||
|
will create a file `build/janet.c`, which is a single C file
|
||||||
Janet can be embedded in a host program very easily. There is a make target
|
|
||||||
`make amalg` which creates the file `build/janet.c`, which is a single C file
|
|
||||||
that contains all the source to Janet. This file, along with
|
that contains all the source to Janet. This file, along with
|
||||||
`src/include/janet.h` and `src/include/janetconf.h` can dragged into any C
|
`src/include/janet.h` and `src/include/janetconf.h` can dragged into any C
|
||||||
project and compiled into the project. Janet should be compiled with `-std=c99`
|
project and compiled into the project. Janet should be compiled with `-std=c99`
|
||||||
@ -200,6 +205,8 @@ the dynamic linker, `-ldl`, if one wants to be able to load dynamic modules. If
|
|||||||
there is no need for dynamic modules, add the define
|
there is no need for dynamic modules, add the define
|
||||||
`-DJANET_NO_DYNAMIC_MODULES` to the compiler options.
|
`-DJANET_NO_DYNAMIC_MODULES` to the compiler options.
|
||||||
|
|
||||||
|
See the [Embedding Section](https://janet-lang.org/capi/embedding.html) on the website for more information.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
See the examples directory for some example janet code.
|
See the examples directory for some example janet code.
|
||||||
|
@ -244,26 +244,30 @@
|
|||||||
[(,not= :error (,fiber/status ,f)) ,r])))
|
[(,not= :error (,fiber/status ,f)) ,r])))
|
||||||
|
|
||||||
(defmacro and
|
(defmacro and
|
||||||
"Evaluates to the last argument if all preceding elements are true, otherwise
|
"Evaluates to the last argument if all preceding elements are truthy, otherwise
|
||||||
evaluates to false."
|
evaluates to the first falsey argument."
|
||||||
[& forms]
|
[& forms]
|
||||||
(var ret true)
|
(var ret true)
|
||||||
(def len (length forms))
|
(def len (length forms))
|
||||||
(var i len)
|
(var i len)
|
||||||
(while (> i 0)
|
(while (> i 0)
|
||||||
(-- i)
|
(-- i)
|
||||||
|
(def v (in forms i))
|
||||||
(set ret (if (= ret true)
|
(set ret (if (= ret true)
|
||||||
(in forms i)
|
v
|
||||||
(tuple 'if (in forms i) ret))))
|
(if (idempotent? v)
|
||||||
|
['if v ret v]
|
||||||
|
(do (def s (gensym))
|
||||||
|
['if ['def s v] ret s])))))
|
||||||
ret)
|
ret)
|
||||||
|
|
||||||
(defmacro or
|
(defmacro or
|
||||||
"Evaluates to the last argument if all preceding elements are false, otherwise
|
"Evaluates to the last argument if all preceding elements are falsey, otherwise
|
||||||
evaluates to true."
|
evaluates to the first truthy element."
|
||||||
[& forms]
|
[& forms]
|
||||||
(var ret nil)
|
|
||||||
(def len (length forms))
|
(def len (length forms))
|
||||||
(var i len)
|
(var i (- len 1))
|
||||||
|
(var ret (in forms i))
|
||||||
(while (> i 0)
|
(while (> i 0)
|
||||||
(-- i)
|
(-- i)
|
||||||
(def fi (in forms i))
|
(def fi (in forms i))
|
||||||
@ -362,6 +366,16 @@
|
|||||||
,;body
|
,;body
|
||||||
(set ,i (,delta ,i ,step))))))
|
(set ,i (,delta ,i ,step))))))
|
||||||
|
|
||||||
|
(defn- check-indexed [x]
|
||||||
|
(if (indexed? x)
|
||||||
|
x
|
||||||
|
(error (string "expected tuple for range, got " x))))
|
||||||
|
|
||||||
|
(defn- range-template
|
||||||
|
[binding object rest op comparison]
|
||||||
|
(let [[start stop step] (check-indexed object)]
|
||||||
|
(for-template binding start stop (or step 1) comparison op [rest])))
|
||||||
|
|
||||||
(defn- each-template
|
(defn- each-template
|
||||||
[binding inx body]
|
[binding inx body]
|
||||||
(with-syms [k]
|
(with-syms [k]
|
||||||
@ -395,11 +409,6 @@
|
|||||||
(def ,binding ,i)
|
(def ,binding ,i)
|
||||||
,body))))
|
,body))))
|
||||||
|
|
||||||
(defn- check-indexed [x]
|
|
||||||
(if (indexed? x)
|
|
||||||
x
|
|
||||||
(error (string "expected tuple for range, got " x))))
|
|
||||||
|
|
||||||
(defn- loop1
|
(defn- loop1
|
||||||
[body head i]
|
[body head i]
|
||||||
|
|
||||||
@ -429,12 +438,12 @@
|
|||||||
(def {(+ i 2) object} head)
|
(def {(+ i 2) object} head)
|
||||||
(let [rest (loop1 body head (+ i 3))]
|
(let [rest (loop1 body head (+ i 3))]
|
||||||
(case verb
|
(case verb
|
||||||
:range (let [[start stop step] (check-indexed object)]
|
:range (range-template binding object rest + <)
|
||||||
(for-template binding start stop (or step 1) < + [rest]))
|
:range-to (range-template binding object rest + <=)
|
||||||
|
:down (range-template binding object rest - >)
|
||||||
|
:down-to (range-template binding object rest - >=)
|
||||||
:keys (keys-template binding object false [rest])
|
:keys (keys-template binding object false [rest])
|
||||||
:pairs (keys-template binding object true [rest])
|
:pairs (keys-template binding object true [rest])
|
||||||
:down (let [[start stop step] (check-indexed object)]
|
|
||||||
(for-template binding start stop (or step 1) > - [rest]))
|
|
||||||
:in (each-template binding object [rest])
|
:in (each-template binding object [rest])
|
||||||
:iterate (iterate-template binding object rest)
|
:iterate (iterate-template binding object rest)
|
||||||
:generate (with-syms [f s]
|
:generate (with-syms [f s]
|
||||||
@ -477,11 +486,14 @@
|
|||||||
\t:iterate - repeatedly evaluate and bind to the expression while it is truthy.\n
|
\t:iterate - repeatedly evaluate and bind to the expression while it is truthy.\n
|
||||||
\t:range - loop over a range. The object should be two element tuple with a start
|
\t:range - loop over a range. The object should be two element tuple with a start
|
||||||
and end value, and an optional positive step. The range is half open, [start, end).\n
|
and end value, and an optional positive step. The range is half open, [start, end).\n
|
||||||
\t:down - Same as range, but loops in reverse.\n
|
\t:range-to - same as :range, but the range is inclusive [start, end].\n
|
||||||
\t:keys - Iterate over the keys in a data structure.\n
|
\t:down - loop over a range, stepping downwards. The object should be two element tuple
|
||||||
\t:pairs - Iterate over the keys value pairs in a data structure.\n
|
with a start and (exclusive) end value, and an optional (positive!) step size.\n
|
||||||
\t:in - Iterate over the values in an indexed data structure or byte sequence.\n
|
\t:down-to - same :as down, but the range is inclusive [start, end].\n
|
||||||
\t:generate - Iterate over values yielded from a fiber. Can be paired with the generator
|
\t:keys - iterate over the keys in a data structure.\n
|
||||||
|
\t:pairs - iterate over the keys value pairs as tuples in a data structure.\n
|
||||||
|
\t:in - iterate over the values in a data structure.\n
|
||||||
|
\t:generate - iterate over values yielded from a fiber. Can be paired with the generator
|
||||||
function for the producer/consumer pattern.\n\n
|
function for the producer/consumer pattern.\n\n
|
||||||
loop also accepts conditionals to refine the looping further. Conditionals are of
|
loop also accepts conditionals to refine the looping further. Conditionals are of
|
||||||
the form:\n\n
|
the form:\n\n
|
||||||
@ -505,6 +517,7 @@
|
|||||||
(put _env 'iterate-template nil)
|
(put _env 'iterate-template nil)
|
||||||
(put _env 'each-template nil)
|
(put _env 'each-template nil)
|
||||||
(put _env 'keys-template nil)
|
(put _env 'keys-template nil)
|
||||||
|
(put _env 'range-template nil)
|
||||||
|
|
||||||
(defmacro seq
|
(defmacro seq
|
||||||
"Similar to loop, but accumulates the loop body into an array and returns that.
|
"Similar to loop, but accumulates the loop body into an array and returns that.
|
||||||
@ -1276,7 +1289,7 @@
|
|||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defn pp
|
(defn pp
|
||||||
"Pretty print to stdout or (dyn :out)."
|
`Pretty print to stdout or (dyn :out). The format string used is (dyn :pretty-format "%q").`
|
||||||
[x]
|
[x]
|
||||||
(printf (dyn :pretty-format "%q") x)
|
(printf (dyn :pretty-format "%q") x)
|
||||||
(flush))
|
(flush))
|
||||||
@ -1312,6 +1325,9 @@
|
|||||||
[pattern expr onmatch seen]
|
[pattern expr onmatch seen]
|
||||||
(cond
|
(cond
|
||||||
|
|
||||||
|
(= '_ pattern)
|
||||||
|
(onmatch)
|
||||||
|
|
||||||
(symbol? pattern)
|
(symbol? pattern)
|
||||||
(if (in seen pattern)
|
(if (in seen pattern)
|
||||||
~(if (= ,pattern ,expr) ,(onmatch) ,sentinel)
|
~(if (= ,pattern ,expr) ,(onmatch) ,sentinel)
|
||||||
@ -1352,23 +1368,26 @@
|
|||||||
~(if (,dictionary? ,$dict)
|
~(if (,dictionary? ,$dict)
|
||||||
,((fn aux []
|
,((fn aux []
|
||||||
(set key (next pattern key))
|
(set key (next pattern key))
|
||||||
|
(def $val (gensym))
|
||||||
(if (= key nil)
|
(if (= key nil)
|
||||||
(onmatch)
|
(onmatch)
|
||||||
(match-1 [(in pattern key) [not= (in pattern key) nil]] [in $dict key] aux seen))))
|
~(do (def ,$val (,get ,$dict ,key))
|
||||||
|
,(match-1 [(in pattern key) [not= nil $val]] $val aux seen)))))
|
||||||
,sentinel)))
|
,sentinel)))
|
||||||
|
|
||||||
:else ~(if (= ,pattern ,expr) ,(onmatch) ,sentinel)))
|
:else ~(if (= ,pattern ,expr) ,(onmatch) ,sentinel)))
|
||||||
|
|
||||||
(defmacro match
|
(defmacro match
|
||||||
"Pattern matching. Match an expression x against
|
"Pattern matching. Match an expression x against
|
||||||
any number of cases. Easy case is a pattern to match against, followed
|
any number of cases. Each case is a pattern to match against, followed
|
||||||
by an expression to evaluate to if that case is matched. A pattern that is
|
by an expression to evaluate to if that case is matched. A pattern that is
|
||||||
a symbol will match anything, binding x's value to that symbol. An array
|
a symbol will match anything, binding x's value to that symbol. An array
|
||||||
will match only if all of it's elements match the corresponding elements in
|
will match only if all of it's elements match the corresponding elements in
|
||||||
x. A table or struct will match if all values match with the corresponding
|
x. A table or struct will match if all values match with the corresponding
|
||||||
values in x. A tuple pattern will match if it's first element matches, and the following
|
values in x. A tuple pattern will match if it's first element matches, and the following
|
||||||
elements are treated as predicates and are true. Any other value pattern will only
|
elements are treated as predicates and are true. The last special case is
|
||||||
match if it is equal to x."
|
the '_ symbol, which is a wildcard that will match any value without creating a binding.
|
||||||
|
Any other value pattern will only match if it is equal to x."
|
||||||
[x & cases]
|
[x & cases]
|
||||||
(with-idemp $x x
|
(with-idemp $x x
|
||||||
(def len (length cases))
|
(def len (length cases))
|
||||||
|
@ -369,19 +369,23 @@ tail:
|
|||||||
s->mode = oldmode;
|
s->mode = oldmode;
|
||||||
if (!result) return NULL;
|
if (!result) return NULL;
|
||||||
|
|
||||||
Janet cap;
|
Janet cap = janet_wrap_nil();
|
||||||
Janet constant = s->constants[rule[2]];
|
Janet constant = s->constants[rule[2]];
|
||||||
switch (janet_type(constant)) {
|
switch (janet_type(constant)) {
|
||||||
default:
|
default:
|
||||||
cap = constant;
|
cap = constant;
|
||||||
break;
|
break;
|
||||||
case JANET_STRUCT:
|
case JANET_STRUCT:
|
||||||
cap = janet_struct_get(janet_unwrap_struct(constant),
|
if (s->captures->count) {
|
||||||
s->captures->data[s->captures->count - 1]);
|
cap = janet_struct_get(janet_unwrap_struct(constant),
|
||||||
|
s->captures->data[s->captures->count - 1]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case JANET_TABLE:
|
case JANET_TABLE:
|
||||||
cap = janet_table_get(janet_unwrap_table(constant),
|
if (s->captures->count) {
|
||||||
s->captures->data[s->captures->count - 1]);
|
cap = janet_table_get(janet_unwrap_table(constant),
|
||||||
|
s->captures->data[s->captures->count - 1]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case JANET_CFUNCTION:
|
case JANET_CFUNCTION:
|
||||||
cap = janet_unwrap_cfunction(constant)(s->captures->count - cs.cap,
|
cap = janet_unwrap_cfunction(constant)(s->captures->count - cs.cap,
|
||||||
|
@ -765,6 +765,9 @@ static int line() {
|
|||||||
case '.': /* Alt-. */
|
case '.': /* Alt-. */
|
||||||
historymove(-JANET_HISTORY_MAX);
|
historymove(-JANET_HISTORY_MAX);
|
||||||
break;
|
break;
|
||||||
|
case 127: /* Alt-backspace */
|
||||||
|
kbackspacew();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -212,13 +212,17 @@
|
|||||||
|
|
||||||
(assert (= 7 (case :a :b 5 :c 6 :u 10 7)) "case with default")
|
(assert (= 7 (case :a :b 5 :c 6 :u 10 7)) "case with default")
|
||||||
|
|
||||||
# Testing the loop and for macros
|
# Testing the loop and seq macros
|
||||||
(def xs (apply tuple (seq [x :range [0 10] :when (even? x)] (tuple (/ x 2) x))))
|
(def xs (apply tuple (seq [x :range [0 10] :when (even? x)] (tuple (/ x 2) x))))
|
||||||
(assert (= xs '((0 0) (1 2) (2 4) (3 6) (4 8))) "seq macro 1")
|
(assert (= xs '((0 0) (1 2) (2 4) (3 6) (4 8))) "seq macro 1")
|
||||||
|
|
||||||
(def xs (apply tuple (seq [x :down [8 -2] :when (even? x)] (tuple (/ x 2) x))))
|
(def xs (apply tuple (seq [x :down [8 -2] :when (even? x)] (tuple (/ x 2) x))))
|
||||||
(assert (= xs '((4 8) (3 6) (2 4) (1 2) (0 0))) "seq macro 2")
|
(assert (= xs '((4 8) (3 6) (2 4) (1 2) (0 0))) "seq macro 2")
|
||||||
|
|
||||||
|
# :range-to and :down-to
|
||||||
|
(assert (deep= (seq [x :range-to [0 10]] x) (seq [x :range [0 11]] x)) "loop :range-to")
|
||||||
|
(assert (deep= (seq [x :down-to [10 0]] x) (seq [x :down [10 -1]] x)) "loop :down-to")
|
||||||
|
|
||||||
# Some testing for not=
|
# Some testing for not=
|
||||||
(assert (not= 1 1 0) "not= 1")
|
(assert (not= 1 1 0) "not= 1")
|
||||||
(assert (not= 0 1 1) "not= 2")
|
(assert (not= 0 1 1) "not= 2")
|
||||||
|
@ -107,4 +107,23 @@
|
|||||||
(assert (= nil (match [1 2] [a b c] a)) "match 4")
|
(assert (= nil (match [1 2] [a b c] a)) "match 4")
|
||||||
(assert (= 2 (match [1 2] [a b] b)) "match 5")
|
(assert (= 2 (match [1 2] [a b] b)) "match 5")
|
||||||
|
|
||||||
|
# And/or checks
|
||||||
|
|
||||||
|
(assert (= false (and false false)) "and 1")
|
||||||
|
(assert (= false (or false false)) "or 1")
|
||||||
|
|
||||||
|
# #300 Regression test
|
||||||
|
|
||||||
|
# Just don't segfault
|
||||||
|
(assert (peg/match '{:main (replace "S" {"S" :spade})} "S7") "regression #300")
|
||||||
|
|
||||||
|
# Test cases for #293
|
||||||
|
(assert (= :yes (match [1 2 3] [_ a _] :yes :no)) "match wildcard 1")
|
||||||
|
(assert (= :no (match [1 2 3] [__ a __] :yes :no)) "match wildcard 2")
|
||||||
|
(assert (= :yes (match [1 2 [1 2 3]] [_ a [_ _ _]] :yes :no)) "match wildcard 3")
|
||||||
|
(assert (= :yes (match [1 2 3] (_ (even? 2)) :yes :no)) "match wildcard 4")
|
||||||
|
(assert (= :yes (match {:a 1} {:a _} :yes :no)) "match wildcard 5")
|
||||||
|
(assert (= false (match {:a 1 :b 2 :c 3} {:a a :b _ :c _ :d _} :no {:a _ :b _ :c _} false :no)) "match wildcard 6")
|
||||||
|
(assert (= nil (match {:a 1 :b 2 :c 3} {:a a :b _ :c _ :d _} :no {:a _ :b _ :c _} nil :no)) "match wildcard 7")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user