1
0
mirror of https://github.com/janet-lang/janet synced 2025-11-05 10:03:06 +00:00

Compare commits

..

146 Commits

Author SHA1 Message Date
Calvin Rose
87f8fe14dd Prepare for 1.16.1 release. 2021-06-09 19:08:24 -05:00
Calvin Rose
2eadb21eb7 Update changelog. 2021-05-31 16:51:53 -05:00
Calvin Rose
8b97a0dbbf Merge pull request #707 from pepe/fix-shadow
Rename level const to not to shadow line in eval1
2021-05-31 16:05:41 -05:00
Calvin Rose
69afa2a7a3 Merge branch 'master' into fix-shadow 2021-05-31 16:05:29 -05:00
Calvin Rose
da5328bae5 Merge branch 'master' of git.sr.ht:~bakpakin/janet 2021-05-31 15:14:39 -05:00
Josef Pospíšil
a4325372e2 Rename level const to not to shadow line in eval1 2021-05-31 21:51:31 +02:00
Calvin Rose
4b96b73858 Add -w and -x flags to janet for linting. 2021-05-31 14:36:25 -05:00
Calvin Rose
bbae43f259 Update copyright dates. 2021-05-31 13:46:02 -05:00
bakpakin
14fedbf063 Update copyright. 2021-05-31 09:53:52 -05:00
Calvin Rose
ab974c409d Remove externeous typedarray defines in janet.h 2021-05-31 09:23:45 -05:00
Calvin Rose
2040709585 Re-add make docs.
Wasn't hurting anything.
2021-05-30 16:44:37 -05:00
Calvin Rose
60214dc659 Update for windows compiler warning. 2021-05-30 16:42:58 -05:00
Calvin Rose
b990d77f16 Prepare for 1.16.0 release. 2021-05-30 12:15:56 -05:00
Calvin Rose
d204e06e11 Use lint information in run-context. 2021-05-30 10:33:46 -05:00
Calvin Rose
f6b37dbc77 Merge branch 'master' into linting 2021-05-30 09:34:32 -05:00
Calvin Rose
ff4d49f556 Set JANET_DIST_DIR on release. 2021-05-30 09:23:52 -05:00
Calvin Rose
dfa5fa1187 Remove some stupid shell gymnastics in Makefile. 2021-05-30 09:14:34 -05:00
Calvin Rose
1f4f69a5b6 Fix windows syntax issue. 2021-05-29 20:40:26 -05:00
Calvin Rose
84f82f5465 Remove code delimtiers from defn and defmacro. 2021-05-29 20:37:30 -05:00
Calvin Rose
c911f7c47e Address #694 - Update doc-format with more features.
Also allows having doc-format print in color with
(dyn :doc-color).
2021-05-29 20:34:22 -05:00
Calvin Rose
33c000daea Expose linting array to macros.
This has a lot of possible uses, and would let users add a macro-based
type system on top of Janet that would integrate with the usual linting
and warning system.
2021-05-28 15:15:34 -05:00
Calvin Rose
7ff204ec44 Work on system for adding compiler warnings.
This is the beginning of a system for compiler warnings. This includes
linting, deprecation notices, and other compiler warnings that are best
detected by the `compile` function and don't require the partial
evalutaion of the flychecker.
2021-05-28 15:12:05 -05:00
Calvin Rose
7c757ef3bf Make jpm configurable for environments like MinGW. 2021-05-26 10:07:11 -05:00
Calvin Rose
2db7945d6f Fix peg bug when there is no default grammar set.
This could result in a segfault when we attempt to
read from a NULL pointer.
2021-05-20 21:57:22 -05:00
Calvin Rose
81186bf262 Merge branch 'master' of github.com:janet-lang/janet 2021-05-19 18:43:50 -05:00
Calvin Rose
eeef5b0896 Add as-macro and module/add-syspath 2021-05-19 18:18:00 -05:00
Calvin Rose
8189b6fc11 Merge pull request #690 from sogaiu/specials-doc
Make doc work for special forms
2021-05-09 13:54:46 -05:00
sogaiu
e5a2df93ab Make doc work for special forms 2021-05-07 08:47:33 +09:00
Calvin Rose
c3f770da27 Fix meson build. 2021-04-29 15:59:44 -05:00
Calvin Rose
49f66a936c Merge commit 'f4c9064b79d5b32fd74e5ddf25266356c22dd53b' 2021-04-29 15:58:41 -05:00
Calvin Rose
83dda98240 Update jpm to work post patch. 2021-04-29 14:28:54 -05:00
Calvin Rose
b4ddbd0097 Address #670 - Allow modifying jpm to link to extra libraries. 2021-04-29 14:04:18 -05:00
Calvin Rose
cbe92bb985 Merge branch 'master' of github.com:janet-lang/janet 2021-04-29 13:13:55 -05:00
Calvin Rose
60c6a0d334 Add :native-deps option to jpm.
Use is like:

```
(declare-native
 :name "my-nuermical-library"
 :source @["numerical_lib.c"]
 :native-deps ["tarray"])

```

Where `tarray` is a native generated by o ne of the project
dependencies. This will lets us move more C functionality out of the
core of Janet while still allowing it's use from natives.
2021-04-29 13:11:46 -05:00
Calvin Rose
1baab5eb61 Remove typed arrays from the core.
Typed arrays will instead live in an external jpm nodule.
Also, changes have been made to `jpm` to allow other natives to use the
typedarray headers.
2021-04-29 12:33:49 -05:00
Calvin Rose
8fc8974b60 Add from-pairs to core. #683
This always creates a table, use `table/to-struct` to
create a struct.
2021-04-29 12:06:24 -05:00
Calvin Rose
ecb49c2e5e Merge pull request #688 from cjones051073/use-nsgetenviron-on-apple
Use _NSGetEnviron() on Apple
2021-04-29 12:00:35 -05:00
Chris Jones
29797b9eb0 Use _NSGetEnviron() on Apple 2021-04-27 11:54:24 +01:00
Calvin Rose
e181ee586b Prepare for 1.15.5 release. 2021-04-25 14:00:16 -05:00
Calvin Rose
7b7d742bec Add declare-headers to jpm. 2021-04-25 13:38:24 -05:00
Calvin Rose
612eaff9ff Fix #682 - Don't hardcode size of sun_path. 2021-04-15 14:57:40 -05:00
Calvin Rose
d76ef187e8 Merge pull request #681 from pyrmont/patch-2
Fix link to Introduction
2021-04-09 20:04:42 -05:00
Michael Camilleri
e01ab86a89 Fix link to Introduction 2021-04-08 16:10:24 +09:00
Calvin Rose
89b59b4ffc Merge branch 'master' of github.com:janet-lang/janet 2021-04-06 23:36:11 -05:00
Calvin Rose
e367ecf806 Update cannonical link. 2021-04-06 23:35:57 -05:00
Calvin Rose
effc9e0f33 Merge pull request #677 from uvtc/patch-1
Add note about sponsorship to README
2021-04-02 15:00:21 -05:00
John Gabriele
da06e6c6e3 Update README.md
Co-authored-by: Michael Camilleri <mike@inqk.net>
2021-03-31 21:40:30 -04:00
John Gabriele
c258bee54f Add note about sponsorship to README 2021-03-31 21:27:03 -04:00
Calvin Rose
cde4a505cf Fix #673 - check typed array index bounds as well as buffer count. 2021-03-30 21:14:42 -05:00
Calvin Rose
2802e66259 Merge branch 'master' of github.com:janet-lang/janet 2021-03-26 15:45:14 -05:00
Calvin Rose
3a3003029a Merge branch 'master' of github.com:janet-lang/janet 2021-03-26 15:44:43 -05:00
Calvin Rose
08bca8fb63 Merge branch 'master' of github.com:janet-lang/janet 2021-03-26 15:36:50 -05:00
Calvin Rose
7c7ff802fa Add net/shutdown to allow better networking with streams. 2021-03-26 15:36:25 -05:00
Calvin Rose
0945acc780 Merge pull request #672 from Luewd/cc-file-ext
Allow .cc file extension in jpm declare-native
2021-03-26 15:13:12 -05:00
Lue
64ec9f9cb6 Allow .cc file extension in jpm declare-native 2021-03-25 13:19:05 -04:00
Calvin Rose
83f7de33c0 Merge pull request #671 from pyrmont/feature.metadata
Support adding arbitrary metadata to bindings
2021-03-24 16:56:25 -05:00
Michael Camilleri
ec2d7bf349 Support adding arbitrary metadata to bindings 2021-03-24 09:38:12 +09:00
Andrew Chambers
f4c9064b79 Add config support for custom allocators. 2021-03-23 23:00:48 +13:00
Calvin Rose
8ede16dc26 Merge pull request #669 from dbready/dist_layout
Create Folder Hierarchy for Linux Release
2021-03-22 11:51:21 -05:00
Damien Ready
27e400fba3 Prepare the .tar distribution with folder layout 2021-03-20 10:53:51 -05:00
Calvin Rose
37d6cb469b Merge pull request #668 from ffontaine/master
meson.build: fix build without threads
2021-03-19 15:44:25 -05:00
Calvin Rose
100a82feb2 Version bump (development version). 2021-03-19 15:41:34 -05:00
Calvin Rose
90e5828d5d Update printing when entering debugger. 2021-03-19 15:38:46 -05:00
Calvin Rose
b3e80308d4 Change inheritance rule. 2021-03-19 15:18:19 -05:00
Fabrice Fontaine
a7abe11105 meson.build: fix build without threads
Fix the following build failure with -Dsingle_threaded=true on embedded
toolchains without pthread:

FAILED: janet.p/meson-generated_.._janet.c.o
/home/buildroot/autobuild/run/instance-3/output-1/host/bin/arm-linux-gcc -Ijanet.p -I. -I.. -I../src/include -fdiagnostics-color=always -pipe -Wall -Winvalid-pch -std=c99 -O3 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -pthread -fvisibility=hidden -MD -MQ janet.p/meson-generated_.._janet.c.o -MF janet.p/meson-generated_.._janet.c.o.d -o janet.p/meson-generated_.._janet.c.o -c janet.c
In file included from /home/buildroot/autobuild/run/instance-3/output-1/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/include/stdlib.h:24,
                 from ../src/include/janet.h:300,
                 from src/core/features.h:57:
/home/buildroot/autobuild/run/instance-3/output-1/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/include/features.h:218:5: warning: #warning requested reentrant code, but thread support was disabled [-Wcpp]
  218 | #   warning requested reentrant code, but thread support was disabled
      |     ^~~~~~~
src/core/ev.c:39:10: fatal error: pthread.h: No such file or directory

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2021-03-18 09:13:22 +01:00
Calvin Rose
3c63a48df4 (#667) Add constant inlining for tuples and structs.
Structs and tuples composed entirely out of constant values
will themselves be considered constant values during compilation.
This reduces the amount of generated code.
2021-03-16 20:52:55 -05:00
Calvin Rose
fcb88e5a98 Merge branch 'master' of github.com:janet-lang/janet 2021-03-16 20:12:47 -05:00
Calvin Rose
a467b34de4 Prepare for 1.15.4 release. 2021-03-16 20:12:33 -05:00
Calvin Rose
a24cc77ff8 Merge pull request #666 from pyrmont/patch-1
Remove instructions to add tags
2021-03-14 16:16:42 -05:00
Michael Camilleri
d6675d9909 Remove instructions to add tags 2021-03-14 15:07:33 +09:00
Calvin Rose
fa163093d2 Update CHANGELOG.md 2021-03-13 19:22:47 -06:00
Calvin Rose
e70f64e23d Sort keys initial. 2021-03-13 19:17:07 -06:00
Calvin Rose
6f605f8141 Update pretty printing default depth. 2021-03-13 17:43:19 -06:00
Calvin Rose
d9419ef994 Merge pull request #660 from ffontaine/master
meson.build: fix static build
2021-03-12 19:06:33 -06:00
Calvin Rose
7e8639a682 Merge pull request #664 from leahneukirchen/meson-pkgconfig2
Fix include path when using meson
2021-03-12 17:11:54 -06:00
Leah Neukirchen
452b303b4c Fix include path when using meson
Closes #661.
2021-03-12 18:49:50 +01:00
Fabrice Fontaine
b0f1a4967d meson.build: fix static build
Don't enforce -rdynamic when building statically to avoid the following
build failure:

/home/giuliobenetti/autobuild/run/instance-2/output-1/host/bin/arm-linux-gcc  -o janet janet.p/meson-generated_.._janet.c.o janet.p/src_mainclient_shell.c.o -Wl,--as-needed -Wl,--allow-shlib-undefined -Wl,-O1 -rdynamic -Wl,-elf2flt -static -Wl,--start-group -lm -ldl -Wl,--end-group -pthread
arm-linux-gcc.br_real: error: unrecognized command line option '-rdynamic'

Fixes:
 - http://autobuild.buildroot.org/results/a4f927f73a7b80e65408c992d7b6023609a1eacc

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2021-03-12 08:46:05 +01:00
Calvin Rose
9eb4c59c04 Require opt-in behavior per script.
This means a binscript needs to indicate that it is a Janet script, and
then the user who is installing the script can choose whether or not to
do the magic shebang replacement.
2021-03-11 18:47:53 -06:00
Calvin Rose
0d42506cde Merge branch 'master' of github.com:janet-lang/janet 2021-03-11 18:37:54 -06:00
Calvin Rose
c8a13ce475 Add --auto-shebang option to jpm. 2021-03-11 18:37:45 -06:00
Calvin Rose
05e3467d09 Merge pull request #655 from uvtc/patch-1
Update os.c
2021-03-11 18:12:54 -06:00
Calvin Rose
90639e5068 Merge pull request #658 from pyrmont/bugfix.jpm-realpath
Fix argument passing to os/realpath in jpm
2021-03-11 18:12:38 -06:00
Calvin Rose
73c7711c78 Merge pull request #657 from ffontaine/master
meson.build: defaults to c99 for "build.c_std"
2021-03-11 18:12:25 -06:00
Calvin Rose
78f6b6a507 Add auto-shebang functionality. 2021-03-11 18:10:33 -06:00
Michael Camilleri
84f0ab5356 Fix argument passing to os/realpath in jpm 2021-03-10 17:11:12 +09:00
Fabrice Fontaine
546437d799 meson.build: defaults to c99 for "build.c_std"
Since Meson 0.51, there are special build options for "native:true"
builds, prefixed with "build.".  This change breaks cross builds
because `janet-boot/src_core_asm.c` is no longer built with `-std=c99`:

FAILED: janet-boot.p/src_core_asm.c.o
/usr/bin/gcc -Ijanet-boot.p -I. -I.. -I../src/include -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O3 -pthread -DJANET_BOOTSTRAP -MD -MQ janet-boot.p/src_core_asm.c.o -MF janet-boot.p/src_core_asm.c.o.d -o janet-boot.p/src_core_asm.c.o -c ../src/core/asm.c
../src/core/asm.c: In function 'janet_disasm_bytecode':
../src/core/asm.c:866:5: error: 'for' loop initial declarations are only allowed in C99 mode
     for (int32_t i = 0; i < def->bytecode_length; i++) {
     ^

Fixes:
 - http://autobuild.buildroot.net/results/355e0992338a8d132050517f83a3884606b00529

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2021-03-10 07:57:53 +01:00
John Gabriele
0f05aec563 Update os.c
Doc typo
2021-03-09 14:39:09 -05:00
Calvin Rose
c9097623d6 Add group-by and partition-by to the core.
Semantics are mostly emulated from Clojure.
2021-03-04 19:34:36 -06:00
Calvin Rose
6392b37c47 Merge branch 'master' of github.com:janet-lang/janet 2021-02-28 13:05:05 -06:00
Calvin Rose
4fcc8075d4 Release 1.15.3 2021-02-28 13:04:24 -06:00
Calvin Rose
b2d6a55335 Merge pull request #646 from pyrmont/bugfix.run-context-match
Fix call to match in run-context
2021-02-28 10:48:43 -06:00
Michael Camilleri
1fea5f8fe7 Fix call to match in run-context 2021-02-28 14:23:17 +09:00
Calvin Rose
d3e52a2afb Fix makefile to attach build identifier. 2021-02-27 19:50:31 -06:00
Calvin Rose
d6ea1989cc Merge branch 'master' of github.com:janet-lang/janet 2021-02-26 17:29:25 -06:00
Calvin Rose
96513665d6 Address #641 - add undef combinator.
The (undef rule :tag) combinator lets a user "scope" tagged captures.
After the rule has matched, all captures with tag :tag can no longer be
refered to by their tag. However, such captures from outside
rule are kept as is. If no tag is given, all tagged captures from rule
are unreferenced. Note that this doesn't `drop` the captures, merely
removes their association with the tag. This means subsequent calls to
`backref` and `backmatch` will no longer "see" these tagged captures.
2021-02-26 17:25:09 -06:00
Calvin Rose
b795d13f61 Merge pull request #642 from pyrmont/feature.run-context-location
Allow source location in run-context to be updated
2021-02-26 16:36:03 -06:00
Calvin Rose
970f9b3981 Merge pull request #643 from uvtc/patch-1
`sort` doc
2021-02-26 16:28:27 -06:00
John Gabriele
be7dab4d17 Update boot.janet 2021-02-23 22:30:42 -05:00
John Gabriele
0e44ce5cba Update boot.janet 2021-02-23 22:26:53 -05:00
John Gabriele
1f8c2781dd sort doc
Clarify doc for `sort` and `sorted`. Also in `sort`, changed arg name.
2021-02-23 22:24:59 -05:00
Michael Camilleri
f381a9c773 Check that new source location is a string 2021-02-22 12:50:44 +09:00
Michael Camilleri
855a9a01fc Allow source location in run-context to be updated 2021-02-22 12:38:56 +09:00
Calvin Rose
a5f237993d Don't fail testing when ev disabled. 2021-02-20 10:56:54 -06:00
Calvin Rose
c68264802a Fix #638 - update fiber status in certain cases.
This fixes a regression from changes to janet_try. In some cases, we
would not update the status of a fiber when signaling, which left the
fiber's status as whatever it had previously. This could lead to strange
control flow issues.
2021-02-20 10:55:16 -06:00
Calvin Rose
742469a8bc Address #640.
Allow for a zero length match at the end of a string when using the
to or thru combinators.
2021-02-19 16:10:03 -06:00
Calvin Rose
92928d5c4f Update definition of or. 2021-02-16 17:00:27 -06:00
Calvin Rose
8320e25d64 Merge pull request #639 from leahneukirchen/or
Fix or with zero arguments
2021-02-16 16:57:21 -06:00
Leah Neukirchen
c16a9d8463 Fix or with zero arguments.
The value is nil to be consistent for and/or and all/some.
Also add some tests for and/or.
2021-02-16 19:59:03 +01:00
Calvin Rose
f1819c916a Fix build error for 1.15.2 2021-02-15 10:27:19 -06:00
Calvin Rose
dd14b24d2a 1.15.1 release. 2021-02-15 10:21:22 -06:00
Calvin Rose
050d7c12a3 Prepare for 1.15.1 release. 2021-02-15 10:19:24 -06:00
Calvin Rose
7e2c433abc Fix #636 2021-02-14 14:34:52 -06:00
Calvin Rose
6713b23a65 Change behavior of empty env table passed to os/execute on windows. 2021-02-14 11:22:20 -06:00
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
94 changed files with 1956 additions and 1811 deletions

View File

@@ -4,12 +4,20 @@ sources:
packages:
- meson
tasks:
- build: |
- with-epoll: |
cd janet
meson setup build --buildtype=release
cd build
meson setup with-epoll --buildtype=release
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
ninja
ninja test
sudo ninja install
sudo jpm --verbose install circlet
sudo jpm --verbose install spork

6
.gitignore vendored
View File

@@ -32,8 +32,9 @@ lockfile.janet
# Local directory for testing
local
# Common test file I use.
# Common test files I use.
temp.janet
scratch.janet
# Emscripten
*.bc
@@ -140,3 +141,6 @@ compile_commands.json
CTestTestfile.cmake
# End of https://www.gitignore.io/api/cmake
# Astyle
*.orig

View File

@@ -4,7 +4,7 @@ script:
- make test
- sudo make install
- make test-install
- make build/janet-${TRAVIS_TAG}-${TRAVIS_OS_NAME}.tar.gz
- JANET_DIST_DIR=janet-${TRAVIS_TAG}-${TRAVIS_OS_NAME} make build/janet-${TRAVIS_TAG}-${TRAVIS_OS_NAME}.tar.gz
compiler:
- clang
- gcc

View File

@@ -1,6 +1,70 @@
# Changelog
All notable changes to this project will be documented in this file.
## 1.16.1 - 2021-06-09
- Add `maclintf` - a utility for adding linting messages when inside macros.
- Print source code of offending line on compiler warnings and errors.
- Fix some issues with linting and re-add missing `make docs`.
- Allow controlling linting with dynamic bindings `:lint-warn`, `:lint-error`, and `:lint-levels`.
- Add `-w` and `-x` command line flags to the `janet` binary to set linting thresholds.
linting thresholds are as follows:
- :none - will never be trigger.
- :relaxed - will only trigger on `:relaxed` lints.
- :normal - will trigger on `:relaxed` and `:normal` lints.
- :strict - will trigger on `:strict`, `:normal`, and `:relaxed` lints. This will catch the most issues
but can be distracting.
## 1.16.0 - 2021-05-30
- Add color documentation to the `doc` macro - enable/disable with `(dyn :doc-color)`.
- Remove simpler HTML docs from distribution - use website or built-in documentation instead.
- Add compiler warnings and deprecation levels.
- Add `as-macro` to make using macros within quasiquote easier to do hygienically.
- Expose `JANET_OUT_OF_MEMORY` as part of the Janet API.
- Add `native-deps` option to `decalre-native` in `jpm`. This lets native libraries link to other
native libraries when building with jpm.
- Remove the `tarray` module. The functionality of typed arrays will be moved to an external module
that can be installed via `jpm`.
- Add `from-pairs` to core.
- Add `JPM_OS_WHICH` environment variable to jpm to allow changing auto-detection behavior.
- The flychecker will consider any top-level calls of functions that start with `define-` to
be safe to execute and execute them. This allows certain patterns (like spork/path) to be
better processed by the flychecker.
## 1.15.5 - 2021-04-25
- Add `declare-headers` to jpm.
- Fix error using unix pipes on BSDs.
- Support .cc and .cxx extensions in `jpm` for C++ code.
- Change networking code to not create as many HUP errors.
- Add `net/shutdown` to close sockets in one direction without hang ups.
- Update code for printing the debug repl
## 1.15.4 - 2021-03-16
- Increase default nesting depth of pretty printing to `JANET_RECURSION_GUARD`
- Update meson.build
- Add option to automatically add shebang line in installed scripts with `jpm`.
- Add `partition-by` and `group-by` to the core.
- Sort keys in pretty printing output.
## 1.15.3 - 2021-02-28
- Fix a fiber bug that occured in deeply nested fibers
- Add `unref` combinator to pegs.
- Small docstring changes.
## 1.15.2 - 2021-02-15
- Fix bug in windows version of `os/spawn` and `os/execute` with setting environment variables.
- 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.

View File

@@ -14,7 +14,6 @@ Please read this document before making contributions.
on how to reproduce it. If it is a compiler or language bug, please try to include a minimal
example. This means don't post all 200 lines of code from your project, but spend some time
distilling the problem to just the relevant code.
* Add the `bug` tag to the issue.
## Contributing Changes
@@ -30,8 +29,7 @@ may require changes before being merged.
the test folder and make sure it is run when`make test` is invoked.
* Be consistent with the style. For C this means follow the indentation and style in
other files (files have MIT license at top, 4 spaces indentation, no trailing
whitespace, cuddled brackets, etc.) Use `make format` to
automatically format your C code with
whitespace, cuddled brackets, etc.) Use `make format` to automatically format your C code with
[astyle](http://astyle.sourceforge.net/astyle.html). You will probably need
to install this, but it can be installed with most package managers.
@@ -75,4 +73,3 @@ timely manner. In short, if you want extra functionality now, then build it.
* Include a good description of the problem that is being solved
* Include descriptions of potential solutions if you have some in mind.
* Add the appropriate tags to the issue. For new features, add the `enhancement` tag.

View File

@@ -1,4 +1,4 @@
Copyright (c) 2020 Calvin Rose and contributors
Copyright (c) 2021 Calvin Rose and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@@ -27,7 +27,7 @@ PREFIX?=/usr/local
INCLUDEDIR?=$(PREFIX)/include
BINDIR?=$(PREFIX)/bin
LIBDIR?=$(PREFIX)/lib
JANET_BUILD?="\"$(shell git log --pretty=format:'%h' -n 2> /dev/null || echo local)\""
JANET_BUILD?="\"$(shell git log --pretty=format:'%h' -n 1 2> /dev/null || echo local)\""
CLIBS=-lm -lpthread
JANET_TARGET=build/janet
JANET_LIBRARY=build/libjanet.so
@@ -35,6 +35,7 @@ JANET_STATIC_LIBRARY=build/libjanet.a
JANET_PATH?=$(LIBDIR)/janet
JANET_MANPATH?=$(PREFIX)/share/man/man1/
JANET_PKG_CONFIG_PATH?=$(LIBDIR)/pkgconfig
JANET_DIST_DIR?=janet-dist
DEBUGGER=gdb
SONAME_SETTER=-Wl,-soname,
@@ -66,7 +67,7 @@ ifeq ($(UNAME), Haiku)
LDFLAGS=-Wl,--export-dynamic
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
######################
@@ -119,7 +120,6 @@ JANET_CORE_SOURCES=src/core/abstract.c \
src/core/table.c \
src/core/thread.c \
src/core/tuple.c \
src/core/typedarray.c \
src/core/util.c \
src/core/value.c \
src/core/vector.c \
@@ -149,7 +149,7 @@ build/janet_boot: $(JANET_BOOT_OBJECTS)
$(CC) $(BOOT_CFLAGS) -o $@ $(JANET_BOOT_OBJECTS) $(CLIBS)
# 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)' > $@
cksum $@
@@ -157,9 +157,9 @@ build/janet.c: build/janet_boot src/boot/boot.janet
##### Amalgamation #####
########################
SONAME=libjanet.so.1.14
SONAME=libjanet.so.1.16
build/shell.c: src/mainclient/shell.c
build/c/shell.c: src/mainclient/shell.c
cp $< $@
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
cp $< $@
build/janet.o: build/janet.c src/include/janet.h src/conf/janetconf.h
$(HOSTCC) $(BUILD_CFLAGS) -c $< -o $@ -I build
build/janet.o: build/c/janet.c src/conf/janetconf.h src/include/janet.h
$(HOSTCC) $(BUILD_CFLAGS) -c $< -o $@
build/shell.o: build/shell.c src/include/janet.h src/conf/janetconf.h
$(HOSTCC) $(BUILD_CFLAGS) -c $< -o $@ -I build
build/shell.o: build/c/shell.c src/conf/janetconf.h src/include/janet.h
$(HOSTCC) $(BUILD_CFLAGS) -c $< -o $@
$(JANET_TARGET): build/janet.o build/shell.o
$(HOSTCC) $(LDFLAGS) $(BUILD_CFLAGS) -o $@ $^ $(CLIBS)
@@ -224,11 +224,20 @@ dist: build/janet-dist.tar.gz
build/janet-%.tar.gz: $(JANET_TARGET) \
build/janet.h \
jpm.1 janet.1 LICENSE CONTRIBUTING.md $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY) \
build/doc.html README.md build/janet.c build/shell.c jpm
$(eval JANET_DIST_DIR = "janet-$(shell basename $*)")
mkdir -p build/$(JANET_DIST_DIR)
cp -r $^ build/$(JANET_DIST_DIR)/
cd build && tar -czvf ../$@ $(JANET_DIST_DIR)
README.md build/c/janet.c build/c/shell.c jpm
mkdir -p build/$(JANET_DIST_DIR)/bin
cp $(JANET_TARGET) build/$(JANET_DIST_DIR)/bin/
cp jpm build/$(JANET_DIST_DIR)/bin/
mkdir -p build/$(JANET_DIST_DIR)/include
cp build/janet.h build/$(JANET_DIST_DIR)/include/
mkdir -p build/$(JANET_DIST_DIR)/lib/
cp $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY) build/$(JANET_DIST_DIR)/lib/
mkdir -p build/$(JANET_DIST_DIR)/man/man1/
cp janet.1 jpm.1 build/$(JANET_DIST_DIR)/man/man1/
mkdir -p build/$(JANET_DIST_DIR)/src/
cp build/c/janet.c build/c/shell.c build/$(JANET_DIST_DIR)/src/
cp CONTRIBUTING.md LICENSE README.md build/$(JANET_DIST_DIR)/
cd build && tar -czvf ../$@ ./$(JANET_DIST_DIR)
#########################
##### Documentation #####

