1
0
mirror of https://github.com/janet-lang/janet synced 2026-04-19 13:21:26 +00:00

Compare commits

...

50 Commits

Author SHA1 Message Date
Calvin Rose
60078e7950 Change os/execute implementation for windows. 2021-02-14 11:04:59 -06:00
Calvin Rose
69095fbb48 Merge pull request #633 from Alligator/master
Add missing argument to errorf in jpm
2021-02-10 17:51:47 -06:00
alligator
c88a3c64e3 Add missing argument to errorf 2021-02-10 22:45:43 +00:00
Calvin Rose
771b0d0ab1 Version bump. 2021-02-09 20:32:09 -06:00
Calvin Rose
c85310578b Merge pull request #632 from sogaiu/tweak-spec-readint
Tweak spec_readint
2021-02-09 17:47:25 -06:00
sogaiu
60e2992158 Tweak spec_readint 2021-02-10 08:33:46 +09:00
Calvin Rose
2795e8a8b7 Update some sr.ht configs. 2021-02-08 18:26:04 -06:00
Calvin Rose
bdf14170a4 Get ready for 1.15.0 release. 2021-02-08 18:10:46 -06:00
Calvin Rose
10dcbc639a Immediate instuctions will now call :compare method. 2021-02-08 11:53:25 -06:00
Calvin Rose
6a9bb0f4e4 Define immediate comparison instructions for non-integers.
Previous, the instructions were defined only for values that
fit into 32 bit integers for legacy reasons.
2021-02-08 11:41:48 -06:00
Calvin Rose
c941e5a8f4 Merge pull request #628 from yumaikas/master
Switch out `by` to `before?` in sort functions.
2021-02-05 18:17:52 -06:00
Calvin Rose
be91414c7a Improve error message from janet_call.
List expected arity in error messages.
2021-02-05 18:01:52 -06:00
Calvin Rose
6839b603c8 x86 32 bit on windows. 2021-02-04 23:31:04 -06:00
Andrew Owen
926b68d62e Switch out by to before? in sort functions.
Makes docstrings easier to read, and reduces confusion with sorted-by
and sort-by.
2021-02-04 22:28:46 -07:00
Calvin Rose
d374e90033 Update sort documentation. 2021-02-04 20:11:24 -06:00
Calvin Rose
b168b0758a Fix #625 - no fancy mixing in number hasing
Just hash upper 32 bits with lower 32 bits. Trying to get too fancy
was causing slowdowns in very trivial cases. Assuming that all
combinations of 64 bits in a double are equally likely (suspect but
probably not that incorrect), the obvious method of xoring the top
32 bits with the lower 32 bits gives a uniform distribution.
2021-02-04 19:37:11 -06:00
Calvin Rose
54c66ecfc0 Merge pull request #622 from sogaiu/tweak-add-paths-docstring
Tweak module/add-paths docstring
2021-02-04 19:05:34 -06:00
sogaiu
1c158bd4ff Tweak module/add-paths docstring 2021-02-03 21:11:16 +09:00
Calvin Rose
ff24143f54 Merge pull request #620 from sogaiu/marshal-doc
Tweak marshal docstring
2021-02-02 21:29:54 -06:00
Calvin Rose
dd117e81c2 Fix parser/insert.
We need to add the tuple wrapping code there as well.
2021-02-02 18:55:24 -06:00
sogaiu
f4744a18c6 Tweak marshal docstring 2021-02-02 15:00:57 +09:00
Calvin Rose
259d5fabd9 Update Makefile and build_win for better builds.
Use build/c/janet.c in both to prevent accidental inclusion
of build/janet.h (which may be stale) instead of the source headers.
2021-01-31 09:59:53 -06:00
Calvin Rose
d122a75efd Cleanup boot.janet to be more like normal source code.
Don't use `undef`, just use private defines.
2021-01-31 09:08:39 -06:00
Calvin Rose
c9ea3ac304 Address #618 - clarify file/open docs. 2021-01-31 08:39:57 -06:00
Calvin Rose
c63fe6ef8a Make flycheck follow GNU standards for errors. 2021-01-30 12:51:38 -06:00
Calvin Rose
72ec89dfe9 Change output format for line+col. 2021-01-30 11:33:15 -06:00
Calvin Rose
04805d106e Simpler overflow check. 2021-01-29 20:11:38 -06:00
Calvin Rose
9aed578466 Address #616 Buffer extra overflow bug.
We should have a normal error instead of undefined behavior, wrap
around, or wait for realloc to fail.
2021-01-29 18:32:54 -06:00
Calvin Rose
77c5279296 Merge pull request #611 from subsetpark/doc-example-readme
Use a slightly clearer example of the `doc` fun in README
2021-01-24 17:25:37 -06:00
Calvin Rose
af75bf3b64 Update for sending streams to new threads. 2021-01-24 16:48:46 -06:00
Zach Smith
a5157e868b Use a slightly clearer example of the doc fun in README 2021-01-24 15:44:34 -05:00
Calvin Rose
01a3d8f932 Address #478 - Disable core in static binaries/
Add --no-core option to quickbin, as well as :no-core option
to declare executable. This doesn't use the autodetection when
making binaries, instead opting for manual intervention.
2021-01-23 17:47:41 -06:00
Calvin Rose
f22472a644 Begin work on allowing small binaries. 2021-01-23 17:08:11 -06:00
Calvin Rose
5cac8bcf9f Prepare for patch release. 2021-01-23 14:48:36 -06:00
Calvin Rose
a2801fbef9 Fix #610 - POLLHUP should cause us to continue reading. 2021-01-23 14:26:24 -06:00
Calvin Rose
0b14e913da Merge branch 'master' of github.com:janet-lang/janet 2021-01-23 13:54:36 -06:00
Calvin Rose
85155bb2b4 Reference #478 Update peg/compile to use dyn for default grammar. 2021-01-23 13:54:02 -06:00
Calvin Rose
dd8de1e9ac Merge pull request #609 from yumaikas/master
Change tracev to upscope instead of using let
2021-01-22 19:02:27 -06:00
Calvin Rose
c909835b0a Update CHANGELOG. 2021-01-22 12:55:38 -06:00
Calvin Rose
a18aafedfd Merge branch 'master' of github.com:janet-lang/janet 2021-01-22 12:53:28 -06:00
Calvin Rose
317ab6df6b Add ev/thread and ev/do-thread.
- Also fix setting supervisor with net/accept-loop.
2021-01-22 12:52:45 -06:00
Andrew Owen
1fcaffe6b0 Change tracev to upscope, add test 2021-01-21 23:40:28 -07:00
Calvin Rose
3ae5c410dc Merge pull request #606 from snimmagadda/master
Replace malloc + memset with calloc.
2021-01-21 12:59:21 -06:00
Sunil Nimmagadda
381128364e Replace malloc + memset with calloc.
Fixes an overflow warning from gcc with '-Wstringop-overflow' on
NetBSD-current.
2021-01-21 19:35:57 +05:30
Calvin Rose
0acf167e84 Merge pull request #602 from pyrmont/feature.module-docstrings
Display module-level docstrings with (doc)
2021-01-20 22:11:38 -06:00
Calvin Rose
f7ca6deeb0 Merge pull request #603 from pepe/evcal-doc
Fix ev/call doc
2021-01-20 20:52:23 -06:00
Josef Pospíšil
251486e4aa Fix ev/call doc 2021-01-20 20:31:41 +01:00
Michael Camilleri
c6467be60d Conform display of path with existing display of source map info 2021-01-20 10:47:55 +09:00
Michael Camilleri
4dd512ad28 Use print-module-entry function to display docstring 2021-01-20 10:16:59 +09:00
Michael Camilleri
28076b9385 Display module-level docstrings with (doc) 2021-01-20 10:01:31 +09:00
30 changed files with 1351 additions and 1115 deletions

View File

@@ -4,12 +4,20 @@ sources:
packages: packages:
- meson - meson
tasks: tasks:
- build: | - with-epoll: |
cd janet cd janet
meson setup build --buildtype=release meson setup with-epoll --buildtype=release
cd build cd with-epoll
meson configure -Depoll=true
ninja
ninja test
- no-epoll: |
cd janet
meson setup no-epoll --buildtype=release
cd no-epoll
meson configure -Depoll=false meson configure -Depoll=false
ninja ninja
ninja test ninja test
sudo ninja install sudo ninja install
sudo jpm --verbose install circlet sudo jpm --verbose install circlet
sudo jpm --verbose install spork

3
.gitignore vendored
View File

@@ -140,3 +140,6 @@ compile_commands.json
CTestTestfile.cmake CTestTestfile.cmake
# End of https://www.gitignore.io/api/cmake # End of https://www.gitignore.io/api/cmake
# Astyle
*.orig

View File

@@ -1,6 +1,29 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## Unreleased - ???
- Fix documentation typos
- Fix peg integer reading combinators when used with capture tags.
## 1.15.0 - 2021-02-08
- Fix `gtim` and `ltim` bytecode instructions on non-integer values.
- Clean up output of flychecking to be the same as the repl.
- Change behavior of `debug/stacktrace` with a nil error value.
- Add optional argument to `parser/produce`.
- Add `no-core` option to creating standalone binaries to make execution faster.
- Fix bug where a buffer overflow could be confused with an out of memory error.
- Change error output to `file:line:column: message`. Column is in bytes - tabs
are considered to have width 1 (instead of 8).
## 1.14.2 - 2021-01-23
- Allow `JANET_PROFILE` env variable to load a profile before loading the repl.
- Update `tracev` macro to allow `def` and `var` inside to work as expected.
- Use `(dyn :peg-grammar)` for passing a default grammar to `peg/compile` instead of loading
`default-peg-grammar` directly from the root environment.
- Add `ev/thread` for combining threading with the event loop.
- Add `ev/do-thread` to make `ev/thread` easier to use.
- Automatically set supervisor channel in `net/accept-loop` and `net/server` correctly.
## 1.14.1 - 2021-01-18 ## 1.14.1 - 2021-01-18
- Add `doc-of` for reverse documentation lookup. - Add `doc-of` for reverse documentation lookup.
- Add `ev/give-supervsior` to send a message to the supervising channel. - Add `ev/give-supervsior` to send a message to the supervising channel.

View File

@@ -66,7 +66,7 @@ ifeq ($(UNAME), Haiku)
LDFLAGS=-Wl,--export-dynamic LDFLAGS=-Wl,--export-dynamic
endif endif
$(shell mkdir -p build/core build/mainclient build/webclient build/boot) $(shell mkdir -p build/core build/c build/boot)
all: $(JANET_TARGET) $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY) build/janet.h all: $(JANET_TARGET) $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY) build/janet.h
###################### ######################
@@ -149,7 +149,7 @@ build/janet_boot: $(JANET_BOOT_OBJECTS)
$(CC) $(BOOT_CFLAGS) -o $@ $(JANET_BOOT_OBJECTS) $(CLIBS) $(CC) $(BOOT_CFLAGS) -o $@ $(JANET_BOOT_OBJECTS) $(CLIBS)
# Now the reason we bootstrap in the first place # Now the reason we bootstrap in the first place
build/janet.c: build/janet_boot src/boot/boot.janet build/c/janet.c: build/janet_boot src/boot/boot.janet
build/janet_boot . JANET_PATH '$(JANET_PATH)' > $@ build/janet_boot . JANET_PATH '$(JANET_PATH)' > $@
cksum $@ cksum $@
@@ -157,9 +157,9 @@ build/janet.c: build/janet_boot src/boot/boot.janet
##### Amalgamation ##### ##### Amalgamation #####
######################## ########################
SONAME=libjanet.so.1.14 SONAME=libjanet.so.1.15
build/shell.c: src/mainclient/shell.c build/c/shell.c: src/mainclient/shell.c
cp $< $@ cp $< $@
build/janet.h: $(JANET_TARGET) src/include/janet.h src/conf/janetconf.h build/janet.h: $(JANET_TARGET) src/include/janet.h src/conf/janetconf.h
@@ -168,11 +168,11 @@ build/janet.h: $(JANET_TARGET) src/include/janet.h src/conf/janetconf.h
build/janetconf.h: src/conf/janetconf.h build/janetconf.h: src/conf/janetconf.h
cp $< $@ cp $< $@
build/janet.o: build/janet.c src/include/janet.h src/conf/janetconf.h build/janet.o: build/c/janet.c src/conf/janetconf.h src/include/janet.h
$(HOSTCC) $(BUILD_CFLAGS) -c $< -o $@ -I build $(HOSTCC) $(BUILD_CFLAGS) -c $< -o $@
build/shell.o: build/shell.c src/include/janet.h src/conf/janetconf.h build/shell.o: build/c/shell.c src/conf/janetconf.h src/include/janet.h
$(HOSTCC) $(BUILD_CFLAGS) -c $< -o $@ -I build $(HOSTCC) $(BUILD_CFLAGS) -c $< -o $@
$(JANET_TARGET): build/janet.o build/shell.o $(JANET_TARGET): build/janet.o build/shell.o
$(HOSTCC) $(LDFLAGS) $(BUILD_CFLAGS) -o $@ $^ $(CLIBS) $(HOSTCC) $(LDFLAGS) $(BUILD_CFLAGS) -o $@ $^ $(CLIBS)
@@ -224,7 +224,7 @@ dist: build/janet-dist.tar.gz
build/janet-%.tar.gz: $(JANET_TARGET) \ build/janet-%.tar.gz: $(JANET_TARGET) \
build/janet.h \ build/janet.h \
jpm.1 janet.1 LICENSE CONTRIBUTING.md $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY) \ jpm.1 janet.1 LICENSE CONTRIBUTING.md $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY) \
build/doc.html README.md build/janet.c build/shell.c jpm build/doc.html README.md build/c/janet.c build/c/shell.c jpm
$(eval JANET_DIST_DIR = "janet-$(shell basename $*)") $(eval JANET_DIST_DIR = "janet-$(shell basename $*)")
mkdir -p build/$(JANET_DIST_DIR) mkdir -p build/$(JANET_DIST_DIR)
cp -r $^ build/$(JANET_DIST_DIR)/ cp -r $^ build/$(JANET_DIST_DIR)/

View File

@@ -58,9 +58,9 @@ Documentation is also available locally in the REPL.
Use the `(doc symbol-name)` macro to get API Use the `(doc symbol-name)` macro to get API
documentation for symbols in the core library. For example, documentation for symbols in the core library. For example,
``` ```
(doc doc) (doc apply)
``` ```
Shows documentation for the doc macro. Shows documentation for the `apply` function.
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. You environment, use the `(all-bindings)` function. You

View File

@@ -30,7 +30,7 @@ if not "%JANET_BUILD%" == "" (
if not exist build mkdir build if not exist build mkdir build
if not exist build\core mkdir build\core if not exist build\core mkdir build\core
if not exist build\mainclient mkdir build\mainclient if not exist build\c mkdir build\c
if not exist build\boot mkdir build\boot if not exist build\boot mkdir build\boot
@rem Build the bootstrap interpreter @rem Build the bootstrap interpreter
@@ -44,10 +44,10 @@ for %%f in (src\boot\*.c) do (
) )
%JANET_LINK% /out:build\janet_boot.exe build\boot\*.obj %JANET_LINK% /out:build\janet_boot.exe build\boot\*.obj
@if errorlevel 1 goto :BUILDFAIL @if errorlevel 1 goto :BUILDFAIL
build\janet_boot . > build\janet.c build\janet_boot . > build\c\janet.c
@rem Build the sources @rem Build the sources
%JANET_COMPILE% /Fobuild\janet.obj build\janet.c %JANET_COMPILE% /Fobuild\janet.obj build\c\janet.c
@if errorlevel 1 goto :BUILDFAIL @if errorlevel 1 goto :BUILDFAIL
%JANET_COMPILE% /Fobuild\shell.obj src\mainclient\shell.c %JANET_COMPILE% /Fobuild\shell.obj src\mainclient\shell.c
@if errorlevel 1 goto :BUILDFAIL @if errorlevel 1 goto :BUILDFAIL
@@ -102,9 +102,9 @@ exit /b 0
mkdir dist mkdir dist
janet.exe tools\gendoc.janet > dist\doc.html janet.exe tools\gendoc.janet > dist\doc.html
janet.exe tools\removecr.janet dist\doc.html janet.exe tools\removecr.janet dist\doc.html
janet.exe tools\removecr.janet build\janet.c janet.exe tools\removecr.janet build\c\janet.c
copy build\janet.c dist\janet.c copy build\c\janet.c dist\janet.c
copy src\mainclient\shell.c dist\shell.c copy src\mainclient\shell.c dist\shell.c
copy janet.exe dist\janet.exe copy janet.exe dist\janet.exe
copy LICENSE dist\LICENSE copy LICENSE dist\LICENSE