View File

@@ -17,6 +17,9 @@ to run script files. This client program is separate from the core runtime, so
Janet can be embedded in other programs. Try Janet in your browser at
[https://janet-lang.org](https://janet-lang.org).
If you'd like to financially support the ongoing development of Janet, consider
[sponsoring its primary author](https://github.com/sponsors/bakpakin) through GitHub.
<br>
## Use Cases
@@ -58,9 +61,9 @@ Documentation is also available locally in the REPL.
Use the `(doc symbol-name)` macro to get API
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
environment, use the `(all-bindings)` function. You
@@ -170,7 +173,7 @@ Emacs, and Atom will have syntax packages for the Janet language, though.
## Installation
See [the Introduction](https://janet-lang.org/introduction.html) for more details. If you just want
See the [Introduction](https://janet-lang.org/docs/index.html) for more details. If you just want
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
@@ -231,7 +234,7 @@ See the examples directory for some example janet code.
## Discussion
Feel free to ask questions and join the discussion on the [Janet Gitter Channel](https://gitter.im/janet-language/community).
Alternatively, check out [the #janet channel on Freenode](https://webchat.freenode.net/)
Gitter provides Matrix and irc bridges as well.
## FAQ
@@ -243,8 +246,35 @@ will not. If your terminal does not support ANSI escape codes, run the REPL with
the `-n` flag, which disables color output. You can also try the `-s` if further issues
ensue.
## Why Janet
### Where is (favorite feature from other language)?
It may exist, it may not. If you want to propose major language features, go ahead and open an issue, but
they will likely by closed as "will not implement". Often, such features make one usecase simpler at the expense
of 5 others by making the language more complicated.
### Where is the example code?
In the examples directory.
### Is this a Clojure port?
No. It's similar to Clojure superficially because I like Lisps and I like the asthetics.
Internally, Janet is not at all like Clojure.
### Are the immutable data structures (tuples and structs) implemented as hash tries?
No. They are immutable arrays and hash tables. Don't try and use them like Clojure's vectors
and maps, instead they work well as table keys or other identifiers.
### Why can't we add (feature from Clojure) into the core?
Usually, one of a few reasons:
- Often, it already exists in a different form and the Clojure port would be redundant.
- Clojure programs often generate a lot of garbage and rely on the JVM to clean it up.
Janet does not run on the JVM. We admittedly have a much more primitive GC.
- We want to keep the Janet core small. With Lisps, usually a feature can be added as a library
without feeling "bolted on", especially when compared to ALGOL like languages.
## Why is it called "Janet"?
Janet is named after the almost omniscient and friendly artificial being in [The Good Place](https://en.wikipedia.org/wiki/The_Good_Place).
<img src="https://raw.githubusercontent.com/janet-lang/janet/master/assets/janet-the-good-place.gif" alt="Janet logo" width="115px" align="left">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

View File

@@ -30,7 +30,7 @@ if not "%JANET_BUILD%" == "" (
if not exist build mkdir build
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
@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
@if errorlevel 1 goto :BUILDFAIL
build\janet_boot . > build\janet.c
build\janet_boot . > build\c\janet.c
@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
%JANET_COMPILE% /Fobuild\shell.obj src\mainclient\shell.c
@if errorlevel 1 goto :BUILDFAIL
@@ -102,9 +102,9 @@ exit /b 0
mkdir dist
janet.exe tools\gendoc.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 janet.exe dist\janet.exe
copy LICENSE dist\LICENSE

View File

@@ -7,13 +7,13 @@ typedef struct {
} num_array;
static num_array *num_array_init(num_array *array, size_t size) {
array->data = (double *)calloc(size, sizeof(double));
array->data = (double *)janet_calloc(size, sizeof(double));
array->size = size;
return array;
}
static void num_array_deinit(num_array *array) {
free(array->data);
janet_free(array->data);
}
static int num_array_gc(void *p, size_t s) {

View File

@@ -1,73 +0,0 @@
# naive matrix implementation for testing typed array
(defn matrix [nrow ncol] {:nrow nrow :ncol ncol :array (tarray/new :float64 (* nrow ncol))})
(defn matrix/row [mat i]
(def {:nrow nrow :ncol ncol :array array} mat)
(tarray/new :float64 ncol 1 (* i ncol) array))
(defn matrix/column [mat j]
(def {:nrow nrow :ncol ncol :array array} mat)
(tarray/new :float64 nrow ncol j array))
(defn matrix/set [mat i j value]
(def {:nrow nrow :ncol ncol :array array} mat)
(set (array (+ (* i ncol) j)) value))
(defn matrix/get [mat i j value]
(def {:nrow nrow :ncol ncol :array array} mat)
(array (+ (* i ncol) j)))
# other variants to test rows and cols views
(defn matrix/set* [mat i j value]
(set ((matrix/row mat i) j) value))
(defn matrix/set** [mat i j value]
(set ((matrix/column mat j) i) value))
(defn matrix/get* [mat i j value]
((matrix/row mat i) j))
(defn matrix/get** [mat i j value]
((matrix/column mat j) i))
(defn tarray/print [arr]
(def size (tarray/length arr))
(prinf "[%2i]" size)
(for i 0 size
(prinf " %+6.3f " (arr i)))
(print))
(defn matrix/print [mat]
(def {:nrow nrow :ncol ncol :array tarray} mat)
(printf "matrix %iX%i %p" nrow ncol tarray)
(for i 0 nrow
(tarray/print (matrix/row mat i))))
(def nr 5)
(def nc 4)
(def A (matrix nr nc))
(loop (i :range (0 nr) j :range (0 nc))
(matrix/set A i j i))
(matrix/print A)
(loop (i :range (0 nr) j :range (0 nc))
(matrix/set* A i j i))
(matrix/print A)
(loop (i :range (0 nr) j :range (0 nc))
(matrix/set** A i j i))
(matrix/print A)
(printf "properties:\n%p" (tarray/properties (A :array)))
(for i 0 nr
(printf "row properties:[%i]\n%p" i (tarray/properties (matrix/row A i))))
(for i 0 nc
(printf "col properties:[%i]\n%p" i (tarray/properties (matrix/column A i))))

15
janet.1
View File

@@ -8,6 +8,8 @@ janet \- run the Janet language abstract machine
[\fB\-l\fR \fIMODULE\fR]
[\fB\-m\fR \fIPATH\fR]
[\fB\-c\fR \fIMODULE JIMAGE\fR]
[\fB\-w\fR \fILEVEL\fR]
[\fB\-x\fR \fILEVEL\fR]
[\fB\-\-\fR]
.BR script
.BR args ...
@@ -210,7 +212,18 @@ resulting image. Output should usually end with the .jimage extension.
Import a Janet module before running a script or repl. Multiple files can be loaded
in this manner, and exports from each file will be made available to the script
or repl.
.TP
.BR \-w\ level
Set the warning linting level for Janet.
This linting level should be one of :relaxed, :none, :strict, :normal, or a
Janet number. Any linting message that is of a greater lint level than this setting will be displayed as
a warning, but not stop compilation or execution.
.TP
.BR \-x\ level
Set the error linting level for Janet.
This linting level should be one of :relaxed, :none, :strict, :normal, or a
Janet number. Any linting message that is of a greater lint level will cause a compilation error
and stop compilation.
.TP
.BR \-\-
Stop parsing command line arguments. All arguments after this one will be considered file names

261
jpm
View File

@@ -6,14 +6,21 @@
# Basic Path Settings
#
# Windows is the OS outlier
(def- is-win (= (os/which) :windows))
(def- is-mac (= (os/which) :macos))
(def- sep (if is-win "\\" "/"))
(def- objext (if is-win ".obj" ".o"))
(def- modext (if is-win ".dll" ".so"))
(def- statext (if is-win ".static.lib" ".a"))
(def- absprefix (if is-win "C:\\" "/"))
# Allow changing the behavior via an environment variable
(def- host-os (keyword (string/ascii-lower (os/getenv "JPM_OS_WHICH" (os/which)))))
(defn- define-utils
[]
(def is-win (= host-os :windows))
(defglobal 'is-win is-win)
(defglobal 'is-mac (= host-os :macos))
(def sep (if is-win "\\" "/"))
(defglobal 'sep sep)
(defglobal 'objext (if is-win ".obj" ".o"))
(defglobal 'modext (if is-win ".dll" ".so"))
(defglobal 'statext (if is-win ".static.lib" ".a"))
(defglobal 'absprefix (if is-win "C:\\" "/")))
(define-utils)
#
# Defaults
@@ -23,12 +30,12 @@
# Overriden on some installs.
# To configure this script, replace the code between
# the START and END comments and define a function
# the START and END comments and define a function
# (install-paths) that gives the the default paths
# to use. Trailing directory separator not expected.
#
# Example.
#
#
# (defn- install-paths []
# {:headerpath "/usr/local/include/janet"
# :libpath "/usr/local/lib/janet"
@@ -44,15 +51,26 @@
(defn- try-real [path]
"If os/realpath fails just use normal path."
(try (os/realpath) ([_] path)))
(try (os/realpath path) ([_] path)))
(defn- install-paths []
{:headerpath (try-real (string exe-dir "/../include/janet"))
:libpath (try-real (string exe-dir "/../lib"))
:binpath exe-dir})
# If janetconf.h has been modified such that core janet functions and macros require
# linking to external libraries, modify this.
#
# Example - (def- extra-lflags ["-lmimalloc"])
###END###
# Redefine utils in case the above section is overriden on some installs.
(define-utils)
(compwhen (not (dyn 'extra-lflags))
(def- extra-lflags []))
# Default based on janet binary location
(def JANET_HEADERPATH (or (os/getenv "JANET_HEADERPATH")
(get (install-paths) :headerpath)))
@@ -169,9 +187,7 @@
[& args]
(if (dyn :verbose)
(print ;(interpose " " args)))
(def res (os/execute args :p))
(unless (zero? res)
(error (string "command exited with status " res))))
(os/execute args :px))
(defn copy
"Copy a file or directory recursively from one location to another."
@@ -364,11 +380,11 @@
# flags needed for the janet binary and compiling standalone
# executables.
(def janet-lflags
(case (os/which)
:macos ["-ldl" "-lm" ;thread-flags]
:windows [;thread-flags]
:linux ["-lm" "-ldl" "-lrt" ;thread-flags]
["-lm" ;thread-flags]))
(case host-os
:macos ["-ldl" "-lm" ;thread-flags ;extra-lflags]
:windows [;thread-flags ;extra-lflags]
:linux ["-lm" "-ldl" "-lrt" ;thread-flags ;extra-lflags]
["-lm" ;thread-flags ;extra-lflags]))
(def janet-ldflags [])
(def janet-cflags [])
@@ -454,6 +470,7 @@
[opts]
@[;(opt opts :cflags default-cflags)
(string "-I" (dyn :headerpath JANET_HEADERPATH))
(string "-I" (dyn :modpath JANET_MODPATH))
(string "-O" (opt opts :optimize 2))])
(defn- getcppflags
@@ -461,6 +478,7 @@
[opts]
@[;(opt opts :cppflags default-cppflags)
(string "-I" (dyn :headerpath JANET_HEADERPATH))
(string "-I" (dyn :modpath JANET_MODPATH))
(string "-O" (opt opts :optimize 2))])
(defn- entry-name
@@ -523,35 +541,26 @@
(string hpath `\\janet.lib`))
(defn- link-c
"Link C object files together to make a native module."
[opts target & objects]
(def linker (opt opts (if is-win :linker :compiler) default-linker))
(def cflags (getcflags opts))
"Link C or C++ object files together to make a native module."
[has-cpp opts target & objects]
(def linker
(if has-cpp
(opt opts (if is-win :cpp-linker :cpp-compiler) default-cpp-linker)
(opt opts (if is-win :linker :compiler) default-linker)))
(def cflags ((if has-cpp getcppflags getcflags) opts))
(def lflags [;(opt opts :lflags default-lflags)
;(if (opts :static) [] dynamic-lflags)])
(def ldflags [;(opt opts :ldflags [])])
(def deplibs (get opts :native-deps []))
(def dep-ldflags (seq [x :in deplibs] (string (dyn :modpath JANET_MODPATH) sep x modext)))
# Use import libs on windows - we need an import lib to link natives to other natives.
(def dep-importlibs (seq [x :in deplibs] (string (dyn :modpath JANET_MODPATH) sep x ".lib")))
(def ldflags [;(opt opts :ldflags []) ;dep-ldflags])
(rule target objects
(check-cc)
(print "linking " target "...")
(create-dirs target)
(if is-win
(shell linker ;ldflags (string "/OUT:" target) ;objects (win-import-library) ;lflags)
(shell linker ;cflags ;ldflags `-o` target ;objects ;lflags))))
(defn- link-cpp
"Link C++ object files together to make a native module."
[opts target & objects]
(def linker (opt opts (if is-win :cpp-linker :cpp-compiler) default-cpp-linker))
(def cflags (getcppflags opts))
(def lflags [;(opt opts :lflags default-lflags)
;(if (opts :static) [] dynamic-lflags)])
(def ldflags [;(opt opts :ldflags [])])
(rule target objects
(check-cc)
(print "linking " target "...")
(create-dirs target)
(if is-win
(shell linker ;ldflags (string "/OUT:" target) ;objects (win-import-library) ;lflags)
(shell linker ;ldflags (string "/OUT:" target) ;objects (win-import-library) ;dep-importlibs ;lflags)
(shell linker ;cflags ;ldflags `-o` target ;objects ;lflags))))
(defn- archive-c
@@ -602,7 +611,7 @@
(string (string/slice path 0 (- -1 (length modext))) statext))
(defn- make-bin-source
[declarations lookup-into-invocations]
[declarations lookup-into-invocations no-core]
(string
declarations
```
@@ -627,15 +636,22 @@ int main(int argc, const char **argv) {
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 */
JanetTable *env = janet_core_env(NULL);
JanetTable *lookup = janet_env_lookup(env);
JanetTable *temptab;
int handle = janet_gclock();
/* Load natives into unmarshalling dictionary */
```
```)
lookup-into-invocations
```
/* Unmarshal bytecode */
@@ -663,7 +679,6 @@ int main(int argc, const char **argv) {
}
/* Create enviornment */
temptab = janet_table(0);
temptab = env;
janet_table_put(temptab, janet_ckeywordv("args"), janet_wrap_array(args));
janet_gcroot(janet_wrap_table(temptab));
@@ -674,6 +689,14 @@ int main(int argc, const char **argv) {
/* Run everything */
JanetFiber *fiber = janet_fiber(jfunc, 64, argc, argc ? args->data : NULL);
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;
JanetSignal result = janet_continue(fiber, janet_wrap_nil(), &out);
if (result != JANET_SIGNAL_OK && result != JANET_SIGNAL_EVENT) {
@@ -681,11 +704,9 @@ int main(int argc, const char **argv) {
janet_deinit();
return result;
}
#ifdef JANET_NET
janet_loop();
#endif
janet_deinit();
return 0;
#endif
}
```))
@@ -694,7 +715,7 @@ int main(int argc, const char **argv) {
"Links an image with libjanet.a (or .lib) to produce an
executable. Also will try to link native modules into the
final executable as well."
[opts source dest]
[opts source dest no-core]
# Create executable's janet image
(def cimage_dest (string dest ".c"))
@@ -710,7 +731,16 @@ int main(int argc, const char **argv) {
(def dep-ldflags @[])
# 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
(def prefixes @{})
(def static-libs @[])
@@ -755,7 +785,7 @@ int main(int argc, const char **argv) {
# Make image byte buffer
(create-buffer-c-impl image cimage_dest "janet_payload_image")
# 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"))
# Compile and link final exectable
(unless no-compile
@@ -949,17 +979,18 @@ int main(int argc, const char **argv) {
(var has-cpp false)
(def objects
(seq [src :in sources]
(cond
(string/has-suffix? ".cpp" src)
(let [op (out-path src ".cpp" objext)]
(compile-cpp opts src op)
(set has-cpp true)
op)
(string/has-suffix? ".c" src)
(let [op (out-path src ".c" objext)]
(compile-c opts src op)
op)
(errorf "unknown source file type: %s, expected .c or .cpp"))))
(def suffix
(cond
(string/has-suffix? ".cpp" src) ".cpp"
(string/has-suffix? ".cc" src) ".cc"
(string/has-suffix? ".c" src) ".c"
(errorf "unknown source file type: %s, expected .c, .cc, or .cpp" src)))
(def op (out-path src suffix objext))
(if (= suffix ".c")
(compile-c opts src op)
(do (compile-cpp opts src op)
(set has-cpp true)))
op))
(when-let [embedded (opts :embedded)]
(loop [src :in embedded]
@@ -968,7 +999,7 @@ int main(int argc, const char **argv) {
(array/push objects o-src)
(create-buffer-c src c-src (embed-name src))
(compile-c opts c-src o-src)))
((if has-cpp link-cpp link-c) opts lname ;objects)
(link-c has-cpp opts lname ;objects)
(add-dep "build" lname)
(install-rule lname path)
@@ -997,16 +1028,17 @@ int main(int argc, const char **argv) {
# Get static objects
(def sobjects
(seq [src :in sources]
(cond
(string/has-suffix? ".cpp" src)
(let [op (out-path src ".cpp" sobjext)]
(compile-cpp opts src op true)
op)
(string/has-suffix? ".c" src)
(let [op (out-path src ".c" sobjext)]
(compile-c opts src op true)
op)
(errorf "unknown source file type: %s, expected .c or .cpp"))))
(def suffix
(cond
(string/has-suffix? ".cpp" src) ".cpp"
(string/has-suffix? ".cc" src) ".cc"
(string/has-suffix? ".c" src) ".c"
(errorf "unknown source file type: %s, expected .c, .cc, or .cpp" src)))
(def op (out-path src suffix sobjext))
(if (= suffix ".c")
(compile-c opts src op true)
(compile-cpp opts src op true))
op))
(when-let [embedded (opts :embedded)]
(loop [src :in embedded]
@@ -1032,6 +1064,16 @@ int main(int argc, const char **argv) {
(each s sources
(install-rule s path))))
(defn declare-headers
"Declare headers for a library installation. Installed headers can be used by other native
libraries."
[&keys {:headers headers :prefix prefix}]
(def path (string (dyn :modpath JANET_MODPATH) (or prefix "")))
(if (bytes? headers)
(install-rule headers path)
(each h headers
(install-rule h path))))
(defn declare-bin
"Declare a generic file to be installed as an executable."
[&keys {:main main}]
@@ -1044,10 +1086,10 @@ int main(int argc, const char **argv) {
This executable can be installed as well to the --binpath given."
[&keys {:install install :name name :entry entry :headers headers
: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 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
(let [cdest (string dest ".c")]
(add-dep "build" cdest))
@@ -1061,12 +1103,15 @@ int main(int argc, const char **argv) {
(install-rule dest (dyn :binpath JANET_BINPATH))))))
(defn declare-binscript
"Declare a janet file to be installed as an executable script. Creates
``Declare a janet file to be installed as an executable script. Creates
a shim on windows. If hardcode is true, will insert code into the script
such that it will run correctly even when JANET_PATH is changed."
[&keys {:main main :hardcode-syspath hardcode}]
such that it will run correctly even when JANET_PATH is changed. if auto-shebang
is truthy, will also automatically insert a correct shebang line.
``
[&keys {:main main :hardcode-syspath hardcode :is-janet is-janet}]
(def binpath (dyn :binpath JANET_BINPATH))
(if hardcode
(def auto-shebang (and is-janet (dyn :auto-shebang)))
(if (or auto-shebang hardcode)
(let [syspath (dyn :modpath JANET_MODPATH)]
(def parts (peg/match path-splitter main))
(def name (last parts))
@@ -1078,7 +1123,9 @@ int main(int argc, const char **argv) {
(def first-line (:read f :line))
(def second-line (string/format "(put root-env :syspath %v)\n" syspath))
(def rest (:read f :all))
(string first-line second-line rest)))
(string (if auto-shebang
(string "#!" (dyn :binpath JANET_BINPATH) "/janet\n"))
first-line (if hardcode second-line) rest)))
(create-dirs path)
(spit path contents)
(unless is-win (shell "chmod" "+x" path))))
@@ -1354,7 +1401,9 @@ Flags are:
(defn quickbin
[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))
(defn jpm-debug-repl
@@ -1401,26 +1450,30 @@ Flags are:
"load-lockfile" load-lockfile
"quickbin" quickbin})
(def- args (tuple/slice (dyn :args) 1))
(def- len (length args))
(var i :private 0)
(defn- main
"Script entry."
[& argv]
# Get flags
(while (< i len)
(if-let [m (peg/match argpeg (args i))]
(if (= 2 (length m))
(let [[key value] m]
(setdyn (keyword key) value))
(setdyn (keyword (m 0)) true))
(break))
(++ i))
(def- args (tuple/slice argv 1))
(def- len (length args))
(var i :private 0)
# Run subcommand
(if (= i len)
(help)
(do
(if-let [com (subcommands (args i))]
(com ;(tuple/slice args (+ i 1)))
(do
(print "invalid command " (args i))
(help)))))
# Get flags
(while (< i len)
(if-let [m (peg/match argpeg (args i))]
(if (= 2 (length m))
(let [[key value] m]
(setdyn (keyword key) value))
(setdyn (keyword (m 0)) true))
(break))
(++ i))
# Run subcommand
(if (= i len)
(help)
(do
(if-let [com (subcommands (args i))]
(com ;(tuple/slice args (+ i 1)))
(do
(print "invalid command " (args i))
(help))))))

29
jpm.1
View File

@@ -42,6 +42,10 @@ Prevents jpm from going to network to get dependencies - all dependencies should
Use this flag with the deps and update-pkgs subcommands. This is not a surefire way to prevent a build script from accessing
the network, for example, a build script that invokes curl will still have network access.
.TP
.BR \-\-auto\-shebang
Prepends installed scripts with a generated shebang line, such that they will use a janet binary located in JANET_BINPATH.
.SH OPTIONS
.TP
@@ -265,5 +269,30 @@ An optional path to a git executable to use to clone git dependencies. By defaul
if you have a normal install of git.
.RE
.B JPM_OS_WHICH
.RS
Use this option to override the C compiler and build system auto-detection for the host operating system. For example, set this
environment variable to "posix" to make sure that on platforms like MinGW, you will use GCC instead of MSVC. On most platforms, users will not need to
set this environment variable. Set this to one of the following
strings:
.IP
\- windows
.IP
\- macos
.IP
\- linux
.IP
\- freebsd
.IP
\- openbsd
.IP
\- netbsd
.IP
\- bsd
.IP
\- posix
.RE
.SH AUTHOR
Written by Calvin Rose <calsrose@gmail.com>

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose and contributors
# Copyright (c) 2021 Calvin Rose and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -19,8 +19,8 @@
# IN THE SOFTWARE.
project('janet', 'c',
default_options : ['c_std=c99', 'b_lundef=false', 'default_library=both'],
version : '1.14.2')
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
version : '1.16.1')
# Global settings
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
@@ -33,7 +33,7 @@ dl_dep = cc.find_library('dl', required : false)
thread_dep = dependency('threads')
# Link options
if build_machine.system() != 'windows'
if get_option('default_library') != 'static' and build_machine.system() != 'windows'
add_project_link_arguments('-rdynamic', language : 'c')
endif
@@ -60,9 +60,8 @@ conf.set('JANET_NO_SOURCEMAPS', not get_option('sourcemaps'))
conf.set('JANET_NO_ASSEMBLER', not get_option('assembler'))
conf.set('JANET_NO_PEG', not get_option('peg'))
conf.set('JANET_NO_NET', not get_option('net'))
conf.set('JANET_NO_EV', not get_option('ev'))
conf.set('JANET_NO_EV', not get_option('ev') or get_option('single_threaded'))
conf.set('JANET_REDUCED_OS', get_option('reduced_os'))
conf.set('JANET_NO_TYPED_ARRAY', not get_option('typed_array'))
conf.set('JANET_NO_INT_TYPES', not get_option('int_types'))
conf.set('JANET_PRF', get_option('prf'))
conf.set('JANET_RECURSION_GUARD', get_option('recursion_guard'))
@@ -135,7 +134,6 @@ core_src = [
'src/core/table.c',
'src/core/thread.c',
'src/core/tuple.c',
'src/core/typedarray.c',
'src/core/util.c',
'src/core/value.c',
'src/core/vector.c',
@@ -173,9 +171,14 @@ janetc = custom_target('janetc',
'JANET_PATH', janet_path, 'JANET_HEADERPATH', header_path
])
janet_dependencies = [m_dep, dl_dep]
if not get_option('single_threaded')
janet_dependencies += thread_dep
endif
libjanet = library('janet', janetc,
include_directories : incdir,
dependencies : [m_dep, dl_dep, thread_dep],
dependencies : janet_dependencies,
version: meson.project_version(),
soversion: version_parts[0] + '.' + version_parts[1],
install : true)
@@ -189,7 +192,7 @@ else
endif
janet_mainclient = executable('janet', janetc, mainclient_src,
include_directories : incdir,
dependencies : [m_dep, dl_dep, thread_dep],
dependencies : janet_dependencies,
c_args : extra_cflags,
install : true)
@@ -202,7 +205,7 @@ if meson.is_cross_build()
endif
janet_nativeclient = executable('janet-native', janetc, mainclient_src,
include_directories : incdir,
dependencies : [m_dep, dl_dep, thread_dep],
dependencies : janet_dependencies,
c_args : extra_native_cflags,
native : true)
else
@@ -244,6 +247,7 @@ janet_dep = declare_dependency(include_directories : incdir,
# pkgconfig
pkg = import('pkgconfig')
pkg.generate(libjanet,
subdirs: 'janet',
description: 'Library for the Janet programming language.')
# Installation

View File

@@ -8,7 +8,6 @@ option('sourcemaps', type : 'boolean', value : true)
option('reduced_os', type : 'boolean', value : false)
option('assembler', type : 'boolean', value : true)
option('peg', type : 'boolean', value : true)
option('typed_array', type : 'boolean', value : true)
option('int_types', type : 'boolean', value : true)
option('prf', type : 'boolean', value : false)
option('net', type : 'boolean', value : true)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -93,7 +93,7 @@ int main(int argc, const char **argv) {
fseek(boot_file, 0, SEEK_END);
size_t boot_size = ftell(boot_file);
fseek(boot_file, 0, SEEK_SET);
unsigned char *boot_buffer = malloc(boot_size);
unsigned char *boot_buffer = janet_malloc(boot_size);
if (NULL == boot_buffer) {
fprintf(stderr, "Failed to allocate boot buffer\n");
exit(1);
@@ -105,7 +105,7 @@ int main(int argc, const char **argv) {
fclose(boot_file);
status = janet_dobytes(env, boot_buffer, (int32_t) boot_size, boot_filename, NULL);
free(boot_buffer);
janet_free(boot_buffer);
/* Deinitialize vm */
janet_deinit();

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -4,10 +4,10 @@
#define JANETCONF_H
#define JANET_VERSION_MAJOR 1
#define JANET_VERSION_MINOR 14
#define JANET_VERSION_PATCH 2
#define JANET_VERSION_MINOR 16
#define JANET_VERSION_PATCH 1
#define JANET_VERSION_EXTRA ""
#define JANET_VERSION "1.14.2"
#define JANET_VERSION "1.16.1"
/* #define JANET_BUILD "local" */
@@ -27,7 +27,6 @@
/* #define JANET_NO_ASSEMBLER */
/* #define JANET_NO_PEG */
/* #define JANET_NO_NET */
/* #define JANET_NO_TYPED_ARRAY */
/* #define JANET_NO_INT_TYPES */
/* #define JANET_NO_EV */
/* #define JANET_NO_REALPATH */
@@ -49,6 +48,13 @@
/* #define JANET_ARCH_NAME pdp-8 */
/* #define JANET_EV_EPOLL */
/* Custom vm allocator support */
/* #include <mimalloc.h> */
/* #define janet_malloc(X) mi_malloc((X)) */
/* #define janet_realloc(X, Y) mi_realloc((X), (Y)) */
/* #define janet_calloc(X, Y) mi_calloc((X), (Y)) */
/* #define janet_free(X) mi_free((X)) */
/* Main client settings, does not affect library code */
/* #define JANET_SIMPLE_GETLINE */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -36,7 +36,7 @@ JanetArray *janet_array(int32_t capacity) {
Janet *data = NULL;
if (capacity > 0) {
janet_vm_next_collection += capacity * sizeof(Janet);
data = (Janet *) malloc(sizeof(Janet) * (size_t) capacity);
data = (Janet *) janet_malloc(sizeof(Janet) * (size_t) capacity);
if (NULL == data) {
JANET_OUT_OF_MEMORY;
}
@@ -52,7 +52,7 @@ JanetArray *janet_array_n(const Janet *elements, int32_t n) {
JanetArray *array = janet_gcalloc(JANET_MEMORY_ARRAY, sizeof(JanetArray));
array->capacity = n;
array->count = n;
array->data = malloc(sizeof(Janet) * (size_t) n);
array->data = janet_malloc(sizeof(Janet) * (size_t) n);
if (!array->data) {
JANET_OUT_OF_MEMORY;
}
@@ -68,7 +68,7 @@ void janet_array_ensure(JanetArray *array, int32_t capacity, int32_t growth) {
int64_t new_capacity = ((int64_t) capacity) * growth;
if (new_capacity > INT32_MAX) new_capacity = INT32_MAX;
capacity = (int32_t) new_capacity;
newData = realloc(old, capacity * sizeof(Janet));
newData = janet_realloc(old, capacity * sizeof(Janet));
if (NULL == newData) {
JANET_OUT_OF_MEMORY;
}
@@ -275,7 +275,7 @@ static Janet cfun_array_trim(int32_t argc, Janet *argv) {
JanetArray *array = janet_getarray(argv, 0);
if (array->count) {
if (array->count < array->capacity) {
Janet *newData = realloc(array->data, array->count * sizeof(Janet));
Janet *newData = janet_realloc(array->data, array->count * sizeof(Janet));
if (NULL == newData) {
JANET_OUT_OF_MEMORY;
}
@@ -284,7 +284,7 @@ static Janet cfun_array_trim(int32_t argc, Janet *argv) {
}
} else {
array->capacity = 0;
free(array->data);
janet_free(array->data);
array->data = NULL;
}
return argv[0];

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -224,7 +224,7 @@ static int32_t janet_asm_addenv(JanetAssembler *a, Janet envname) {
janet_table_put(&a->envs, envname, janet_wrap_number(envindex));
if (envindex >= a->environments_capacity) {
int32_t newcap = 2 * envindex;
def->environments = realloc(def->environments, newcap * sizeof(int32_t));
def->environments = janet_realloc(def->environments, newcap * sizeof(int32_t));
if (NULL == def->environments) {
JANET_OUT_OF_MEMORY;
}
@@ -582,7 +582,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
x = janet_get1(s, janet_ckeywordv("constants"));
if (janet_indexed_view(x, &arr, &count)) {
def->constants_length = count;
def->constants = malloc(sizeof(Janet) * (size_t) count);
def->constants = janet_malloc(sizeof(Janet) * (size_t) count);
if (NULL == def->constants) {
JANET_OUT_OF_MEMORY;
}
@@ -614,7 +614,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
newlen = def->defs_length + 1;
if (a.defs_capacity < newlen) {
int32_t newcap = newlen;
def->defs = realloc(def->defs, newcap * sizeof(JanetFuncDef *));
def->defs = janet_realloc(def->defs, newcap * sizeof(JanetFuncDef *));
if (NULL == def->defs) {
JANET_OUT_OF_MEMORY;
}
@@ -643,7 +643,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
}
/* Allocate bytecode array */
def->bytecode_length = blength;
def->bytecode = malloc(sizeof(uint32_t) * (size_t) blength);
def->bytecode = janet_malloc(sizeof(uint32_t) * (size_t) blength);
if (NULL == def->bytecode) {
JANET_OUT_OF_MEMORY;
}
@@ -685,7 +685,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
x = janet_get1(s, janet_ckeywordv("sourcemap"));
if (janet_indexed_view(x, &arr, &count)) {
janet_asm_assert(&a, count == def->bytecode_length, "sourcemap must have the same length as the bytecode");
def->sourcemap = malloc(sizeof(JanetSourceMapping) * (size_t) count);
def->sourcemap = janet_malloc(sizeof(JanetSourceMapping) * (size_t) count);
if (NULL == def->sourcemap) {
JANET_OUT_OF_MEMORY;
}
@@ -711,7 +711,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
/* Set environments */
def->environments =
realloc(def->environments, def->environments_length * sizeof(int32_t));
janet_realloc(def->environments, def->environments_length * sizeof(int32_t));
if (NULL == def->environments) {
JANET_OUT_OF_MEMORY;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -33,7 +33,7 @@ JanetBuffer *janet_buffer_init(JanetBuffer *buffer, int32_t capacity) {
uint8_t *data = NULL;
if (capacity < 4) capacity = 4;
janet_gcpressure(capacity);
data = malloc(sizeof(uint8_t) * (size_t) capacity);
data = janet_malloc(sizeof(uint8_t) * (size_t) capacity);
if (NULL == data) {
JANET_OUT_OF_MEMORY;
}
@@ -45,7 +45,7 @@ JanetBuffer *janet_buffer_init(JanetBuffer *buffer, int32_t capacity) {
/* Deinitialize a buffer (free data memory) */
void janet_buffer_deinit(JanetBuffer *buffer) {
free(buffer->data);
janet_free(buffer->data);
}
/* Initialize a buffer */
@@ -62,7 +62,7 @@ void janet_buffer_ensure(JanetBuffer *buffer, int32_t capacity, int32_t growth)
int64_t big_capacity = ((int64_t) capacity) * growth;
capacity = big_capacity > INT32_MAX ? INT32_MAX : (int32_t) big_capacity;
janet_gcpressure(capacity - buffer->capacity);
new_data = realloc(old, (size_t) capacity * sizeof(uint8_t));
new_data = janet_realloc(old, (size_t) capacity * sizeof(uint8_t));
if (NULL == new_data) {
JANET_OUT_OF_MEMORY;
}
@@ -91,8 +91,8 @@ void janet_buffer_extra(JanetBuffer *buffer, int32_t n) {
}
int32_t new_size = buffer->count + n;
if (new_size > buffer->capacity) {
int32_t new_capacity = new_size * 2;
uint8_t *new_data = realloc(buffer->data, new_capacity * sizeof(uint8_t));
int32_t new_capacity = (new_size > (INT32_MAX / 2)) ? INT32_MAX : (new_size * 2);
uint8_t *new_data = janet_realloc(buffer->data, new_capacity * sizeof(uint8_t));
janet_gcpressure(new_capacity - buffer->capacity);
if (NULL == new_data) {
JANET_OUT_OF_MEMORY;
@@ -201,7 +201,7 @@ static Janet cfun_buffer_trim(int32_t argc, Janet *argv) {
JanetBuffer *buffer = janet_getbuffer(argv, 0);
if (buffer->count < buffer->capacity) {
int32_t newcap = buffer->count > 4 ? buffer->count : 4;
uint8_t *newData = realloc(buffer->data, newcap);
uint8_t *newData = janet_realloc(buffer->data, newcap);
if (NULL == newData) {
JANET_OUT_OF_MEMORY;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -53,6 +53,36 @@ void janetc_cerror(JanetCompiler *c, const char *m) {
janetc_error(c, janet_cstring(m));
}
static const char *janet_lint_level_names[] = {
"relaxed",
"normal",
"strict"
};
/* Emit compiler linter messages */
void janetc_lintf(JanetCompiler *c, JanetCompileLintLevel level, const char *format, ...) {
if (NULL != c->lints) {
/* format message */
va_list args;
JanetBuffer buffer;
int32_t len = 0;
while (format[len]) len++;
janet_buffer_init(&buffer, len);
va_start(args, format);
janet_formatbv(&buffer, format, args);
va_end(args);
const uint8_t *str = janet_string(buffer.data, buffer.count);
janet_buffer_deinit(&buffer);
/* construct linting payload */
Janet *payload = janet_tuple_begin(4);
payload[0] = janet_ckeywordv(janet_lint_level_names[level]);
payload[1] = c->current_mapping.line == -1 ? janet_wrap_nil() : janet_wrap_integer(c->current_mapping.line);
payload[2] = c->current_mapping.column == -1 ? janet_wrap_nil() : janet_wrap_integer(c->current_mapping.column);
payload[3] = janet_wrap_string(str);
janet_array_push(c->lints, janet_wrap_tuple(janet_tuple_end(payload)));
}
}
/* Free a slot */
void janetc_freeslot(JanetCompiler *c, JanetSlot s) {
if (s.flags & (JANET_SLOT_CONSTANT | JANET_SLOT_REF | JANET_SLOT_NAMED)) return;
@@ -199,24 +229,41 @@ JanetSlot janetc_resolve(
/* Symbol not found - check for global */
{
Janet check;
JanetBindingType btype = janet_resolve(c->env, sym, &check);
switch (btype) {
JanetBinding binding = janet_resolve_ext(c->env, sym);
switch (binding.type) {
default:
case JANET_BINDING_NONE:
janetc_error(c, janet_formatc("unknown symbol %q", janet_wrap_symbol(sym)));
return janetc_cslot(janet_wrap_nil());
case JANET_BINDING_DEF:
case JANET_BINDING_MACRO: /* Macro should function like defs when not in calling pos */
return janetc_cslot(check);
ret = janetc_cslot(binding.value);
break;
case JANET_BINDING_VAR: {
JanetSlot ret = janetc_cslot(check);
/* TODO save type info */
ret = janetc_cslot(binding.value);
ret.flags |= JANET_SLOT_REF | JANET_SLOT_NAMED | JANET_SLOT_MUTABLE | JANET_SLOTTYPE_ANY;
ret.flags &= ~JANET_SLOT_CONSTANT;
return ret;
break;
}
}
JanetCompileLintLevel depLevel = JANET_C_LINT_RELAXED;
switch (binding.deprecation) {
case JANET_BINDING_DEP_NONE:
break;
case JANET_BINDING_DEP_RELAXED:
depLevel = JANET_C_LINT_RELAXED;
break;
case JANET_BINDING_DEP_NORMAL:
depLevel = JANET_C_LINT_NORMAL;
break;
case JANET_BINDING_DEP_STRICT:
depLevel = JANET_C_LINT_STRICT;
break;
}
if (binding.deprecation != JANET_BINDING_DEP_NONE) {
janetc_lintf(c, depLevel, "%q is deprecated", janet_wrap_symbol(sym));
}
return ret;
}
/* Symbol was found */
@@ -399,6 +446,7 @@ void janetc_throwaway(JanetFopts opts, Janet x) {
int32_t mapbufstart = janet_v_count(c->mapbuffer);
janetc_scope(&unusedScope, c, JANET_SCOPE_UNUSED, "unusued");
janetc_value(opts, x);
janetc_lintf(c, JANET_C_LINT_STRICT, "dead code, consider removing %.2q", x);
janetc_popscope(c);
if (c->buffer) {
janet_v__cnt(c->buffer) = bufstart;
@@ -504,10 +552,40 @@ static JanetSlot janetc_call(JanetFopts opts, JanetSlot *slots, JanetSlot fun) {
static JanetSlot janetc_maker(JanetFopts opts, JanetSlot *slots, int op) {
JanetCompiler *c = opts.compiler;
JanetSlot retslot;
janetc_pushslots(c, slots);
janetc_freeslots(c, slots);
retslot = janetc_gettarget(opts);
janetc_emit_s(c, op, retslot, 1);
/* Check if this structure is composed entirely of constants */
int can_inline = 1;
for (int32_t i = 0; i < janet_v_count(slots); i++) {
if (!(slots[i].flags & JANET_SLOT_CONSTANT) ||
(slots[i].flags & JANET_SLOT_SPLICED)) {
can_inline = 0;
break;
}
}
if (can_inline && (op == JOP_MAKE_STRUCT)) {
JanetKV *st = janet_struct_begin(janet_v_count(slots) / 2);
for (int32_t i = 0; i < janet_v_count(slots); i += 2) {
Janet k = slots[i].constant;
Janet v = slots[i + 1].constant;
janet_struct_put(st, k, v);
}
retslot = janetc_cslot(janet_wrap_struct(janet_struct_end(st)));
janetc_freeslots(c, slots);
} else if (can_inline && (op == JOP_MAKE_TUPLE)) {
Janet *tup = janet_tuple_begin(janet_v_count(slots));
for (int32_t i = 0; i < janet_v_count(slots); i++) {
tup[i] = slots[i].constant;
}
retslot = janetc_cslot(janet_wrap_tuple(janet_tuple_end(tup)));
janetc_freeslots(c, slots);
} else {
janetc_pushslots(c, slots);
janetc_freeslots(c, slots);
retslot = janetc_gettarget(opts);
janetc_emit_s(c, op, retslot, 1);
}
return retslot;
}
@@ -601,6 +679,9 @@ static int macroexpand1(
Janet tempOut;
JanetSignal status = janet_continue(fiberp, janet_wrap_nil(), &tempOut);
janet_table_put(c->env, mf_kw, janet_wrap_nil());
if (c->lints) {
janet_table_put(c->env, janet_ckeywordv("macro-lints"), janet_wrap_array(c->lints));
}
janet_gcunlock(lock);
if (status != JANET_SIGNAL_OK) {
const uint8_t *es = janet_formatc("(macro) %V", tempOut);
@@ -745,7 +826,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
def->bytecode_length = janet_v_count(c->buffer) - scope->bytecode_start;
if (def->bytecode_length) {
size_t s = sizeof(int32_t) * (size_t) def->bytecode_length;
def->bytecode = malloc(s);
def->bytecode = janet_malloc(s);
if (NULL == def->bytecode) {
JANET_OUT_OF_MEMORY;
}
@@ -753,7 +834,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
janet_v__cnt(c->buffer) = scope->bytecode_start;
if (NULL != c->mapbuffer && c->source) {
size_t s = sizeof(JanetSourceMapping) * (size_t) def->bytecode_length;
def->sourcemap = malloc(s);
def->sourcemap = janet_malloc(s);
if (NULL == def->sourcemap) {
JANET_OUT_OF_MEMORY;
}
@@ -778,7 +859,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
int32_t slotchunks = (def->slotcount + 31) >> 5;
/* numchunks is min of slotchunks and scope->ua.count */
int32_t numchunks = slotchunks > scope->ua.count ? scope->ua.count : slotchunks;
uint32_t *chunks = calloc(sizeof(uint32_t), slotchunks);
uint32_t *chunks = janet_calloc(sizeof(uint32_t), slotchunks);
if (NULL == chunks) {
JANET_OUT_OF_MEMORY;
}
@@ -795,7 +876,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
}
/* Initialize a compiler */
static void janetc_init(JanetCompiler *c, JanetTable *env, const uint8_t *where) {
static void janetc_init(JanetCompiler *c, JanetTable *env, const uint8_t *where, JanetArray *lints) {
c->scope = NULL;
c->buffer = NULL;
c->mapbuffer = NULL;
@@ -804,6 +885,7 @@ static void janetc_init(JanetCompiler *c, JanetTable *env, const uint8_t *where)
c->source = where;
c->current_mapping.line = -1;
c->current_mapping.column = -1;
c->lints = lints;
/* Init result */
c->result.error = NULL;
c->result.status = JANET_COMPILE_OK;
@@ -821,12 +903,13 @@ static void janetc_deinit(JanetCompiler *c) {
}
/* Compile a form. */
JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *where) {
JanetCompileResult janet_compile_lint(Janet source,
JanetTable *env, const uint8_t *where, JanetArray *lints) {
JanetCompiler c;
JanetScope rootscope;
JanetFopts fopts;
janetc_init(&c, env, where);
janetc_init(&c, env, where, lints);
/* Push a function scope */
janetc_scope(&rootscope, &c, JANET_SCOPE_FUNCTION | JANET_SCOPE_TOP, "root");
@@ -854,26 +937,35 @@ JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *w
return c.result;
}
JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *where) {
return janet_compile_lint(source, env, where, NULL);
}
/* C Function for compiling */
static Janet cfun(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 3);
janet_arity(argc, 1, 4);
JanetTable *env = argc > 1 ? janet_gettable(argv, 1) : janet_vm_fiber->env;
if (NULL == env) {
env = janet_table(0);
janet_vm_fiber->env = env;
}
const uint8_t *source = NULL;
if (argc == 3) {
if (argc >= 3) {
source = janet_getstring(argv, 2);
}
JanetCompileResult res = janet_compile(argv[0], env, source);
JanetArray *lints = (argc >= 4) ? janet_getarray(argv, 3) : NULL;
JanetCompileResult res = janet_compile_lint(argv[0], env, source, lints);
if (res.status == JANET_COMPILE_OK) {
return janet_wrap_function(janet_thunk(res.funcdef));
} else {
JanetTable *t = janet_table(4);
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));
janet_table_put(t, janet_ckeywordv("column"), janet_wrap_integer(res.error_mapping.column));
if (res.error_mapping.line > 0) {
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) {
janet_table_put(t, janet_ckeywordv("fiber"), janet_wrap_fiber(res.macrofiber));
}
@@ -884,11 +976,13 @@ static Janet cfun(int32_t argc, Janet *argv) {
static const JanetReg compile_cfuns[] = {
{
"compile", cfun,
JDOC("(compile ast &opt env source)\n\n"
JDOC("(compile ast &opt env source lints)\n\n"
"Compiles an Abstract Syntax Tree (ast) into a function. "
"Pair the compile function with parsing functionality to implement "
"eval. Returns a new function and does not modify ast. Returns an error "
"struct with keys :line, :column, and :error if compilation fails.")
"struct with keys :line, :column, and :error if compilation fails. "
"If a `lints` array is given, linting messages will be appended to the array. "
"Each message will be a tuple of the form `(level line col message)`.")
},
{NULL, NULL, NULL}
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -29,6 +29,13 @@
#include "regalloc.h"
#endif
/* Levels for compiler warnings */
typedef enum {
JANET_C_LINT_RELAXED,
JANET_C_LINT_NORMAL,
JANET_C_LINT_STRICT
} JanetCompileLintLevel;
/* Tags for some functions for the prepared inliner */
#define JANET_FUN_DEBUG 1
#define JANET_FUN_ERROR 2
@@ -78,10 +85,10 @@ typedef struct JanetSpecial JanetSpecial;
#define JANET_SLOT_MUTABLE 0x40000
#define JANET_SLOT_REF 0x80000
#define JANET_SLOT_RETURNED 0x100000
/* Needed for handling single element arrays as global vars. */
/* Used for unquote-splicing */
#define JANET_SLOT_SPLICED 0x200000
#define JANET_SLOT_DEP_NOTE 0x200000
#define JANET_SLOT_DEP_WARN 0x400000
#define JANET_SLOT_DEP_ERROR 0x800000
#define JANET_SLOT_SPLICED 0x1000000
#define JANET_SLOTTYPE_ANY 0xFFFF
@@ -164,6 +171,9 @@ struct JanetCompiler {
/* Prevent unbounded recursion */
int recursion_guard;
/* Collect linting results */
JanetArray *lints;
};
#define JANET_FOPTS_TAIL 0x10000
@@ -230,6 +240,9 @@ JanetSlot janetc_return(JanetCompiler *c, JanetSlot s);
void janetc_error(JanetCompiler *c, const uint8_t *m);
void janetc_cerror(JanetCompiler *c, const char *m);
/* Linting */
void janetc_lintf(JanetCompiler *C, JanetCompileLintLevel level, const char *format, ...);
/* Dispatch to correct form compiler */
JanetSlot janetc_value(JanetFopts opts, Janet x);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -70,7 +70,7 @@ static char *get_processed_name(const char *name) {
if (*c == '/') return (char *) name;
}
size_t l = (size_t)(c - name);
char *ret = malloc(l + 3);
char *ret = janet_malloc(l + 3);
if (NULL == ret) {
JANET_OUT_OF_MEMORY;
}
@@ -85,7 +85,7 @@ JanetModule janet_native(const char *name, const uint8_t **error) {
Clib lib = load_clib(processed_name);
JanetModule init;
JanetModconf getter;
if (name != processed_name) free(processed_name);
if (name != processed_name) janet_free(processed_name);
if (!lib) {
*error = janet_cstring(error_clib());
return NULL;
@@ -754,7 +754,7 @@ static void janet_quick_asm(
def->max_arity = max_arity;
def->flags = flags;
def->slotcount = slots;
def->bytecode = malloc(bytecode_size);
def->bytecode = janet_malloc(bytecode_size);
def->bytecode_length = (int32_t)(bytecode_size / sizeof(uint32_t));
def->name = janet_cstring(name);
if (!def->bytecode) {
@@ -1026,9 +1026,6 @@ static void janet_load_libs(JanetTable *env) {
#ifdef JANET_ASSEMBLER
janet_lib_asm(env);
#endif
#ifdef JANET_TYPED_ARRAY
janet_lib_typed_array(env);
#endif
#ifdef JANET_INT_TYPES
janet_lib_inttypes(env);
#endif
@@ -1206,7 +1203,8 @@ JanetTable *janet_core_env(JanetTable *replacements) {
"if native modules are compatible with the host program."));
/* 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_gcroot(janet_wrap_table(env));
@@ -1221,22 +1219,7 @@ JanetTable *janet_core_env(JanetTable *replacements) {
return janet_vm_core_env;
}
/* Load core cfunctions (and some built in janet assembly functions) */
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);
}
}
}
}
JanetTable *dict = janet_core_lookup_table(replacements);
/* Unmarshal bytecode */
Janet marsh_out = janet_unmarshal(
@@ -1270,3 +1253,23 @@ JanetTable *janet_core_env(JanetTable *replacements) {
}
#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

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -102,7 +102,9 @@ void janet_stacktrace(JanetFiber *fiber, Janet err) {
int32_t fi;
const char *errstr = (const char *)janet_to_string(err);
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"));
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);
JanetFiber *fiber = janet_getfiber(argv, 0);
Janet x = argc == 1 ? janet_wrap_nil() : argv[1];
x = janet_checktype(x, JANET_NIL) ? fiber->last_value : x;
janet_stacktrace(fiber, x);
return argv[0];
}
@@ -382,7 +383,7 @@ static const JanetReg debug_cfuns[] = {
JDOC("(debug/stacktrace fiber &opt err)\n\n"
"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 "
"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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -90,7 +90,7 @@ static void janet_q_init(JanetQueue *q) {
}
static void janet_q_deinit(JanetQueue *q) {
free(q->data);
janet_free(q->data);
}
static int32_t janet_q_count(JanetQueue *q) {
@@ -106,7 +106,7 @@ static int janet_q_push(JanetQueue *q, void *item, size_t itemsize) {
if (count + 1 >= JANET_MAX_Q_CAPACITY) return 1;
int32_t newcap = (count + 2) * 2;
if (newcap > JANET_MAX_Q_CAPACITY) newcap = JANET_MAX_Q_CAPACITY;
q->data = realloc(q->data, itemsize * newcap);
q->data = janet_realloc(q->data, itemsize * newcap);
if (NULL == q->data) {
JANET_OUT_OF_MEMORY;
}
@@ -213,7 +213,7 @@ static void add_timeout(JanetTimeout to) {
size_t newcount = oldcount + 1;
if (newcount > janet_vm_tq_capacity) {
size_t newcap = 2 * newcount;
JanetTimeout *tq = realloc(janet_vm_tq, newcap * sizeof(JanetTimeout));
JanetTimeout *tq = janet_realloc(janet_vm_tq, newcap * sizeof(JanetTimeout));
if (NULL == tq) {
JANET_OUT_OF_MEMORY;
}
@@ -247,7 +247,7 @@ static JanetListenerState *janet_listen_impl(JanetStream *stream, JanetListener
}
if (size < sizeof(JanetListenerState))
size = sizeof(JanetListenerState);
JanetListenerState *state = malloc(size);
JanetListenerState *state = janet_malloc(size);
if (NULL == state) {
JANET_OUT_OF_MEMORY;
}
@@ -264,7 +264,7 @@ static JanetListenerState *janet_listen_impl(JanetStream *stream, JanetListener
int resize = janet_vm_listener_cap == janet_vm_listener_count;
if (resize) {
size_t newcap = janet_vm_listener_count ? janet_vm_listener_cap * 2 : 16;
janet_vm_listeners = realloc(janet_vm_listeners, newcap * sizeof(JanetListenerState *));
janet_vm_listeners = janet_realloc(janet_vm_listeners, newcap * sizeof(JanetListenerState *));
if (NULL == janet_vm_listeners) {
JANET_OUT_OF_MEMORY;
}
@@ -301,7 +301,7 @@ static void janet_unlisten_impl(JanetListenerState *state) {
size_t index = state->_index;
janet_vm_listeners[index] = janet_vm_listeners[--janet_vm_listener_count];
janet_vm_listeners[index]->_index = index;
free(state);
janet_free(state);
}
static const JanetMethod ev_default_stream_methods[] = {
@@ -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
* for network sockets, and in general for winsock it is better to nipt duplicate
* 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
/* Marshal after dup becuse it is easier than maintaining our own ref counting. */
int duph = dup(s->handle);
@@ -544,8 +557,8 @@ void janet_ev_init_common(void) {
/* Common deinit code */
void janet_ev_deinit_common(void) {
janet_q_deinit(&janet_vm_spawn);
free(janet_vm_tq);
free(janet_vm_listeners);
janet_free(janet_vm_tq);
janet_free(janet_vm_listeners);
janet_vm_listeners = NULL;
}
@@ -1029,7 +1042,7 @@ void janet_loop1_impl(int has_timeout, JanetTimestamp to) {
/* Custom event */
JanetSelfPipeEvent *response = (JanetSelfPipeEvent *)(overlapped);
response->cb(response->msg);
free(response);
janet_free(response);
janet_ev_dec_refcount();
} else {
/* Normal event */
@@ -1067,7 +1080,7 @@ static JanetTimestamp ts_now(void) {
}
static int make_epoll_events(int mask) {
int events = EPOLLET;
int events = 0;
if (mask & JANET_ASYNC_LISTEN_READ)
events |= EPOLLIN;
if (mask & JANET_ASYNC_LISTEN_WRITE)
@@ -1163,7 +1176,7 @@ void janet_loop1_impl(int has_timeout, JanetTimestamp timeout) {
status2 = state->machine(state, JANET_ASYNC_EVENT_READ);
if (mask & EPOLLERR)
status3 = state->machine(state, JANET_ASYNC_EVENT_ERR);
if (mask & EPOLLHUP)
if ((mask & EPOLLHUP) && !(mask & (EPOLLOUT | EPOLLIN)))
status4 = state->machine(state, JANET_ASYNC_EVENT_HUP);
if (status1 == JANET_ASYNC_STATUS_DONE ||
status2 == JANET_ASYNC_STATUS_DONE ||
@@ -1236,7 +1249,7 @@ JanetListenerState *janet_listen(JanetStream *stream, JanetListener behavior, in
JanetListenerState *state = janet_listen_impl(stream, behavior, mask, size, user);
size_t newsize = janet_vm_listener_cap;
if (newsize > oldsize) {
janet_vm_fds = realloc(janet_vm_fds, (newsize + 1) * sizeof(struct pollfd));
janet_vm_fds = janet_realloc(janet_vm_fds, (newsize + 1) * sizeof(struct pollfd));
if (NULL == janet_vm_fds) {
JANET_OUT_OF_MEMORY;
}
@@ -1293,7 +1306,7 @@ void janet_loop1_impl(int has_timeout, JanetTimestamp timeout) {
status2 = state->machine(state, JANET_ASYNC_EVENT_READ);
if (mask & POLLERR)
status3 = state->machine(state, JANET_ASYNC_EVENT_ERR);
if (mask & POLLHUP)
if ((mask & POLLHUP) && !(mask & (POLLIN | POLLOUT)))
status4 = state->machine(state, JANET_ASYNC_EVENT_HUP);
if (status1 == JANET_ASYNC_STATUS_DONE ||
status2 == JANET_ASYNC_STATUS_DONE ||
@@ -1307,7 +1320,7 @@ void janet_ev_init(void) {
janet_ev_init_common();
janet_vm_fds = NULL;
janet_ev_setup_selfpipe();
janet_vm_fds = malloc(sizeof(struct pollfd));
janet_vm_fds = janet_malloc(sizeof(struct pollfd));
if (NULL == janet_vm_fds) {
JANET_OUT_OF_MEMORY;
}
@@ -1320,7 +1333,7 @@ void janet_ev_init(void) {
void janet_ev_deinit(void) {
janet_ev_deinit_common();
janet_ev_cleanup_selfpipe();
free(janet_vm_fds);
janet_free(janet_vm_fds);
janet_vm_fds = NULL;
}
@@ -1358,7 +1371,7 @@ static void *janet_thread_body(void *ptr) {
JanetThreadedSubroutine subr = init->subr;
JanetThreadedCallback cb = init->cb;
int fd = init->write_pipe;
free(init);
janet_free(init);
JanetSelfPipeEvent response;
response.msg = subr(msg);
response.cb = cb;
@@ -1378,7 +1391,7 @@ static void *janet_thread_body(void *ptr) {
#endif
void janet_ev_threaded_call(JanetThreadedSubroutine fp, JanetEVGenericMessage arguments, JanetThreadedCallback cb) {
JanetEVThreadInit *init = malloc(sizeof(JanetEVThreadInit));
JanetEVThreadInit *init = janet_malloc(sizeof(JanetEVThreadInit));
if (NULL == init) {
JANET_OUT_OF_MEMORY;
}
@@ -1390,7 +1403,7 @@ void janet_ev_threaded_call(JanetThreadedSubroutine fp, JanetEVGenericMessage ar
init->write_pipe = janet_vm_iocp;
HANDLE thread_handle = CreateThread(NULL, 0, janet_thread_body, init, 0, NULL);
if (NULL == thread_handle) {
free(init);
janet_free(init);
janet_panic("failed to create thread");
}
CloseHandle(thread_handle); /* detach from thread */
@@ -1399,7 +1412,7 @@ void janet_ev_threaded_call(JanetThreadedSubroutine fp, JanetEVGenericMessage ar
pthread_t waiter_thread;
int err = pthread_create(&waiter_thread, NULL, janet_thread_body, init);
if (err) {
free(init);
janet_free(init);
janet_panicf("%s", strerror(err));
}
pthread_detach(waiter_thread);
@@ -1422,7 +1435,7 @@ void janet_ev_default_threaded_callback(JanetEVGenericMessage return_value) {
case JANET_EV_TCTAG_STRING:
case JANET_EV_TCTAG_STRINGF:
janet_schedule(return_value.fiber, janet_cstringv((const char *) return_value.argp));
if (return_value.tag == JANET_EV_TCTAG_STRINGF) free(return_value.argp);
if (return_value.tag == JANET_EV_TCTAG_STRINGF) janet_free(return_value.argp);
break;
case JANET_EV_TCTAG_KEYWORD:
janet_schedule(return_value.fiber, janet_ckeywordv((const char *) return_value.argp));
@@ -1430,7 +1443,7 @@ void janet_ev_default_threaded_callback(JanetEVGenericMessage return_value) {
case JANET_EV_TCTAG_ERR_STRING:
case JANET_EV_TCTAG_ERR_STRINGF:
janet_cancel(return_value.fiber, janet_cstringv((const char *) return_value.argp));
if (return_value.tag == JANET_EV_TCTAG_STRINGF) free(return_value.argp);
if (return_value.tag == JANET_EV_TCTAG_STRINGF) janet_free(return_value.argp);
break;
case JANET_EV_TCTAG_ERR_KEYWORD:
janet_cancel(return_value.fiber, janet_ckeywordv((const char *) return_value.argp));
@@ -2079,7 +2092,7 @@ static Janet cfun_ev_thread(int32_t argc, Janet *argv) {
janet_getfiber(argv, 0);
Janet value = argc == 2 ? argv[1] : janet_wrap_nil();
/* Marshal arguments for the new thread. */
JanetBuffer *buffer = malloc(sizeof(JanetBuffer));
JanetBuffer *buffer = janet_malloc(sizeof(JanetBuffer));
if (NULL == buffer) {
JANET_OUT_OF_MEMORY;
}
@@ -2314,6 +2327,7 @@ static const JanetReg ev_cfuns[] = {
void janet_lib_ev(JanetTable *env) {
janet_core_cfuns(env, NULL, ev_cfuns);
janet_register_abstract_type(&janet_stream_type);
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -53,7 +53,7 @@ static JanetFiber *fiber_alloc(int32_t capacity) {
capacity = 32;
}
fiber->capacity = capacity;
data = malloc(sizeof(Janet) * (size_t) capacity);
data = janet_malloc(sizeof(Janet) * (size_t) capacity);
if (NULL == data) {
JANET_OUT_OF_MEMORY;
}
@@ -100,12 +100,12 @@ JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity, int32_t argc, c
static void janet_fiber_refresh_memory(JanetFiber *fiber) {
int32_t n = fiber->capacity;
if (n) {
Janet *newData = malloc(sizeof(Janet) * n);
Janet *newData = janet_malloc(sizeof(Janet) * n);
if (NULL == newData) {
JANET_OUT_OF_MEMORY;
}
memcpy(newData, fiber->data, fiber->capacity * sizeof(Janet));
free(fiber->data);
janet_free(fiber->data);
fiber->data = newData;
}
}
@@ -115,7 +115,7 @@ static void janet_fiber_refresh_memory(JanetFiber *fiber) {
void janet_fiber_setcapacity(JanetFiber *fiber, int32_t n) {
int32_t old_size = fiber->capacity;
int32_t diff = n - old_size;
Janet *newData = realloc(fiber->data, sizeof(Janet) * n);
Janet *newData = janet_realloc(fiber->data, sizeof(Janet) * n);
if (NULL == newData) {
JANET_OUT_OF_MEMORY;
}
@@ -254,7 +254,7 @@ static void janet_env_detach(JanetFuncEnv *env) {
janet_env_valid(env);
int32_t len = env->length;
size_t s = sizeof(Janet) * (size_t) len;
Janet *vmem = malloc(s);
Janet *vmem = janet_malloc(s);
janet_vm_next_collection += (uint32_t) s;
if (NULL == vmem) {
JANET_OUT_OF_MEMORY;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -290,13 +290,13 @@ static void janet_deinit_block(JanetGCObject *mem) {
janet_symbol_deinit(((JanetStringHead *) mem)->data);
break;
case JANET_MEMORY_ARRAY:
free(((JanetArray *) mem)->data);
janet_free(((JanetArray *) mem)->data);
break;
case JANET_MEMORY_TABLE:
free(((JanetTable *) mem)->data);
janet_free(((JanetTable *) mem)->data);
break;
case JANET_MEMORY_FIBER:
free(((JanetFiber *)mem)->data);
janet_free(((JanetFiber *)mem)->data);
break;
case JANET_MEMORY_BUFFER:
janet_buffer_deinit((JanetBuffer *) mem);
@@ -311,18 +311,18 @@ static void janet_deinit_block(JanetGCObject *mem) {
case JANET_MEMORY_FUNCENV: {
JanetFuncEnv *env = (JanetFuncEnv *)mem;
if (0 == env->offset)
free(env->as.values);
janet_free(env->as.values);
}
break;
case JANET_MEMORY_FUNCDEF: {
JanetFuncDef *def = (JanetFuncDef *)mem;
/* TODO - get this all with one alloc and one free */
free(def->defs);
free(def->environments);
free(def->constants);
free(def->bytecode);
free(def->sourcemap);
free(def->closure_bitset);
janet_free(def->defs);
janet_free(def->environments);
janet_free(def->constants);
janet_free(def->bytecode);
janet_free(def->sourcemap);
janet_free(def->closure_bitset);
}
break;
}
@@ -347,7 +347,7 @@ void janet_sweep() {
} else {
janet_vm_blocks = next;
}
free(current);
janet_free(current);
}
current = next;
}
@@ -359,7 +359,7 @@ void *janet_gcalloc(enum JanetMemoryType type, size_t size) {
/* Make sure everything is inited */
janet_assert(NULL != janet_vm_cache, "please initialize janet before use");
mem = malloc(size);
mem = janet_malloc(size);
/* Check for bad malloc */
if (NULL == mem) {
@@ -382,7 +382,7 @@ static void free_one_scratch(JanetScratch *s) {
if (NULL != s->finalize) {
s->finalize((char *) s->mem);
}
free(s);
janet_free(s);
}
/* Free all allocated scratch memory */
@@ -434,7 +434,7 @@ void janet_gcroot(Janet root) {
size_t newcount = janet_vm_root_count + 1;
if (newcount > janet_vm_root_capacity) {
size_t newcap = 2 * newcount;
janet_vm_roots = realloc(janet_vm_roots, sizeof(Janet) * newcap);
janet_vm_roots = janet_realloc(janet_vm_roots, sizeof(Janet) * newcap);
if (NULL == janet_vm_roots) {
JANET_OUT_OF_MEMORY;
}
@@ -494,12 +494,12 @@ void janet_clear_memory(void) {
while (NULL != current) {
janet_deinit_block(current);
JanetGCObject *next = current->next;
free(current);
janet_free(current);
current = next;
}
janet_vm_blocks = NULL;
janet_free_all_scratch();
free(janet_scratch_mem);
janet_free(janet_scratch_mem);
}
/* Primitives for suspending GC. */
@@ -513,14 +513,14 @@ void janet_gcunlock(int handle) {
/* Scratch memory API */
void *janet_smalloc(size_t size) {
JanetScratch *s = malloc(sizeof(JanetScratch) + size);
JanetScratch *s = janet_malloc(sizeof(JanetScratch) + size);
if (NULL == s) {
JANET_OUT_OF_MEMORY;
}
s->finalize = NULL;
if (janet_scratch_len == janet_scratch_cap) {
size_t newcap = 2 * janet_scratch_cap + 2;
JanetScratch **newmem = (JanetScratch **) realloc(janet_scratch_mem, newcap * sizeof(JanetScratch));
JanetScratch **newmem = (JanetScratch **) janet_realloc(janet_scratch_mem, newcap * sizeof(JanetScratch));
if (NULL == newmem) {
JANET_OUT_OF_MEMORY;
}
@@ -547,7 +547,7 @@ void *janet_srealloc(void *mem, size_t size) {
if (janet_scratch_len) {
for (size_t i = janet_scratch_len - 1; ; i--) {
if (janet_scratch_mem[i] == s) {
JanetScratch *news = realloc(s, size + sizeof(JanetScratch));
JanetScratch *news = janet_realloc(s, size + sizeof(JanetScratch));
if (NULL == news) {
JANET_OUT_OF_MEMORY;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -544,7 +544,7 @@ static Janet cfun_io_printf_impl_x(int32_t argc, Janet *argv, int newline,
/* Clear buffer to make things easier for GC */
buf->count = 0;
buf->capacity = 0;
free(buf->data);
janet_free(buf->data);
buf->data = NULL;
return janet_wrap_nil();
}
@@ -746,6 +746,7 @@ static const JanetReg io_cfuns[] = {
"* r - allow reading from the file\n\n"
"* w - allow writing 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"
"* + - append to the file instead of overwriting it\n\n"
"* n - error if the file cannot be opened instead of returning nil")

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -738,7 +738,7 @@ static const uint8_t *unmarshal_one_env(
if (length == 0) {
janet_panic("invalid funcenv length");
}
env->as.values = malloc(sizeof(Janet) * (size_t) length);
env->as.values = janet_malloc(sizeof(Janet) * (size_t) length);
if (!env->as.values) {
JANET_OUT_OF_MEMORY;
}
@@ -834,7 +834,7 @@ static const uint8_t *unmarshal_one_def(
/* Unmarshal constants */
if (constants_length) {
def->constants = malloc(sizeof(Janet) * constants_length);
def->constants = janet_malloc(sizeof(Janet) * constants_length);
if (!def->constants) {
JANET_OUT_OF_MEMORY;
}
@@ -846,7 +846,7 @@ static const uint8_t *unmarshal_one_def(
def->constants_length = constants_length;
/* Unmarshal bytecode */
def->bytecode = malloc(sizeof(uint32_t) * bytecode_length);
def->bytecode = janet_malloc(sizeof(uint32_t) * bytecode_length);
if (!def->bytecode) {
JANET_OUT_OF_MEMORY;
}
@@ -855,7 +855,7 @@ static const uint8_t *unmarshal_one_def(
/* Unmarshal environments */
if (def->flags & JANET_FUNCDEF_FLAG_HASENVS) {
def->environments = calloc(1, sizeof(int32_t) * (size_t) environments_length);
def->environments = janet_calloc(1, sizeof(int32_t) * (size_t) environments_length);
if (!def->environments) {
JANET_OUT_OF_MEMORY;
}
@@ -869,7 +869,7 @@ static const uint8_t *unmarshal_one_def(
/* Unmarshal sub funcdefs */
if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) {
def->defs = calloc(1, sizeof(JanetFuncDef *) * (size_t) defs_length);
def->defs = janet_calloc(1, sizeof(JanetFuncDef *) * (size_t) defs_length);
if (!def->defs) {
JANET_OUT_OF_MEMORY;
}
@@ -884,7 +884,7 @@ static const uint8_t *unmarshal_one_def(
/* Unmarshal source maps if needed */
if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCEMAP) {
int32_t current = 0;
def->sourcemap = malloc(sizeof(JanetSourceMapping) * (size_t) bytecode_length);
def->sourcemap = janet_malloc(sizeof(JanetSourceMapping) * (size_t) bytecode_length);
if (!def->sourcemap) {
JANET_OUT_OF_MEMORY;
}
@@ -900,7 +900,7 @@ static const uint8_t *unmarshal_one_def(
/* Unmarshal closure bitset if needed */
if (def->flags & JANET_FUNCDEF_FLAG_HASCLOBITSET) {
int32_t n = (def->slotcount + 31) >> 5;
def->closure_bitset = malloc(sizeof(uint32_t) * (size_t) n);
def->closure_bitset = janet_malloc(sizeof(uint32_t) * (size_t) n);
if (NULL == def->closure_bitset) {
JANET_OUT_OF_MEMORY;
}
@@ -961,7 +961,7 @@ static const uint8_t *unmarshal_one_fiber(
/* Allocate stack memory */
fiber->capacity = fiber_stacktop + 10;
fiber->data = malloc(sizeof(Janet) * fiber->capacity);
fiber->data = janet_malloc(sizeof(Janet) * fiber->capacity);
if (!fiber->data) {
JANET_OUT_OF_MEMORY;
}
@@ -1428,9 +1428,9 @@ static const JanetReg marsh_cfuns[] = {
"marshal", cfun_marshal,
JDOC("(marshal x &opt reverse-lookup buffer)\n\n"
"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 "
"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 "
"unmarshalling.")
},

View File

@@ -265,19 +265,20 @@ static struct addrinfo *janet_get_addrinfo(Janet *argv, int32_t offset, int sock
#ifndef JANET_WINDOWS
if (janet_keyeq(argv[offset], "unix")) {
const char *path = janet_getcstring(argv, offset + 1);
struct sockaddr_un *saddr = calloc(1, sizeof(struct sockaddr_un));
struct sockaddr_un *saddr = janet_calloc(1, sizeof(struct sockaddr_un));
if (saddr == NULL) {
JANET_OUT_OF_MEMORY;
}
saddr->sun_family = AF_UNIX;
size_t path_size = sizeof(saddr->sun_path);
#ifdef JANET_LINUX
if (path[0] == '@') {
saddr->sun_path[0] = '\0';
snprintf(saddr->sun_path + 1, 107, "%s", path + 1);
snprintf(saddr->sun_path + 1, path_size - 1, "%s", path + 1);
} else
#endif
{
snprintf(saddr->sun_path, 108, "%s", path);
snprintf(saddr->sun_path, path_size, "%s", path);
}
*is_unix = 1;
return (struct addrinfo *) saddr;
@@ -397,7 +398,7 @@ static Janet cfun_net_connect(int32_t argc, Janet *argv) {
#else
int status = connect(sock, addr, addrlen);
if (is_unix) {
free(ai);
janet_free(ai);
} else {
freeaddrinfo(ai);
}
@@ -431,6 +432,47 @@ static const char *serverify_socket(JSock sfd) {
return NULL;
}
#ifdef JANET_WINDOWS
#define JANET_SHUTDOWN_RW SD_BOTH
#define JANET_SHUTDOWN_R SD_RECEIVE
#define JANET_SHUTDOWN_W SD_SEND
#else
#define JANET_SHUTDOWN_RW SHUT_RDWR
#define JANET_SHUTDOWN_R SHUT_RD
#define JANET_SHUTDOWN_W SHUT_WR
#endif
static Janet cfun_net_shutdown(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
janet_stream_flags(stream, JANET_STREAM_SOCKET);
int shutdown_type = JANET_SHUTDOWN_RW;
if (argc == 2) {
const uint8_t *kw = janet_getkeyword(argv, 1);
if (0 == janet_cstrcmp(kw, "rw")) {
shutdown_type = JANET_SHUTDOWN_RW;
} else if (0 == janet_cstrcmp(kw, "r")) {
shutdown_type = JANET_SHUTDOWN_R;
} else if (0 == janet_cstrcmp(kw, "w")) {
shutdown_type = JANET_SHUTDOWN_W;
} else {
janet_panicf("unexpected keyword %v", argv[1]);
}
}
int status;
#ifdef JANET_WINDOWS
status = shutdown((SOCKET) stream->handle, shutdown_type);
#else
do {
status = shutdown(stream->handle, shutdown_type);
} while (status == -1 && errno == EINTR);
#endif
if (status) {
janet_panicf("could not shutdown socket: %V", janet_ev_lasterr());
}
return argv[0];
}
static Janet cfun_net_listen(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 3);
@@ -444,20 +486,20 @@ static Janet cfun_net_listen(int32_t argc, Janet *argv) {
if (is_unix) {
sfd = socket(AF_UNIX, socktype | JSOCKFLAGS, 0);
if (!JSOCKVALID(sfd)) {
free(ai);
janet_free(ai);
janet_panicf("could not create socket: %V", janet_ev_lasterr());
}
const char *err = serverify_socket(sfd);
if (NULL != err || bind(sfd, (struct sockaddr *)ai, sizeof(struct sockaddr_un))) {
JSOCKCLOSE(sfd);
free(ai);
janet_free(ai);
if (err) {
janet_panic(err);
} else {
janet_panicf("could not bind socket: %V", janet_ev_lasterr());
}
}
free(ai);
janet_free(ai);
} else
#endif
{
@@ -622,6 +664,7 @@ static const JanetMethod net_stream_methods[] = {
{"evread", janet_cfun_stream_read},
{"evchunk", janet_cfun_stream_chunk},
{"evwrite", janet_cfun_stream_write},
{"shutdown", cfun_net_shutdown},
{NULL, NULL}
};
@@ -709,6 +752,16 @@ static const JanetReg net_cfuns[] = {
"that can be used to communicate with the server. Type is an optional keyword "
"to specify a connection type, either :stream or :datagram. The default is :stream. ")
},
{
"net/shutdown", cfun_net_shutdown,
JDOC("(net/shutdown stream &opt mode)\n\n"
"Stop communication on this socket in a graceful manner, either in both directions or just "
"reading/writing from the stream. The `mode` parameter controls which communication to stop on the socket. "
"\n\n* `:wr` is the default and prevents both reading new data from the socket and writing new data to the socket.\n"
"* `:r` disables reading new data from the socket.\n"
"* `:w` disable writing data to the socket.\n\n"
"Returns the original socket.")
},
{NULL, NULL, NULL}
};

View File

@@ -56,7 +56,12 @@
#include <dirent.h>
#include <sys/types.h>
#include <sys/wait.h>
#ifdef JANET_APPLE
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#else
extern char **environ;
#endif
#ifdef JANET_THREADS
#include <pthread.h>
#endif
@@ -187,49 +192,71 @@ static Janet os_exit(int32_t argc, Janet *argv) {
#ifndef JANET_NO_PROCESSES
/* Get env for os_execute */
static char **os_execute_env(int32_t argc, const Janet *argv) {
char **envp = NULL;
if (argc > 2) {
JanetDictView dict = janet_getdictionary(argv, 2);
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;
#ifdef JANET_WINDOWS
typedef char *EnvBlock;
#else
typedef char **EnvBlock;
#endif
/* Get env for os_execute */
static EnvBlock os_execute_env(int32_t argc, const Janet *argv) {
if (argc <= 2) return NULL;
JanetDictView dict = janet_getdictionary(argv, 2);
#ifdef JANET_WINDOWS
JanetBuffer *temp = janet_buffer(10);
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);
janet_buffer_push_bytes(temp, keys, janet_string_length(keys));
janet_buffer_push_u8(temp, '=');
janet_buffer_push_bytes(temp, vals, janet_string_length(vals));
janet_buffer_push_u8(temp, '\0');
}
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;
#endif
}
/* Free memory from os_execute. Not actually needed, but doesn't pressure the GC
in the happy path. */
static void os_execute_cleanup(char **envp, const char **child_argv) {
static void os_execute_cleanup(EnvBlock envp, const char **child_argv) {
#ifdef JANET_WINDOWS
(void) child_argv;
if (NULL != envp) janet_sfree(envp);
#else
janet_sfree((void *)child_argv);
#endif
if (NULL != envp) {
char **envitem = envp;
while (*envitem != NULL) {
@@ -238,6 +265,7 @@ static void os_execute_cleanup(char **envp, const char **child_argv) {
}
}
janet_sfree(envp);
#endif
}
#ifdef JANET_WINDOWS
@@ -730,12 +758,11 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
uint64_t flags = 0;
if (argc > 1) {
flags = janet_getflags(argv, 1, "epx");
}
/* Get environment */
int use_environ = !janet_flag_at(flags, 0);
char **envp = os_execute_env(argc, argv);
EnvBlock envp = os_execute_env(argc, argv);
/* Get arguments */
JanetView exargs = janet_getindexed(argv, 0);
@@ -919,7 +946,6 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
janet_unlock_environ();
}
/* Wait for child */
os_execute_cleanup(envp, child_argv);
if (status) {
janet_panicf("%p: %s", argv[0], strerror(errno));
@@ -977,7 +1003,7 @@ static Janet os_spawn(int32_t argc, Janet *argv) {
/* Runs in a separate thread */
static JanetEVGenericMessage os_shell_subr(JanetEVGenericMessage args) {
int stat = system((const char *) args.argp);
free(args.argp);
janet_free(args.argp);
if (args.argi) {
args.tag = JANET_EV_TCTAG_INTEGER;
} else {
@@ -1740,7 +1766,7 @@ static Janet os_realpath(int32_t argc, Janet *argv) {
#endif
if (NULL == dest) janet_panicf("%s: %s", strerror(errno), src);
Janet ret = janet_cstringv(dest);
free(dest);
janet_free(dest);
return ret;
#endif
}
@@ -2064,7 +2090,7 @@ static const JanetReg os_cfuns[] = {
#ifndef JANET_NO_PROCESSES
{
"os/execute", os_execute,
JDOC("(os/execute args &opts flags env)\n\n"
JDOC("(os/execute args &opt flags env)\n\n"
"Execute a program on the system and pass it string arguments. `flags` "
"is a keyword that modifies how the program will execute.\n\n"
"* :e - enables passing an environment to the program. Without :e, the "
@@ -2084,7 +2110,7 @@ static const JanetReg os_cfuns[] = {
},
{
"os/spawn", os_spawn,
JDOC("(os/spawn args &opts flags env)\n\n"
JDOC("(os/spawn args &opt flags env)\n\n"
"Execute a program on the system and return a handle to the process. Otherwise, the "
"same arguments as os/execute. Does not wait for the process.")
},

View File

@@ -123,7 +123,7 @@ static void NAME(JanetParser *p, T x) { \
if (newcount > p->STACKCAP) { \
T *next; \
size_t newcap = 2 * newcount; \
next = realloc(p->STACK, sizeof(T) * newcap); \
next = janet_realloc(p->STACK, sizeof(T) * newcap); \
if (NULL == next) { \
JANET_OUT_OF_MEMORY; \
} \
@@ -175,7 +175,14 @@ static void popstate(JanetParser *p, Janet val) {
if (newtop->flags & PFLAG_CONTAINER) {
newtop->argn++;
/* 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);
return;
} else if (newtop->flags & PFLAG_READERMAC) {
@@ -730,6 +737,19 @@ const char *janet_parser_error(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;
size_t i;
if (parser->pending == 0) return janet_wrap_nil();
@@ -763,9 +783,9 @@ void janet_parser_init(JanetParser *parser) {
}
void janet_parser_deinit(JanetParser *parser) {
free(parser->args);
free(parser->buf);
free(parser->states);
janet_free(parser->args);
janet_free(parser->buf);
janet_free(parser->states);
}
void janet_parser_clone(const JanetParser *src, JanetParser *dest) {
@@ -792,17 +812,17 @@ void janet_parser_clone(const JanetParser *src, JanetParser *dest) {
dest->states = NULL;
dest->buf = NULL;
if (dest->bufcap) {
dest->buf = malloc(dest->bufcap);
dest->buf = janet_malloc(dest->bufcap);
if (!dest->buf) goto nomem;
memcpy(dest->buf, src->buf, dest->bufcap);
}
if (dest->argcap) {
dest->args = malloc(sizeof(Janet) * dest->argcap);
dest->args = janet_malloc(sizeof(Janet) * dest->argcap);
if (!dest->args) goto nomem;
memcpy(dest->args, src->args, dest->argcap * sizeof(Janet));
}
if (dest->statecap) {
dest->states = malloc(sizeof(JanetParseState) * dest->statecap);
dest->states = janet_malloc(sizeof(JanetParseState) * dest->statecap);
if (!dest->states) goto nomem;
memcpy(dest->states, src->states, dest->statecap * sizeof(JanetParseState));
}
@@ -910,15 +930,20 @@ static Janet cfun_parse_insert(int32_t argc, Janet *argv) {
if (s->flags & PFLAG_COMMENT) s--;
if (s->flags & PFLAG_CONTAINER) {
s->argn++;
if (p->statecount == 1) p->pending++;
push_arg(p, argv[1]);
if (p->statecount == 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)) {
const uint8_t *str = janet_to_string(argv[1]);
int32_t slen = janet_string_length(str);
size_t newcount = p->bufcount + slen;
if (p->bufcap < newcount) {
size_t newcap = 2 * newcount;
p->buf = realloc(p->buf, newcap);
p->buf = janet_realloc(p->buf, newcap);
if (p->buf == NULL) {
JANET_OUT_OF_MEMORY;
}
@@ -980,9 +1005,13 @@ static Janet cfun_parse_error(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);
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) {
@@ -1217,10 +1246,12 @@ static const JanetReg parse_cfuns[] = {
},
{
"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 "
"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,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -286,7 +286,7 @@ tail:
const uint8_t *next_text;
CapState cs = cap_save(s);
down1(s);
while (text < s->text_end) {
while (text <= s->text_end) {
CapState cs2 = cap_save(s);
next_text = peg_rule(s, rule_a, text);
if (next_text) {
@@ -296,7 +296,7 @@ tail:
text++;
}
up1(s);
if (text >= s->text_end) {
if (text > s->text_end) {
cap_load(s, cs);
return NULL;
}
@@ -596,6 +596,30 @@ tail:
return text + width;
}
case RULE_UNREF: {
int32_t tcap = s->tags->count;
down1(s);
const uint8_t *result = peg_rule(s, s->bytecode + rule[1], text);
up1(s);
if (!result) return NULL;
int32_t final_tcap = s->tags->count;
/* Truncate tagged captures to not include items of the given tag */
int32_t w = tcap;
/* If no tag is given, drop ALL tagged captures */
if (rule[2]) {
for (int32_t i = tcap; i < final_tcap; i++) {
if (s->tags->data[i] != (0xFF & rule[2])) {
s->tags->data[w] = s->tags->data[i];
s->tagged_captures->data[w] = s->tagged_captures->data[i];
w++;
}
}
}
s->tags->count = w;
s->tagged_captures->count = w;
return result;
}
}
}
@@ -919,15 +943,15 @@ static void spec_error(Builder *b, int32_t argc, const Janet *argv) {
spec_onerule(b, argc, argv, RULE_ERROR);
}
}
static void spec_drop(Builder *b, int32_t argc, const Janet *argv) {
spec_onerule(b, argc, argv, RULE_DROP);
}
static void spec_to(Builder *b, int32_t argc, const Janet *argv) {
spec_onerule(b, argc, argv, RULE_TO);
}
static void spec_thru(Builder *b, int32_t argc, const Janet *argv) {
spec_onerule(b, argc, argv, RULE_THRU);
}
static void spec_drop(Builder *b, int32_t argc, const Janet *argv) {
spec_onerule(b, argc, argv, RULE_DROP);
}
/* Rule of the form [rule, tag] */
static void spec_cap1(Builder *b, int32_t argc, const Janet *argv, uint32_t op) {
@@ -947,6 +971,9 @@ static void spec_accumulate(Builder *b, int32_t argc, const Janet *argv) {
static void spec_group(Builder *b, int32_t argc, const Janet *argv) {
spec_cap1(b, argc, argv, RULE_GROUP);
}
static void spec_unref(Builder *b, int32_t argc, const Janet *argv) {
spec_cap1(b, argc, argv, RULE_UNREF);
}
static void spec_reference(Builder *b, int32_t argc, const Janet *argv) {
peg_arity(b, argc, 1, 2);
@@ -1027,7 +1054,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) {
peg_arity(b, argc, 1, 2);
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]);
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);
@@ -1104,6 +1131,7 @@ static const SpecialPair peg_specials[] = {
{"to", spec_to},
{"uint", spec_uint_le},
{"uint-be", spec_uint_be},
{"unref", spec_unref},
};
/* Compile a janet value into a rule and return the rule index. */
@@ -1120,7 +1148,9 @@ static uint32_t peg_compile1(Builder *b, Janet peg) {
for (; i > 0 && janet_checktype(peg, JANET_KEYWORD); --i) {
Janet nextPeg = janet_table_get_ex(grammar, peg, &grammar);
if (!grammar || janet_checktype(nextPeg, JANET_NIL)) {
nextPeg = janet_table_get(b->default_grammar, peg);
nextPeg = (b->default_grammar == NULL)
? janet_wrap_nil()
: janet_table_get(b->default_grammar, peg);
if (janet_checktype(nextPeg, JANET_NIL)) {
peg_panic(b, "unknown rule");
}
@@ -1307,7 +1337,7 @@ static void *peg_unmarshal(JanetMarshalContext *ctx) {
* bytecode. */
uint32_t blen = (int32_t) peg->bytecode_len;
uint32_t clen = peg->num_constants;
uint8_t *op_flags = calloc(1, blen);
uint8_t *op_flags = janet_calloc(1, blen);
if (NULL == op_flags) {
JANET_OUT_OF_MEMORY;
}
@@ -1392,6 +1422,7 @@ static void *peg_unmarshal(JanetMarshalContext *ctx) {
case RULE_ACCUMULATE:
case RULE_GROUP:
case RULE_CAPTURE:
case RULE_UNREF:
/* [rule, tag] */
if (rule[1] >= blen) goto bad;
op_flags[rule[1]] |= 0x01;
@@ -1437,11 +1468,11 @@ static void *peg_unmarshal(JanetMarshalContext *ctx) {
peg->bytecode = bytecode;
peg->constants = constants;
peg->has_backref = has_backref;
free(op_flags);
janet_free(op_flags);
return peg;
bad:
free(op_flags);
janet_free(op_flags);
janet_panic("invalid peg bytecode");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -351,6 +351,9 @@ struct pretty {
int indent;
int flags;
int32_t bufstartlen;
int32_t *keysort_buffer;
int32_t keysort_capacity;
int32_t keysort_start;
JanetTable seen;
};
@@ -594,31 +597,55 @@ static void janet_pretty_one(struct pretty *S, Janet x, int is_dict_value) {
janet_buffer_push_cstring(S->buffer, "...");
} else {
int32_t i = 0, len = 0, cap = 0;
int first_kv_pair = 1;
const JanetKV *kvs = NULL;
int counter = 0;
janet_dictionary_view(x, &kvs, &len, &cap);
if (!istable && !(S->flags & JANET_PRETTY_ONELINE) && len >= JANET_PRETTY_DICT_ONELINE)
janet_buffer_push_u8(S->buffer, ' ');
if (is_dict_value && len >= JANET_PRETTY_DICT_ONELINE) print_newline(S, 0);
for (i = 0; i < cap; i++) {
if (!janet_checktype(kvs[i].key, JANET_NIL)) {
if (counter == JANET_PRETTY_DICT_LIMIT && !(S->flags & JANET_PRETTY_NOTRUNC)) {
print_newline(S, 0);
janet_buffer_push_cstring(S->buffer, "...");
break;
}
if (first_kv_pair) {
first_kv_pair = 0;
} else {
print_newline(S, len < JANET_PRETTY_DICT_ONELINE);
}
janet_pretty_one(S, kvs[i].key, 0);
janet_buffer_push_u8(S->buffer, ' ');
janet_pretty_one(S, kvs[i].value, 1);
counter++;
int32_t ks_start = S->keysort_start;
/* Ensure buffer is large enough to sort keys. */
int truncated = 0;
int64_t mincap = (int64_t) len + (int64_t) ks_start;
if (mincap > INT32_MAX) {
truncated = 1;
len = 0;
mincap = ks_start;
}
if (S->keysort_capacity < mincap) {
if (mincap >= INT32_MAX / 2) {
S->keysort_capacity = INT32_MAX;
} else {
S->keysort_capacity = (int32_t)(mincap * 2);
}
S->keysort_buffer = janet_srealloc(S->keysort_buffer, sizeof(int32_t) * S->keysort_capacity);
if (NULL == S->keysort_buffer) {
JANET_OUT_OF_MEMORY;
}
}
janet_sorted_keys(kvs, cap, S->keysort_buffer + ks_start);
S->keysort_start += len;
if (!(S->flags & JANET_PRETTY_NOTRUNC) && (len > JANET_PRETTY_DICT_LIMIT)) {
len = JANET_PRETTY_DICT_LIMIT;
truncated = 1;
}
for (i = 0; i < len; i++) {
if (i) print_newline(S, len < JANET_PRETTY_DICT_ONELINE);
int32_t j = S->keysort_buffer[i + ks_start];
janet_pretty_one(S, kvs[j].key, 0);
janet_buffer_push_u8(S->buffer, ' ');
janet_pretty_one(S, kvs[j].value, 1);
}
if (truncated) {
print_newline(S, 0);
janet_buffer_push_cstring(S->buffer, "...");
}
S->keysort_start = ks_start;
}
S->indent -= 2;
S->depth++;
@@ -641,6 +668,9 @@ static JanetBuffer *janet_pretty_(JanetBuffer *buffer, int depth, int flags, Jan
S.indent = 0;
S.flags = flags;
S.bufstartlen = startlen;
S.keysort_capacity = 0;
S.keysort_buffer = NULL;
S.keysort_start = 0;
janet_table_init(&S.seen, 10);
janet_pretty_one(&S, x, 0);
janet_table_deinit(&S.seen);
@@ -663,6 +693,9 @@ static JanetBuffer *janet_jdn_(JanetBuffer *buffer, int depth, Janet x, int32_t
S.indent = 0;
S.flags = 0;
S.bufstartlen = startlen;
S.keysort_capacity = 0;
S.keysort_buffer = NULL;
S.keysort_start = 0;
janet_table_init(&S.seen, 10);
int res = print_jdn_one(&S, x, depth);
janet_table_deinit(&S.seen);
@@ -822,7 +855,7 @@ void janet_formatbv(JanetBuffer *b, const char *format, va_list args) {
case 'P':
case 'p': { /* janet pretty , precision = depth */
int depth = atoi(precision);
if (depth < 1) depth = 4;
if (depth < 1) depth = JANET_RECURSION_GUARD;
char d = c[-1];
int has_color = (d == 'P') || (d == 'Q') || (d == 'M') || (d == 'N');
int has_oneline = (d == 'Q') || (d == 'q') || (d == 'N') || (d == 'n');
@@ -974,7 +1007,7 @@ void janet_buffer_format(
case 'P':
case 'p': { /* janet pretty , precision = depth */
int depth = atoi(precision);
if (depth < 1) depth = 4;
if (depth < 1) depth = JANET_RECURSION_GUARD;
char d = strfrmt[-1];
int has_color = (d == 'P') || (d == 'Q') || (d == 'M') || (d == 'N');
int has_oneline = (d == 'Q') || (d == 'q') || (d == 'N') || (d == 'n');

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -36,7 +36,7 @@ void janetc_regalloc_init(JanetcRegisterAllocator *ra) {
}
void janetc_regalloc_deinit(JanetcRegisterAllocator *ra) {
free(ra->chunks);
janet_free(ra->chunks);
}
/* Fallbacks for when ctz not available */
@@ -70,7 +70,7 @@ void janetc_regalloc_clone(JanetcRegisterAllocator *dest, JanetcRegisterAllocato
size = sizeof(uint32_t) * (size_t) dest->capacity;
dest->regtemps = 0;
if (size) {
dest->chunks = malloc(size);
dest->chunks = janet_malloc(size);
if (!dest->chunks) {
JANET_OUT_OF_MEMORY;
}
@@ -87,7 +87,7 @@ static void pushchunk(JanetcRegisterAllocator *ra) {
int32_t newcount = ra->count + 1;
if (newcount > ra->capacity) {
int32_t newcapacity = newcount * 2;
ra->chunks = realloc(ra->chunks, (size_t) newcapacity * sizeof(uint32_t));
ra->chunks = janet_realloc(ra->chunks, (size_t) newcapacity * sizeof(uint32_t));
if (!ra->chunks) {
JANET_OUT_OF_MEMORY;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -251,6 +251,9 @@ static JanetTable *handleattr(JanetCompiler *c, int32_t argn, const Janet *argv)
case JANET_STRING:
janet_table_put(tab, janet_ckeywordv("doc"), attr);
break;
case JANET_STRUCT:
janet_table_merge_struct(tab, janet_unwrap_struct(attr));
break;
}
}
return tab;
@@ -407,7 +410,9 @@ static JanetSlot janetc_if(JanetFopts opts, int32_t argn, const Janet *argv) {
right = janetc_value(bodyopts, truebody);
if (!drop && !tail) janetc_copy(c, target, right);
janetc_popscope(c);
janetc_throwaway(bodyopts, falsebody);
if (!janet_checktype(falsebody, JANET_NIL)) {
janetc_throwaway(bodyopts, falsebody);
}
janetc_popscope(c);
return target;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -108,7 +108,7 @@ static void kmp_init(
if (patlen == 0) {
janet_panic("expected non-empty pattern");
}
int32_t *lookup = calloc(patlen, sizeof(int32_t));
int32_t *lookup = janet_calloc(patlen, sizeof(int32_t));
if (!lookup) {
JANET_OUT_OF_MEMORY;
}
@@ -131,7 +131,7 @@ static void kmp_init(
}
static void kmp_deinit(struct kmp_state *state) {
free(state->lookup);
janet_free(state->lookup);
}
static void kmp_seti(struct kmp_state *state, int32_t i) {
@@ -589,14 +589,14 @@ static const JanetReg string_cfuns[] = {
},
{
"string/find", cfun_string_find,
JDOC("(string/find patt str)\n\n"
JDOC("(string/find patt str &opt start-index)\n\n"
"Searches for the first instance of pattern patt in string "
"str. Returns the index of the first character in patt if found, "
"otherwise returns nil.")
},
{
"string/find-all", cfun_string_findall,
JDOC("(string/find-all patt str)\n\n"
JDOC("(string/find-all patt str &opt start-index)\n\n"
"Searches for all instances of pattern patt in string "
"str. Returns an array of all indices of found patterns. Overlapping "
"instances of the pattern are counted individually, meaning a byte in str "

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -87,7 +87,7 @@ static uint32_t *bignat_extra(struct BigNat *mant, int32_t n) {
int32_t newn = oldn + n;
if (mant->cap < newn) {
int32_t newcap = 2 * newn;
uint32_t *mem = realloc(mant->digits, (size_t) newcap * sizeof(uint32_t));
uint32_t *mem = janet_realloc(mant->digits, (size_t) newcap * sizeof(uint32_t));
if (NULL == mem) {
JANET_OUT_OF_MEMORY;
}
@@ -368,11 +368,11 @@ int janet_scan_number(
goto error;
*out = convert(neg, &mant, base, ex);
free(mant.digits);
janet_free(mant.digits);
return 0;
error:
free(mant.digits);
janet_free(mant.digits);
return 1;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -45,7 +45,7 @@ JANET_THREAD_LOCAL uint32_t janet_vm_cache_deleted = 0;
/* Initialize the cache (allocate cache memory) */
void janet_symcache_init() {
janet_vm_cache_capacity = 1024;
janet_vm_cache = calloc(1, (size_t) janet_vm_cache_capacity * sizeof(const uint8_t *));
janet_vm_cache = janet_calloc(1, (size_t) janet_vm_cache_capacity * sizeof(const uint8_t *));
if (NULL == janet_vm_cache) {
JANET_OUT_OF_MEMORY;
}
@@ -55,7 +55,7 @@ void janet_symcache_init() {
/* Deinitialize the cache (free the cache memory) */
void janet_symcache_deinit() {
free((void *)janet_vm_cache);
janet_free((void *)janet_vm_cache);
janet_vm_cache = NULL;
janet_vm_cache_capacity = 0;
janet_vm_cache_count = 0;
@@ -122,7 +122,7 @@ notfound:
static void janet_cache_resize(uint32_t newCapacity) {
uint32_t i, oldCapacity;
const uint8_t **oldCache = janet_vm_cache;
const uint8_t **newCache = calloc(1, (size_t) newCapacity * sizeof(const uint8_t *));
const uint8_t **newCache = janet_calloc(1, (size_t) newCapacity * sizeof(const uint8_t *));
if (newCache == NULL) {
JANET_OUT_OF_MEMORY;
}
@@ -145,7 +145,7 @@ static void janet_cache_resize(uint32_t newCapacity) {
}
}
/* Free the old cache */
free((void *)oldCache);
janet_free((void *)oldCache);
}
/* Add an item to the cache */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -117,7 +117,7 @@ static void janet_table_rehash(JanetTable *t, int32_t size) {
if (islocal) {
janet_sfree(olddata);
} else {
free(olddata);
janet_free(olddata);
}
}
@@ -237,7 +237,7 @@ JanetTable *janet_table_clone(JanetTable *table) {
newTable->capacity = table->capacity;
newTable->deleted = table->deleted;
newTable->proto = table->proto;
newTable->data = malloc(newTable->capacity * sizeof(JanetKV));
newTable->data = janet_malloc(newTable->capacity * sizeof(JanetKV));
if (NULL == newTable->data) {
JANET_OUT_OF_MEMORY;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -84,13 +84,16 @@ static JANET_THREAD_LOCAL JanetTable *janet_vm_thread_decode = NULL;
static JanetTable *janet_thread_get_decode(void) {
if (janet_vm_thread_decode == NULL) {
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));
}
return janet_vm_thread_decode;
}
static JanetMailbox *janet_mailbox_create(int refCount, uint16_t capacity) {
JanetMailbox *mailbox = malloc(sizeof(JanetMailbox) + sizeof(JanetBuffer) * (size_t) capacity);
JanetMailbox *mailbox = janet_malloc(sizeof(JanetMailbox) + sizeof(JanetBuffer) * (size_t) capacity);
if (NULL == mailbox) {
JANET_OUT_OF_MEMORY;
}
@@ -123,7 +126,7 @@ static void janet_mailbox_destroy(JanetMailbox *mailbox) {
for (uint16_t i = 0; i < mailbox->messageCapacity; i++) {
janet_buffer_deinit(mailbox->messages + i);
}
free(mailbox);
janet_free(mailbox);
}
static void janet_mailbox_lock(JanetMailbox *mailbox) {
@@ -182,7 +185,7 @@ static int thread_mark(void *p, size_t size) {
}
static JanetMailboxPair *make_mailbox_pair(JanetMailbox *original, uint64_t flags) {
JanetMailboxPair *pair = malloc(sizeof(JanetMailboxPair));
JanetMailboxPair *pair = janet_malloc(sizeof(JanetMailboxPair));
if (NULL == pair) {
JANET_OUT_OF_MEMORY;
}
@@ -196,7 +199,7 @@ static JanetMailboxPair *make_mailbox_pair(JanetMailbox *original, uint64_t flag
static void destroy_mailbox_pair(JanetMailboxPair *pair) {
janet_mailbox_ref(pair->original, -1);
janet_mailbox_ref(pair->newbox, -1);
free(pair);
janet_free(pair);
}
/* Abstract waiting for timeout across windows/posix */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,614 +0,0 @@
/*
* Copyright (c) 2020 Calvin Rose & contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef JANET_AMALG
#include "features.h"
#include <janet.h>
#include "util.h"
#endif
#ifdef JANET_TYPED_ARRAY
static char *ta_type_names[] = {
"uint8",
"int8",
"uint16",
"int16",
"uint32",
"int32",
"uint64",
"int64",
"float32",
"float64",
"?"
};
static size_t ta_type_sizes[] = {
sizeof(uint8_t),
sizeof(int8_t),
sizeof(uint16_t),
sizeof(int16_t),
sizeof(uint32_t),
sizeof(int32_t),
sizeof(uint64_t),
sizeof(int64_t),
sizeof(float),
sizeof(double),
0
};
#define TA_COUNT_TYPES (JANET_TARRAY_TYPE_F64 + 1)
#define TA_ATOM_MAXSIZE 8
#define TA_FLAG_BIG_ENDIAN 1
static JanetTArrayType get_ta_type_by_name(const uint8_t *name) {
for (int i = 0; i < TA_COUNT_TYPES; i++) {
if (!janet_cstrcmp(name, ta_type_names[i]))
return i;
}
janet_panicf("invalid typed array type %S", name);
return 0;
}
static JanetTArrayBuffer *ta_buffer_init(JanetTArrayBuffer *buf, size_t size) {
buf->data = NULL;
if (size > 0) {
buf->data = (uint8_t *)calloc(size, sizeof(uint8_t));
if (buf->data == NULL) {
JANET_OUT_OF_MEMORY;
}
}
buf->size = size;
#ifdef JANET_BIG_ENDIAN
buf->flags = TA_FLAG_BIG_ENDIAN;
#else
buf->flags = 0;
#endif
return buf;
}
static int ta_buffer_gc(void *p, size_t s) {
(void) s;
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
free(buf->data);
return 0;
}
static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) {
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p;
janet_marshal_abstract(ctx, p);
janet_marshal_size(ctx, buf->size);
janet_marshal_int(ctx, buf->flags);
janet_marshal_bytes(ctx, buf->data, buf->size);
}
static void *ta_buffer_unmarshal(JanetMarshalContext *ctx) {
JanetTArrayBuffer *buf = janet_unmarshal_abstract(ctx, sizeof(JanetTArrayBuffer));
size_t size = janet_unmarshal_size(ctx);
int32_t flags = janet_unmarshal_int(ctx);
ta_buffer_init(buf, size);
buf->flags = flags;
janet_unmarshal_bytes(ctx, buf->data, size);
return buf;
}
const JanetAbstractType janet_ta_buffer_type = {
"ta/buffer",
ta_buffer_gc,
NULL,
NULL,
NULL,
ta_buffer_marshal,
ta_buffer_unmarshal,
JANET_ATEND_UNMARSHAL
};
static int ta_mark(void *p, size_t s) {
(void) s;
JanetTArrayView *view = (JanetTArrayView *)p;
janet_mark(janet_wrap_abstract(view->buffer));
return 0;
}
static void ta_view_marshal(void *p, JanetMarshalContext *ctx) {
JanetTArrayView *view = (JanetTArrayView *)p;
size_t offset = (view->buffer->data - view->as.u8);
janet_marshal_abstract(ctx, p);
janet_marshal_size(ctx, view->size);
janet_marshal_size(ctx, view->stride);
janet_marshal_int(ctx, view->type);
janet_marshal_size(ctx, offset);
janet_marshal_janet(ctx, janet_wrap_abstract(view->buffer));
}
static void *ta_view_unmarshal(JanetMarshalContext *ctx) {
size_t offset;
int32_t atype;
Janet buffer;
JanetTArrayView *view = janet_unmarshal_abstract(ctx, sizeof(JanetTArrayView));
view->size = janet_unmarshal_size(ctx);
view->stride = janet_unmarshal_size(ctx);
atype = janet_unmarshal_int(ctx);
if (atype < 0 || atype >= TA_COUNT_TYPES)
janet_panic("bad typed array type");
view->type = atype;
offset = janet_unmarshal_size(ctx);
buffer = janet_unmarshal_janet(ctx);
if (!janet_checktype(buffer, JANET_ABSTRACT) ||
(janet_abstract_type(janet_unwrap_abstract(buffer)) != &janet_ta_buffer_type)) {
janet_panicf("expected typed array buffer");
}
view->buffer = (JanetTArrayBuffer *)janet_unwrap_abstract(buffer);
size_t buf_need_size = offset + (ta_type_sizes[view->type]) * ((view->size - 1) * view->stride + 1);
if (view->buffer->size < buf_need_size)
janet_panic("bad typed array offset in marshalled data");
view->as.u8 = view->buffer->data + offset;
return view;
}
static JanetMethod tarray_view_methods[6];
static int ta_getter(void *p, Janet key, Janet *out) {
size_t index, i;
JanetTArrayView *array = p;
if (janet_checktype(key, JANET_KEYWORD)) {
return janet_getmethod(janet_unwrap_keyword(key), tarray_view_methods, out);
}
if (!janet_checksize(key)) janet_panic("expected size as key");
index = (size_t) janet_unwrap_number(key);
i = index * array->stride;
if (index >= array->size) {
return 0;
} else {
switch (array->type) {
case JANET_TARRAY_TYPE_U8:
*out = janet_wrap_number(array->as.u8[i]);
break;
case JANET_TARRAY_TYPE_S8:
*out = janet_wrap_number(array->as.s8[i]);
break;
case JANET_TARRAY_TYPE_U16:
*out = janet_wrap_number(array->as.u16[i]);
break;
case JANET_TARRAY_TYPE_S16:
*out = janet_wrap_number(array->as.s16[i]);
break;
case JANET_TARRAY_TYPE_U32:
*out = janet_wrap_number(array->as.u32[i]);
break;
case JANET_TARRAY_TYPE_S32:
*out = janet_wrap_number(array->as.s32[i]);
break;
#ifdef JANET_INT_TYPES
case JANET_TARRAY_TYPE_U64:
*out = janet_wrap_u64(array->as.u64[i]);
break;
case JANET_TARRAY_TYPE_S64:
*out = janet_wrap_s64(array->as.s64[i]);
break;
#endif
case JANET_TARRAY_TYPE_F32:
*out = janet_wrap_number_safe(array->as.f32[i]);
break;
case JANET_TARRAY_TYPE_F64:
*out = janet_wrap_number_safe(array->as.f64[i]);
break;
default:
janet_panicf("cannot get from typed array of type %s",
ta_type_names[array->type]);
break;
}
}
return 1;
}
static void ta_setter(void *p, Janet key, Janet value) {
size_t index, i;
if (!janet_checksize(key)) janet_panic("expected size as key");
index = (size_t) janet_unwrap_number(key);
JanetTArrayView *array = p;
i = index * array->stride;
if (index >= array->size) {
janet_panic("index out of bounds");
}
if (!janet_checktype(value, JANET_NUMBER) &&
array->type != JANET_TARRAY_TYPE_U64 &&
array->type != JANET_TARRAY_TYPE_S64) {
janet_panic("expected number value");
}
switch (array->type) {
case JANET_TARRAY_TYPE_U8:
array->as.u8[i] = (uint8_t) janet_unwrap_number(value);
break;
case JANET_TARRAY_TYPE_S8:
array->as.s8[i] = (int8_t) janet_unwrap_number(value);
break;
case JANET_TARRAY_TYPE_U16:
array->as.u16[i] = (uint16_t) janet_unwrap_number(value);
break;
case JANET_TARRAY_TYPE_S16:
array->as.s16[i] = (int16_t) janet_unwrap_number(value);
break;
case JANET_TARRAY_TYPE_U32:
array->as.u32[i] = (uint32_t) janet_unwrap_number(value);
break;
case JANET_TARRAY_TYPE_S32:
array->as.s32[i] = (int32_t) janet_unwrap_number(value);
break;
#ifdef JANET_INT_TYPES
case JANET_TARRAY_TYPE_U64:
array->as.u64[i] = janet_unwrap_u64(value);
break;
case JANET_TARRAY_TYPE_S64:
array->as.s64[i] = janet_unwrap_s64(value);
break;
#endif
case JANET_TARRAY_TYPE_F32:
array->as.f32[i] = (float) janet_unwrap_number(value);
break;
case JANET_TARRAY_TYPE_F64:
array->as.f64[i] = janet_unwrap_number(value);
break;
default:
janet_panicf("cannot set typed array of type %s",
ta_type_names[array->type]);
break;
}
}
static Janet ta_view_next(void *p, Janet key) {
JanetTArrayView *view = p;
if (janet_checktype(key, JANET_NIL)) {
if (view->size > 0) {
return janet_wrap_number(0);
} else {
return janet_wrap_nil();
}
}
if (!janet_checksize(key)) janet_panic("expected size as key");
size_t index = (size_t) janet_unwrap_number(key);
index++;
if (index < view->size) {
return janet_wrap_number((double) index);
}
return janet_wrap_nil();
}
const JanetAbstractType janet_ta_view_type = {
"ta/view",
NULL,
ta_mark,
ta_getter,
ta_setter,
ta_view_marshal,
ta_view_unmarshal,
NULL,
NULL,
NULL,
ta_view_next,
JANET_ATEND_NEXT
};
JanetTArrayBuffer *janet_tarray_buffer(size_t size) {
JanetTArrayBuffer *buf = janet_abstract(&janet_ta_buffer_type, sizeof(JanetTArrayBuffer));
ta_buffer_init(buf, size);
return buf;
}
JanetTArrayView *janet_tarray_view(
JanetTArrayType type,
size_t size,
size_t stride,
size_t offset,
JanetTArrayBuffer *buffer) {
JanetTArrayView *view = janet_abstract(&janet_ta_view_type, sizeof(JanetTArrayView));
if ((stride < 1) || (size < 1)) janet_panic("stride and size should be > 0");
size_t buf_size = offset + ta_type_sizes[type] * ((size - 1) * stride + 1);
if (NULL == buffer) {
buffer = janet_abstract(&janet_ta_buffer_type, sizeof(JanetTArrayBuffer));
ta_buffer_init(buffer, buf_size);
}
if (buffer->size < buf_size) {
janet_panicf("bad buffer size, %i bytes allocated < %i required",
buffer->size,
buf_size);
}
view->buffer = buffer;
view->stride = stride;
view->size = size;
view->as.u8 = buffer->data + offset;
view->type = type;
return view;
}
JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n) {
return janet_getabstract(argv, n, &janet_ta_buffer_type);
}
JanetTArrayView *janet_gettarray_any(const Janet *argv, int32_t n) {
return janet_getabstract(argv, n, &janet_ta_view_type);
}
JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, JanetTArrayType type) {
JanetTArrayView *view = janet_getabstract(argv, n, &janet_ta_view_type);
if (view->type != type) {
janet_panicf("bad slot #%d, expected typed array of type %s, got %v",
n, ta_type_names[type], argv[n]);
}
return view;
}
static Janet cfun_typed_array_new(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 5);
size_t offset = 0;
size_t stride = 1;
JanetTArrayBuffer *buffer = NULL;
const uint8_t *keyw = janet_getkeyword(argv, 0);
JanetTArrayType type = get_ta_type_by_name(keyw);
size_t size = janet_getsize(argv, 1);
if (argc > 2)
stride = janet_getsize(argv, 2);
if (argc > 3)
offset = janet_getsize(argv, 3);
if (argc > 4) {
int32_t blen;
const uint8_t *bytes;
if (janet_bytes_view(argv[4], &bytes, &blen)) {
buffer = janet_abstract(&janet_ta_buffer_type, sizeof(JanetTArrayBuffer));
ta_buffer_init(buffer, (size_t) blen);
memcpy(buffer->data, bytes, blen);
} else {
if (!janet_checktype(argv[4], JANET_ABSTRACT)) {
janet_panicf("bad slot #%d, expected ta/view|ta/buffer, got %v",
4, argv[4]);
}
void *p = janet_unwrap_abstract(argv[4]);
if (janet_abstract_type(p) == &janet_ta_view_type) {
JanetTArrayView *view = (JanetTArrayView *)p;
offset = (view->buffer->data - view->as.u8) + offset * ta_type_sizes[view->type];
stride *= view->stride;
buffer = view->buffer;
} else if (janet_abstract_type(p) == &janet_ta_buffer_type) {
buffer = p;
} else {
janet_panicf("bad slot #%d, expected ta/view|ta/buffer, got %v",
4, argv[4]);
}
}
}
JanetTArrayView *view = janet_tarray_view(type, size, stride, offset, buffer);
return janet_wrap_abstract(view);
}
static JanetTArrayView *ta_is_view(Janet x) {
if (!janet_checktype(x, JANET_ABSTRACT)) return NULL;
void *abst = janet_unwrap_abstract(x);
if (janet_abstract_type(abst) != &janet_ta_view_type) return NULL;
return (JanetTArrayView *)abst;
}
static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
JanetTArrayView *view;
if ((view = ta_is_view(argv[0]))) {
return janet_wrap_abstract(view->buffer);
}
size_t size = janet_getsize(argv, 0);
JanetTArrayBuffer *buf = janet_tarray_buffer(size);
return janet_wrap_abstract(buf);
}
static Janet cfun_typed_array_size(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
JanetTArrayView *view;
if ((view = ta_is_view(argv[0]))) {
return janet_wrap_number((double) view->size);
}
JanetTArrayBuffer *buf = (JanetTArrayBuffer *)janet_getabstract(argv, 0, &janet_ta_buffer_type);
return janet_wrap_number((double) buf->size);
}
static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
JanetTArrayView *view;
if ((view = ta_is_view(argv[0]))) {
JanetTArrayView *view = janet_unwrap_abstract(argv[0]);
JanetKV *props = janet_struct_begin(6);
ptrdiff_t boffset = view->as.u8 - view->buffer->data;
janet_struct_put(props, janet_ckeywordv("size"),
janet_wrap_number((double) view->size));
janet_struct_put(props, janet_ckeywordv("byte-offset"),
janet_wrap_number((double) boffset));
janet_struct_put(props, janet_ckeywordv("stride"),
janet_wrap_number((double) view->stride));
janet_struct_put(props, janet_ckeywordv("type"),
janet_ckeywordv(ta_type_names[view->type]));
janet_struct_put(props, janet_ckeywordv("type-size"),
janet_wrap_number((double) ta_type_sizes[view->type]));
janet_struct_put(props, janet_ckeywordv("buffer"),
janet_wrap_abstract(view->buffer));
return janet_wrap_struct(janet_struct_end(props));
} else {
JanetTArrayBuffer *buffer = janet_gettarray_buffer(argv, 0);
JanetKV *props = janet_struct_begin(2);
janet_struct_put(props, janet_ckeywordv("size"),
janet_wrap_number((double) buffer->size));
janet_struct_put(props, janet_ckeywordv("big-endian"),
janet_wrap_boolean(buffer->flags & TA_FLAG_BIG_ENDIAN));
return janet_wrap_struct(janet_struct_end(props));
}
}
static Janet cfun_typed_array_slice(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 3);
JanetTArrayView *src = janet_getabstract(argv, 0, &janet_ta_view_type);
JanetRange range;
int32_t length = (int32_t)src->size;
if (argc == 1) {
range.start = 0;
range.end = length;
} else if (argc == 2) {
range.start = janet_gethalfrange(argv, 1, length, "start");
range.end = length;
} else {
range.start = janet_gethalfrange(argv, 1, length, "start");
range.end = janet_gethalfrange(argv, 2, length, "end");
if (range.end < range.start)
range.end = range.start;
}
JanetArray *array = janet_array(range.end - range.start);
if (array->data) {
for (int32_t i = range.start; i < range.end; i++) {
if (!ta_getter(src, janet_wrap_number(i), &array->data[i - range.start]))
array->data[i - range.start] = janet_wrap_nil();
}
}
array->count = range.end - range.start;
return janet_wrap_array(array);
}
static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) {
janet_arity(argc, 4, 5);
JanetTArrayView *src = janet_getabstract(argv, 0, &janet_ta_view_type);
size_t index_src = janet_getsize(argv, 1);
JanetTArrayView *dst = janet_getabstract(argv, 2, &janet_ta_view_type);
size_t index_dst = janet_getsize(argv, 3);
size_t count = (argc == 5) ? janet_getsize(argv, 4) : 1;
size_t src_atom_size = ta_type_sizes[src->type];
size_t dst_atom_size = ta_type_sizes[dst->type];
size_t step_src = src->stride * src_atom_size;
size_t step_dst = dst->stride * dst_atom_size;
size_t pos_src = (src->as.u8 - src->buffer->data) + (index_src * step_src);
size_t pos_dst = (dst->as.u8 - dst->buffer->data) + (index_dst * step_dst);
uint8_t *ps = src->buffer->data + pos_src, * pd = dst->buffer->data + pos_dst;
if ((pos_dst + (count - 1)*step_dst + src_atom_size <= dst->buffer->size) &&
(pos_src + (count - 1)*step_src + src_atom_size <= src->buffer->size)) {
for (size_t i = 0; i < count; i++) {
memmove(pd, ps, src_atom_size);
pd += step_dst;
ps += step_src;
}
} else {
janet_panic("typed array copy out of bounds");
}
return janet_wrap_nil();
}
static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) {
janet_arity(argc, 4, 5);
JanetTArrayView *src = janet_getabstract(argv, 0, &janet_ta_view_type);
size_t index_src = janet_getsize(argv, 1);
JanetTArrayView *dst = janet_getabstract(argv, 2, &janet_ta_view_type);
size_t index_dst = janet_getsize(argv, 3);
size_t count = (argc == 5) ? janet_getsize(argv, 4) : 1;
size_t src_atom_size = ta_type_sizes[src->type];
size_t dst_atom_size = ta_type_sizes[dst->type];
size_t step_src = src->stride * src_atom_size;
size_t step_dst = dst->stride * dst_atom_size;
size_t pos_src = (src->as.u8 - src->buffer->data) + (index_src * step_src);
size_t pos_dst = (dst->as.u8 - dst->buffer->data) + (index_dst * step_dst);
uint8_t *ps = src->buffer->data + pos_src, * pd = dst->buffer->data + pos_dst;
uint8_t temp[TA_ATOM_MAXSIZE];
if ((pos_dst + (count - 1)*step_dst + src_atom_size <= dst->buffer->size) &&
(pos_src + (count - 1)*step_src + src_atom_size <= src->buffer->size)) {
for (size_t i = 0; i < count; i++) {
memcpy(temp, ps, src_atom_size);
memcpy(ps, pd, src_atom_size);
memcpy(pd, temp, src_atom_size);
pd += step_dst;
ps += step_src;
}
} else {
janet_panic("typed array swap out of bounds");
}
return janet_wrap_nil();
}
static const JanetReg ta_cfuns[] = {
{
"tarray/new", cfun_typed_array_new,
JDOC("(tarray/new type size &opt stride offset tarray|buffer)\n\n"
"Create new typed array.")
},
{
"tarray/buffer", cfun_typed_array_buffer,
JDOC("(tarray/buffer array|size)\n\n"
"Return typed array buffer or create a new buffer.")
},
{
"tarray/length", cfun_typed_array_size,
JDOC("(tarray/length array|buffer)\n\n"
"Return typed array or buffer size.")
},
{
"tarray/properties", cfun_typed_array_properties,
JDOC("(tarray/properties array)\n\n"
"Return typed array properties as a struct.")
},
{
"tarray/copy-bytes", cfun_typed_array_copy_bytes,
JDOC("(tarray/copy-bytes src sindex dst dindex &opt count)\n\n"
"Copy count elements (default 1) of src array from index sindex "
"to dst array at position dindex "
"memory can overlap.")
},
{
"tarray/swap-bytes", cfun_typed_array_swap_bytes,
JDOC("(tarray/swap-bytes src sindex dst dindex &opt count)\n\n"
"Swap count elements (default 1) between src array from index sindex "
"and dst array at position dindex "
"memory can overlap.")
},
{
"tarray/slice", cfun_typed_array_slice,
JDOC("(tarray/slice tarr &opt start end)\n\n"
"Takes a slice of a typed array from start to end. The range is half "
"open, [start, end). Indexes can also be negative, indicating indexing "
"from the end of the end of the typed array. By default, start is 0 and end is "
"the size of the typed array. Returns a new janet array.")
},
{NULL, NULL, NULL}
};
static JanetMethod tarray_view_methods[] = {
{"length", cfun_typed_array_size},
{"properties", cfun_typed_array_properties},
{"copy-bytes", cfun_typed_array_copy_bytes},
{"swap-bytes", cfun_typed_array_swap_bytes},
{"slice", cfun_typed_array_slice},
{NULL, NULL}
};
/* Module entry point */
void janet_lib_typed_array(JanetTable *env) {
janet_core_cfuns(env, NULL, ta_cfuns);
janet_register_abstract_type(&janet_ta_buffer_type);
janet_register_abstract_type(&janet_ta_view_type);
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -397,7 +397,7 @@ static void _janet_cfuns_prefix(JanetTable *env, const char *regprefix, const Ja
if (NULL != regprefix) {
prefixlen = strlen(regprefix);
bufsize = prefixlen + 256;
longname_buffer = malloc(bufsize);
longname_buffer = janet_malloc(bufsize);
if (NULL == longname_buffer) {
JANET_OUT_OF_MEMORY;
}
@@ -413,7 +413,7 @@ static void _janet_cfuns_prefix(JanetTable *env, const char *regprefix, const Ja
int32_t totallen = (int32_t) prefixlen + nmlen;
if ((size_t) totallen > bufsize) {
bufsize = (size_t)(totallen) + 128;
longname_buffer = realloc(longname_buffer, bufsize);
longname_buffer = janet_realloc(longname_buffer, bufsize);
if (NULL == longname_buffer) {
JANET_OUT_OF_MEMORY;
}
@@ -436,7 +436,7 @@ static void _janet_cfuns_prefix(JanetTable *env, const char *regprefix, const Ja
janet_table_put(janet_vm_registry, fun, name);
cfuns++;
}
free(longname_buffer);
(janet_free)(longname_buffer);
}
void janet_cfuns_prefix(JanetTable *env, const char *regprefix, const JanetReg *cfuns) {
@@ -487,27 +487,60 @@ void janet_core_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cf
}
#endif
/* Resolve a symbol in the environment */
JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out) {
JanetBinding janet_resolve_ext(JanetTable *env, const uint8_t *sym) {
Janet ref;
JanetTable *entry_table;
Janet entry = janet_table_get(env, janet_wrap_symbol(sym));
JanetBinding binding = {
JANET_BINDING_NONE,
janet_wrap_nil(),
JANET_BINDING_DEP_NONE
};
/* Check environment for entry */
if (!janet_checktype(entry, JANET_TABLE))
return JANET_BINDING_NONE;
return binding;
entry_table = janet_unwrap_table(entry);
/* deprecation check */
Janet deprecate = janet_table_get(entry_table, janet_ckeywordv("deprecated"));
if (janet_checktype(deprecate, JANET_KEYWORD)) {
JanetKeyword depkw = janet_unwrap_keyword(deprecate);
if (!janet_cstrcmp(depkw, "relaxed")) {
binding.deprecation = JANET_BINDING_DEP_RELAXED;
} else if (!janet_cstrcmp(depkw, "normal")) {
binding.deprecation = JANET_BINDING_DEP_NORMAL;
} else if (!janet_cstrcmp(depkw, "strict")) {
binding.deprecation = JANET_BINDING_DEP_STRICT;
}
} else if (!janet_checktype(deprecate, JANET_NIL)) {
binding.deprecation = JANET_BINDING_DEP_NORMAL;
}
if (!janet_checktype(
janet_table_get(entry_table, janet_ckeywordv("macro")),
JANET_NIL)) {
*out = janet_table_get(entry_table, janet_ckeywordv("value"));
return JANET_BINDING_MACRO;
binding.value = janet_table_get(entry_table, janet_ckeywordv("value"));
binding.type = JANET_BINDING_MACRO;
return binding;
}
ref = janet_table_get(entry_table, janet_ckeywordv("ref"));
if (janet_checktype(ref, JANET_ARRAY)) {
*out = ref;
return JANET_BINDING_VAR;
binding.value = ref;
binding.type = JANET_BINDING_VAR;
return binding;
}
*out = janet_table_get(entry_table, janet_ckeywordv("value"));
return JANET_BINDING_DEF;
binding.value = janet_table_get(entry_table, janet_ckeywordv("value"));
binding.type = JANET_BINDING_DEF;
return binding;
}
JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out) {
JanetBinding binding = janet_resolve_ext(env, sym);
*out = binding.value;
return binding.type;
}
/* Resolve a symbol in the core environment. */
@@ -602,6 +635,38 @@ JanetTable *janet_get_core_table(const char *name) {
return janet_unwrap_table(out);
}
/* Sort keys of a dictionary type */
int32_t janet_sorted_keys(const JanetKV *dict, int32_t cap, int32_t *index_buffer) {
/* First, put populated indices into index_buffer */
int32_t next_index = 0;
for (int32_t i = 0; i < cap; i++) {
if (!janet_checktype(dict[i].key, JANET_NIL)) {
index_buffer[next_index++] = i;
}
}
/* Next, sort those (simple insertion sort here for now) */
for (int32_t i = 1; i < next_index; i++) {
int32_t index_to_insert = index_buffer[i];
Janet lhs = dict[index_to_insert].key;
for (int32_t j = i - 1; j >= 0; j--) {
index_buffer[j + 1] = index_buffer[j];
Janet rhs = dict[index_buffer[j]].key;
if (janet_compare(lhs, rhs) >= 0) {
index_buffer[j + 1] = index_to_insert;
break;
} else if (j == 0) {
index_buffer[0] = index_to_insert;
}
}
}
/* Return number of indices found */
return next_index;
}
/* Clock shims for various platforms */
#ifdef JANET_GETTIME
/* For macos */
@@ -688,3 +753,21 @@ int janet_cryptorand(uint8_t *out, size_t n) {
return -1;
#endif
}
/* Alloc function macro fills */
void *(janet_malloc)(size_t size) {
return janet_malloc(size);
}
void (janet_free)(void *ptr) {
janet_free(ptr);
}
void *(janet_calloc)(size_t nmemb, size_t size) {
return janet_calloc(nmemb, size);
}
void *(janet_realloc)(void *ptr, size_t size) {
return janet_realloc(ptr, size);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -52,12 +52,6 @@
if (!(c)) JANET_EXIT((m)); \
} while (0)
/* What to do when out of memory */
#ifndef JANET_OUT_OF_MEMORY
#include <stdio.h>
#define JANET_OUT_OF_MEMORY do { fprintf(stderr, "janet out of memory\n"); exit(1); } while (0)
#endif
/* Omit docstrings in some builds */
#ifndef JANET_BOOTSTRAP
#define JDOC(x) NULL
@@ -108,6 +102,11 @@ void janet_core_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cf
int janet_gettime(struct timespec *spec);
#endif
/* strdup */
#ifdef JANET_WINDOWS
#define strdup(x) _strdup(x)
#endif
#define RETRY_EINTR(RC, CALL) do { (RC) = CALL; } while((RC) < 0 && errno == EINTR)
/* Initialize builtin libraries */

View File

@@ -47,7 +47,7 @@ static void push_traversal_node(void *lhs, void *rhs, int32_t index2) {
if (newsize < 128) {
newsize = 128;
}
JanetTraversalNode *tn = realloc(janet_vm_traversal_base, newsize * sizeof(JanetTraversalNode));
JanetTraversalNode *tn = janet_realloc(janet_vm_traversal_base, newsize * sizeof(JanetTraversalNode));
if (tn == NULL) {
JANET_OUT_OF_MEMORY;
}
@@ -307,18 +307,14 @@ int32_t janet_hash(Janet x) {
hash = janet_struct_hash(janet_unwrap_struct(x));
break;
case JANET_NUMBER: {
double num = janet_unwrap_number(x);
if (isnan(num) || isinf(num) || num == 0) {
hash = 0;
} else {
hash = (int32_t)num;
hash = ((hash >> 16) ^ hash) * 0x45d9f3b;
hash = ((hash >> 16) ^ hash) * 0x45d9f3b;
hash = (hash >> 16) ^ hash;
uint32_t lo = (uint32_t)(janet_u64(x) & 0xFFFFFFFF);
hash ^= lo + 0x9e3779b9 + (hash << 6) + (hash >> 2);
}
union {
double d;
uint64_t u;
} as;
as.d = janet_unwrap_number(x);
uint32_t lo = (uint32_t)(as.u & 0xFFFFFFFF);
uint32_t hi = (uint32_t)(as.u >> 32);
hash = (int32_t)(hi ^ (lo >> 3));
break;
}
case JANET_ABSTRACT: {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -43,7 +43,7 @@ void *janet_v_flattenmem(void *v, int32_t itemsize) {
int32_t *p;
if (NULL == v) return NULL;
size_t size = (size_t) itemsize * janet_v__cnt(v);
p = malloc(size);
p = janet_malloc(size);
if (NULL != p) {
safe_memcpy(p, v, size);
return p;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -202,6 +202,20 @@ JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf = NULL;
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 */
static void vm_do_trace(JanetFunction *func, int32_t argc, const Janet *argv) {
@@ -261,11 +275,16 @@ static Janet call_nonfn(JanetFiber *fiber, Janet callee) {
return janet_method_invoke(callee, argc, fiber->data + fiber->stacktop);
}
/* Method lookup could potentially handle tables specially... */
static Janet method_to_fun(Janet method, Janet obj) {
return janet_get(obj, method);
}
/* Get a callable from a keyword method name and ensure that it is valid. */
static Janet resolve_method(Janet name, JanetFiber *fiber) {
int32_t argc = fiber->stacktop - fiber->stackstart;
if (argc < 1) janet_panicf("method call (%v) takes at least 1 argument, got 0", name);
Janet callee = janet_get(fiber->data[fiber->stackstart], name);
Janet callee = method_to_fun(name, fiber->data[fiber->stackstart]);
if (janet_checktype(callee, JANET_NIL))
janet_panicf("unknown method %v invoked on %v", name, fiber->data[fiber->stackstart]);
return callee;
@@ -273,8 +292,7 @@ static Janet resolve_method(Janet name, JanetFiber *fiber) {
/* Lookup method on value x */
static Janet janet_method_lookup(Janet x, const char *name) {
Janet kname = janet_ckeywordv(name);
return janet_get(x, kname);
return method_to_fun(janet_ckeywordv(name), x);
}
/* Call a method first on the righthand side, and then on the left hand side with a prefix */
@@ -780,8 +798,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
vm_compop( <=);
VM_OP(JOP_LESS_THAN_IMMEDIATE)
stack[A] = janet_wrap_boolean(janet_unwrap_integer(stack[B]) < CS);
vm_pcnext();
vm_compop_imm( <);
VM_OP(JOP_GREATER_THAN)
vm_compop( >);
@@ -790,15 +807,14 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
vm_compop( >=);
VM_OP(JOP_GREATER_THAN_IMMEDIATE)
stack[A] = janet_wrap_boolean(janet_unwrap_integer(stack[B]) > CS);
vm_pcnext();
vm_compop_imm( >);
VM_OP(JOP_EQUALS)
stack[A] = janet_wrap_boolean(janet_equals(stack[B], stack[C]));
vm_pcnext();
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_OP(JOP_NOT_EQUALS)
@@ -806,7 +822,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
vm_pcnext();
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_OP(JOP_COMPARE)
@@ -1276,7 +1292,14 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
/* Push frame */
janet_fiber_pushn(janet_vm_fiber, argv, argc);
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;
@@ -1359,6 +1382,7 @@ static JanetSignal janet_continue_no_check(JanetFiber *fiber, Janet in, Janet *o
if (janet_vm_root_fiber == fiber) janet_vm_root_fiber = NULL;
if (sig != JANET_SIGNAL_OK && !(child->flags & (1 << sig))) {
*out = in;
janet_fiber_set_status(fiber, sig);
return sig;
}
/* Check if we need any special handling for certain opcodes */
@@ -1398,23 +1422,23 @@ static JanetSignal janet_continue_no_check(JanetFiber *fiber, Janet in, Janet *o
/* Save global state */
JanetTryState tstate;
JanetSignal signal = janet_try(&tstate);
if (!signal) {
JanetSignal sig = janet_try(&tstate);
if (!sig) {
/* Normal setup */
if (janet_vm_root_fiber == NULL) janet_vm_root_fiber = fiber;
janet_vm_fiber = fiber;
janet_fiber_set_status(fiber, JANET_STATUS_ALIVE);
signal = run_vm(fiber, in);
sig = run_vm(fiber, in);
}
/* Restore */
if (janet_vm_root_fiber == fiber) janet_vm_root_fiber = NULL;
janet_fiber_set_status(fiber, signal);
janet_fiber_set_status(fiber, sig);
janet_restore(&tstate);
fiber->last_value = tstate.payload;
*out = tstate.payload;
return signal;
return sig;
}
/* Enter the main vm loop */
@@ -1522,7 +1546,7 @@ int janet_init(void) {
void janet_deinit(void) {
janet_clear_memory();
janet_symcache_deinit();
free(janet_vm_roots);
janet_free(janet_vm_roots);
janet_vm_roots = NULL;
janet_vm_root_count = 0;
janet_vm_root_capacity = 0;
@@ -1530,7 +1554,7 @@ void janet_deinit(void) {
janet_vm_abstract_registry = NULL;
janet_vm_core_env = NULL;
janet_vm_top_dyns = NULL;
free(janet_vm_traversal_base);
janet_free(janet_vm_traversal_base);
janet_vm_fiber = NULL;
janet_vm_root_fiber = NULL;
#ifdef JANET_THREADS

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -162,7 +162,7 @@ Janet(janet_wrap_number)(double x) {
void *janet_memalloc_empty(int32_t count) {
int32_t i;
void *mem = malloc((size_t) count * sizeof(JanetKV));
void *mem = janet_malloc((size_t) count * sizeof(JanetKV));
janet_vm_next_collection += (size_t) count * sizeof(JanetKV);
if (NULL == mem) {
JANET_OUT_OF_MEMORY;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -172,11 +172,6 @@ extern "C" {
#define JANET_PEG
#endif
/* Enable or disable the typedarray module */
#ifndef JANET_NO_TYPED_ARRAY
#define JANET_TYPED_ARRAY
#endif
/* Enable or disable event loop */
#if !defined(JANET_NO_EV) && !defined(__EMSCRIPTEN__)
#define JANET_EV
@@ -288,15 +283,21 @@ typedef struct {
JANET_CURRENT_CONFIG_BITS })
#endif
/* What to do when out of memory */
#ifndef JANET_OUT_OF_MEMORY
#include <stdio.h>
#define JANET_OUT_OF_MEMORY do { fprintf(stderr, "janet out of memory\n"); exit(1); } while (0)
#endif
/***** END SECTION CONFIG *****/
/***** START SECTION TYPES *****/
#ifdef JANET_WINDOWS
// Must be defined before including stdlib.h
/* Must be defined before including stdlib.h */
#define _CRT_RAND_S
#endif
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@@ -1367,6 +1368,7 @@ JANET_API void janet_parser_deinit(JanetParser *parser);
JANET_API void janet_parser_consume(JanetParser *parser, uint8_t c);
JANET_API enum JanetParserStatus janet_parser_status(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 void janet_parser_flush(JanetParser *parser);
JANET_API void janet_parser_eof(JanetParser *parser);
@@ -1403,9 +1405,15 @@ struct JanetCompileResult {
enum JanetCompileStatus status;
};
JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, JanetString where);
JANET_API JanetCompileResult janet_compile_lint(
Janet source,
JanetTable *env,
JanetString where,
JanetArray *lints);
/* Get the default environment for janet */
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_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out);
@@ -1628,6 +1636,7 @@ JANET_API Janet janet_wrap_number_safe(double x);
JANET_API int janet_keyeq(Janet x, const char *cstring);
JANET_API int janet_streq(Janet x, const char *cstring);
JANET_API int janet_symeq(Janet x, const char *cstring);
JANET_API int32_t janet_sorted_keys(const JanetKV *dict, int32_t cap, int32_t *index_buffer);
/* VM functions */
JANET_API int janet_init(void);
@@ -1656,11 +1665,24 @@ typedef enum {
JANET_BINDING_VAR,
JANET_BINDING_MACRO
} JanetBindingType;
typedef struct {
JanetBindingType type;
Janet value;
enum {
JANET_BINDING_DEP_NONE,
JANET_BINDING_DEP_RELAXED,
JANET_BINDING_DEP_NORMAL,
JANET_BINDING_DEP_STRICT,
} deprecation;
} JanetBinding;
JANET_API void janet_def(JanetTable *env, const char *name, Janet val, const char *documentation);
JANET_API void janet_var(JanetTable *env, const char *name, Janet val, const char *documentation);
JANET_API void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns);
JANET_API void janet_cfuns_prefix(JanetTable *env, const char *regprefix, const JanetReg *cfuns);
JANET_API JanetBindingType janet_resolve(JanetTable *env, JanetSymbol sym, Janet *out);
JANET_API JanetBinding janet_resolve_ext(JanetTable *env, JanetSymbol sym);
JANET_API void janet_register(const char *name, JanetCFunction cfun);
/* Get values from the core environment. */
@@ -1839,7 +1861,8 @@ typedef enum {
RULE_LENPREFIX, /* [rule_a, rule_b (repeat rule_b rule_a times)] */
RULE_READINT, /* [(signedness << 4) | (endianess << 5) | bytewidth, tag] */
RULE_LINE, /* [tag] */
RULE_COLUMN /* [tag] */
RULE_COLUMN, /* [tag] */
RULE_UNREF /* [rule, tag] */
} JanetPegOpcod;
typedef struct {
@@ -1852,59 +1875,6 @@ typedef struct {
#endif
#ifdef JANET_TYPED_ARRAY
extern JANET_API const JanetAbstractType janet_ta_view_type;
extern JANET_API const JanetAbstractType janet_ta_buffer_type;
typedef enum {
JANET_TARRAY_TYPE_U8,
JANET_TARRAY_TYPE_S8,
JANET_TARRAY_TYPE_U16,
JANET_TARRAY_TYPE_S16,
JANET_TARRAY_TYPE_U32,
JANET_TARRAY_TYPE_S32,
JANET_TARRAY_TYPE_U64,
JANET_TARRAY_TYPE_S64,
JANET_TARRAY_TYPE_F32,
JANET_TARRAY_TYPE_F64
} JanetTArrayType;
typedef struct {
uint8_t *data;
size_t size;
int32_t flags;
} JanetTArrayBuffer;
typedef struct {
union {
void *pointer;
uint8_t *u8;
int8_t *s8;
uint16_t *u16;
int16_t *s16;
uint32_t *u32;
int32_t *s32;
uint64_t *u64;
int64_t *s64;
float *f32;
double *f64;
} as;
JanetTArrayBuffer *buffer;
size_t size;
size_t stride;
JanetTArrayType type;
} JanetTArrayView;
JANET_API JanetTArrayBuffer *janet_tarray_buffer(size_t size);
JANET_API JanetTArrayView *janet_tarray_view(JanetTArrayType type, size_t size, size_t stride, size_t offset, JanetTArrayBuffer *buffer);
JANET_API int janet_is_tarray_view(Janet x, JanetTArrayType type);
JANET_API JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n);
JANET_API JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, JanetTArrayType type);
JanetTArrayView *janet_gettarray_any(const Janet *argv, int32_t n);
#endif
#ifdef JANET_INT_TYPES
extern JANET_API const JanetAbstractType janet_s64_type;
@@ -1936,6 +1906,24 @@ JANET_API JanetThread *janet_thread_current(void);
#endif
/* Custom allocator support */
JANET_API void *(janet_malloc)(size_t);
JANET_API void *(janet_realloc)(void *, size_t);
JANET_API void *(janet_calloc)(size_t, size_t);
JANET_API void (janet_free)(void *);
#ifndef janet_malloc
#define janet_malloc(X) malloc((X))
#endif
#ifndef janet_realloc
#define janet_realloc(X, Y) realloc((X), (Y))
#endif
#ifndef janet_calloc
#define janet_calloc(X, Y) calloc((X), (Y))
#endif
#ifndef janet_free
#define janet_free(X) free((X))
#endif
/***** END SECTION MAIN *****/
/* Re-enable popped variable length array warnings */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -152,7 +152,7 @@ static const char *badterms[] = {
static char *sdup(const char *s) {
size_t len = strlen(s) + 1;
char *mem = malloc(len);
char *mem = janet_malloc(len);
if (!mem) {
return NULL;
}
@@ -300,7 +300,7 @@ static int insert(char c, int draw) {
static void historymove(int delta) {
if (gbl_history_count > 1) {
free(gbl_history[gbl_historyi]);
janet_free(gbl_history[gbl_historyi]);
gbl_history[gbl_historyi] = sdup(gbl_buf);
gbl_historyi += delta;
@@ -326,7 +326,7 @@ static void addhistory(void) {
gbl_history[gbl_history_count++] = newline;
len++;
} else {
free(gbl_history[JANET_HISTORY_MAX - 1]);
janet_free(gbl_history[JANET_HISTORY_MAX - 1]);
}
for (i = len - 1; i > 0; i--) {
gbl_history[i] = gbl_history[i - 1];
@@ -338,7 +338,7 @@ static void replacehistory(void) {
/* History count is always > 0 here */
if (gbl_len == 0 || (gbl_history_count > 1 && !strcmp(gbl_buf, gbl_history[1]))) {
/* Delete history */
free(gbl_history[0]);
janet_free(gbl_history[0]);
for (int i = 1; i < gbl_history_count; i++) {
gbl_history[i - 1] = gbl_history[i];
}
@@ -346,7 +346,7 @@ static void replacehistory(void) {
} else {
char *newline = sdup(gbl_buf);
if (!newline) return;
free(gbl_history[0]);
janet_free(gbl_history[0]);
gbl_history[0] = newline;
}
}
@@ -934,7 +934,7 @@ void janet_line_deinit() {
int i;
norawmode();
for (i = 0; i < gbl_history_count; i++)
free(gbl_history[i]);
janet_free(gbl_history[i]);
gbl_historyi = 0;
}
@@ -1042,19 +1042,23 @@ int main(int argc, char **argv) {
janet_table_put(env, janet_ckeywordv("executable"), janet_cstringv(argv[0]));
/* Run startup script */
Janet mainfun, out;
Janet mainfun;
janet_resolve(env, janet_csymbol("cli-main"), &mainfun);
Janet mainargs[1] = { janet_wrap_array(args) };
JanetFiber *fiber = janet_fiber(janet_unwrap_function(mainfun), 64, 1, mainargs);
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);
if (status != JANET_SIGNAL_OK && status != JANET_SIGNAL_EVENT) {
janet_stacktrace(fiber, out);
}
#ifdef JANET_EV
status = JANET_SIGNAL_OK;
janet_loop();
#endif
/* Deinitialize vm */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -2,20 +2,24 @@
:name "testmod")
(declare-native
:name "testmod"
:source @["testmod.c"])
:name "testmod"
:source @["testmod.c"])
(declare-native
:name "testmod2"
:source @["testmod2.c"])
:name "testmod2"
:source @["testmod2.c"])
(declare-native
:name "testmod3"
:source @["testmod3.cpp"])
:name "testmod3"
:source @["testmod3.cpp"])
(declare-native
:name "test-mod-4"
:source @["testmod4.c"])
:name "test-mod-4"
:source @["testmod4.c"])
(declare-native
:name "testmod5"
:source @["testmod5.cc"])
(declare-executable
:name "testexec"

View File

@@ -2,7 +2,8 @@
(use /build/testmod2)
(use /build/testmod3)
(use /build/test-mod-4)
(use /build/testmod5)
(defn main [&]
(print "Hello from executable!")
(print (+ (get5) (get6) (get7) (get8))))
(print (+ (get5) (get6) (get7) (get8) (get9))))

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose and contributors
* Copyright (c) 2021 Calvin Rose and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose and contributors
* Copyright (c) 2021 Calvin Rose and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose and contributors
* Copyright (c) 2021 Calvin Rose and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose and contributors
* Copyright (c) 2021 Calvin Rose and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to

42
test/install/testmod5.cc Normal file
View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 Calvin Rose and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/* A very simple native module */
#include <janet.h>
#include <iostream>
static Janet cfun_get_nine(int32_t argc, Janet *argv) {
(void) argv;
janet_fixarity(argc, 0);
std::cout << "Hello!" << std::endl;
return janet_wrap_number(9.0);
}
static const JanetReg array_cfuns[] = {
{"get9", cfun_get_nine, NULL},
{NULL, NULL, NULL}
};
JANET_MODULE_ENTRY(JanetTable *env) {
janet_cfuns(env, NULL, array_cfuns);
}

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose
# Copyright (c) 2021 Calvin Rose
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose
# Copyright (c) 2021 Calvin Rose
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -294,4 +294,25 @@
(sort (mapcat (fn [[x y z]] [z y x]) (partition 3 (range 99))))) "sort 5")
(assert (<= ;(sort (map (fn [x] (math/random)) (range 1000)))) "sort 6")
# And and or
(assert (= (and true true) true) "and true true")
(assert (= (and true false) false) "and true false")
(assert (= (and false true) false) "and false true")
(assert (= (and true true true) true) "and true true true")
(assert (= (and 0 1 2) 2) "and 0 1 2")
(assert (= (and 0 1 nil) nil) "and 0 1 nil")
(assert (= (and 1) 1) "and 1")
(assert (= (and) true) "and with no arguments")
(assert (= (or true true) true) "or true true")
(assert (= (or true false) true) "or true false")
(assert (= (or false true) true) "or false true")
(assert (= (or false false) false) "or false true")
(assert (= (or true true false) true) "or true true false")
(assert (= (or 0 1 2) 0) "or 0 1 2")
(assert (= (or nil 1 2) 1) "or nil 1 2")
(assert (= (or 1) 1) "or 1")
(assert (= (or) nil) "or with no arguments")
(end-suite)

View File

@@ -1,4 +1,4 @@
#' Copyright (c) 2020 Calvin Rose
# Copyright (c) 2021 Calvin Rose
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose
# Copyright (c) 2021 Calvin Rose
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -473,4 +473,24 @@
(check-deep '(* (int 2) -1) "123" nil)
# to/thru bug
(check-deep '(to -1) "aaaa" @[])
(check-deep '(thru -1) "aaaa" @[])
(check-deep ''(to -1) "aaaa" @["aaaa"])
(check-deep ''(thru -1) "aaaa" @["aaaa"])
(check-deep '(to "b") "aaaa" nil)
(check-deep '(thru "b") "aaaa" nil)
# unref
(def grammar
(peg/compile
~{:main (* :tagged -1)
:tagged (unref (replace (* :open-tag :value :close-tag) ,struct))
:open-tag (* (constant :tag) "<" (capture :w+ :tag-name) ">")
:value (* (constant :value) (group (any (+ :tagged :untagged))))
:close-tag (* "</" (backmatch :tag-name) ">")
:untagged (capture (any (if-not "<" 1)))}))
(check-deep grammar "<p><em>foobar</em></p>" @[{:tag "p" :value @[{:tag "em" :value @["foobar"]}]}])
(check-deep grammar "<p>foobar</p>" @[{:tag "p" :value @["foobar"]}])
(end-suite)

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose
# Copyright (c) 2021 Calvin Rose
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -70,5 +70,17 @@
(assert (= ~(,defn 1 2 3) [defn 1 2 3]) "bracket tuples are never macros")
(assert (= ~(,+ 1 2 3) [+ 1 2 3]) "bracket tuples are never function calls")
# Metadata
(def foo-with-tags :a-tag :bar)
(assert (get (dyn 'foo-with-tags) :a-tag) "extra keywords in def are metadata tags")
(def foo-with-meta {:baz :quux} :bar)
(assert (= :quux (get (dyn 'foo-with-meta) :baz)) "extra struct in def is metadata")
(defn foo-fn-with-meta {:baz :quux} "This is a function" [x] (identity x))
(assert (= :quux (get (dyn 'foo-fn-with-meta) :baz)) "extra struct in defn is metadata")
(assert (= "(foo-fn-with-meta x)\n\nThis is a function" (get (dyn 'foo-fn-with-meta) :doc)) "extra string in defn is docstring")
(end-suite)

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose & contributors
# Copyright (c) 2021 Calvin Rose & contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -21,54 +21,6 @@
(import ./helper :prefix "" :exit true)
(start-suite 5)
# some tests typed array
(defn inspect-tarray
[x]
(def a @[])
(for i 0 (tarray/length x) (array/push a (x i)))
(pp a))
(assert-no-error
"create some typed arrays"
(do
(def a (tarray/new :float64 10))
(def b (tarray/new :float64 5 2 0 a))
(def c (tarray/new :uint32 20))))
(assert-no-error
"create some typed arrays from a buffer"
(do
(def buf (tarray/buffer (+ 64 (* (+ 1 (* (- 10 1) 2)) 8))))
(def b (tarray/new :float64 10 2 64 buf))))
(def a (tarray/new :float64 10))
(def b (tarray/new :float64 5 2 0 a))
(assert-no-error
"fill tarray"
(for i 0 (tarray/length a)
(set (a i) i)))
(assert (= (tarray/buffer a) (tarray/buffer b)) "tarray views pointing same buffer")
(assert (= (a 2) (b 1) ) "tarray views pointing same buffer")
(assert (= ((tarray/slice b) 3) (b 3) (a 6) 6) "tarray slice")
(assert (= ((tarray/slice b 1) 2) (b 3) (a 6) 6) "tarray slice")
(assert (= (:length a) (length a)) "length method and function")
(assert (= ((unmarshal (marshal b)) 3) (b 3)) "marshal")
# Issue 408
(assert-error :invalid-type (tarray/new :int32 10 1 0 (int/u64 7)) "tarray/new should only allow tarray or buffer for last argument")
(def ta (tarray/new :int32 10))
(assert (= (next a nil) 0) "tarray next 1")
(assert (= (next a 0) 1) "tarray next 2")
(assert (= (next a 8) 9) "tarray next 3")
(assert (nil? (next a 9)) "tarray next 4")
(put ta 3 7)
(put ta 9 7)
(assert (= 2 (count |(= $ 7) ta)) "tarray count")
# Array remove
(assert (deep= (array/remove @[1 2 3 4 5] 2) @[1 2 4 5]) "array/remove 1")

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose & contributors
# Copyright (c) 2021 Calvin Rose & contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -72,22 +72,6 @@
"trap INT64_MIN / -1"
(:/ (int/s64 "-0x8000_0000_0000_0000") -1))
# int64 typed arrays
(assert (let [t (tarray/new :int64 10)
b (i64 1000)]
(set (t 0) 1000)
(set (t 1) b)
(set (t 2) "1000")
(set (t 3) (t 0))
(set (t 4) (u64 1000))
(and
(= (t 0) (t 1))
(= (t 1) (t 2))
(= (t 2) (t 3))
(= (t 3) (t 4))
))
"int64 typed arrays")
# Dynamic bindings
(setdyn :a 10)
(assert (= 40 (with-dyns [:a 25 :b 15] (+ (dyn :a) (dyn :b)))) "dyn usage 1")

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose & contributors
# Copyright (c) 2021 Calvin Rose & contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -112,19 +112,6 @@
(check-table-clone @{:a 123 :b 34 :c :hello : 945 0 1 2 3 4 5} "table/clone 1")
(check-table-clone @{} "table/clone 1")
# Issue #142
(def buffer (tarray/buffer 8))
(def buffer-float64-view (tarray/new :float64 1 1 0 buffer))
(def buffer-uint32-view (tarray/new :uint32 2 1 0 buffer))
(set (buffer-uint32-view 1) 0xfffe9234)
(set (buffer-uint32-view 0) 0x56789abc)
(assert (buffer-float64-view 0) "issue #142 nanbox hijack 1")
(assert (= (type (buffer-float64-view 0)) :number) "issue #142 nanbox hijack 2")
(assert (= (type (unmarshal @"\xC8\xbc\x9axV4\x92\xfe\xff")) :number) "issue #142 nanbox hijack 3")
# Make sure Carriage Returns don't end up in doc strings.
(assert (not (string/find "\r" (get ((fiber/getenv (fiber/current)) 'cond) :doc ""))) "no \\r in doc strings")

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2020 Calvin Rose & contributors
# Copyright (c) 2021 Calvin Rose & contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to

View File

@@ -1,4 +1,4 @@
#- Copyright (c) 2020 Calvin Rose & contributors
# Copyright (c) 2021 Calvin Rose & contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -137,4 +137,28 @@
(assert (deep= (string/split "qq" "1qqqqz") @["1" "" "z"]) "string/split 1")
(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")
# os/execute with environment variables
(assert (= 0 (os/execute [(dyn :executable) "-e" "(+ 1 2 3)"] :pe {"HELLO" "WORLD"})) "os/execute with env")
# Regression #638
(compwhen
(dyn 'ev/go)
(assert
(= [true :caught]
(protect
(try
(do
(ev/sleep 0)
(with-dyns []
(ev/sleep 0)
(error "oops")))
([err] :caught))))
"regression #638"))
(end-suite)

Binary file not shown.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Calvin Rose
* Copyright (c) 2021 Calvin Rose
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to