55
jpm
View File

@@ -602,7 +602,7 @@
(string (string/slice path 0 (- -1 (length modext))) statext)) (string (string/slice path 0 (- -1 (length modext))) statext))
(defn- make-bin-source (defn- make-bin-source
[declarations lookup-into-invocations] [declarations lookup-into-invocations no-core]
(string (string
declarations declarations
``` ```
@@ -627,15 +627,22 @@ int main(int argc, const char **argv) {
janet_init(); janet_init();
```
(if no-core
```
/* Get core env */
JanetTable *env = janet_table(8);
JanetTable *lookup = janet_core_lookup_table(NULL);
JanetTable *temptab;
int handle = janet_gclock();
```
```
/* Get core env */ /* Get core env */
JanetTable *env = janet_core_env(NULL); JanetTable *env = janet_core_env(NULL);
JanetTable *lookup = janet_env_lookup(env); JanetTable *lookup = janet_env_lookup(env);
JanetTable *temptab; JanetTable *temptab;
int handle = janet_gclock(); int handle = janet_gclock();
```)
/* Load natives into unmarshalling dictionary */
```
lookup-into-invocations lookup-into-invocations
``` ```
/* Unmarshal bytecode */ /* Unmarshal bytecode */
@@ -663,7 +670,6 @@ int main(int argc, const char **argv) {
} }
/* Create enviornment */ /* Create enviornment */
temptab = janet_table(0);
temptab = env; temptab = env;
janet_table_put(temptab, janet_ckeywordv("args"), janet_wrap_array(args)); janet_table_put(temptab, janet_ckeywordv("args"), janet_wrap_array(args));
janet_gcroot(janet_wrap_table(temptab)); janet_gcroot(janet_wrap_table(temptab));
@@ -674,6 +680,14 @@ int main(int argc, const char **argv) {
/* Run everything */ /* Run everything */
JanetFiber *fiber = janet_fiber(jfunc, 64, argc, argc ? args->data : NULL); JanetFiber *fiber = janet_fiber(jfunc, 64, argc, argc ? args->data : NULL);
fiber->env = temptab; fiber->env = temptab;
#ifdef JANET_EV
janet_gcroot(janet_wrap_fiber(fiber));
janet_schedule(fiber, janet_wrap_nil());
janet_loop();
int status = janet_fiber_status(fiber);
janet_deinit();
return status;
#else
Janet out; Janet out;
JanetSignal result = janet_continue(fiber, janet_wrap_nil(), &out); JanetSignal result = janet_continue(fiber, janet_wrap_nil(), &out);
if (result != JANET_SIGNAL_OK && result != JANET_SIGNAL_EVENT) { if (result != JANET_SIGNAL_OK && result != JANET_SIGNAL_EVENT) {
@@ -681,11 +695,9 @@ int main(int argc, const char **argv) {
janet_deinit(); janet_deinit();
return result; return result;
} }
#ifdef JANET_NET
janet_loop();
#endif
janet_deinit(); janet_deinit();
return 0; return 0;
#endif
} }
```)) ```))
@@ -694,7 +706,7 @@ int main(int argc, const char **argv) {
"Links an image with libjanet.a (or .lib) to produce an "Links an image with libjanet.a (or .lib) to produce an
executable. Also will try to link native modules into the executable. Also will try to link native modules into the
final executable as well." final executable as well."
[opts source dest] [opts source dest no-core]
# Create executable's janet image # Create executable's janet image
(def cimage_dest (string dest ".c")) (def cimage_dest (string dest ".c"))
@@ -710,7 +722,16 @@ int main(int argc, const char **argv) {
(def dep-ldflags @[]) (def dep-ldflags @[])
# Create marshalling dictionary # Create marshalling dictionary
(def mdict (invert (env-lookup root-env))) (def mdict1 (invert (env-lookup root-env)))
(def mdict
(if no-core
(let [temp @{}]
(eachp [k v] mdict1
(if (or (cfunction? k) (abstract? k))
(put temp k v)))
temp)
mdict1))
# Load all native modules # Load all native modules
(def prefixes @{}) (def prefixes @{})
(def static-libs @[]) (def static-libs @[])
@@ -755,7 +776,7 @@ int main(int argc, const char **argv) {
# Make image byte buffer # Make image byte buffer
(create-buffer-c-impl image cimage_dest "janet_payload_image") (create-buffer-c-impl image cimage_dest "janet_payload_image")
# Append main function # Append main function
(spit cimage_dest (make-bin-source declarations lookup-into-invocations) :ab) (spit cimage_dest (make-bin-source declarations lookup-into-invocations no-core) :ab)
(def oimage_dest (out-path cimage_dest ".c" ".o")) (def oimage_dest (out-path cimage_dest ".c" ".o"))
# Compile and link final exectable # Compile and link final exectable
(unless no-compile (unless no-compile
@@ -959,7 +980,7 @@ int main(int argc, const char **argv) {
(let [op (out-path src ".c" objext)] (let [op (out-path src ".c" objext)]
(compile-c opts src op) (compile-c opts src op)
op) op)
(errorf "unknown source file type: %s, expected .c or .cpp")))) (errorf "unknown source file type: %s, expected .c or .cpp" src))))
(when-let [embedded (opts :embedded)] (when-let [embedded (opts :embedded)]
(loop [src :in embedded] (loop [src :in embedded]
@@ -1044,10 +1065,10 @@ int main(int argc, const char **argv) {
This executable can be installed as well to the --binpath given." This executable can be installed as well to the --binpath given."
[&keys {:install install :name name :entry entry :headers headers [&keys {:install install :name name :entry entry :headers headers
:cflags cflags :lflags lflags :deps deps :ldflags ldflags :cflags cflags :lflags lflags :deps deps :ldflags ldflags
:no-compile no-compile}] :no-compile no-compile :no-core no-core}]
(def name (if is-win (string name ".exe") name)) (def name (if is-win (string name ".exe") name))
(def dest (string "build" sep name)) (def dest (string "build" sep name))
(create-executable @{:cflags cflags :lflags lflags :ldflags ldflags :no-compile no-compile} entry dest) (create-executable @{:cflags cflags :lflags lflags :ldflags ldflags :no-compile no-compile} entry dest no-core)
(if no-compile (if no-compile
(let [cdest (string dest ".c")] (let [cdest (string dest ".c")]
(add-dep "build" cdest)) (add-dep "build" cdest))
@@ -1354,7 +1375,9 @@ Flags are:
(defn quickbin (defn quickbin
[input output] [input output]
(create-executable @{} input output) (if (= (os/stat output :mode) :file)
(print "output " output " exists."))
(create-executable @{:no-compile (dyn :no-compile)} input output (dyn :no-core))
(do-rule output)) (do-rule output))
(defn jpm-debug-repl (defn jpm-debug-repl

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,10 @@
#define JANETCONF_H #define JANETCONF_H
#define JANET_VERSION_MAJOR 1 #define JANET_VERSION_MAJOR 1
#define JANET_VERSION_MINOR 14 #define JANET_VERSION_MINOR 15
#define JANET_VERSION_PATCH 1 #define JANET_VERSION_PATCH 1
#define JANET_VERSION_EXTRA "" #define JANET_VERSION_EXTRA "-dev"
#define JANET_VERSION "1.14.1" #define JANET_VERSION "1.15.1-dev"
/* #define JANET_BUILD "local" */ /* #define JANET_BUILD "local" */

View File

@@ -91,7 +91,7 @@ void janet_buffer_extra(JanetBuffer *buffer, int32_t n) {
} }
int32_t new_size = buffer->count + n; int32_t new_size = buffer->count + n;
if (new_size > buffer->capacity) { if (new_size > buffer->capacity) {
int32_t new_capacity = new_size * 2; int32_t new_capacity = (new_size > (INT32_MAX / 2)) ? INT32_MAX : (new_size * 2);
uint8_t *new_data = realloc(buffer->data, new_capacity * sizeof(uint8_t)); uint8_t *new_data = realloc(buffer->data, new_capacity * sizeof(uint8_t));
janet_gcpressure(new_capacity - buffer->capacity); janet_gcpressure(new_capacity - buffer->capacity);
if (NULL == new_data) { if (NULL == new_data) {

View File

@@ -53,7 +53,9 @@ JANET_NO_RETURN static void janet_top_level_signal(const char *msg) {
void janet_signalv(JanetSignal sig, Janet message) { void janet_signalv(JanetSignal sig, Janet message) {
if (janet_vm_return_reg != NULL) { if (janet_vm_return_reg != NULL) {
*janet_vm_return_reg = message; *janet_vm_return_reg = message;
janet_vm_fiber->flags |= JANET_FIBER_DID_LONGJUMP; if (NULL != janet_vm_fiber) {
janet_vm_fiber->flags |= JANET_FIBER_DID_LONGJUMP;
}
#if defined(JANET_BSD) || defined(JANET_APPLE) #if defined(JANET_BSD) || defined(JANET_APPLE)
_longjmp(*janet_vm_jmp_buf, sig); _longjmp(*janet_vm_jmp_buf, sig);
#else #else

View File

@@ -872,8 +872,12 @@ static Janet cfun(int32_t argc, Janet *argv) {
} else { } else {
JanetTable *t = janet_table(4); JanetTable *t = janet_table(4);
janet_table_put(t, janet_ckeywordv("error"), janet_wrap_string(res.error)); janet_table_put(t, janet_ckeywordv("error"), janet_wrap_string(res.error));
janet_table_put(t, janet_ckeywordv("line"), janet_wrap_integer(res.error_mapping.line)); if (res.error_mapping.line > 0) {
janet_table_put(t, janet_ckeywordv("column"), janet_wrap_integer(res.error_mapping.column)); janet_table_put(t, janet_ckeywordv("line"), janet_wrap_integer(res.error_mapping.line));
}
if (res.error_mapping.column > 0) {
janet_table_put(t, janet_ckeywordv("column"), janet_wrap_integer(res.error_mapping.column));
}
if (res.macrofiber) { if (res.macrofiber) {
janet_table_put(t, janet_ckeywordv("fiber"), janet_wrap_fiber(res.macrofiber)); janet_table_put(t, janet_ckeywordv("fiber"), janet_wrap_fiber(res.macrofiber));
} }

View File

@@ -1206,7 +1206,8 @@ JanetTable *janet_core_env(JanetTable *replacements) {
"if native modules are compatible with the host program.")); "if native modules are compatible with the host program."));
/* Allow references to the environment */ /* Allow references to the environment */
janet_def(env, "_env", janet_wrap_table(env), JDOC("The environment table for the current scope.")); janet_def(env, "root-env", janet_wrap_table(env),
JDOC("The root environment used to create environments with (make-env)."));
janet_load_libs(env); janet_load_libs(env);
janet_gcroot(janet_wrap_table(env)); janet_gcroot(janet_wrap_table(env));
@@ -1221,22 +1222,7 @@ JanetTable *janet_core_env(JanetTable *replacements) {
return janet_vm_core_env; return janet_vm_core_env;
} }
/* Load core cfunctions (and some built in janet assembly functions) */ JanetTable *dict = janet_core_lookup_table(replacements);
JanetTable *dict = janet_table(512);
janet_load_libs(dict);
/* Add replacements */
if (replacements != NULL) {
for (int32_t i = 0; i < replacements->capacity; i++) {
JanetKV kv = replacements->data[i];
if (!janet_checktype(kv.key, JANET_NIL)) {
janet_table_put(dict, kv.key, kv.value);
if (janet_checktype(kv.value, JANET_CFUNCTION)) {
janet_table_put(janet_vm_registry, kv.value, kv.key);
}
}
}
}
/* Unmarshal bytecode */ /* Unmarshal bytecode */
Janet marsh_out = janet_unmarshal( Janet marsh_out = janet_unmarshal(
@@ -1270,3 +1256,23 @@ JanetTable *janet_core_env(JanetTable *replacements) {
} }
#endif #endif
JanetTable *janet_core_lookup_table(JanetTable *replacements) {
JanetTable *dict = janet_table(512);
janet_load_libs(dict);
/* Add replacements */
if (replacements != NULL) {
for (int32_t i = 0; i < replacements->capacity; i++) {
JanetKV kv = replacements->data[i];
if (!janet_checktype(kv.key, JANET_NIL)) {
janet_table_put(dict, kv.key, kv.value);
if (janet_checktype(kv.value, JANET_CFUNCTION)) {
janet_table_put(janet_vm_registry, kv.value, kv.key);
}
}
}
}
return dict;
}

View File

@@ -102,7 +102,9 @@ void janet_stacktrace(JanetFiber *fiber, Janet err) {
int32_t fi; int32_t fi;
const char *errstr = (const char *)janet_to_string(err); const char *errstr = (const char *)janet_to_string(err);
JanetFiber **fibers = NULL; JanetFiber **fibers = NULL;
int wrote_error = 0;
/* Don't print error line if it is nil. */
int wrote_error = janet_checktype(err, JANET_NIL);
int print_color = janet_truthy(janet_dyn("err-color")); int print_color = janet_truthy(janet_dyn("err-color"));
if (print_color) janet_eprintf("\x1b[31m"); if (print_color) janet_eprintf("\x1b[31m");
@@ -302,7 +304,6 @@ static Janet cfun_debug_stacktrace(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2); janet_arity(argc, 1, 2);
JanetFiber *fiber = janet_getfiber(argv, 0); JanetFiber *fiber = janet_getfiber(argv, 0);
Janet x = argc == 1 ? janet_wrap_nil() : argv[1]; Janet x = argc == 1 ? janet_wrap_nil() : argv[1];
x = janet_checktype(x, JANET_NIL) ? fiber->last_value : x;
janet_stacktrace(fiber, x); janet_stacktrace(fiber, x);
return argv[0]; return argv[0];
} }
@@ -382,7 +383,7 @@ static const JanetReg debug_cfuns[] = {
JDOC("(debug/stacktrace fiber &opt err)\n\n" JDOC("(debug/stacktrace fiber &opt err)\n\n"
"Prints a nice looking stacktrace for a fiber. Can optionally provide " "Prints a nice looking stacktrace for a fiber. Can optionally provide "
"an error value to print the stack trace with. If `err` is nil or not " "an error value to print the stack trace with. If `err` is nil or not "
"provided, will default to `(fiber/last-value fiber)`. Returns the fiber.") "provided, will skipp the error line. Returns the fiber.")
}, },
{ {
"debug/lineage", cfun_debug_lineage, "debug/lineage", cfun_debug_lineage,

View File

@@ -393,7 +393,20 @@ static void janet_stream_marshal(void *p, JanetMarshalContext *ctx) {
* while in transit, and it's value gets reused. DuplicateHandle does not work * while in transit, and it's value gets reused. DuplicateHandle does not work
* for network sockets, and in general for winsock it is better to nipt duplicate * for network sockets, and in general for winsock it is better to nipt duplicate
* unless there is a need to. */ * unless there is a need to. */
janet_marshal_int64(ctx, (int64_t)(s->handle)); HANDLE duph = INVALID_HANDLE_VALUE;
if (s->flags & JANET_STREAM_SOCKET) {
duph = s->handle;
} else {
DuplicateHandle(
GetCurrentProcess(),
s->handle,
GetCurrentProcess(),
&duph,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
}
janet_marshal_int64(ctx, (int64_t)(duph));
#else #else
/* Marshal after dup becuse it is easier than maintaining our own ref counting. */ /* Marshal after dup becuse it is easier than maintaining our own ref counting. */
int duph = dup(s->handle); int duph = dup(s->handle);
@@ -1614,8 +1627,7 @@ JanetAsyncStatus ev_machine_read(JanetListenerState *s, JanetAsyncEvent event) {
} }
break; break;
#else #else
case JANET_ASYNC_EVENT_ERR: case JANET_ASYNC_EVENT_ERR: {
case JANET_ASYNC_EVENT_HUP: {
if (state->bytes_read) { if (state->bytes_read) {
janet_schedule(s->fiber, janet_wrap_buffer(state->buf)); janet_schedule(s->fiber, janet_wrap_buffer(state->buf));
} else { } else {
@@ -1623,6 +1635,7 @@ JanetAsyncStatus ev_machine_read(JanetListenerState *s, JanetAsyncEvent event) {
} }
return JANET_ASYNC_STATUS_DONE; return JANET_ASYNC_STATUS_DONE;
} }
case JANET_ASYNC_EVENT_HUP:
case JANET_ASYNC_EVENT_READ: { case JANET_ASYNC_EVENT_READ: {
JanetBuffer *buffer = state->buf; JanetBuffer *buffer = state->buf;
int32_t bytes_left = state->bytes_left; int32_t bytes_left = state->bytes_left;
@@ -2033,6 +2046,64 @@ static Janet cfun_ev_go(int32_t argc, Janet *argv) {
return argv[0]; return argv[0];
} }
/* For ev/thread - Run an interpreter in the new thread. */
static JanetEVGenericMessage janet_go_thread_subr(JanetEVGenericMessage args) {
JanetBuffer *buffer = (JanetBuffer *) args.argp;
const uint8_t *nextbytes = buffer->data;
const uint8_t *endbytes = nextbytes + buffer->count;
janet_init();
JanetTryState tstate;
JanetSignal signal = janet_try(&tstate);
if (!signal) {
Janet aregv = janet_unmarshal(nextbytes, endbytes - nextbytes,
JANET_MARSHAL_UNSAFE, NULL, &nextbytes);
if (!janet_checktype(aregv, JANET_TABLE)) janet_panic("expected table for abstract registry");
janet_vm_abstract_registry = janet_unwrap_table(aregv);
Janet regv = janet_unmarshal(nextbytes, endbytes - nextbytes,
JANET_MARSHAL_UNSAFE, NULL, &nextbytes);
if (!janet_checktype(regv, JANET_TABLE)) janet_panic("expected table for cfunction registry");
janet_vm_registry = janet_unwrap_table(regv);
Janet fiberv = janet_unmarshal(nextbytes, endbytes - nextbytes,
JANET_MARSHAL_UNSAFE, NULL, &nextbytes);
Janet value = janet_unmarshal(nextbytes, endbytes - nextbytes,
JANET_MARSHAL_UNSAFE, NULL, &nextbytes);
if (!janet_checktype(fiberv, JANET_FIBER)) janet_panic("expected fiber");
JanetFiber *fiber = janet_unwrap_fiber(fiberv);
janet_schedule(fiber, value);
janet_loop();
args.tag = JANET_EV_TCTAG_NIL;
} else {
if (janet_checktype(tstate.payload, JANET_STRING)) {
args.tag = JANET_EV_TCTAG_ERR_STRINGF;
args.argp = strdup((const char *) janet_unwrap_string(tstate.payload));
} else {
args.tag = JANET_EV_TCTAG_ERR_STRING;
args.argp = "failed to start thread";
}
}
janet_buffer_deinit(buffer);
janet_restore(&tstate);
janet_deinit();
return args;
}
static Janet cfun_ev_thread(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 3);
janet_getfiber(argv, 0);
Janet value = argc == 2 ? argv[1] : janet_wrap_nil();
/* Marshal arguments for the new thread. */
JanetBuffer *buffer = malloc(sizeof(JanetBuffer));
if (NULL == buffer) {
JANET_OUT_OF_MEMORY;
}
janet_buffer_init(buffer, 0);
janet_marshal(buffer, janet_wrap_table(janet_vm_abstract_registry), NULL, JANET_MARSHAL_UNSAFE);
janet_marshal(buffer, janet_wrap_table(janet_vm_registry), NULL, JANET_MARSHAL_UNSAFE);
janet_marshal(buffer, argv[0], NULL, JANET_MARSHAL_UNSAFE);
janet_marshal(buffer, value, NULL, JANET_MARSHAL_UNSAFE);
janet_ev_threaded_await(janet_go_thread_subr, 0, argc, buffer);
}
static Janet cfun_ev_give_supervisor(int32_t argc, Janet *argv) { static Janet cfun_ev_give_supervisor(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1); janet_arity(argc, 1, -1);
JanetChannel *chan = janet_vm_root_fiber->supervisor_channel; JanetChannel *chan = janet_vm_root_fiber->supervisor_channel;
@@ -2146,6 +2217,14 @@ static const JanetReg ev_cfuns[] = {
"events occur in the newly scheduled fiber, an event will be pushed to the supervisor. " "events occur in the newly scheduled fiber, an event will be pushed to the supervisor. "
"If not provided, the new fiber will inherit the current supervisor.") "If not provided, the new fiber will inherit the current supervisor.")
}, },
{
"ev/thread", cfun_ev_thread,
JDOC("(ev/thread fiber &opt value flags)\n\n"
"Resume a (copy of a) `fiber` in a new operating system thread, optionally passing `value` "
"to resume with. "
"Unlike `ev/go`, this function will suspend the current fiber until the thread is complete. "
"The the final result.")
},
{ {
"ev/give-supervisor", cfun_ev_give_supervisor, "ev/give-supervisor", cfun_ev_give_supervisor,
JDOC("(ev/give-supervsior tag & payload)\n\n" JDOC("(ev/give-supervsior tag & payload)\n\n"
@@ -2248,6 +2327,7 @@ static const JanetReg ev_cfuns[] = {
void janet_lib_ev(JanetTable *env) { void janet_lib_ev(JanetTable *env) {
janet_core_cfuns(env, NULL, ev_cfuns); janet_core_cfuns(env, NULL, ev_cfuns);
janet_register_abstract_type(&janet_stream_type);
} }
#endif #endif

View File

@@ -746,6 +746,7 @@ static const JanetReg io_cfuns[] = {
"* r - allow reading from the file\n\n" "* r - allow reading from the file\n\n"
"* w - allow writing to the file\n\n" "* w - allow writing to the file\n\n"
"* a - append to the file\n\n" "* a - append to the file\n\n"
"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" "* b - open the file in binary mode (rather than text mode)\n\n"
"* + - append to the file instead of overwriting it\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")

View File

@@ -938,6 +938,7 @@ static const uint8_t *unmarshal_one_fiber(
#ifdef JANET_EV #ifdef JANET_EV
fiber->waiting = NULL; fiber->waiting = NULL;
fiber->sched_id = 0; fiber->sched_id = 0;
fiber->supervisor_channel = NULL;
#endif #endif
/* Push fiber to seen stack */ /* Push fiber to seen stack */
@@ -1427,9 +1428,9 @@ static const JanetReg marsh_cfuns[] = {
"marshal", cfun_marshal, "marshal", cfun_marshal,
JDOC("(marshal x &opt reverse-lookup buffer)\n\n" JDOC("(marshal x &opt reverse-lookup buffer)\n\n"
"Marshal a value into a buffer and return the buffer. The buffer " "Marshal a value into a buffer and return the buffer. The buffer "
"can the later be unmarshalled to reconstruct the initial value. " "can then later be unmarshalled to reconstruct the initial value. "
"Optionally, one can pass in a reverse lookup table to not marshal " "Optionally, one can pass in a reverse lookup table to not marshal "
"aliased values that are found in the table. Then a forward" "aliased values that are found in the table. Then a forward "
"lookup table can be used to recover the original value when " "lookup table can be used to recover the original value when "
"unmarshalling.") "unmarshalling.")
}, },

View File

@@ -146,6 +146,7 @@ JanetAsyncStatus net_machine_accept(JanetListenerState *s, JanetAsyncEvent event
if (state->function) { if (state->function) {
/* Schedule worker */ /* Schedule worker */
JanetFiber *fiber = janet_fiber(state->function, 64, 1, &streamv); JanetFiber *fiber = janet_fiber(state->function, 64, 1, &streamv);
fiber->supervisor_channel = s->fiber->supervisor_channel;
janet_schedule(fiber, janet_wrap_nil()); janet_schedule(fiber, janet_wrap_nil());
/* Now listen again for next connection */ /* Now listen again for next connection */
Janet err; Janet err;
@@ -222,6 +223,7 @@ JanetAsyncStatus net_machine_accept(JanetListenerState *s, JanetAsyncEvent event
Janet streamv = janet_wrap_abstract(stream); Janet streamv = janet_wrap_abstract(stream);
if (state->function) { if (state->function) {
JanetFiber *fiber = janet_fiber(state->function, 64, 1, &streamv); JanetFiber *fiber = janet_fiber(state->function, 64, 1, &streamv);
fiber->supervisor_channel = s->fiber->supervisor_channel;
janet_schedule(fiber, janet_wrap_nil()); janet_schedule(fiber, janet_wrap_nil());
} else { } else {
janet_schedule(s->fiber, streamv); janet_schedule(s->fiber, streamv);
@@ -263,12 +265,11 @@ static struct addrinfo *janet_get_addrinfo(Janet *argv, int32_t offset, int sock
#ifndef JANET_WINDOWS #ifndef JANET_WINDOWS
if (janet_keyeq(argv[offset], "unix")) { if (janet_keyeq(argv[offset], "unix")) {
const char *path = janet_getcstring(argv, offset + 1); const char *path = janet_getcstring(argv, offset + 1);
struct sockaddr_un *saddr = malloc(sizeof(struct sockaddr_un)); struct sockaddr_un *saddr = calloc(1, sizeof(struct sockaddr_un));
if (saddr == NULL) { if (saddr == NULL) {
JANET_OUT_OF_MEMORY; JANET_OUT_OF_MEMORY;
} }
saddr->sun_family = AF_UNIX; saddr->sun_family = AF_UNIX;
memset(&saddr->sun_path, 0, 108);
#ifdef JANET_LINUX #ifdef JANET_LINUX
if (path[0] == '@') { if (path[0] == '@') {
saddr->sun_path[0] = '\0'; saddr->sun_path[0] = '\0';

View File

@@ -187,57 +187,81 @@ static Janet os_exit(int32_t argc, Janet *argv) {
#ifndef JANET_NO_PROCESSES #ifndef JANET_NO_PROCESSES
/* Get env for os_execute */ /* Get env for os_execute */
static char **os_execute_env(int32_t argc, const Janet *argv) { #ifdef JANET_WINDOWS
char **envp = NULL; typedef char *EnvBlock;
if (argc > 2) { #else
JanetDictView dict = janet_getdictionary(argv, 2); typedef char **EnvBlock;
envp = janet_smalloc(sizeof(char *) * ((size_t)dict.len + 1)); #endif
int32_t j = 0;
for (int32_t i = 0; i < dict.cap; i++) { /* Get env for os_execute */
const JanetKV *kv = dict.kvs + i; static EnvBlock os_execute_env(int32_t argc, const Janet *argv) {
if (!janet_checktype(kv->key, JANET_STRING)) continue; if (argc <= 2) return NULL;
if (!janet_checktype(kv->value, JANET_STRING)) continue; JanetDictView dict = janet_getdictionary(argv, 2);
const uint8_t *keys = janet_unwrap_string(kv->key); #ifdef JANET_WINDOWS
const uint8_t *vals = janet_unwrap_string(kv->value); JanetBuffer *temp = janet_buffer(10);
int32_t klen = janet_string_length(keys); for (int32_t i = 0; i < dict.cap; i++) {
int32_t vlen = janet_string_length(vals); const JanetKV *kv = dict.kvs + i;
/* Check keys has no embedded 0s or =s. */ if (!janet_checktype(kv->key, JANET_STRING)) continue;
int skip = 0; if (!janet_checktype(kv->value, JANET_STRING)) continue;
for (int32_t k = 0; k < klen; k++) { const uint8_t *keys = janet_unwrap_string(kv->key);
if (keys[k] == '\0' || keys[k] == '=') { const uint8_t *vals = janet_unwrap_string(kv->value);
skip = 1; janet_buffer_push_bytes(temp, keys, janet_string_length(keys));
break; janet_buffer_push_u8(temp, '=');
} janet_buffer_push_bytes(temp, vals, janet_string_length(vals));
} janet_buffer_push_u8(temp, '\0');
if (skip) continue;
char *envitem = janet_smalloc((size_t) klen + (size_t) vlen + 2);
memcpy(envitem, keys, klen);
envitem[klen] = '=';
memcpy(envitem + klen + 1, vals, vlen);
envitem[klen + vlen + 1] = 0;
envp[j++] = envitem;
}
envp[j] = NULL;
} }
if (temp->count == 0) return NULL;
janet_buffer_push_u8(temp, '\0');
char *ret = janet_smalloc(temp->count);
memcpy(ret, temp->data, temp->count);
return ret;
#else
char **envp = janet_smalloc(sizeof(char *) * ((size_t)dict.len + 1));
int32_t j = 0;
for (int32_t i = 0; i < dict.cap; i++) {
const JanetKV *kv = dict.kvs + i;
if (!janet_checktype(kv->key, JANET_STRING)) continue;
if (!janet_checktype(kv->value, JANET_STRING)) continue;
const uint8_t *keys = janet_unwrap_string(kv->key);
const uint8_t *vals = janet_unwrap_string(kv->value);
int32_t klen = janet_string_length(keys);
int32_t vlen = janet_string_length(vals);
/* Check keys has no embedded 0s or =s. */
int skip = 0;
for (int32_t k = 0; k < klen; k++) {
if (keys[k] == '\0' || keys[k] == '=') {
skip = 1;
break;
}
}
if (skip) continue;
char *envitem = janet_smalloc((size_t) klen + (size_t) vlen + 2);
memcpy(envitem, keys, klen);
envitem[klen] = '=';
memcpy(envitem + klen + 1, vals, vlen);
envitem[klen + vlen + 1] = 0;
envp[j++] = envitem;
}
envp[j] = NULL;
return envp; return envp;
#endif
} }
/* Free memory from os_execute. Not actually needed, but doesn't pressure the GC static void os_execute_cleanup(EnvBlock envp, const char **child_argv) {
in the happy path. */
static void os_execute_cleanup(char **envp, const char **child_argv) {
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
(void) child_argv; (void) child_argv;
janet_sfree(envp);
#else #else
janet_sfree((void *)child_argv); janet_sfree((void *)child_argv);
#endif
if (NULL != envp) { if (NULL != envp) {
char **envitem = envp; char **envitem = envp;
while (*envitem != NULL) { while (*envitem != NULL) {
janet_sfree(*envitem); free(*envitem);
envitem++; envitem++;
} }
} }
janet_sfree(envp); janet_sfree(envp);
#endif
} }
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
@@ -730,12 +754,11 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
uint64_t flags = 0; uint64_t flags = 0;
if (argc > 1) { if (argc > 1) {
flags = janet_getflags(argv, 1, "epx"); flags = janet_getflags(argv, 1, "epx");
} }
/* Get environment */ /* Get environment */
int use_environ = !janet_flag_at(flags, 0); int use_environ = !janet_flag_at(flags, 0);
char **envp = os_execute_env(argc, argv); EnvBlock envp = os_execute_env(argc, argv);
/* Get arguments */ /* Get arguments */
JanetView exargs = janet_getindexed(argv, 0); JanetView exargs = janet_getindexed(argv, 0);

View File

@@ -175,7 +175,14 @@ static void popstate(JanetParser *p, Janet val) {
if (newtop->flags & PFLAG_CONTAINER) { if (newtop->flags & PFLAG_CONTAINER) {
newtop->argn++; newtop->argn++;
/* Keep track of number of values in the root state */ /* Keep track of number of values in the root state */
if (p->statecount == 1) p->pending++; if (p->statecount == 1) {
p->pending++;
/* Root items are always wrapped in a tuple for source map info. */
const Janet *tup = janet_tuple_n(&val, 1);
janet_tuple_sm_line(tup) = (int32_t) top.line;
janet_tuple_sm_column(tup) = (int32_t) top.column;
val = janet_wrap_tuple(tup);
}
push_arg(p, val); push_arg(p, val);
return; return;
} else if (newtop->flags & PFLAG_READERMAC) { } else if (newtop->flags & PFLAG_READERMAC) {
@@ -730,6 +737,19 @@ const char *janet_parser_error(JanetParser *parser) {
} }
Janet janet_parser_produce(JanetParser *parser) { Janet janet_parser_produce(JanetParser *parser) {
Janet ret;
size_t i;
if (parser->pending == 0) return janet_wrap_nil();
ret = janet_unwrap_tuple(parser->args[0])[0];
for (i = 1; i < parser->argcount; i++) {
parser->args[i - 1] = parser->args[i];
}
parser->pending--;
parser->argcount--;
return ret;
}
Janet janet_parser_produce_wrapped(JanetParser *parser) {
Janet ret; Janet ret;
size_t i; size_t i;
if (parser->pending == 0) return janet_wrap_nil(); if (parser->pending == 0) return janet_wrap_nil();
@@ -910,8 +930,13 @@ static Janet cfun_parse_insert(int32_t argc, Janet *argv) {
if (s->flags & PFLAG_COMMENT) s--; if (s->flags & PFLAG_COMMENT) s--;
if (s->flags & PFLAG_CONTAINER) { if (s->flags & PFLAG_CONTAINER) {
s->argn++; s->argn++;
if (p->statecount == 1) p->pending++; if (p->statecount == 1) {
push_arg(p, argv[1]); p->pending++;
Janet tup = janet_wrap_tuple(janet_tuple_n(argv + 1, 1));
push_arg(p, tup);
} else {
push_arg(p, argv[1]);
}
} else if (s->flags & (PFLAG_STRING | PFLAG_LONGSTRING)) { } else if (s->flags & (PFLAG_STRING | PFLAG_LONGSTRING)) {
const uint8_t *str = janet_to_string(argv[1]); const uint8_t *str = janet_to_string(argv[1]);
int32_t slen = janet_string_length(str); int32_t slen = janet_string_length(str);
@@ -980,9 +1005,13 @@ static Janet cfun_parse_error(int32_t argc, Janet *argv) {
} }
static Janet cfun_parse_produce(int32_t argc, Janet *argv) { static Janet cfun_parse_produce(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1); janet_arity(argc, 1, 2);
JanetParser *p = janet_getabstract(argv, 0, &janet_parser_type); JanetParser *p = janet_getabstract(argv, 0, &janet_parser_type);
return janet_parser_produce(p); if (argc == 2 && janet_truthy(argv[1])) {
return janet_parser_produce_wrapped(p);
} else {
return janet_parser_produce(p);
}
} }
static Janet cfun_parse_flush(int32_t argc, Janet *argv) { static Janet cfun_parse_flush(int32_t argc, Janet *argv) {
@@ -1217,10 +1246,12 @@ static const JanetReg parse_cfuns[] = {
}, },
{ {
"parser/produce", cfun_parse_produce, "parser/produce", cfun_parse_produce,
JDOC("(parser/produce parser)\n\n" JDOC("(parser/produce parser &opt wrap)\n\n"
"Dequeue the next value in the parse queue. Will return nil if " "Dequeue the next value in the parse queue. Will return nil if "
"no parsed values are in the queue, otherwise will dequeue the " "no parsed values are in the queue, otherwise will dequeue the "
"next value.") "next value. If `wrap` is truthy, will return a 1-element tuple that "
"wraps the result. This tuple can be used for source-mapping "
"purposes.")
}, },
{ {
"parser/consume", cfun_parse_consume, "parser/consume", cfun_parse_consume,

View File

@@ -1027,7 +1027,7 @@ static void spec_matchtime(Builder *b, int32_t argc, const Janet *argv) {
static void spec_readint(Builder *b, int32_t argc, const Janet *argv, uint32_t mask) { static void spec_readint(Builder *b, int32_t argc, const Janet *argv, uint32_t mask) {
peg_arity(b, argc, 1, 2); peg_arity(b, argc, 1, 2);
Reserve r = reserve(b, 3); Reserve r = reserve(b, 3);
uint32_t tag = (argc == 2) ? emit_tag(b, argv[3]) : 0; uint32_t tag = (argc == 2) ? emit_tag(b, argv[1]) : 0;
int32_t width = peg_getnat(b, argv[0]); int32_t width = peg_getnat(b, argv[0]);
if ((width < 0) || (width > JANET_MAX_READINT_WIDTH)) { if ((width < 0) || (width > JANET_MAX_READINT_WIDTH)) {
peg_panicf(b, "width must be between 0 and %d, got %d", JANET_MAX_READINT_WIDTH, width); peg_panicf(b, "width must be between 0 and %d, got %d", JANET_MAX_READINT_WIDTH, width);
@@ -1486,7 +1486,13 @@ static JanetPeg *make_peg(Builder *b) {
static JanetPeg *compile_peg(Janet x) { static JanetPeg *compile_peg(Janet x) {
Builder builder; Builder builder;
builder.grammar = janet_table(0); builder.grammar = janet_table(0);
builder.default_grammar = janet_get_core_table("default-peg-grammar"); builder.default_grammar = NULL;
{
Janet default_grammarv = janet_dyn("peg-grammar");
if (janet_checktype(default_grammarv, JANET_TABLE)) {
builder.default_grammar = janet_unwrap_table(default_grammarv);
}
}
builder.tags = janet_table(0); builder.tags = janet_table(0);
builder.constants = NULL; builder.constants = NULL;
builder.bytecode = NULL; builder.bytecode = NULL;
@@ -1656,7 +1662,8 @@ static const JanetReg peg_cfuns[] = {
"peg/compile", cfun_peg_compile, "peg/compile", cfun_peg_compile,
JDOC("(peg/compile peg)\n\n" JDOC("(peg/compile peg)\n\n"
"Compiles a peg source data structure into a <core/peg>. This will speed up matching " "Compiles a peg source data structure into a <core/peg>. This will speed up matching "
"if the same peg will be used multiple times.") "if the same peg will be used multiple times. Will also use `(dyn :peg-grammar)` to suppliment "
"the grammar of the peg for otherwise undefined peg keywords.")
}, },
{ {
"peg/match", cfun_peg_match, "peg/match", cfun_peg_match,

View File

@@ -84,6 +84,9 @@ static JANET_THREAD_LOCAL JanetTable *janet_vm_thread_decode = NULL;
static JanetTable *janet_thread_get_decode(void) { static JanetTable *janet_thread_get_decode(void) {
if (janet_vm_thread_decode == NULL) { if (janet_vm_thread_decode == NULL) {
janet_vm_thread_decode = janet_get_core_table("load-image-dict"); janet_vm_thread_decode = janet_get_core_table("load-image-dict");
if (NULL == janet_vm_thread_decode) {
janet_vm_thread_decode = janet_table(0);
}
janet_gcroot(janet_wrap_table(janet_vm_thread_decode)); janet_gcroot(janet_wrap_table(janet_vm_thread_decode));
} }
return janet_vm_thread_decode; return janet_vm_thread_decode;
@@ -520,7 +523,7 @@ static int thread_worker(JanetMailboxPair *pair) {
janet_stacktrace(fiber, out); janet_stacktrace(fiber, out);
} }
#ifdef JANET_NET #ifdef JANET_EV
janet_loop(); janet_loop();
#endif #endif

View File

@@ -108,6 +108,11 @@ void janet_core_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cf
int janet_gettime(struct timespec *spec); int janet_gettime(struct timespec *spec);
#endif #endif
/* strdup */
#ifdef JANET_WINDOWS
#define strdup(x) _strdup(x)
#endif
#define RETRY_EINTR(RC, CALL) do { (RC) = CALL; } while((RC) < 0 && errno == EINTR) #define RETRY_EINTR(RC, CALL) do { (RC) = CALL; } while((RC) < 0 && errno == EINTR)
/* Initialize builtin libraries */ /* Initialize builtin libraries */

View File

@@ -307,18 +307,14 @@ int32_t janet_hash(Janet x) {
hash = janet_struct_hash(janet_unwrap_struct(x)); hash = janet_struct_hash(janet_unwrap_struct(x));
break; break;
case JANET_NUMBER: { case JANET_NUMBER: {
double num = janet_unwrap_number(x); union {
if (isnan(num) || isinf(num) || num == 0) { double d;
hash = 0; uint64_t u;
} else { } as;
hash = (int32_t)num; as.d = janet_unwrap_number(x);
hash = ((hash >> 16) ^ hash) * 0x45d9f3b; uint32_t lo = (uint32_t)(as.u & 0xFFFFFFFF);
hash = ((hash >> 16) ^ hash) * 0x45d9f3b; uint32_t hi = (uint32_t)(as.u >> 32);
hash = (hash >> 16) ^ hash; hash = (int32_t)(hi ^ (lo >> 3));
uint32_t lo = (uint32_t)(janet_u64(x) & 0xFFFFFFFF);
hash ^= lo + 0x9e3779b9 + (hash << 6) + (hash >> 2);
}
break; break;
} }
case JANET_ABSTRACT: { case JANET_ABSTRACT: {

View File

@@ -202,6 +202,20 @@ JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf = NULL;
vm_checkgc_pcnext();\ vm_checkgc_pcnext();\
}\ }\
} }
#define vm_compop_imm(op) \
{\
Janet op1 = stack[B];\
if (janet_checktype(op1, JANET_NUMBER)) {\
double x1 = janet_unwrap_number(op1);\
double x2 = (double) CS; \
stack[A] = janet_wrap_boolean(x1 op x2);\
vm_pcnext();\
} else {\
vm_commit();\
stack[A] = janet_wrap_boolean(janet_compare(op1, janet_wrap_integer(CS)) op 0);\
vm_checkgc_pcnext();\
}\
}
/* Trace a function call */ /* Trace a function call */
static void vm_do_trace(JanetFunction *func, int32_t argc, const Janet *argv) { static void vm_do_trace(JanetFunction *func, int32_t argc, const Janet *argv) {
@@ -780,8 +794,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
vm_compop( <=); vm_compop( <=);
VM_OP(JOP_LESS_THAN_IMMEDIATE) VM_OP(JOP_LESS_THAN_IMMEDIATE)
stack[A] = janet_wrap_boolean(janet_unwrap_integer(stack[B]) < CS); vm_compop_imm( <);
vm_pcnext();
VM_OP(JOP_GREATER_THAN) VM_OP(JOP_GREATER_THAN)
vm_compop( >); vm_compop( >);
@@ -790,15 +803,14 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
vm_compop( >=); vm_compop( >=);
VM_OP(JOP_GREATER_THAN_IMMEDIATE) VM_OP(JOP_GREATER_THAN_IMMEDIATE)
stack[A] = janet_wrap_boolean(janet_unwrap_integer(stack[B]) > CS); vm_compop_imm( >);
vm_pcnext();
VM_OP(JOP_EQUALS) VM_OP(JOP_EQUALS)
stack[A] = janet_wrap_boolean(janet_equals(stack[B], stack[C])); stack[A] = janet_wrap_boolean(janet_equals(stack[B], stack[C]));
vm_pcnext(); vm_pcnext();
VM_OP(JOP_EQUALS_IMMEDIATE) VM_OP(JOP_EQUALS_IMMEDIATE)
stack[A] = janet_wrap_boolean(janet_unwrap_integer(stack[B]) == CS); stack[A] = janet_wrap_boolean(janet_unwrap_number(stack[B]) == (double) CS);
vm_pcnext(); vm_pcnext();
VM_OP(JOP_NOT_EQUALS) VM_OP(JOP_NOT_EQUALS)
@@ -806,7 +818,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
vm_pcnext(); vm_pcnext();
VM_OP(JOP_NOT_EQUALS_IMMEDIATE) VM_OP(JOP_NOT_EQUALS_IMMEDIATE)
stack[A] = janet_wrap_boolean(janet_unwrap_integer(stack[B]) != CS); stack[A] = janet_wrap_boolean(janet_unwrap_number(stack[B]) != (double) CS);
vm_pcnext(); vm_pcnext();
VM_OP(JOP_COMPARE) VM_OP(JOP_COMPARE)
@@ -1276,7 +1288,14 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
/* Push frame */ /* Push frame */
janet_fiber_pushn(janet_vm_fiber, argv, argc); janet_fiber_pushn(janet_vm_fiber, argv, argc);
if (janet_fiber_funcframe(janet_vm_fiber, fun)) { if (janet_fiber_funcframe(janet_vm_fiber, fun)) {
janet_panicf("arity mismatch in %v", janet_wrap_function(fun)); int32_t min = fun->def->min_arity;
int32_t max = fun->def->max_arity;
Janet funv = janet_wrap_function(fun);
if (min == max && min != argc)
janet_panicf("arity mismatch in %v, expected %d, got %d", funv, min, argc);
if (min >= 0 && argc < min)
janet_panicf("arity mismatch in %v, expected at least %d, got %d", funv, min, argc);
janet_panicf("arity mismatch in %v, expected at most %d, got %d", funv, max, argc);
} }
janet_fiber_frame(janet_vm_fiber)->flags |= JANET_STACKFRAME_ENTRANCE; janet_fiber_frame(janet_vm_fiber)->flags |= JANET_STACKFRAME_ENTRANCE;

View File

@@ -1367,6 +1367,7 @@ JANET_API void janet_parser_deinit(JanetParser *parser);
JANET_API void janet_parser_consume(JanetParser *parser, uint8_t c); JANET_API void janet_parser_consume(JanetParser *parser, uint8_t c);
JANET_API enum JanetParserStatus janet_parser_status(JanetParser *parser); JANET_API enum JanetParserStatus janet_parser_status(JanetParser *parser);
JANET_API Janet janet_parser_produce(JanetParser *parser); JANET_API Janet janet_parser_produce(JanetParser *parser);
JANET_API Janet janet_parser_produce_wrapped(JanetParser *parser);
JANET_API const char *janet_parser_error(JanetParser *parser); JANET_API const char *janet_parser_error(JanetParser *parser);
JANET_API void janet_parser_flush(JanetParser *parser); JANET_API void janet_parser_flush(JanetParser *parser);
JANET_API void janet_parser_eof(JanetParser *parser); JANET_API void janet_parser_eof(JanetParser *parser);
@@ -1406,6 +1407,7 @@ JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, JanetS
/* Get the default environment for janet */ /* Get the default environment for janet */
JANET_API JanetTable *janet_core_env(JanetTable *replacements); JANET_API JanetTable *janet_core_env(JanetTable *replacements);
JANET_API JanetTable *janet_core_lookup_table(JanetTable *replacements);
JANET_API int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out); JANET_API int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out);
JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out); JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out);

View File

@@ -1042,19 +1042,23 @@ int main(int argc, char **argv) {
janet_table_put(env, janet_ckeywordv("executable"), janet_cstringv(argv[0])); janet_table_put(env, janet_ckeywordv("executable"), janet_cstringv(argv[0]));
/* Run startup script */ /* Run startup script */
Janet mainfun, out; Janet mainfun;
janet_resolve(env, janet_csymbol("cli-main"), &mainfun); janet_resolve(env, janet_csymbol("cli-main"), &mainfun);
Janet mainargs[1] = { janet_wrap_array(args) }; Janet mainargs[1] = { janet_wrap_array(args) };
JanetFiber *fiber = janet_fiber(janet_unwrap_function(mainfun), 64, 1, mainargs); JanetFiber *fiber = janet_fiber(janet_unwrap_function(mainfun), 64, 1, mainargs);
fiber->env = env; fiber->env = env;
#ifdef JANET_EV
janet_gcroot(janet_wrap_fiber(fiber));
janet_schedule(fiber, janet_wrap_nil());
janet_loop();
status = janet_fiber_status(fiber);
#else
Janet out;
status = janet_continue(fiber, janet_wrap_nil(), &out); status = janet_continue(fiber, janet_wrap_nil(), &out);
if (status != JANET_SIGNAL_OK && status != JANET_SIGNAL_EVENT) { if (status != JANET_SIGNAL_OK && status != JANET_SIGNAL_EVENT) {
janet_stacktrace(fiber, out); janet_stacktrace(fiber, out);
} }
#ifdef JANET_EV
status = JANET_SIGNAL_OK;
janet_loop();
#endif #endif
/* Deinitialize vm */ /* Deinitialize vm */

View File

@@ -320,4 +320,8 @@
(array/push a x)) (array/push a x))
(assert (deep= (range 4) a) "eachk 1") (assert (deep= (range 4) a) "eachk 1")
(tracev (def my-unique-var-name true))
(assert my-unique-var-name "tracev upscopes")
(end-suite) (end-suite)

View File

@@ -137,4 +137,10 @@
(assert (deep= (string/split "qq" "1qqqqz") @["1" "" "z"]) "string/split 1") (assert (deep= (string/split "qq" "1qqqqz") @["1" "" "z"]) "string/split 1")
(assert (deep= (string/split "aa" "aaa") @["" "a"]) "string/split 2") (assert (deep= (string/split "aa" "aaa") @["" "a"]) "string/split 2")
# Comparisons
(assert (> 1e23 100) "less than immediate 1")
(assert (> 1e23 1000) "less than immediate 2")
(assert (< 100 1e23) "greater than immediate 1")
(assert (< 1000 1e23) "greater than immediate 2")
(end-suite) (end-suite)