1
0
mirror of https://github.com/janet-lang/janet synced 2025-11-07 19:13:02 +00:00

Compare commits

..

115 Commits

Author SHA1 Message Date
Calvin Rose
be1ec1b973 Conditionally install jpm in meson. 2020-06-14 14:27:22 -05:00
Calvin Rose
1bddb87a0c Fix MSVC Warnings. 2020-06-14 14:20:38 -05:00
Calvin Rose
fbe23d8c33 Prepare for 1.10.0 release. 2020-06-14 14:16:01 -05:00
Calvin Rose
f435bb24ab Remove extra function on some installs. 2020-06-14 14:09:32 -05:00
Calvin Rose
853b33b67c On nix platforms, patch jpm with path information.
This means we no longer need to guess paths after install.
Custom directory layouts can now be better supported at install
time without need for environment variables.
2020-06-14 14:04:23 -05:00
Calvin Rose
19f3568e18 Update for 1.10.0. 2020-06-14 12:15:56 -05:00
Calvin Rose
911c2cbe58 Update CHANGELOG.md 2020-06-14 12:12:41 -05:00
Calvin Rose
17bdfbb08b Fix broken trace functionality.
This was an older regression that caused trace to emit
garbage output in most cases.
2020-06-14 11:58:20 -05:00
Calvin Rose
80f29ae859 Add some more bindings for jpm for future proofing. 2020-06-14 11:43:26 -05:00
Calvin Rose
0b114d680e Update CHANGELOG.md. 2020-06-13 14:10:35 -05:00
Calvin Rose
c87a0910d0 Add some flags to creating threads for more control.
Allow lightweight/heavyweight threads, and make default lightweight.
This means multithreaded programs can save lots of memory by default.
2020-06-13 09:42:16 -05:00
Calvin Rose
86e12369b6 Add alias for PEG repeat.
A tuple where the first element is an integer is
a shortand for this.
2020-06-11 11:23:43 -05:00
Calvin Rose
6d096551f0 Add Peg combinators 'to' and 'thru'.
Inpsired by the REBOL operators of the same name, these
combinators match bytes up to or inculding a given pattern.
(to patt) is (almost) equalivalent to (any (if-not patt 1)), and
(thru patt) is equivalent to (* (to patt) patt). The one difference
is that if the end of the input is reached and patt is not
matched, the entire pattern does not match.
2020-06-10 21:18:50 -05:00
Calvin Rose
2595c8a853 Properly hide private functions in boot.janet 2020-06-10 00:02:07 -05:00
Calvin Rose
2a9923999b Merge pull request #422 from MikeBeller/compare
Implement polymorphic compare
2020-06-10 00:58:33 -04:00
Calvin Rose
03cbeac1ea Remove snapcraft.yaml.
Removing explicit snapcraft support from janet. Getting things working
with snapcraft is not something I have had luck with, and snapcraft.io
has been spamming me with emails. Since this is not completely zero
overhead, I am simply removing support for snapcraft.
2020-06-06 11:35:43 -05:00
Mike Beller
9824a34d76 Remove dead code. 2020-06-06 08:55:20 -04:00
Mike Beller
76c3436377 Remove vestigial comparison methods from int types 2020-06-05 11:07:48 -04:00
Mike Beller
a4178d4b3c All tests pass for compare. 2020-06-05 10:51:35 -04:00
Mike Beller
3e423722c6 Actually got the comparisons working for s64 (still need to fix u64) 2020-06-04 18:27:48 -04:00
Mike Beller
01837f2bb6 All tests pass. 2020-06-04 15:27:36 -04:00
Mike Beller
411c5da6d3 compare functions now work for built ins and 'objects' 2020-06-04 13:49:09 -04:00
Mike Beller
7658ea8335 primitive tests working. issues remain with polymorphic. 2020-06-04 12:46:58 -04:00
Mike Beller
81d301a42b Initial commit of base functionality for compare 2020-06-04 12:23:54 -04:00
MikeBeller
0b500730e0 Merge pull request #1 from janet-lang/master
Bringing fork up to date
2020-06-04 10:35:03 -04:00
Calvin Rose
6c08dbab0e Merge pull request #420 from leafgarland/master
Implement os/realpath with _fullpath
2020-06-02 20:57:28 -04:00
Leaf
bed02c2f95 Remove unused flags 2020-06-02 09:14:31 +00:00
Leaf
75bc69ba2f Implement os/realpath on Window with _fullpath
This is similar to realpath but differs in that realpath will complain
if the path does not exist. We could add our own exists check if we
really wanted to match that behaviour.
2020-06-02 09:05:41 +00:00
Calvin Rose
eb9f74a273 Silence MSVC warning. 2020-05-30 10:06:39 -04:00
Calvin Rose
4056b94e01 Merge pull request #418 from ahungry/bugfix/Fix-double-free-fclose
Fix for double free on fclose due to GC not knowing it failed
2020-05-28 17:24:09 -04:00
Matthew Carter
ee94828355 Fix for double free on fclose due to GC not knowing it failed 2020-05-28 15:35:09 -04:00
Calvin Rose
fff66649aa Fix issue #416.
Be really sure we don't pass too large of a size to memcpy.
There seem to be some situations where the slotcount and the ua.count
do not match at all, so use the mimimum for copying.
2020-05-28 10:47:22 -05:00
Calvin Rose
b33fdc1674 Merge pull request #415 from leafgarland/fix_numarray_example
Fix numarray example to work with jpm and latest Janet c-api
2020-05-25 14:04:58 -04:00
Leaf Garland
6909d9c9c9 Fix c code for latest Janet 2020-05-24 21:30:23 +12:00
Leaf Garland
0d5d820f4f Remove cook code 2020-05-24 21:29:20 +12:00
Leaf Garland
6fbca3416a Move tests to tests dir 2020-05-24 21:28:16 +12:00
Leaf Garland
466d9b31ce Add project.janet for numarray 2020-05-24 21:25:52 +12:00
Calvin Rose
b6fdaaac41 Merge pull request #414 from roobie/update-readme
adds WiX details to README
2020-05-23 12:08:35 -04:00
Calvin Rose
c19bbfce78 Make style consistent. 2020-05-23 11:07:57 -05:00
Calvin Rose
e9fdbe0c89 Merge pull request #411 from LouisJackman/make-ctrl-c-interrupt-current-form
Make Ctrl-C Cancel the Current Form; Only Exit if Column 0 Outside of Form
2020-05-23 11:33:19 -04:00
bjorn roberg
f2299eab8f rephrase the info about WiX and .msi 2020-05-23 14:15:19 +02:00
LouisJackman
e220f44953 Simplify and don't replace history for cancelled forms 2020-05-23 08:36:40 +01:00
bjorn roberg
b750a84ab1 adds WiX details to README 2020-05-22 23:53:31 +02:00
Calvin Rose
41f8be2c53 Fix flycheck when using the use macro.
Flycheck originally expected `use` to have
the same arguments as `import`, but this is not the case.
2020-05-21 18:51:17 -05:00
LouisJackman
c3e4cbe950 Address compilation warning about modifier order 2020-05-21 18:51:25 +01:00
LouisJackman
50df5000c2 Update older run-context code 2020-05-21 18:47:47 +01:00
LouisJackman
3c8930b72b Get tests passing again by returning keyword rather than nil from chunks 2020-05-21 18:37:15 +01:00
LouisJackman
f0572c4d5f Remove REPL-within-form thread-local bool 2020-05-21 18:31:21 +01:00
Calvin Rose
057ba8a4e1 Fixes #409
Use the correct count in a memcpy.
2020-05-21 01:35:37 -05:00
Calvin Rose
677737d345 Fixes #412 Lookahead does not move cursor. 2020-05-21 01:22:08 -05:00
Calvin Rose
930ac9c57d Merge branch 'master' of https://github.com/janet-lang/janet 2020-05-21 00:18:45 -04:00
Calvin Rose
5caa0371c4 Replace forward slash in xcopy commands.
xcopy doesn't handle them in paths.
2020-05-21 00:18:07 -04:00
Calvin Rose
e6e1cb1b43 Merge pull request #410 from MikeBeller/tarray-next
Fix issue #408 -- make "next" work for typed arrays, and also fix
2020-05-20 19:00:06 -04:00
LouisJackman
164ed0b325 Get expected behaviour; cleanup after confirming behaviour is desired 2020-05-20 22:40:05 +01:00
Mike Beller
8263789602 Fix issue #408 -- make "next" work for typed arrays, and also fix
bug where tarray/new failed to fully check the type of it's last
argument.
2020-05-20 13:30:48 -04:00
Calvin Rose
a99906c6f0 Remove NSIS artifacts.
NSIS installer has been replaced by WiX installer.
2020-05-19 22:25:04 -05:00
Calvin Rose
617338457d More windows shenanigans with jpm.
Cannot remove open file, get rid of double rm.
2020-05-19 20:03:49 -04:00
Calvin Rose
1026d2173b Quick fix. 2020-05-19 19:21:30 -04:00
Calvin Rose
ca9c9ee807 Add the clear-manifest command. 2020-05-19 19:20:09 -04:00
Calvin Rose
bef51fe9ff Fix jpm. 2020-05-19 18:41:17 -04:00
Calvin Rose
b72845609f Add JANET_GIT to jpm.
This should allow work arounds for some windows installs.
Also, be clever about finding the location of te current git
executable on windows to avoid some path issues that seem to
occur on some windows installations.
2020-05-19 18:36:58 -04:00
Calvin Rose
ccd8b71c4b Fix os/shell usage in jpm on windows. 2020-05-19 16:28:43 -05:00
Calvin Rose
e623690295 Use keywords in the assembly interface.
This is simply more idiomatic, removes some unused and undocumented
features of the assembly interface, and simplifies it somewhat.
2020-05-19 13:51:39 -05:00
Calvin Rose
070baea3c4 Merge branch 'master' of github.com:janet-lang/janet 2020-05-19 09:47:11 -05:00
Calvin Rose
0e828792ae Fix segfault on bad loop. Fixes #407. 2020-05-19 09:45:45 -05:00
Calvin Rose
31a8dfa063 Merge pull request #406 from leafgarland/master
Add Wix/msi installer for Windows
2020-05-19 06:49:41 -04:00
Leaf Garland
338ef8f2e4 Update Appveyor to build Wix installer 2020-05-19 17:00:42 +12:00
Leaf Garland
737fee94d0 Change build_win.bat to build Wix installer 2020-05-19 16:57:26 +12:00
Leaf Garland
4a2d770066 Add Wix/msi installer for Windows 2020-05-19 16:56:50 +12:00
Calvin Rose
b7cfc08fc5 Improve line and col tracking in parser.
Unconditionally add line and column information if
a parsed value is a tuple - before, some parsed tuples
had line and col information omitted.
2020-05-18 19:05:27 -05:00
Calvin Rose
92f0e1719b Be less eager to set macro-form in macex1. 2020-05-18 18:37:41 -05:00
Calvin Rose
9e5f203302 Expose line, col in macros via (dyn :macro-form)
This exposes line and column indirectly via
tuple/sourcemap and allows interesting debug macros.
2020-05-18 18:27:35 -05:00
Calvin Rose
17cb0c1aee Merge pull request #402 from andrewchambers/linelockfiles
Format lock files for nicer diffs.
2020-05-18 18:45:25 -04:00
Calvin Rose
df32cd0aca Update tracev macro to be simpler and single arity.
Reference #401
2020-05-18 17:43:41 -05:00
Calvin Rose
ae5dc8c45b Merge pull request #401 from LouisJackman/add-dbg-core-macro
Add a dbg macro for easy var dumping
2020-05-18 18:30:14 -04:00
LouisJackman
b1ed5b0707 Add "trace " prefix missed out from previous commit 2020-05-18 22:02:56 +01:00
Calvin Rose
eefdb3f156 Merge pull request #403 from kryptine/master
Fix spelling errors
2020-05-18 17:01:41 -04:00
LouisJackman
e9a5cfaddd Adopt Andrew Chamber's suggestions 2020-05-18 21:55:21 +01:00
kryptine
f5f2997cc2 Fix spelling errors 2020-05-18 06:32:00 +00:00
Andrew Chambers
43d2ba6275 Format lock files for nicer diffs. 2020-05-18 15:43:52 +12:00
Calvin Rose
8b98b331cc Add :hardcode-syspath option to declare-binscript.
This should make fully correct installs easier.
2020-05-17 09:29:45 -05:00
LouisJackman
e0130e7fd7 "Literal" -> "Expression" for trace-pp msg 2020-05-17 08:18:44 +01:00
LouisJackman
fb491f0d7c Put back erroneously deleted "Literal" 2020-05-17 08:12:54 +01:00
Calvin Rose
33b5d9651f Remove more mentions of lisp in descriptions. 2020-05-16 15:22:34 -05:00
LouisJackman
9109e369ff Incorporate suggestions from PR 2020-05-16 20:18:00 +01:00
Calvin Rose
b97e011715 Remove some lisp claims from README for branding. 2020-05-16 14:12:21 -05:00
Calvin Rose
1bb9a9368b Make sure winsock2.h is included before windows.h
This should be true in the normal build, and especially in the
amalgamated build.
2020-05-16 12:41:26 -05:00
LouisJackman
ca3dac7e87 Return an immutable tuple instead 2020-05-16 15:50:47 +01:00
LouisJackman
59302d4f42 Return dbg values to work inside complex exprs 2020-05-16 15:42:16 +01:00
LouisJackman
fabb722c8d Add a dbg macro for easy var dumping 2020-05-16 15:15:57 +01:00
Calvin Rose
657fae490c Update CHANGELOG.md 2020-05-16 08:36:32 -05:00
Calvin Rose
e9acebe0e8 Merge branch 'master' of github.com:janet-lang/janet 2020-05-16 08:29:30 -05:00
Calvin Rose
7a84fc4742 Fix infinite loop in some cases.
Problem - reusing a tainted variable without reinitializing.
2020-05-16 08:28:50 -05:00
Calvin Rose
4be3d66a32 Merge pull request #395 from zyga/master
Add snapcraft packaging
2020-05-15 19:04:26 -04:00
Calvin Rose
92df01b99d Add valtest and debug to Makefile help. 2020-05-15 17:59:05 -05:00
Calvin Rose
5c9c738913 Merge pull request #399 from LouisJackman/add-make-help-target
Add make help target
2020-05-15 18:55:23 -04:00
Calvin Rose
83c357d9d1 Merge branch 'master' of github.com:janet-lang/janet 2020-05-15 17:24:21 -05:00
Calvin Rose
3bb3adefbb Rename jpm repl to jpm debug-repl. 2020-05-15 17:22:30 -05:00
Calvin Rose
cf670153f9 Add :fresh option to import. 2020-05-15 17:19:37 -05:00
LouisJackman
d6cd69e659 Add make help target 2020-05-15 07:51:21 +01:00
Calvin Rose
48d31ad7bc Merge pull request #396 from halfhorst/documentation/update-readme-embedding
update janetconf.h path in README embedding section
2020-05-13 18:13:53 -04:00
halfhorst
20aa258f0e update janetconf.h path in README embedding section 2020-05-13 14:54:44 -07:00
Zygmunt Krynicki
45a60956a6 Add snapcraft packaging
Snapcraft allows the latest version of Janet to be immediately available
to developers on most popular Linux distributions. This patch provides
the snapcraft.yaml file, which provides information about the package,
how to build it and how to install it.

Both janet and jpm are exposed, though the latter requires a store side
alias to be provided, as snap names also control application names, to
avoid clashes between applications.

For this prototype I've selected classic confinement. Application
language packages are usually provided with classic confinement, as that
is most flexible for developers.

Snaps do not support providing manual pages yet, so no entries for those
were created.

Signed-off-by: Zygmunt Krynicki <me@zygoon.pl>
2020-05-13 19:04:10 +02:00
Calvin Rose
4ae372262b 1.9.1 release. 2020-05-12 09:19:09 -05:00
Calvin Rose
02167a15d1 Add new Makefile options to meson. 2020-05-12 09:04:38 -05:00
Calvin Rose
b50a4669d2 Update README and CHANGELOG. 2020-05-12 08:56:58 -05:00
Calvin Rose
c947bda604 Remove .breakall and .clearall conditionally.
If disasm not available, these functions cannot be implemented.
2020-05-12 08:52:36 -05:00
Calvin Rose
00451777fe Add meson builds to sourcehut CI. 2020-05-12 08:46:26 -05:00
Calvin Rose
a65386e925 Merge branch 'master' of github.com:janet-lang/janet 2020-05-11 01:10:58 -05:00
Calvin Rose
2d7d154ffc Merge pull request #392 from t6/patch-meson
Unbreak Meson build
2020-05-11 00:08:25 -04:00
Calvin Rose
3100080a50 Add NO_UMASK and NO_REALPATH config options. 2020-05-10 23:07:54 -05:00
Tobias Kortkamp
7275370ae5 Unbreak Meson build
The Meson build system
Version: 0.54.0
Source dir: /wrkdirs/usr/ports/lang/janet/work/janet-1.9.0
Build dir: /wrkdirs/usr/ports/lang/janet/work/janet-1.9.0/_build
Build type: native build

meson.build:225:2: ERROR: Expecting rbracket got string.
  'test/suite9.janet'
  ^
For a block that started at 215,13
test_files = [
             ^
2020-05-11 06:02:26 +02:00
Calvin Rose
e013381e72 Conditionally ignore pclose as well as popen. 2020-05-10 21:06:52 -05:00
Calvin Rose
d05bb1c125 Fix nanboxing issue. 2020-05-10 20:14:47 -05:00
Calvin Rose
273d1ff2d0 Fix external grammar to disallow | and \ in symbols. 2020-05-10 16:57:42 -05:00
48 changed files with 1189 additions and 516 deletions

12
.builds/meson.yml Normal file
View File

@@ -0,0 +1,12 @@
image: openbsd/latest
sources:
- https://git.sr.ht/~bakpakin/janet
packages:
- meson
tasks:
- build: |
cd janet
meson setup build --buildtype=release
cd build
ninja
ninja test

23
.builds/meson_min.yml Normal file
View File

@@ -0,0 +1,23 @@
image: openbsd/latest
sources:
- https://git.sr.ht/~bakpakin/janet
packages:
- meson
tasks:
- build: |
cd janet
meson setup build --buildtype=release
cd build
meson configure -Dsingle_threaded=true
meson configure -Dnanbox=false
meson configure -Ddynamic_modules=false
meson configure -Ddocstrings=false
meson configure -Dnet=false
meson configure -Dsourcemaps=false
meson configure -Dpeg=false
meson configure -Dassembler=false
meson configure -Dint_types=false
meson configure -Dtyped_arrays=false
meson configure -Dreduced_os=true
meson configure -Dprf=false
ninja # will not pass tests but should build

0
.gitattributes vendored
View File

View File

@@ -1,6 +1,37 @@
# Changelog
All notable changes to this project will be documented in this file.
## 1.10.1 - 2020-06-14
- Hardcode default jpm paths on install so env variables are needed in fewer cases.
- Add `:no-compile` to `create-executable` option for jpm.
- Fix bug with the `trace` function.
- Add `:h`, `:a`, and `:c` flags to `thread/new` for creating new kinds of threads.
By default, threads will now consume much less memory per thread, but sending data between
threads may cost more.
- Fix flychecking when using the `use` macro.
- CTRL-C no longer exits the repl, and instead cancels the current form.
- Various small bug fixes
- New MSI installer instead of NSIS based installer.
- Make `os/realpath` work on windows.
- Add polymorphic `compare` functions for comparing numbers.
- Add `to` and `thru` peg combinators.
- Add `JANET_GIT` environment variable to jpm to use a specific git binary (useful mainly on windows).
- `asm` and `disasm` functions now use keywords instead of macros for keys. Also
some slight changes to the way constants are encoded (remove wrapping `quote` in some cases).
- Expose current macro form inside macros as (dyn :macro-form)
- Add `tracev` macro.
- Fix compiler bug that emitted incorrect code in some cases for while loops that create closures.
- Add `:fresh` option to `(import ...)` to overwrite the module cache.
- `(range x y 0)` will return an empty array instead of hanging forever.
- Rename `jpm repl` to `jpm debug-repl`.
## 1.9.1 - 2020-05-12
- Add :prefix option to declare-source
- Re-enable minimal builds with the debugger.
- Add several flags for configuring Janet on different platforms.
- Fix broken meson build from 1.9.0 and add meson to CI.
- Fix compilation issue when nanboxing is disabled.
## 1.9.0 - 2020-05-10
- Add `:ldflags` option to many jpm declare functions.
- Add `errorf` to core.

View File

@@ -35,8 +35,9 @@ may require changes before being merged.
[astyle](http://astyle.sourceforge.net/astyle.html). You will probably need
to install this, but it can be installed with most package managers.
For janet code, the use lisp indentation with 2 spaces. One can use janet.vim to
do this indentation, or approximate as close as possible.
For janet code, use lisp indentation with 2 spaces. One can use janet.vim to
do this indentation, or approximate as close as possible. There is a janet formatter
in [spork](https://github.com/janet-lang/spork.git) that can be used to format code as well.
## C style

View File

@@ -149,7 +149,7 @@ build/janet.c: build/janet_boot src/boot/boot.janet
##### Amalgamation #####
########################
SONAME=libjanet.so.1.9
SONAME=libjanet.so.1.10
build/shell.c: src/mainclient/shell.c
cp $< $@
@@ -233,6 +233,10 @@ build/doc.html: $(JANET_TARGET) tools/gendoc.janet
##### Installation #####
########################
build/jpm: jpm $(JANET_TARGET)
$(JANET_TARGET) tools/patch-jpm.janet jpm build/jpm "--libpath=$(LIBDIR)" "--headerpath=$(INCLUDEDIR)/janet" "--binpath=$(BINDIR)"
chmod +x build/jpm
.INTERMEDIATE: build/janet.pc
build/janet.pc: $(JANET_TARGET)
echo 'prefix=$(PREFIX)' > $@
@@ -248,7 +252,7 @@ build/janet.pc: $(JANET_TARGET)
echo 'Libs: -L$${libdir} -ljanet' >> $@
echo 'Libs.private: $(CLIBS)' >> $@
install: $(JANET_TARGET) build/janet.pc
install: $(JANET_TARGET) build/janet.pc build/jpm
mkdir -p '$(DESTDIR)$(BINDIR)'
cp $(JANET_TARGET) '$(DESTDIR)$(BINDIR)/janet'
mkdir -p '$(DESTDIR)$(INCLUDEDIR)/janet'
@@ -259,7 +263,7 @@ install: $(JANET_TARGET) build/janet.pc
cp $(JANET_STATIC_LIBRARY) '$(DESTDIR)$(LIBDIR)/libjanet.a'
ln -sf $(SONAME) '$(DESTDIR)$(LIBDIR)/libjanet.so'
ln -sf libjanet.so.$(shell $(JANET_TARGET) -e '(print janet/version)') $(DESTDIR)$(LIBDIR)/$(SONAME)
cp -rf jpm '$(DESTDIR)$(BINDIR)'
cp -rf build/jpm '$(DESTDIR)$(BINDIR)'
mkdir -p '$(DESTDIR)$(MANPATH)'
cp janet.1 '$(DESTDIR)$(MANPATH)'
cp jpm.1 '$(DESTDIR)$(MANPATH)'
@@ -306,5 +310,27 @@ test-install:
cd test/install && jpm --verbose --test --modpath=./modpath install https://github.com/janet-lang/path.git
cd test/install && jpm --verbose --test --modpath=./modpath install https://github.com/janet-lang/argparse.git
help:
@echo
@echo 'Janet: A Dynamic Language & Bytecode VM'
@echo
@echo Usage:
@echo ' make Build Janet'
@echo ' make repl Start a REPL from a built Janet'
@echo
@echo ' make test Test a built Janet'
@echo ' make valgrind Assess Janet with Valgrind'
@echo ' make callgrind Assess Janet with Valgrind, using Callgrind'
@echo ' make valtest Run the test suite with Valgrind to check for memory leaks'
@echo ' make dist Create a distribution tarball'
@echo ' make docs Generate documentation'
@echo ' make debug Run janet with GDB or LLDB'
@echo ' make install Install into the current filesystem'
@echo ' make uninstall Uninstall from the current filesystem'
@echo ' make clean Clean intermediate build artifacts'
@echo " make format Format Janet's own source files"
@echo ' make grammar Generate a TextMate language grammar'
@echo
.PHONY: clean install repl debug valgrind test \
valtest emscripten dist uninstall docs grammar format
valtest dist uninstall docs grammar format help

View File

@@ -4,11 +4,13 @@
[![Build Status](https://travis-ci.org/janet-lang/janet.svg?branch=master)](https://travis-ci.org/janet-lang/janet)
[![builds.sr.ht status](https://builds.sr.ht/~bakpakin/janet/freebsd.yml.svg)](https://builds.sr.ht/~bakpakin/janet/freebsd.yml?)
[![builds.sr.ht status](https://builds.sr.ht/~bakpakin/janet/openbsd.yml.svg)](https://builds.sr.ht/~bakpakin/janet/openbsd.yml?)
[![builds.sr.ht status](https://builds.sr.ht/~bakpakin/janet/meson.yml.svg)](https://builds.sr.ht/~bakpakin/janet/meson.yml?)
[![builds.sr.ht status](https://builds.sr.ht/~bakpakin/janet/meson_min.yml.svg)](https://builds.sr.ht/~bakpakin/janet/meson_min.yml?)
<img src="https://raw.githubusercontent.com/janet-lang/janet/master/assets/janet-w200.png" alt="Janet logo" width=200 align="left">
**Janet** is a functional and imperative programming language and bytecode interpreter. It is a
modern lisp, but lists are replaced
lisp-like language, but lists are replaced
by other data structures (arrays, tables (hash table), struct (immutable hash table), tuples).
The language also supports bridging to native code written in C, meta-programming with macros, and bytecode assembly.
@@ -35,7 +37,7 @@ Lua, but smaller than GNU Guile or Python.
* Mutable and immutable arrays (array/tuple)
* Mutable and immutable hashtables (table/struct)
* Mutable and immutable strings (buffer/string)
* Lisp Macros
* Macros
* Byte code interpreter with an assembly interface, as well as bytecode verification
* Tailcall Optimization
* Direct interop with C via abstract types and C functions
@@ -75,7 +77,7 @@ the SourceHut mirror is actively maintained.
## Building
### macos and Unix-like
### macOS and Unix-like
The Makefile is non-portable and requires GNU-flavored make.
@@ -86,6 +88,8 @@ make test
make repl
```
Find out more about the available make targets by running `make help`.
### 32-bit Haiku
32-bit Haiku build instructions are the same as the unix-like build instructions,
@@ -118,6 +122,13 @@ gmake repl
3. Run `build_win` to compile janet.
4. Run `build_win test` to make sure everything is working.
To build an `.msi` installer executable, in addition to the above steps, you will have to:
5. Install, or otherwise add to your PATH the [WiX 3.11 Toolset](https://github.com/wixtoolset/wix3/releases)
6. run `build_win dist`
Now you should have an `.msi`. You can run `build_win install` to install the `.msi`, or execute the file itself.
### Meson
Janet also has a build file for [Meson](https://mesonbuild.com/), a cross platform build
@@ -135,6 +146,7 @@ cd janet
meson setup build \
--buildtype release \
--optimization 2 \
--libdir /usr/local/lib \
-Dgit_hash=$(git log --pretty=format:'%h' -n 1)
ninja -C build
@@ -200,7 +212,7 @@ If installed, you can also run `man janet` and `man jpm` to get usage informatio
Janet can be embedded in a host program very easily. The normal build
will create a file `build/janet.c`, which is a single C file
that contains all the source to Janet. This file, along with
`src/include/janet.h` and `src/include/janetconf.h` can dragged into any C
`src/include/janet.h` and `src/conf/janetconf.h` can be dragged into any C
project and compiled into the project. Janet should be compiled with `-std=c99`
on most compilers, and will need to be linked to the math library, `-lm`, and
the dynamic linker, `-ldl`, if one wants to be able to load dynamic modules. If
@@ -220,10 +232,10 @@ Alternatively, check out [the #janet channel on Freenode](https://webchat.freeno
## FAQ
### Why is my terminal is spitting out junk when I run the repl?
### Why is my terminal spitting out junk when I run the repl?
Make sure your terminal supports ANSI escape codes. Most modern terminals will
support these, but some older terminals, windows consoles, or embedded terminals
support these, but some older terminals, Windows consoles, or embedded terminals
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.

View File

@@ -19,10 +19,6 @@ init:
install:
- set JANET_BUILD=%appveyor_repo_commit:~0,7%
- choco install nsis -y -pre --version 3.05
# Replace makensis.exe and files with special long string build. This should
# prevent issues when setting PATH during installation.
- 7z e "tools\nsis-3.05-strlen_8192.zip" -o"C:\Program Files (x86)\NSIS\" -y
- build_win all
- refreshenv
# We need to reload vcvars after refreshing
@@ -48,7 +44,7 @@ artifacts:
- name: "janet-$(janet_outname)-windows-%platform%"
path: dist
type: Zip
- path: "janet-$(janet_outname)-windows-%platform%-installer.exe"
- path: "janet-$(janet_outname)-windows-%platform%-installer.msi"
type: File
deploy:

View File

@@ -121,18 +121,29 @@ copy tools\jpm.bat dist\jpm.bat
@rem Create installer
janet.exe -e "(->> janet/version (peg/match ''(* :d+ `.` :d+ `.` :d+)) first print)" > build\version.txt
janet.exe -e "(print (= (os/arch) :x64))" > build\64bit.txt
janet.exe -e "(print (os/arch))" > build\arch.txt
set /p JANET_VERSION= < build\version.txt
set /p SIXTYFOUR= < build\64bit.txt
set /p BUILDARCH= < build\arch.txt
echo "JANET_VERSION is %JANET_VERSION%"
"C:\Program Files (x86)\NSIS\makensis.exe" /DVERSION=%JANET_VERSION% /DSIXTYFOUR=%SIXTYFOUR% janet-installer.nsi
if defined APPVEYOR_REPO_TAG_NAME (
set RELEASE_VERSION=%APPVEYOR_REPO_TAG_NAME%
) else (
set RELEASE_VERSION=%JANET_VERSION%
)
if defined CI (
set WIXBIN="c:\Program Files (x86)\WiX Toolset v3.11\bin\"
) else (
set WIXBIN=
)
%WIXBIN%candle.exe tools\msi\janet.wxs -arch %BUILDARCH% -out build\
%WIXBIN%light.exe "-sice:ICE38" -b tools\msi -ext WixUIExtension build\janet.wixobj -out janet-%RELEASE_VERSION%-windows-%BUILDARCH%-installer.msi
exit /b 0
@rem Run the installer. (Installs to the local user with default settings)
:INSTALL
@echo Running Installer...
FOR %%a in (janet-*-windows-*-installer.exe) DO (
%%a /S /CurrentUser
FOR %%a in (janet-*-windows-*-installer.msi) DO (
@echo Running Installer %%a...
%%a /QN
)
exit /b 0

View File

@@ -23,7 +23,7 @@ static int num_array_gc(void *p, size_t s) {
return 0;
}
Janet num_array_get(void *p, Janet key);
int num_array_get(void *p, Janet key, Janet *out);
void num_array_put(void *p, Janet key, Janet value);
static const JanetAbstractType num_array_type = {
@@ -31,7 +31,8 @@ static const JanetAbstractType num_array_type = {
num_array_gc,
NULL,
num_array_get,
num_array_put
num_array_put,
JANET_ATEND_PUT
};
static Janet num_array_new(int32_t argc, Janet *argv) {
@@ -81,21 +82,20 @@ static const JanetMethod methods[] = {
{NULL, NULL}
};
Janet num_array_get(void *p, Janet key) {
int num_array_get(void *p, Janet key, Janet *out) {
size_t index;
Janet value;
num_array *array = (num_array *)p;
if (janet_checktype(key, JANET_KEYWORD))
return janet_getmethod(janet_unwrap_keyword(key), methods);
return janet_getmethod(janet_unwrap_keyword(key), methods, out);
if (!janet_checkint(key))
janet_panic("expected integer key");
index = (size_t)janet_unwrap_integer(key);
if (index >= array->size) {
value = janet_wrap_nil();
return 0;
} else {
value = janet_wrap_number(array->data[index]);
*out = janet_wrap_number(array->data[index]);
}
return value;
return 1;
}
static const JanetReg cfuns[] = {

View File

@@ -0,0 +1,7 @@
(declare-project
:name "numarray"
:description "Example c lib with abstract type")
(declare-native
:name "numarray"
:source @["numarray.c"])

View File

@@ -1,10 +1,4 @@
(import cook)
(cook/make-native
:name "numarray"
:source @["numarray.c"])
(import build/numarray :as numarray)
(import build/numarray)
(def a (numarray/new 30))
(print (get a 20))

View File

@@ -1,217 +0,0 @@
# This file is invoked by build_win.bat
# Relevant configuration variables are set there.
SetCompressor /FINAL /SOLID lzma
Unicode True
!echo "Program Files: ${PROGRAMFILES}"
!addplugindir "tools\"
# Version
!define PRODUCT_VERSION "${VERSION}.0"
VIProductVersion "${PRODUCT_VERSION}"
VIFileVersion "${PRODUCT_VERSION}"
# Use the modern UI
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "Software\Janet\${VERSION}"
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME ""
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "Software\Janet\${VERSION}"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
!define MULTIUSER_INSTALLMODE_INSTDIR "Janet-${VERSION}"
!if ${SIXTYFOUR} == "true"
!define MULTIUSER_USE_PROGRAMFILES64
!define PLATNAME "x64"
!else
!define PLATNAME "x86"
!endif
# Includes
!include "MultiUser.nsh"
!include "MUI2.nsh"
!include "LogicLib.nsh"
# Basics
Name "Janet"
# Do some NSIS-fu to figure out at compile time if we are in appveyor
!define OUTNAME $%APPVEYOR_REPO_TAG_NAME%
!define "CHECK_${OUTNAME}"
!define DOLLAR "$"
!ifdef CHECK_${DOLLAR}%APPVEYOR_REPO_TAG_NAME%
# We are not in the appveyor environment, use version name
!define OUTNAME_PART ${VERSION}
!else
# We are in appveyor, use git tag name for installer
!define OUTNAME_PART ${OUTNAME}
!endif
OutFile "janet-${OUTNAME_PART}-windows-${PLATNAME}-installer.exe"
# Some Configuration
!define APPNAME "Janet"
!define DESCRIPTION "The Janet Programming Language"
!define HELPURL "http://janet-lang.org"
BrandingText "The Janet Programming Language"
# Macros for setting registry values
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\Janet-${VERSION}"
!macro WriteEnv key value
${If} $MultiUser.InstallMode == "AllUsers"
WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "${key}" "${value}"
${Else}
WriteRegExpandStr HKCU "Environment" "${key}" "${value}"
${EndIf}
!macroend
!macro DelEnv key
${If} $MultiUser.InstallMode == "AllUsers"
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "${key}"
${Else}
DeleteRegValue HKCU "Environment" "${key}"
${EndIf}
!macroend
# MUI Configuration
!define MUI_ICON "assets\icon.ico"
!define MUI_UNICON "assets\icon.ico"
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "assets\janet-w200.png"
!define MUI_HEADERIMAGE_RIGHT
!define MUI_ABORTWARNING
# Show a welcome page first
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "LICENSE"
# Pick Install Directory
!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
# Done
!insertmacro MUI_PAGE_FINISH
# Need to set a language.
!insertmacro MUI_LANGUAGE "English"
function .onInit
!insertmacro MULTIUSER_INIT
functionEnd
section "Janet" BfWSection
createDirectory "$INSTDIR\Library"
createDirectory "$INSTDIR\C"
createDirectory "$INSTDIR\bin"
createDirectory "$INSTDIR\docs"
setOutPath "$INSTDIR"
# Bin files
file /oname=bin\janet.exe dist\janet.exe
file /oname=logo.ico assets\icon.ico
file /oname=bin\jpm.janet .\jpm
file /oname=bin\jpm.bat tools\jpm.bat
# C headers and library files
file /oname=C\janet.h dist\janet.h
file /oname=C\janetconf.h dist\janetconf.h
file /oname=C\janet.lib dist\janet.lib
file /oname=C\janet.exp dist\janet.exp
file /oname=C\janet.c dist\janet.c
file /oname=C\libjanet.lib dist\libjanet.lib
# Documentation
file /oname=docs\docs.html dist\doc.html
# Other
file README.md
file LICENSE
# Uninstaller - See function un.onInit and section "uninstall" for configuration
writeUninstaller "$INSTDIR\uninstall.exe"
# Start Menu
createShortCut "$SMPROGRAMS\Janet.lnk" "$INSTDIR\bin\janet.exe" "" "$INSTDIR\logo.ico"
# Update path
${If} $MultiUser.InstallMode == "AllUsers"
EnVar::SetHKLM
${Else}
EnVar::SetHKCU
${EndIf}
EnVar::AddValue "PATH" "$INSTDIR\bin"
Pop $0
# Set up Environment variables
!insertmacro WriteEnv JANET_PATH "$INSTDIR\Library"
!insertmacro WriteEnv JANET_HEADERPATH "$INSTDIR\C"
!insertmacro WriteEnv JANET_LIBPATH "$INSTDIR\C"
!insertmacro WriteEnv JANET_BINPATH "$INSTDIR\bin"
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
# Registry information for add/remove programs
WriteRegStr SHCTX "${UNINST_KEY}" "DisplayName" "Janet"
WriteRegStr SHCTX "${UNINST_KEY}" "InstallLocation" "$INSTDIR"
WriteRegStr SHCTX "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\logo.ico"
WriteRegStr SHCTX "${UNINST_KEY}" "Publisher" "Janet-Lang.org"
WriteRegStr SHCTX "${UNINST_KEY}" "HelpLink" "${HELPURL}"
WriteRegStr SHCTX "${UNINST_KEY}" "URLUpdateInfo" "${HELPURL}"
WriteRegStr SHCTX "${UNINST_KEY}" "URLInfoAbout" "${HELPURL}"
WriteRegStr SHCTX "${UNINST_KEY}" "DisplayVersion" "${VERSION}"
WriteRegDWORD SHCTX "${UNINST_KEY}" "NoModify" 1
WriteRegDWORD SHCTX "${UNINST_KEY}" "NoRepair" 1
WriteRegDWORD SHCTX "${UNINST_KEY}" "EstimatedSize" 1000
# Add uninstall
WriteRegStr SHCTX "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\" /$MultiUser.InstallMode"
WriteRegStr SHCTX "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /$MultiUser.InstallMode /S"
sectionEnd
# Uninstaller
function un.onInit
!insertmacro MULTIUSER_UNINIT
functionEnd
section "uninstall"
# Remove Start Menu launcher
delete "$SMPROGRAMS\Janet.lnk"
# Remove files
delete "$INSTDIR\logo.ico"
delete "$INSTDIR\README.md"
delete "$INSTDIR\LICENSE"
rmdir /r "$INSTDIR\Library"
rmdir /r "$INSTDIR\bin"
rmdir /r "$INSTDIR\C"
rmdir /r "$INSTDIR\docs"
# Remove env vars
!insertmacro DelEnv JANET_PATH
!insertmacro DelEnv JANET_HEADERPATH
!insertmacro DelEnv JANET_LIBPATH
!insertmacro DelEnv JANET_BINPATH
# Unset PATH
${If} $MultiUser.InstallMode == "AllUsers"
EnVar::SetHKLM
${Else}
EnVar::SetHKCU
${EndIf}
EnVar::DeleteValue "PATH" "$INSTDIR\bin"
Pop $0
# make sure windows knows about the change
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
# Always delete uninstaller as the last action
delete "$INSTDIR\uninstall.exe"
# Remove uninstaller information from the registry
DeleteRegKey SHCTX "${UNINST_KEY}"
sectionEnd

View File

@@ -13,8 +13,8 @@ janet \- run the Janet language abstract machine
.BR args ...
.SH DESCRIPTION
Janet is a functional and imperative programming language and bytecode interpreter.
It is a modern lisp, but lists are replaced by other data structures with better utility
and performance (arrays, tables, structs, tuples). The language also features bridging
It is a Lisp-like language, but lists are replaced by other data structures
(arrays, tables, structs, tuples). The language also features bridging
to native code written in C, meta-programming with macros, and bytecode assembly.
There is a repl for trying out the language, as well as the ability to run script files.

171
jpm
View File

@@ -19,6 +19,9 @@
# Defaults
#
###START###
# Overriden on some installs.
(def- exe-dir
"Directory containing jpm script"
(do
@@ -26,21 +29,28 @@
(def i (last (string/find-all sep exe)))
(slice exe 0 i)))
(def JANET_MODPATH (or (os/getenv "JANET_MODPATH") (dyn :syspath)))
(def- install-paths
{:headerpath (os/realpath (string exe-dir "/../include/janet"))
:libpath (os/realpath (string exe-dir "/../lib"))
:binpath exe-dir})
###END###
# Default based on janet binary location
(def JANET_HEADERPATH (or (os/getenv "JANET_HEADERPATH")
(string exe-dir "/../include/janet")))
(get install-paths :headerpath)))
(def JANET_LIBPATH (or (os/getenv "JANET_LIBPATH")
(string exe-dir "/../lib")))
(get install-paths :libpath)))
# We want setting JANET_PATH to contain installed binaries. However, it is convenient
# to have globally installed binaries got to the same place as jpm itself, which is on
# the $PATH.
(def JANET_BINPATH (or (os/getenv "JANET_BINPATH")
(if-let [mp (os/getenv "JANET_MODPATH")] (string mp "/bin"))
(if-let [mp (os/getenv "JANET_PATH")] (string mp "/bin"))
exe-dir))
(get install-paths :binpath)))
# modpath should only be derived from the syspath being used or an environment variable.
(def JANET_MODPATH (or (os/getenv "JANET_MODPATH") (dyn :syspath)))
#
# Utilities
@@ -78,16 +88,23 @@
[path]
(if is-win
# windows get rid of read-only files
(os/shell `rmdir /S /Q "` path `"`))
(rm path))
(os/shell (string `rmdir /S /Q "` path `"`))
(rm path)))
(defn clear-cache
"Clear the global git cache."
[]
(def cache (find-cache))
(print "clearing " cache "...")
(print "clearing cache " cache "...")
(rimraf cache))
(defn clear-manifest
"Clear the global installation manifest."
[]
(def manifest (find-manifest-dir))
(print "clearing manifests " manifest "...")
(rimraf manifest))
(def- default-pkglist
(or (os/getenv "JANET_PKGLIST") "https://github.com/janet-lang/pkgs.git"))
@@ -134,7 +151,9 @@
(if is-win
(let [end (last (peg/match path-splitter src))
isdir (= (os/stat src :mode) :directory)]
(shell "xcopy" src (if isdir (string dest "\\" end) dest) "/y" "/s" "/e" "/i"))
(shell "C:\\Windows\\System32\\xcopy.exe"
(string/replace "/" "\\" src) (string/replace "/" "\\" (if isdir (string dest "\\" end) dest))
"/y" "/s" "/e" "/i"))
(shell "cp" "-rf" src dest)))
(defn mkdir
@@ -301,26 +320,30 @@
# Detect threads
(def env (fiber/getenv (fiber/current)))
(def threads? (not (not (env 'thread/new))))
# Default libraries to link
(def- thread-flags
(if is-win []
(if threads? ["-lpthread"] [])))
# lflags needed for the janet binary.
# 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]))
(def janet-ldflags [])
(def janet-cflags [])
# Default flags for natives, but not required
# How can we better detect the need for -pthread?
# we probably want to better detect compiler
(def default-lflags (if is-win ["/nologo"] []))
(def default-cflags
(if is-win
["/nologo" "/MD"]
["-std=c99" "-Wall" "-Wextra"]))
(def default-ldflags [])
# Required flags for dynamic libraries. These
# are used no matter what for dynamic libraries.
@@ -330,7 +353,7 @@
["-fPIC"]))
(def- dynamic-lflags
(if is-win
["/DLL" ;thread-flags]
["/DLL"]
(if is-mac
["-shared" "-undefined" "dynamic_lookup" ;thread-flags]
["-shared" ;thread-flags])))
@@ -376,8 +399,8 @@
"Generate strings for adding custom defines to the compiler."
[define value]
(if value
(string (if is-win "/D" "-D") define "=" value)
(string (if is-win "/D" "-D") define)))
(string "-D" define "=" value)
(string "-D" define)))
(defn- make-defines
"Generate many defines. Takes a dictionary of defines. If a value is
@@ -389,8 +412,8 @@
"Generate the c flags from the input options."
[opts]
@[;(opt opts :cflags default-cflags)
(string (if is-win "/I" "-I") (dyn :headerpath JANET_HEADERPATH))
(string (if is-win "/O" "-O") (opt opts :optimize 2))])
(string "-I" (dyn :headerpath JANET_HEADERPATH))
(string "-O" (opt opts :optimize 2))])
(defn- entry-name
"Name of symbol that enters static compilation of a module."
@@ -576,7 +599,8 @@ int main(int argc, const char **argv) {
# Create executable's janet image
(def cimage_dest (string dest ".c"))
(rule dest [source]
(def no-compile (opts :no-compile))
(rule (if no-compile cimage_dest dest) [source]
(check-cc)
(print "generating executable c source...")
(create-dirs dest)
@@ -632,11 +656,11 @@ int main(int argc, const char **argv) {
# Append main function
(spit cimage_dest (make-bin-source declarations lookup-into-invocations) :ab)
# Compile and link final exectable
(do
(unless no-compile
(def cc (opt opts :compiler default-compiler))
(def ldflags [;dep-ldflags ;(opt opts :ldflags [])])
(def ldflags [;dep-ldflags ;(opt opts :ldflags []) ;janet-ldflags])
(def lflags [;static-libs (libjanet) ;dep-lflags ;(opt opts :lflags default-lflags) ;janet-lflags])
(def cflags (getcflags opts))
(def cflags [;(getcflags opts) ;janet-cflags])
(def defines (make-defines (opt opts :defines {})))
(print "compiling and linking " dest "...")
(if is-win
@@ -647,6 +671,17 @@ int main(int argc, const char **argv) {
# Installation and Dependencies
#
(var- stored-git-path nil)
(defn- git-path
"Get the location of git such that it can be passed as an argument to os/execute."
"(Some builds/configurations of windows don't like just the string 'git')"
[]
(if stored-git-path (break stored-git-path))
(set stored-git-path
(if is-win
(or (os/getenv "JANET_GIT") (pslurp "where git"))
(os/getenv "JANET_GIT" "git"))))
(defn uninstall
"Uninstall bundle named name"
[name]
@@ -656,7 +691,8 @@ int main(int argc, const char **argv) {
(each path (get man :paths [])
(print "removing " path)
(rm path))
(print "removing " manifest)
(print "removing manifest " manifest)
(:close f) # I hate windows
(rm manifest)
(print "Uninstalled.")))
@@ -695,7 +731,7 @@ int main(int argc, const char **argv) {
(when (mkdir module-dir)
(set fresh true)
(print "cloning repository " repo " to " module-dir)
(unless (zero? (os/execute ["git" "clone" repo module-dir] :p))
(unless (zero? (os/execute [(git-path) "clone" repo module-dir] :p))
(rimraf module-dir)
(error (string "could not clone git dependency " repo)))))
(def olddir (os/cwd))
@@ -707,11 +743,11 @@ int main(int argc, const char **argv) {
:binpath (abspath (dyn :binpath JANET_BINPATH))]
(os/cd module-dir)
(unless fresh
(os/execute ["git" "pull" "origin" "master"] :p))
(os/execute [(git-path) "pull" "origin" "master"] :p))
(when tag
(os/execute ["git" "reset" "--hard" tag] :p))
(os/execute [(git-path) "reset" "--hard" tag] :p))
(unless (dyn :offline)
(os/execute ["git" "submodule" "update" "--init" "--recursive"] :p))
(os/execute [(git-path) "submodule" "update" "--init" "--recursive"] :p))
(import-rules "./project.janet")
(unless no-deps (do-rule "install-deps"))
(do-rule "build")
@@ -758,8 +794,15 @@ int main(int argc, const char **argv) {
(unless made-progress
(error (string/format "could not resolve package order for: %j"
(filter (complement resolved) (map |($ :repo) packages))))))
# Write to file
(with [f (file/open filename :w)] (with-dyns [:out f] (printf "%j" ordered-packages))))
# Write to file, manual format for better diffs.
(with [f (file/open filename :w)]
(with-dyns [:out f]
(prin "@[")
(eachk i ordered-packages
(unless (zero? i)
(prin "\n "))
(prinf "%j" (ordered-packages i)))
(print "]"))))
(defn- load-lockfile
[&opt filename]
@@ -833,10 +876,13 @@ int main(int argc, const char **argv) {
(install-rule sname path)))
(defn declare-source
"Create a Janet modules. This does not actually build the module(s),
but registers it for packaging and installation."
[&keys {:source sources}]
(def path (dyn :modpath JANET_MODPATH))
"Create Janet modules. This does not actually build the module(s),
but registers them for packaging and installation. :source should be an
array of files and directores to copy into JANET_MODPATH or JANET_PATH.
:prefix can optionally be given to modify the destination path to be
(string JANET_PATH prefix source)."
[&keys {:source sources :prefix prefix}]
(def path (string (dyn :modpath JANET_MODPATH) (or prefix "")))
(if (bytes? sources)
(install-rule sources path)
(each s sources
@@ -853,25 +899,46 @@ int main(int argc, const char **argv) {
is marshalled into bytecode which is then embedded in a final executable for distribution.\n\n
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}]
:cflags cflags :lflags lflags :deps deps :ldflags ldflags
:no-compile no-compile}]
(def name (if is-win (string name ".exe") name))
(def dest (string "build" sep name))
(create-executable @{:cflags cflags :lflags lflags :ldflags ldflags} entry dest)
(add-dep "build" dest)
(when headers
(each h headers (add-dep dest h)))
(when deps
(each d deps (add-dep dest d)))
(when install
(install-rule dest (dyn :binpath JANET_BINPATH))))
(create-executable @{:cflags cflags :lflags lflags :ldflags ldflags :no-compile no-compile} entry dest)
(if no-compile
(let [cdest (string dest ".c")]
(add-dep "build" cdest))
(do
(add-dep "build" dest)
(when headers
(each h headers (add-dep dest h)))
(when deps
(each d deps (add-dep dest d)))
(when install
(install-rule dest (dyn :binpath JANET_BINPATH))))))
(defn declare-binscript
"Declare a janet file to be installed as an executable script. Creates
a shim on windows."
[&keys opts]
(def main (opts :main))
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}]
(def binpath (dyn :binpath JANET_BINPATH))
(install-rule main binpath)
(if hardcode
(let [syspath (dyn :modpath JANET_MODPATH)]
(def parts (peg/match path-splitter main))
(def name (last parts))
(def path (string binpath sep name))
(array/push (dyn :installed-files) path)
(add-body "install"
(def contents
(with [f (file/open main)]
(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)))
(create-dirs path)
(spit path contents)
(unless is-win (shell "chmod" "+x" path))))
(install-rule main binpath))
# Create a dud batch file when on windows.
(when is-win
(def name (last (peg/match path-splitter main)))
@@ -929,8 +996,8 @@ int main(int argc, const char **argv) {
(phony "manifest" []
(print "generating " manifest "...")
(mkdir manifests)
(def sha (pslurp "git rev-parse HEAD"))
(def url (pslurp "git remote get-url origin"))
(def sha (pslurp (string "\"" (git-path) "\" rev-parse HEAD")))
(def url (pslurp (string "\"" (git-path) "\" remote get-url origin")))
(def man
{:sha (if-not (empty? sha) sha)
:repo (if-not (empty? url) url)
@@ -1006,6 +1073,7 @@ Subcommands are:
test : run tests. Tests should be .janet files in the test/ directory relative to project.janet.
deps : install dependencies for the current project.
clear-cache : clear the git cache. Useful for updating dependencies.
clear-manifest : clear the manifest. Useful for fixing broken installs.
run rule : run a rule. Can also run custom rules added via (phony "task" [deps...] ...)
or (rule "ouput.file" [deps...] ...).
rules : list rules available with run.
@@ -1021,8 +1089,8 @@ Subcommands are:
name is lockfile.jdn.
load-lockfile (lockfile) : Install modules from a lockfile in a reproducible way. The
default lockfile name is lockfile.jdn.
repl : Run a repl in the context of the current project.janet file. This lets you run rules and
otherwise debug the current project.janet file.
debug-repl : Run a repl in the context of the current project.janet file. This lets you run rules and
otherwise debug the current project.janet file.
Keys are:
--modpath : The directory to install modules to. Defaults to $JANET_MODPATH, $JANET_PATH, or (dyn :syspath)
@@ -1106,7 +1174,7 @@ Flags are:
(create-executable @{} input output)
(do-rule output))
(defn jpm-repl
(defn jpm-debug-repl
[]
(def env
(try
@@ -1135,10 +1203,11 @@ Flags are:
"test" test
"help" help
"deps" deps
"repl" jpm-repl
"debug-repl" jpm-debug-repl
"rule-tree" show-rule-tree
"show-paths" show-paths
"clear-cache" clear-cache
"clear-manifest" clear-manifest
"run" local-rule
"rules" list-rules
"update-pkgs" update-pkgs

17
jpm.1
View File

@@ -26,7 +26,7 @@ More interesting are the local commands. For more information on jpm usage, see
.TP
.BR \-\-nocolor
Disable color in the jpm repl.
Disable color in the jpm debug repl.
.TP
.BR \-\-verbose
@@ -139,6 +139,14 @@ date or too large, clear-cache will remove the cache and jpm will rebuild it
when needed. clear-cache is a global command, so a project.janet is not
required.
.TP
.BR clear-manifest
jpm creates a manifest directory that contains a list of all installed files.
By deleting this directory, jpm will think that nothing is installed and will
try reinstalling everything on the jpm deps or jpm load-lockfile commands. Be careful with
this command, as it may leave extra files on your system and shouldn't be needed
most of the time in a healthy install.
.TP
.BR run\ [\fBrule\fR]
Run a given rule defined in project.janet. Project definitions files (project.janet) usually
@@ -172,7 +180,7 @@ as function arguments. The entry file can import other modules, including native
jpm will attempt to include the dependencies into the generated executable.
.TP
.BR repl
.BR debug-repl
Load the current project.janet file and start a repl in it's environment. This lets a user better
debug the project file, as well as run rules manually.
@@ -237,5 +245,10 @@ The git repository URL that contains a listing of packages. This allows installi
is mostly a convenience. However, package dependencies can use short names, package listings
can be used to choose a particular set of dependency versions for a whole project.
.B JANET_GIT
.RS
An optional path to a git executable to use to clone git dependencies. By default, uses "git" on the current $PATH. You shouldn't need to set this
if you have a normal install of git.
.SH AUTHOR
Written by Calvin Rose <calsrose@gmail.com>

View File

@@ -20,7 +20,7 @@
project('janet', 'c',
default_options : ['c_std=c99', 'b_lundef=false', 'default_library=both'],
version : '1.9.0')
version : '1.10.0')
# Global settings
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
@@ -68,6 +68,9 @@ conf.set('JANET_RECURSION_GUARD', get_option('recursion_guard'))
conf.set('JANET_MAX_PROTO_DEPTH', get_option('max_proto_depth'))
conf.set('JANET_MAX_MACRO_EXPAND', get_option('max_macro_expand'))
conf.set('JANET_STACK_MAX', get_option('stack_max'))
conf.set('JANET_NO_UMASK', not get_option('umask'))
conf.set('JANET_NO_REALPATH', not get_option('realpath'))
conf.set('JANET_NO_PROCESSES', not get_option('processes'))
if get_option('os_name') != ''
conf.set('JANET_OS_NAME', get_option('os_name'))
endif
@@ -221,7 +224,7 @@ test_files = [
'test/suite5.janet',
'test/suite6.janet',
'test/suite7.janet',
'test/suite8.janet'
'test/suite8.janet',
'test/suite9.janet'
]
foreach t : test_files
@@ -242,7 +245,18 @@ pkg.generate(libjanet,
# Installation
install_man('janet.1')
install_man('jpm.1')
install_headers(['src/include/janet.h', jconf], subdir: 'janet')
install_data(sources : ['jpm'], install_dir : get_option('bindir'))
install_data(sources : ['tools/.keep'], install_dir : join_paths(get_option('libdir'), 'janet'))
if get_option('peg') and not get_option('reduced_os') and get_option('processes')
install_man('jpm.1')
patched_jpm = custom_target('patched-jpm',
input : ['tools/patch-jpm.janet', 'jpm'],
install : true,
install_dir : get_option('bindir'),
build_by_default : true,
output : ['jpm'],
command : [janet_nativeclient, '@INPUT@', '@OUTPUT@',
'--binpath=' + join_paths(get_option('prefix'), get_option('bindir')),
'--libpath=' + join_paths(get_option('prefix'), get_option('libdir'), 'janet'),
'--headerpath=' + join_paths(get_option('prefix'), get_option('includedir'))])
endif

View File

@@ -12,6 +12,9 @@ option('typed_array', type : 'boolean', value : true)
option('int_types', type : 'boolean', value : true)
option('prf', type : 'boolean', value : true)
option('net', type : 'boolean', value : true)
option('processes', type : 'boolean', value : true)
option('umask', type : 'boolean', value : true)
option('realpath', type : 'boolean', value : true)
option('recursion_guard', type : 'integer', min : 10, max : 8000, value : 1024)
option('max_proto_depth', type : 'integer', min : 10, max : 8000, value : 200)

View File

@@ -667,6 +667,68 @@
[xs]
(get xs (- (length xs) 1)))
## Polymorphic comparisons
(defn compare-primitive
"Compare x and y using primitive operators.
Returns -1,0,1 for x < y, x = y, x > y respectively.
Present mostly for constructing 'compare' methods in prototypes."
[x y]
(cond
(= x y) 0
(< x y) -1
(> x y) 1))
(defn compare
"Polymorphic compare. Returns -1,0,1 for x < y, x = y, x > y respectively.
Differs from the primitive comparators in that it first checks to
see whether either x or y implement a 'compare' method which can
compare x and y. If so it uses that compare method. If not, it
delegates to the primitive comparators."
[x y]
(or
(when-let [f (get x :compare)] (f x y))
(when-let [f (get y :compare)
fyx (f y x)] (- fyx))
(compare-primitive x y)))
(defn- compare-reduce [op xs]
(var r true)
(loop [i :range [0 (- (length xs) 1)]
:let [c (compare (xs i) (xs (+ i 1)))
ok (op c 0)]
:when (not ok)]
(set r false)
(break))
r)
(defn compare=
"Equivalent of '=' but using compare function instead of primitive comparator"
[& xs]
(compare-reduce = xs))
(defn compare<
"Equivalent of '<' but using compare function instead of primitive comparator"
[& xs]
(compare-reduce < xs))
(defn compare<=
"Equivalent of '<=' but using compare function instead of primitive comparator"
[& xs]
(compare-reduce <= xs))
(defn compare>
"Equivalent of '>' but using compare function instead of primitive comparator"
[& xs]
(compare-reduce > xs))
(defn compare>=
"Equivalent of '>=' but using compare function instead of primitive comparator"
[& xs]
(compare-reduce >= xs))
(put _env 'compare-reduce nil)
###
###
### Indexed Combinators
@@ -848,8 +910,9 @@
arr)
3 (do
(def [n m s] args)
(if (neg? s)
(seq [i :down [n m (- s)]] i)
(cond
(zero? s) @[]
(neg? s) (seq [i :down [n m (- s)]] i)
(seq [i :range [n m s]] i)))
(error "expected 1 to 3 arguments to range")))
@@ -945,6 +1008,21 @@
(array/push parts (tuple apply f $args)))
(tuple 'fn (tuple '& $args) (tuple/slice parts 0)))
(defmacro tracev
"Print a value and a description of the form that produced that value to
stderr. Evaluates to x."
[x]
(def [l c] (tuple/sourcemap (dyn :macro-form ())))
(def cf (dyn :current-file))
(def fmt-1 (if cf (string/format "trace [%s]" cf) "trace"))
(def fmt-2 (if (or (neg? l) (neg? c)) ":" (string/format " on line %d, column %d:" l c)))
(def fmt (string fmt-1 fmt-2 " %j is "))
(def s (gensym))
~(let [,s ,x]
(,eprinf ,fmt ',x)
(,eprintf (,dyn :pretty-format "%q") ,s)
,s))
(defmacro ->
"Threading macro. Inserts x as the second value in the first form
in forms, and inserts the modified first form into the second form
@@ -1696,7 +1774,7 @@
(def m? (entry :macro))
(cond
s (s t)
m? (m ;(tuple/slice t 1))
m? (do (setdyn :macro-form t) (m ;(tuple/slice t 1)))
(tuple/slice (map recur t))))
(def ret
@@ -2001,19 +2079,26 @@
(while going
(if (env :exit) (break))
(buffer/clear buf)
(chunks buf p)
(var pindex 0)
(var pstatus nil)
(def len (length buf))
(when (= len 0)
(parser/eof p)
(set going false))
(while (> len pindex)
(+= pindex (parser/consume p buf pindex))
(while (parser/has-more p)
(eval1 (parser/produce p)))
(when (= (parser/status p) :error)
(parse-err p where))))
(if (= (chunks buf p)
:cancel)
(do
# A :cancel chunk represents a cancelled form in the REPL, so reset.
(parser/flush p)
(buffer/clear buf))
(do
(var pindex 0)
(var pstatus nil)
(def len (length buf))
(when (= len 0)
(parser/eof p)
(set going false))
(while (> len pindex)
(+= pindex (parser/consume p buf pindex))
(while (parser/has-more p)
(eval1 (parser/produce p)))
(when (= (parser/status p) :error)
(parse-err p where))))))
# Check final parser state
(while (parser/has-more p)
(eval1 (parser/produce p)))
@@ -2131,11 +2216,12 @@
(defn- find-prefix
[pre]
(or (find-index |(and (string? ($ 0)) (string/has-prefix? pre ($ 0))) module/paths) 0))
(array/insert module/paths 0 [(string ":cur:/:all:" ext) loader check-.])
(def all-index (find-prefix ":all:"))
(array/insert module/paths all-index [(string ":all:" ext) loader not-check-.])
(def sys-index (find-prefix ":sys:"))
(array/insert module/paths sys-index [(string ":sys:/:all:" ext) loader not-check-.])
(def curall-index (find-prefix ":cur:/:all:"))
(array/insert module/paths curall-index [(string ":cur:/:all:" ext) loader check-.])
module/paths)
(module/add-paths ":native:" :native)
@@ -2262,14 +2348,11 @@
newenv)
:image (fn [path &] (load-image (slurp path)))})
(defn require
"Require a module with the given name. Will search all of the paths in
module/paths. Returns the new environment
returned from compiling and running the file."
[path & args]
(defn require-1
[path args kargs]
(def [fullpath mod-kind] (module/find path))
(unless fullpath (error mod-kind))
(if-let [check (in module/cache fullpath)]
(if-let [check (if-not (kargs :fresh) (in module/cache fullpath))]
check
(if (module/loading fullpath)
(error (string "circular dependency " fullpath " detected"))
@@ -2280,15 +2363,23 @@
(put module/cache fullpath env)
env))))
(defn require
"Require a module with the given name. Will search all of the paths in
module/paths. Returns the new environment
returned from compiling and running the file."
[path & args]
(require-1 path args (struct ;args)))
(defn import*
"Function form of import. Same parameters, but the path
and other symbol parameters should be strings instead."
[path & args]
(def env (fiber/getenv (fiber/current)))
(def kargs (table ;args))
(def {:as as
:prefix prefix
:export ep} (table ;args))
(def newenv (require path ;args))
:export ep} kargs)
(def newenv (require-1 path args kargs))
(def prefix (or
(and as (string as "/"))
prefix
@@ -2297,6 +2388,8 @@
(def newv (table/setproto @{:private (not ep)} v))
(put env (symbol prefix k) newv)))
(put _env 'require-1 nil)
(defmacro import
"Import a module. First requires the module, and then merges its
symbols into the current environment, prepending a given prefix as needed.
@@ -2304,7 +2397,8 @@
use the name of the module as a prefix. One can also use :export true
to re-export the imported symbols. If :exit true is given as an argument,
any errors encountered at the top level in the module will cause (os/exit 1)
to be called. Dynamic bindings will NOT be imported."
to be called. Dynamic bindings will NOT be imported. Use :fresh to bypass the
module cache."
[path & args]
(def argm (map |(if (keyword? $) $ (string $)) args))
(tuple import* (string path) ;argm))
@@ -2372,7 +2466,7 @@
(defn .bytecode
"Get the bytecode for the current function."
[&opt n]
((.disasm n) 'bytecode))
((.disasm n) :bytecode))
(defn .ppasm
"Pretty prints the assembly for the current function"
@@ -2380,13 +2474,13 @@
(def frame (.frame n))
(def func (frame :function))
(def dasm (disasm-alias func))
(def bytecode (in dasm 'bytecode))
(def bytecode (in dasm :bytecode))
(def pc (frame :pc))
(def sourcemap (in dasm 'sourcemap))
(def sourcemap (in dasm :sourcemap))
(var last-loc [-2 -2])
(print "\n signal: " (.signal))
(print " function: " (dasm 'name) " [" (in dasm 'source "") "]")
(when-let [constants (dasm 'constants)]
(print " function: " (dasm :name) " [" (in dasm :source "") "]")
(when-let [constants (dasm :constants)]
(printf " constants: %.4q" constants))
(printf " slots: %.4q\n" (frame :slots))
(def padding (string/repeat " " 20))
@@ -2404,20 +2498,6 @@
(print))
(print))
(unless (get _env 'disasm)
(put _env '.disasm nil)
(put _env '.bytecode nil)
(put _env '.ppasm nil))
(put _env 'disasm-alias nil)
(defn .source
"Show the source code for the function being debugged."
[&opt n]
(def frame (.frame n))
(def s (frame :source))
(def all-source (slurp s))
(print "\n" all-source "\n"))
(defn .breakall
"Set breakpoints on all instructions in the current function."
[&opt n]
@@ -2436,6 +2516,22 @@
(debug/unfbreak fun i))
(print "Cleared " (length bytecode) " breakpoints in " fun))
(unless (get _env 'disasm)
(put _env '.disasm nil)
(put _env '.bytecode nil)
(put _env '.breakall nil)
(put _env '.clearall nil)
(put _env '.ppasm nil))
(put _env 'disasm-alias nil)
(defn .source
"Show the source code for the function being debugged."
[&opt n]
(def frame (.frame n))
(def s (frame :source))
(def all-source (slurp s))
(print "\n" all-source "\n"))
(defn .break
"Set breakpoint at the current pc."
[]
@@ -2573,7 +2669,9 @@
'def is-safe-def 'var is-safe-def 'def- is-safe-def 'var- is-safe-def
'defglobal is-safe-def 'varglobal is-safe-def})
(def- importers {'import true 'import* true 'use true 'dofile true 'require true})
(def- importers {'import true 'import* true 'dofile true 'require true})
(defn- use-2 [evaluator args]
(each a args (import* (string a) :prefix "" :evaluator evaluator)))
# conditional compilation for reduced os
(def- getenv-alias (if-let [entry (in _env 'os/getenv)] (entry :value) (fn [&])))
@@ -2661,6 +2759,9 @@
# Always safe form
safe-check
(thunk)
# Use
(= 'use head)
(use-2 evaluator (tuple/slice source 1))
# Import-like form
(importers head)
(do
@@ -2711,6 +2812,7 @@
(put _env 'is-safe-def nil)
(put _env 'safe-forms nil)
(put _env 'importers nil)
(put _env 'use-2 nil)
(put _env 'getenv-alias nil)
###
@@ -2840,6 +2942,14 @@
(each h local-headers
(do-one-file h))
# windows.h should not be included in any of the external or internal headers - only in .c files.
(print)
(print "/* Windows work around - winsock2 must be included before windows.h, especially in amalgamated build */")
(print "#if defined(JANET_WINDOWS) && defined(JANET_NET)")
(print "#include <winsock2.h>")
(print "#endif")
(print)
(each s core-sources
(do-one-file s))

View File

@@ -27,10 +27,10 @@
#define JANETCONF_H
#define JANET_VERSION_MAJOR 1
#define JANET_VERSION_MINOR 9
#define JANET_VERSION_MINOR 10
#define JANET_VERSION_PATCH 0
#define JANET_VERSION_EXTRA ""
#define JANET_VERSION "1.9.0"
#define JANET_VERSION "1.10.0"
/* #define JANET_BUILD "local" */
@@ -55,7 +55,9 @@
/* Other settings */
/* #define JANET_NO_PRF */
/* #define JANET_NO_UTC_MKTIME */
/* #define JANET_NO_REALPATH */
/* #define JANET_NO_SYMLINKS */
/* #define JANET_NO_UMASK */
/* #define JANET_OUT_OF_MEMORY do { printf("janet out of memory\n"); exit(1); } while (0) */
/* #define JANET_EXIT(msg) do { printf("C assert failed executing janet: %s\n", msg); exit(1); } while (0) */
/* #define JANET_TOP_LEVEL_SIGNAL(msg) call_my_function((msg), stderr) */

View File

@@ -53,7 +53,6 @@ struct JanetAssembler {
Janet name;
JanetTable labels; /* keyword -> bytecode index */
JanetTable constants; /* symbol -> constant index */
JanetTable slots; /* symbol -> slot index */
JanetTable envs; /* symbol -> environment index */
JanetTable defs; /* symbol -> funcdefs index */
@@ -172,7 +171,6 @@ static void janet_asm_deinit(JanetAssembler *a) {
janet_table_deinit(&a->slots);
janet_table_deinit(&a->labels);
janet_table_deinit(&a->envs);
janet_table_deinit(&a->constants);
janet_table_deinit(&a->defs);
}
@@ -252,9 +250,6 @@ static int32_t doarg_1(
case JANET_OAT_ENVIRONMENT:
c = &a->envs;
break;
case JANET_OAT_CONSTANT:
c = &a->constants;
break;
case JANET_OAT_LABEL:
c = &a->labels;
break;
@@ -506,7 +501,6 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
a.defs_capacity = 0;
a.name = janet_wrap_nil();
janet_table_init(&a.labels, 0);
janet_table_init(&a.constants, 0);
janet_table_init(&a.slots, 0);
janet_table_init(&a.envs, 0);
janet_table_init(&a.defs, 0);
@@ -534,34 +528,34 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
"expected struct or table for assembly source");
/* Check for function name */
a.name = janet_get1(s, janet_csymbolv("name"));
a.name = janet_get1(s, janet_ckeywordv("name"));
if (!janet_checktype(a.name, JANET_NIL)) {
def->name = janet_to_string(a.name);
}
/* Set function arity */
x = janet_get1(s, janet_csymbolv("arity"));
x = janet_get1(s, janet_ckeywordv("arity"));
def->arity = janet_checkint(x) ? janet_unwrap_integer(x) : 0;
janet_asm_assert(&a, def->arity >= 0, "arity must be non-negative");
x = janet_get1(s, janet_csymbolv("max-arity"));
x = janet_get1(s, janet_ckeywordv("max-arity"));
def->max_arity = janet_checkint(x) ? janet_unwrap_integer(x) : def->arity;
janet_asm_assert(&a, def->max_arity >= def->arity, "max-arity must be greater than or equal to arity");
x = janet_get1(s, janet_csymbolv("min-arity"));
x = janet_get1(s, janet_ckeywordv("min-arity"));
def->min_arity = janet_checkint(x) ? janet_unwrap_integer(x) : def->arity;
janet_asm_assert(&a, def->min_arity <= def->arity, "min-arity must be less than or equal to arity");
/* Check vararg */
x = janet_get1(s, janet_csymbolv("vararg"));
x = janet_get1(s, janet_ckeywordv("vararg"));
if (janet_truthy(x)) def->flags |= JANET_FUNCDEF_FLAG_VARARG;
/* Check source */
x = janet_get1(s, janet_csymbolv("source"));
x = janet_get1(s, janet_ckeywordv("source"));
if (janet_checktype(x, JANET_STRING)) def->source = janet_unwrap_string(x);
/* Create slot aliases */
x = janet_get1(s, janet_csymbolv("slots"));
x = janet_get1(s, janet_ckeywordv("slots"));
if (janet_indexed_view(x, &arr, &count)) {
for (i = 0; i < count; i++) {
Janet v = arr[i];
@@ -582,7 +576,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
}
/* Parse constants */
x = janet_get1(s, janet_csymbolv("constants"));
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);
@@ -591,25 +585,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
}
for (i = 0; i < count; i++) {
Janet ct = arr[i];
if (janet_checktype(ct, JANET_TUPLE) &&
janet_tuple_length(janet_unwrap_tuple(ct)) > 1 &&
janet_checktype(janet_unwrap_tuple(ct)[0], JANET_SYMBOL)) {
const Janet *t = janet_unwrap_tuple(ct);
int32_t tcount = janet_tuple_length(t);
const uint8_t *macro = janet_unwrap_symbol(t[0]);
if (0 == janet_cstrcmp(macro, "quote")) {
def->constants[i] = t[1];
} else if (tcount == 3 &&
janet_checktype(t[1], JANET_SYMBOL) &&
0 == janet_cstrcmp(macro, "def")) {
def->constants[i] = t[2];
janet_table_put(&a.constants, t[1], janet_wrap_integer(i));
} else {
janet_asm_errorv(&a, janet_formatc("could not parse constant \"%v\"", ct));
}
} else {
def->constants[i] = ct;
}
def->constants[i] = ct;
}
} else {
def->constants = NULL;
@@ -617,7 +593,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
}
/* Parse sub funcdefs */
x = janet_get1(s, janet_csymbolv("closures"));
x = janet_get1(s, janet_ckeywordv("closures"));
if (janet_indexed_view(x, &arr, &count)) {
int32_t i;
for (i = 0; i < count; i++) {
@@ -628,7 +604,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
if (subres.status != JANET_ASSEMBLE_OK) {
janet_asm_errorv(&a, subres.error);
}
subname = janet_get1(arr[i], janet_csymbolv("name"));
subname = janet_get1(arr[i], janet_ckeywordv("name"));
if (!janet_checktype(subname, JANET_NIL)) {
janet_table_put(&a.defs, subname, janet_wrap_integer(def->defs_length));
}
@@ -647,7 +623,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
}
/* Parse bytecode and labels */
x = janet_get1(s, janet_csymbolv("bytecode"));
x = janet_get1(s, janet_ckeywordv("bytecode"));
if (janet_indexed_view(x, &arr, &count)) {
/* Do labels and find length */
int32_t blength = 0;
@@ -703,7 +679,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
a.errindex = -1;
/* Check for source mapping */
x = janet_get1(s, janet_csymbolv("sourcemap"));
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);
@@ -864,33 +840,26 @@ Janet janet_disasm(JanetFuncDef *def) {
JanetArray *bcode = janet_array(def->bytecode_length);
JanetArray *constants;
JanetTable *ret = janet_table(10);
janet_table_put(ret, janet_csymbolv("arity"), janet_wrap_integer(def->arity));
janet_table_put(ret, janet_csymbolv("min-arity"), janet_wrap_integer(def->min_arity));
janet_table_put(ret, janet_csymbolv("max-arity"), janet_wrap_integer(def->max_arity));
janet_table_put(ret, janet_csymbolv("bytecode"), janet_wrap_array(bcode));
janet_table_put(ret, janet_ckeywordv("arity"), janet_wrap_integer(def->arity));
janet_table_put(ret, janet_ckeywordv("min-arity"), janet_wrap_integer(def->min_arity));
janet_table_put(ret, janet_ckeywordv("max-arity"), janet_wrap_integer(def->max_arity));
janet_table_put(ret, janet_ckeywordv("bytecode"), janet_wrap_array(bcode));
if (NULL != def->source) {
janet_table_put(ret, janet_csymbolv("source"), janet_wrap_string(def->source));
janet_table_put(ret, janet_ckeywordv("source"), janet_wrap_string(def->source));
}
if (def->flags & JANET_FUNCDEF_FLAG_VARARG) {
janet_table_put(ret, janet_csymbolv("vararg"), janet_wrap_true());
janet_table_put(ret, janet_ckeywordv("vararg"), janet_wrap_true());
}
if (NULL != def->name) {
janet_table_put(ret, janet_csymbolv("name"), janet_wrap_string(def->name));
janet_table_put(ret, janet_ckeywordv("name"), janet_wrap_string(def->name));
}
/* Add constants */
if (def->constants_length > 0) {
constants = janet_array(def->constants_length);
janet_table_put(ret, janet_csymbolv("constants"), janet_wrap_array(constants));
janet_table_put(ret, janet_ckeywordv("constants"), janet_wrap_array(constants));
for (i = 0; i < def->constants_length; i++) {
Janet src = def->constants[i];
Janet dest;
if (janet_checktype(src, JANET_TUPLE)) {
dest = janet_wrap_tuple(tup2(janet_csymbolv("quote"), src));
} else {
dest = src;
}
constants->data[i] = dest;
constants->data[i] = def->constants[i];
}
constants->count = def->constants_length;
}
@@ -912,7 +881,7 @@ Janet janet_disasm(JanetFuncDef *def) {
sourcemap->data[i] = janet_wrap_tuple(janet_tuple_end(t));
}
sourcemap->count = def->bytecode_length;
janet_table_put(ret, janet_csymbolv("sourcemap"), janet_wrap_array(sourcemap));
janet_table_put(ret, janet_ckeywordv("sourcemap"), janet_wrap_array(sourcemap));
}
/* Add environments */
@@ -922,7 +891,7 @@ Janet janet_disasm(JanetFuncDef *def) {
envs->data[i] = janet_wrap_integer(def->environments[i]);
}
envs->count = def->environments_length;
janet_table_put(ret, janet_csymbolv("environments"), janet_wrap_array(envs));
janet_table_put(ret, janet_ckeywordv("environments"), janet_wrap_array(envs));
}
/* Add closures */
@@ -933,11 +902,11 @@ Janet janet_disasm(JanetFuncDef *def) {
defs->data[i] = janet_disasm(def->defs[i]);
}
defs->count = def->defs_length;
janet_table_put(ret, janet_csymbolv("defs"), janet_wrap_array(defs));
janet_table_put(ret, janet_ckeywordv("defs"), janet_wrap_array(defs));
}
/* Add slotcount */
janet_table_put(ret, janet_csymbolv("slotcount"), janet_wrap_integer(def->slotcount));
janet_table_put(ret, janet_ckeywordv("slotcount"), janet_wrap_integer(def->slotcount));
return janet_wrap_struct(janet_table_to_struct(ret));
}

View File

@@ -596,8 +596,11 @@ static int macroexpand1(
/* Set env */
fiberp->env = c->env;
int lock = janet_gclock();
Janet mf_kw = janet_ckeywordv("macro-form");
janet_table_put(c->env, mf_kw, x);
Janet tempOut;
JanetSignal status = janet_continue(fiberp, janet_wrap_nil(), &tempOut);
janet_table_put(c->env, mf_kw, janet_wrap_nil());
janet_gcunlock(lock);
if (status != JANET_SIGNAL_OK) {
const uint8_t *es = janet_formatc("(macro) %V", tempOut);
@@ -747,8 +750,10 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
/* Copy upvalue bitset */
if (scope->ua.count) {
/* Number of u32s we need to create a bitmask for all slots */
int32_t numchunks = (def->slotcount + 31) >> 5;
uint32_t *chunks = malloc(sizeof(uint32_t) * numchunks);
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);
if (NULL == chunks) {
JANET_OUT_OF_MEMORY;
}

View File

@@ -687,7 +687,7 @@ static const JanetReg corelib_cfuns[] = {
"\t:dir:\tthe directory containing the current file\n"
"\t:name:\tthe name component of path, with extension if given\n"
"\t:native:\tthe extension used to load natives, .so or .dll\n"
"\t:sys:\tthe system path, or (syn :syspath)")
"\t:sys:\tthe system path, or (dyn :syspath)")
},
{
"int?", janet_core_check_int,

View File

@@ -197,6 +197,122 @@ static Janet cfun_it_u64_new(int32_t argc, Janet *argv) {
return janet_wrap_u64(janet_unwrap_u64(argv[0]));
}
// Code to support polymorphic comparison.
//
// int/u64 and int/s64 support a "compare" method that allows
// comparison to each other, and to Janet numbers, using the
// "compare" "compare<" ... functions.
//
// In the following code explicit casts are sometimes used to help
// make it clear when int/float conversions are happening.
//
static int compare_double_double(double x, double y) {
return (x < y) ? -1 : ((x > y) ? 1 : 0);
}
static int compare_int64_double(int64_t x, double y) {
if (isnan(y)) {
return 0; // clojure and python do this
} else if ((y > (- ((double) MAX_INT_IN_DBL))) && (y < ((double) MAX_INT_IN_DBL))) {
double dx = (double) x;
return compare_double_double(dx, y);
} else if (y > ((double) INT64_MAX)) {
return -1;
} else if (y < ((double) INT64_MIN)) {
return 1;
} else {
int64_t yi = (int64_t) y;
return (x < yi) ? -1 : ((x > yi) ? 1 : 0);
}
}
static int compare_uint64_double(uint64_t x, double y) {
if (isnan(y)) {
return 0; // clojure and python do this
} else if (y < 0) {
return 1;
} else if ((y >= 0) && (y < ((double) MAX_INT_IN_DBL))) {
double dx = (double) x;
return compare_double_double(dx, y);
} else if (y > ((double) UINT64_MAX)) {
return -1;
} else {
uint64_t yi = (uint64_t) y;
return (x < yi) ? -1 : ((x > yi) ? 1 : 0);
}
}
static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) {
janet_fixarity(argc, 2);
if (janet_is_int(argv[0]) != JANET_INT_S64)
janet_panic("compare method requires int/s64 as first argument");
int64_t x = janet_unwrap_s64(argv[0]);
switch (janet_type(argv[1])) {
default:
break;
case JANET_NUMBER : {
double y = janet_unwrap_number(argv[1]);
return janet_wrap_number(compare_int64_double(x, y));
}
case JANET_ABSTRACT: {
void *abst = janet_unwrap_abstract(argv[1]);
if (janet_abstract_type(abst) == &janet_s64_type) {
int64_t y = *(int64_t *)abst;
return janet_wrap_number((x < y) ? -1 : (x > y ? 1 : 0));
} else if (janet_abstract_type(abst) == &janet_u64_type) {
// comparing signed to unsigned -- be careful!
uint64_t y = *(uint64_t *)abst;
if (x < 0) {
return janet_wrap_number(-1);
} else if (y > INT64_MAX) {
return janet_wrap_number(-1);
} else {
int64_t y2 = (int64_t) y;
return janet_wrap_number((x < y2) ? -1 : (x > y2 ? 1 : 0));
}
}
break;
}
}
return janet_wrap_nil();
}
static Janet cfun_it_u64_compare(int32_t argc, Janet *argv) {
janet_fixarity(argc, 2);
if (janet_is_int(argv[0]) != JANET_INT_U64) // is this needed?
janet_panic("compare method requires int/u64 as first argument");
uint64_t x = janet_unwrap_u64(argv[0]);
switch (janet_type(argv[1])) {
default:
break;
case JANET_NUMBER : {
double y = janet_unwrap_number(argv[1]);
return janet_wrap_number(compare_uint64_double(x, y));
}
case JANET_ABSTRACT: {
void *abst = janet_unwrap_abstract(argv[1]);
if (janet_abstract_type(abst) == &janet_u64_type) {
uint64_t y = *(uint64_t *)abst;
return janet_wrap_number((x < y) ? -1 : (x > y ? 1 : 0));
} else if (janet_abstract_type(abst) == &janet_s64_type) {
// comparing unsigned to signed -- be careful!
int64_t y = *(int64_t *)abst;
if (y < 0) {
return janet_wrap_number(1);
} else if (x > INT64_MAX) {
return janet_wrap_number(1);
} else {
int64_t x2 = (int64_t) x;
return janet_wrap_number((x2 < y) ? -1 : (x2 > y ? 1 : 0));
}
}
break;
}
}
return janet_wrap_nil();
}
#define OPMETHOD(T, type, name, oper) \
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
janet_arity(argc, 2, -1); \
@@ -266,14 +382,6 @@ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
return janet_wrap_abstract(box); \
} \
#define COMPMETHOD(T, type, name, oper) \
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
janet_fixarity(argc, 2); \
T v1 = janet_unwrap_##type(argv[0]); \
T v2 = janet_unwrap_##type(argv[1]); \
return janet_wrap_boolean(v1 oper v2); \
}
static Janet cfun_it_s64_mod(int32_t argc, Janet *argv) {
janet_arity(argc, 2, -1);
int64_t *box = janet_abstract(&janet_s64_type, sizeof(int64_t));
@@ -316,13 +424,6 @@ OPMETHOD(int64_t, s64, or, |)
OPMETHOD(int64_t, s64, xor, ^)
OPMETHOD(int64_t, s64, lshift, <<)
OPMETHOD(int64_t, s64, rshift, >>)
COMPMETHOD(int64_t, s64, lt, <)
COMPMETHOD(int64_t, s64, gt, >)
COMPMETHOD(int64_t, s64, le, <=)
COMPMETHOD(int64_t, s64, ge, >=)
COMPMETHOD(int64_t, s64, eq, ==)
COMPMETHOD(int64_t, s64, ne, !=)
OPMETHOD(uint64_t, u64, add, +)
OPMETHOD(uint64_t, u64, sub, -)
OPMETHODINVERT(uint64_t, u64, subi, -)
@@ -336,18 +437,13 @@ OPMETHOD(uint64_t, u64, or, |)
OPMETHOD(uint64_t, u64, xor, ^)
OPMETHOD(uint64_t, u64, lshift, <<)
OPMETHOD(uint64_t, u64, rshift, >>)
COMPMETHOD(uint64_t, u64, lt, <)
COMPMETHOD(uint64_t, u64, gt, >)
COMPMETHOD(uint64_t, u64, le, <=)
COMPMETHOD(uint64_t, u64, ge, >=)
COMPMETHOD(uint64_t, u64, eq, ==)
COMPMETHOD(uint64_t, u64, ne, !=)
#undef OPMETHOD
#undef DIVMETHOD
#undef DIVMETHOD_SIGNED
#undef COMPMETHOD
static JanetMethod it_s64_methods[] = {
{"+", cfun_it_s64_add},
{"r+", cfun_it_s64_add},
@@ -361,12 +457,6 @@ static JanetMethod it_s64_methods[] = {
{"rmod", cfun_it_s64_modi},
{"%", cfun_it_s64_rem},
{"r%", cfun_it_s64_remi},
{"<", cfun_it_s64_lt},
{">", cfun_it_s64_gt},
{"<=", cfun_it_s64_le},
{">=", cfun_it_s64_ge},
{"=", cfun_it_s64_eq},
{"!=", cfun_it_s64_ne},
{"&", cfun_it_s64_and},
{"r&", cfun_it_s64_and},
{"|", cfun_it_s64_or},
@@ -375,6 +465,7 @@ static JanetMethod it_s64_methods[] = {
{"r^", cfun_it_s64_xor},
{"<<", cfun_it_s64_lshift},
{">>", cfun_it_s64_rshift},
{"compare", cfun_it_s64_compare},
{NULL, NULL}
};
@@ -392,12 +483,6 @@ static JanetMethod it_u64_methods[] = {
{"rmod", cfun_it_u64_modi},
{"%", cfun_it_u64_mod},
{"r%", cfun_it_u64_modi},
{"<", cfun_it_u64_lt},
{">", cfun_it_u64_gt},
{"<=", cfun_it_u64_le},
{">=", cfun_it_u64_ge},
{"=", cfun_it_u64_eq},
{"!=", cfun_it_u64_ne},
{"&", cfun_it_u64_and},
{"r&", cfun_it_u64_and},
{"|", cfun_it_u64_or},
@@ -406,6 +491,7 @@ static JanetMethod it_u64_methods[] = {
{"r^", cfun_it_u64_xor},
{"<<", cfun_it_u64_lshift},
{">>", cfun_it_u64_rshift},
{"compare", cfun_it_u64_compare},
{NULL, NULL}
};

View File

@@ -253,7 +253,9 @@ static int cfun_io_gc(void *p, size_t len) {
if (!(iof->flags & (JANET_FILE_NOT_CLOSEABLE | JANET_FILE_CLOSED))) {
/* We can't panic inside a gc, so just ignore bad statuses here */
if (iof->flags & JANET_FILE_PIPED) {
#ifndef JANET_NO_PROCESSES
pclose(iof->file);
#endif
} else {
fclose(iof->file);
}
@@ -270,12 +272,17 @@ static Janet cfun_io_fclose(int32_t argc, Janet *argv) {
if (iof->flags & (JANET_FILE_NOT_CLOSEABLE))
janet_panic("file not closable");
if (iof->flags & JANET_FILE_PIPED) {
#ifndef JANET_NO_PROCESSES
int status = pclose(iof->file);
iof->flags |= JANET_FILE_CLOSED;
if (status == -1) janet_panic("could not close file");
return janet_wrap_integer(WEXITSTATUS(status));
#endif
} else {
if (fclose(iof->file)) janet_panic("could not close file");
if (fclose(iof->file)) {
iof->flags |= JANET_FILE_NOT_CLOSEABLE;
janet_panic("could not close file");
}
iof->flags |= JANET_FILE_CLOSED;
return janet_wrap_nil();
}

View File

@@ -26,9 +26,11 @@
#include "util.h"
#endif
#ifdef JANET_NET
#ifdef JANET_WINDOWS
#include <windows.h>
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
@@ -675,3 +677,5 @@ void janet_net_deinit(void) {
WSACleanup();
#endif
}
#endif

View File

@@ -339,7 +339,7 @@ static Janet os_execute(int32_t argc, Janet *argv) {
JanetBuffer *buf = os_exec_escape(exargs);
if (buf->count > 8191) {
janet_panic("command line string too long");
janet_panic("command line string too long (max 8191 characters)");
}
const char *path = (const char *) janet_unwrap_string(exargs.items[0]);
char *cargv[2] = {(char *) buf->data, NULL};
@@ -877,6 +877,7 @@ static Janet os_remove(int32_t argc, Janet *argv) {
return janet_wrap_nil();
}
#ifndef JANET_NO_SYMLINKS
static Janet os_readlink(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
#ifdef JANET_WINDOWS
@@ -893,6 +894,7 @@ static Janet os_readlink(int32_t argc, Janet *argv) {
return janet_stringv((const uint8_t *)buffer, len);
#endif
}
#endif
#ifdef JANET_WINDOWS
@@ -1161,6 +1163,7 @@ static Janet os_chmod(int32_t argc, Janet *argv) {
return janet_wrap_nil();
}
#ifndef JANET_NO_UMASK
static Janet os_umask(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
int mask = (int) os_getmode(argv, 0);
@@ -1171,6 +1174,7 @@ static Janet os_umask(int32_t argc, Janet *argv) {
#endif
return janet_wrap_integer(janet_perm_to_unix(res));
}
#endif
static Janet os_dir(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
@@ -1220,17 +1224,16 @@ static Janet os_rename(int32_t argc, Janet *argv) {
static Janet os_realpath(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
#ifdef JANET_WINDOWS
(void) argv;
janet_panic("os/realpath not supported on Windows");
#else
const char *src = janet_getcstring(argv, 0);
#ifdef JANET_WINDOWS
char *dest = _fullpath(NULL, src, _MAX_PATH);
#else
char *dest = realpath(src, NULL);
#endif
if (NULL == dest) janet_panicf("%s: %s", strerror(errno), src);
Janet ret = janet_cstringv(dest);
free(dest);
return ret;
#endif
}
static Janet os_permission_string(int32_t argc, Janet *argv) {
@@ -1339,11 +1342,13 @@ static const JanetReg os_cfuns[] = {
JDOC("(os/cd path)\n\n"
"Change current directory to path. Returns nil on success, errors on failure.")
},
#ifndef JANET_NO_UMASK
{
"os/umask", os_umask,
JDOC("(os/umask mask)\n\n"
"Set a new umask, returns the old umask.")
},
#endif
{
"os/mkdir", os_mkdir,
JDOC("(os/mkdir path)\n\n"
@@ -1369,6 +1374,7 @@ static const JanetReg os_cfuns[] = {
"Iff symlink is falsey or not provided, "
"creates a hard link. Does not work on Windows.")
},
#ifndef JANET_NO_SYMLINKS
{
"os/symlink", os_symlink,
JDOC("(os/symlink oldpath newpath)\n\n"
@@ -1379,6 +1385,7 @@ static const JanetReg os_cfuns[] = {
JDOC("(os/readlink path)\n\n"
"Read the contents of a symbolic link. Does not work on Windows.\n")
},
#endif
#ifndef JANET_NO_PROCESSES
{
"os/execute", os_execute,

View File

@@ -167,12 +167,12 @@ static void popstate(JanetParser *p, Janet val) {
for (;;) {
JanetParseState top = p->states[--p->statecount];
JanetParseState *newtop = p->states + p->statecount - 1;
/* Source mapping info */
if (janet_checktype(val, JANET_TUPLE)) {
janet_tuple_sm_line(janet_unwrap_tuple(val)) = (int32_t) top.line;
janet_tuple_sm_column(janet_unwrap_tuple(val)) = (int32_t) top.column;
}
if (newtop->flags & PFLAG_CONTAINER) {
/* Source mapping info */
if (janet_checktype(val, JANET_TUPLE)) {
janet_tuple_sm_line(janet_unwrap_tuple(val)) = (int32_t) top.line;
janet_tuple_sm_column(janet_unwrap_tuple(val)) = (int32_t) top.column;
}
newtop->argn++;
/* Keep track of number of values in the root state */
if (p->statecount == 1) p->pending++;

View File

@@ -150,6 +150,7 @@ tail:
down1(s);
const uint8_t *result = peg_rule(s, s->bytecode + rule[2], text);
up1(s);
text -= ((int32_t *)rule)[1];
return result ? text : NULL;
}
@@ -205,6 +206,29 @@ tail:
return (result) ? NULL : text;
}
case RULE_THRU:
case RULE_TO: {
const uint32_t *rule_a = s->bytecode + rule[1];
const uint8_t *next_text;
CapState cs = cap_save(s);
down1(s);
while (text < s->text_end) {
CapState cs2 = cap_save(s);
next_text = peg_rule(s, rule_a, text);
if (next_text) {
if (rule[0] == RULE_TO) cap_load(s, cs2);
break;
}
text++;
}
up1(s);
if (text >= s->text_end) {
cap_load(s, cs);
return NULL;
}
return rule[0] == RULE_TO ? text : next_text;
}
case RULE_BETWEEN: {
uint32_t lo = rule[1];
uint32_t hi = rule[2];
@@ -764,6 +788,12 @@ static void spec_error(Builder *b, int32_t argc, const Janet *argv) {
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);
}
/* Rule of the form [rule, tag] */
static void spec_cap1(Builder *b, int32_t argc, const Janet *argv, uint32_t op) {
@@ -894,6 +924,8 @@ static const SpecialPair peg_specials[] = {
{"sequence", spec_sequence},
{"set", spec_set},
{"some", spec_some},
{"thru", spec_thru},
{"to", spec_to},
};
/* Compile a janet value into a rule and return the rule index. */
@@ -996,6 +1028,14 @@ static uint32_t peg_compile1(Builder *b, Janet peg) {
const Janet *tup = janet_unwrap_tuple(peg);
int32_t len = janet_tuple_length(tup);
if (len == 0) peg_panic(b, "tuple in grammar must have non-zero length");
if (janet_checkint(tup[0])) {
int32_t n = janet_unwrap_integer(tup[0]);
if (n < 0) {
peg_panicf(b, "expected non-negative integer, got %d", n);
}
spec_repeat(b, len, tup);
break;
}
if (!janet_checktype(tup[0], JANET_SYMBOL))
peg_panicf(b, "expected grammar command, found %v", tup[0]);
const uint8_t *sym = janet_unwrap_symbol(tup[0]);
@@ -1179,6 +1219,8 @@ static void *peg_unmarshal(JanetMarshalContext *ctx) {
case RULE_ERROR:
case RULE_DROP:
case RULE_NOT:
case RULE_TO:
case RULE_THRU:
/* [rule] */
if (rule[1] >= blen) goto bad;
op_flags[rule[1]] |= 0x01;

View File

@@ -622,10 +622,11 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
/* Check if closure created in while scope. If so,
* recompile in a function scope. */
if (tempscope.flags & JANET_SCOPE_CLOSURE) {
subopts = janetc_fopts_default(c);
tempscope.flags |= JANET_SCOPE_UNUSED;
janetc_popscope(c);
janet_v__cnt(c->buffer) = labelwt;
janet_v__cnt(c->mapbuffer) = labelwt;
if (c->buffer) janet_v__cnt(c->buffer) = labelwt;
if (c->mapbuffer) janet_v__cnt(c->mapbuffer) = labelwt;
janetc_scope(&tempscope, c, JANET_SCOPE_FUNCTION, "while-iife");

View File

@@ -66,9 +66,15 @@ struct JanetMailbox {
JanetBuffer messages[];
};
#define JANET_THREAD_HEAVYWEIGHT 0x1
#define JANET_THREAD_ABSTRACTS 0x2
#define JANET_THREAD_CFUNCTIONS 0x4
static const char janet_thread_flags[] = "hac";
typedef struct {
JanetMailbox *original;
JanetMailbox *newbox;
uint64_t flags;
} JanetMailboxPair;
static JANET_THREAD_LOCAL JanetMailbox *janet_vm_mailbox = NULL;
@@ -175,7 +181,7 @@ static int thread_mark(void *p, size_t size) {
return 0;
}
static JanetMailboxPair *make_mailbox_pair(JanetMailbox *original) {
static JanetMailboxPair *make_mailbox_pair(JanetMailbox *original, uint64_t flags) {
JanetMailboxPair *pair = malloc(sizeof(JanetMailboxPair));
if (NULL == pair) {
JANET_OUT_OF_MEMORY;
@@ -183,6 +189,7 @@ static JanetMailboxPair *make_mailbox_pair(JanetMailbox *original) {
pair->original = original;
janet_mailbox_ref(original, 1);
pair->newbox = janet_mailbox_create(1, 16);
pair->flags = flags;
return pair;
}
@@ -442,16 +449,44 @@ static int thread_worker(JanetMailboxPair *pair) {
janet_init();
/* Get dictionaries for default encode/decode */
JanetTable *encode = janet_get_core_table("make-image-dict");
JanetTable *encode;
if (pair->flags & JANET_THREAD_HEAVYWEIGHT) {
encode = janet_get_core_table("make-image-dict");
} else {
encode = NULL;
janet_vm_thread_decode = janet_table(0);
janet_gcroot(janet_wrap_table(janet_vm_thread_decode));
}
/* Create parent thread */
JanetThread *parent = janet_make_thread(pair->original, encode);
Janet parentv = janet_wrap_abstract(parent);
/* Unmarshal the abstract registry */
if (pair->flags & JANET_THREAD_ABSTRACTS) {
Janet reg;
int status = janet_thread_receive(&reg, INFINITY);
if (status) goto error;
if (!janet_checktype(reg, JANET_TABLE)) goto error;
janet_gcunroot(janet_wrap_table(janet_vm_abstract_registry));
janet_vm_abstract_registry = janet_unwrap_table(reg);
janet_gcroot(janet_wrap_table(janet_vm_abstract_registry));
}
/* Unmarshal the normal registry */
if (pair->flags & JANET_THREAD_CFUNCTIONS) {
Janet reg;
int status = janet_thread_receive(&reg, INFINITY);
if (status) goto error;
if (!janet_checktype(reg, JANET_TABLE)) goto error;
janet_gcunroot(janet_wrap_table(janet_vm_registry));
janet_vm_registry = janet_unwrap_table(reg);
janet_gcroot(janet_wrap_table(janet_vm_registry));
}
/* Unmarshal the function */
Janet funcv;
int status = janet_thread_receive(&funcv, INFINITY);
if (status) goto error;
if (!janet_checktype(funcv, JANET_FUNCTION)) goto error;
JanetFunction *func = janet_unwrap_function(funcv);
@@ -558,22 +593,40 @@ static Janet cfun_thread_current(int32_t argc, Janet *argv) {
}
static Janet cfun_thread_new(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
janet_arity(argc, 1, 3);
/* Just type checking */
janet_getfunction(argv, 0);
int32_t cap = janet_optinteger(argv, argc, 1, 10);
if (cap < 1 || cap > UINT16_MAX) {
janet_panicf("bad slot #1, expected integer in range [1, 65535], got %d", cap);
}
JanetTable *encode = janet_get_core_table("make-image-dict");
uint64_t flags = argc >= 3 ? janet_getflags(argv, 2, janet_thread_flags) : JANET_THREAD_ABSTRACTS;
JanetTable *encode;
if (flags & JANET_THREAD_HEAVYWEIGHT) {
encode = janet_get_core_table("make-image-dict");
} else {
encode = NULL;
}
JanetMailboxPair *pair = make_mailbox_pair(janet_vm_mailbox);
JanetMailboxPair *pair = make_mailbox_pair(janet_vm_mailbox, flags);
JanetThread *thread = janet_make_thread(pair->newbox, encode);
if (janet_thread_start_child(pair)) {
destroy_mailbox_pair(pair);
janet_panic("could not start thread");
}
if (flags & JANET_THREAD_ABSTRACTS) {
if (janet_thread_send(thread, janet_wrap_table(janet_vm_abstract_registry), INFINITY)) {
janet_panic("could not send abstract registry to thread");
}
}
if (flags & JANET_THREAD_CFUNCTIONS) {
if (janet_thread_send(thread, janet_wrap_table(janet_vm_registry), INFINITY)) {
janet_panic("could not send registry to thread");
}
}
/* If thread started, send the worker function. */
if (janet_thread_send(thread, argv[0], INFINITY)) {
janet_panicf("could not send worker function %v to thread", argv[0]);
@@ -638,10 +691,14 @@ static const JanetReg threadlib_cfuns[] = {
},
{
"thread/new", cfun_thread_new,
JDOC("(thread/new func &opt capacity)\n\n"
JDOC("(thread/new func &opt capacity flags)\n\n"
"Start a new thread that will start immediately. "
"If capacity is provided, that is how many messages can be stored in the thread's mailbox before blocking senders. "
"The capacity must be between 1 and 65535 inclusive, and defaults to 10. "
"Can optionally provide flags to the new thread - supported flags are:\n"
"\t:h - Start a heavyweight thread. This loads the core environment by default, so may use more memory initially. Messages may compress better, though.\n"
"\t:a - Allow sending over registered abstract types to the new thread\n"
"\t:c - Send over cfunction information to the new thread.\n"
"Returns a handle to the new thread.")
},
{

View File

@@ -275,6 +275,24 @@ static void ta_setter(void *p, Janet key, Janet value) {
}
}
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,
@@ -283,7 +301,11 @@ const JanetAbstractType janet_ta_view_type = {
ta_setter,
ta_view_marshal,
ta_view_unmarshal,
JANET_ATEND_UNMARSHAL
NULL,
NULL,
NULL,
ta_view_next,
JANET_ATEND_NEXT
};
JanetTArrayBuffer *janet_tarray_buffer(size_t size) {
@@ -364,8 +386,11 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) {
offset = (view->buffer->data - view->as.u8) + offset * ta_type_sizes[view->type];
stride *= view->stride;
buffer = view->buffer;
} else {
} 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);

View File

@@ -929,7 +929,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
if (janet_checktype(callee, JANET_FUNCTION)) {
func = janet_unwrap_function(callee);
if (func->gc.flags & JANET_FUNCFLAG_TRACE) {
vm_do_trace(func, fiber->stacktop - fiber->stackstart, stack);
vm_do_trace(func, fiber->stacktop - fiber->stackstart, fiber->data + fiber->stackstart);
}
janet_stack_frame(stack)->pc = pc;
if (janet_fiber_funcframe(fiber, func)) {
@@ -968,7 +968,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
if (janet_checktype(callee, JANET_FUNCTION)) {
func = janet_unwrap_function(callee);
if (func->gc.flags & JANET_FUNCFLAG_TRACE) {
vm_do_trace(func, fiber->stacktop - fiber->stackstart, stack);
vm_do_trace(func, fiber->stacktop - fiber->stackstart, fiber->data + fiber->stackstart);
}
if (janet_fiber_funcframe_tail(fiber, func)) {
janet_stack_frame(fiber->data + fiber->frame)->pc = pc;

View File

@@ -359,6 +359,26 @@ typedef struct JanetDictView JanetDictView;
typedef struct JanetRange JanetRange;
typedef struct JanetRNG JanetRNG;
/* Basic types for all Janet Values */
typedef enum JanetType {
JANET_NUMBER,
JANET_NIL,
JANET_BOOLEAN,
JANET_FIBER,
JANET_STRING,
JANET_SYMBOL,
JANET_KEYWORD,
JANET_ARRAY,
JANET_TUPLE,
JANET_TABLE,
JANET_STRUCT,
JANET_BUFFER,
JANET_FUNCTION,
JANET_CFUNCTION,
JANET_ABSTRACT,
JANET_POINTER
} JanetType;
/* Recursive type (Janet) */
#ifdef JANET_NANBOX_64
typedef union Janet Janet;
@@ -414,26 +434,6 @@ typedef const Janet *JanetTuple;
typedef const JanetKV *JanetStruct;
typedef void *JanetAbstract;
/* Basic types for all Janet Values */
typedef enum JanetType {
JANET_NUMBER,
JANET_NIL,
JANET_BOOLEAN,
JANET_FIBER,
JANET_STRING,
JANET_SYMBOL,
JANET_KEYWORD,
JANET_ARRAY,
JANET_TUPLE,
JANET_TABLE,
JANET_STRUCT,
JANET_BUFFER,
JANET_FUNCTION,
JANET_CFUNCTION,
JANET_ABSTRACT,
JANET_POINTER
} JanetType;
#define JANET_COUNT_TYPES (JANET_POINTER + 1)
/* Type flags */
@@ -1582,6 +1582,8 @@ typedef enum {
RULE_ERROR, /* [rule] */
RULE_DROP, /* [rule] */
RULE_BACKMATCH, /* [tag] */
RULE_TO, /* [rule] */
RULE_THRU, /* [rule] */
RULE_LENPREFIX, /* [rule_a, rule_b (repeat rule_b rule_a times)] */
} JanetPegOpcode;

View File

@@ -40,6 +40,8 @@ void janet_line_deinit();
void janet_line_get(const char *p, JanetBuffer *buffer);
Janet janet_line_getter(int32_t argc, Janet *argv);
static JANET_THREAD_LOCAL int gbl_cancel_current_repl_form = 0;
/*
* Line Editing
*/
@@ -54,7 +56,17 @@ Janet janet_line_getter(int32_t argc, Janet *argv) {
gbl_complete_env = (argc >= 3) ? janet_gettable(argv, 2) : NULL;
janet_line_get(str, buf);
gbl_complete_env = NULL;
return janet_wrap_buffer(buf);
Janet result;
if (gbl_cancel_current_repl_form) {
gbl_cancel_current_repl_form = 0;
/* Signal that the user bailed out of the current form */
result = janet_ckeywordv("cancel");
} else {
result = janet_wrap_buffer(buf);
}
return result;
}
static void simpleline(JanetBuffer *buffer) {
@@ -746,8 +758,7 @@ static int line() {
kleft();
break;
case 3: /* ctrl-c */
errno = EAGAIN;
gbl_sigint_flag = 1;
gbl_cancel_current_repl_form = 1;
clearlines();
return -1;
case 4: /* ctrl-d, eof */

View File

@@ -334,5 +334,86 @@
(assert (deep= @{:a 3 :b 2} @{:a 1 :b 2 :a 3}) "table literal duplicate keys")
(assert (deep= @{:a 3 :b 2} (table :a 1 :b 2 :a 3)) "table constructor duplicate keys")
## Polymorphic comparison -- Issue #272
# confirm polymorphic comparison delegation to primitive comparators:
(assert (= 0 (compare-primitive 3 3)) "compare-primitive integers (1)")
(assert (= -1 (compare-primitive 3 5)) "compare-primitive integers (2)")
(assert (= 1 (compare-primitive "foo" "bar")) "compare-primitive strings")
(assert (= 0 (compare 1 1)) "compare integers (1)")
(assert (= -1 (compare 1 2)) "compare integers (2)")
(assert (= 1 (compare "foo" "bar")) "compare strings (1)")
(assert (compare< 1 2 3 4 5 6) "compare less than integers")
(assert (not (compare> 1 2 3 4 5 6)) "compare not greater than integers")
(assert (compare< 1.0 2.0 3.0 4.0 5.0 6.0) "compare less than reals")
(assert (compare> 6 5 4 3 2 1) "compare greater than integers")
(assert (compare> 6.0 5.0 4.0 3.0 2.0 1.0) "compare greater than reals")
(assert (not (compare< 6.0 5.0 4.0 3.0 2.0 1.0)) "compare less than reals")
(assert (compare<= 1 2 3 3 4 5 6) "compare less than or equal to integers")
(assert (compare<= 1.0 2.0 3.0 3.0 4.0 5.0 6.0) "compare less than or equal to reals")
(assert (compare>= 6 5 4 4 3 2 1) "compare greater than or equal to integers")
(assert (compare>= 6.0 5.0 4.0 4.0 3.0 2.0 1.0) "compare greater than or equal to reals")
(assert (compare< 1.0 nil false true
(fiber/new (fn [] 1))
"hi"
(quote hello)
:hello
(array 1 2 3)
(tuple 1 2 3)
(table "a" "b" "c" "d")
(struct 1 2 3 4)
(buffer "hi")
(fn [x] (+ x x))
print) "compare type ordering")
# test polymorphic compare with 'objects' (table/setproto)
(def mynum
@{:type :mynum :v 0 :compare
(fn [self other]
(case (type other)
:number (compare-primitive (self :v) other)
:table (when (= (get other :type) :mynum)
(compare-primitive (self :v) (other :v)))))})
(let [n3 (table/setproto @{:v 3} mynum)]
(assert (= 0 (compare 3 n3)) "compare num to object (1)")
(assert (= -1 (compare n3 4)) "compare object to num (2)")
(assert (= 1 (compare (table/setproto @{:v 4} mynum) n3)) "compare object to object")
(assert (compare< 2 n3 4) "compare< poly")
(assert (compare> 4 n3 2) "compare> poly")
(assert (compare<= 2 3 n3 4) "compare<= poly")
(assert (compare= 3 n3 (table/setproto @{:v 3} mynum)) "compare= poly")
(assert (deep= (sorted @[4 5 n3 2] compare<) @[2 n3 4 5]) "polymorphic sort"))
(let [
MAX_INT_64_STRING "9223372036854775807"
MAX_UINT_64_STRING "18446744073709551615"
MAX_INT_IN_DBL_STRING "9007199254740991"
NAN (math/log -1)
INF (/ 1 0)
MINUS_INF (/ -1 0)
compare-poly-tests
[
[(int/s64 3) (int/u64 3) 0]
[(int/s64 -3) (int/u64 3) -1]
[(int/s64 3) (int/u64 2) 1]
[(int/s64 3) 3 0] [(int/s64 3) 4 -1] [(int/s64 3) -9 1]
[(int/u64 3) 3 0] [(int/u64 3) 4 -1] [(int/u64 3) -9 1]
[3 (int/s64 3) 0] [3 (int/s64 4) -1] [3 (int/s64 -5) 1]
[3 (int/u64 3) 0] [3 (int/u64 4) -1] [3 (int/u64 2) 1]
[(int/s64 MAX_INT_64_STRING) (int/u64 MAX_UINT_64_STRING) -1]
[(int/s64 MAX_INT_IN_DBL_STRING) (scan-number MAX_INT_IN_DBL_STRING) 0]
[(int/u64 MAX_INT_IN_DBL_STRING) (scan-number MAX_INT_IN_DBL_STRING) 0]
[(+ 1 (int/u64 MAX_INT_IN_DBL_STRING)) (scan-number MAX_INT_IN_DBL_STRING) 1]
[(int/s64 0) INF -1] [(int/u64 0) INF -1]
[MINUS_INF (int/u64 0) -1] [MINUS_INF (int/s64 0) -1]
[(int/s64 1) NAN 0] [NAN (int/u64 1) 0]
]]
(each [x y c] compare-poly-tests
(assert (= c (compare x y)) (string/format "compare polymorphic %q %q %d" x y c)))
)
(end-suite)

View File

@@ -91,8 +91,8 @@
# Assembly test
# Fibonacci sequence, implemented with naive recursion.
(def fibasm (asm '{
arity 1
bytecode [
:arity 1
:bytecode [
(ltim 1 0 0x2) # $1 = $0 < 2
(jmpif 1 :done) # if ($1) goto :done
(lds 1) # $1 = self

View File

@@ -58,6 +58,17 @@
(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

@@ -23,7 +23,6 @@
# Using a large test grammar
(def- core-env (table/getproto (fiber/getenv (fiber/current))))
(def- specials {'fn true
'var true
'do true
@@ -41,7 +40,7 @@
(defn capture-sym
[text]
(def sym (symbol text))
[(if (or (core-env sym) (specials sym)) :coresym :symbol) text])
[(if (or (root-env sym) (specials sym)) :coresym :symbol) text])
(def grammar
~{:ws (set " \v\t\r\f\n\0")

View File

@@ -281,4 +281,30 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02
(assert (= nil (peg/match peg2 "1:a2:bb:5:cccccc")) "lenprefix 6")
(assert (= nil (peg/match peg2 "1:a2:bb:7:cccccc")) "lenprefix 7")
# Regression #400
(assert (= nil (while (and false false) (fn []) (error "should not happen"))) "strangeloop 1")
(assert (= nil (while (not= nil nil) (fn []) (error "should not happen"))) "strangeloop 2")
# Issue #412
(assert (peg/match '(* "a" (> -1 "a") "b") "abc") "lookhead does not move cursor")
(def peg3
~{:main (* "(" (thru ")"))})
(def peg4 (peg/compile ~(* (thru "(") '(to ")"))))
(assert (peg/match peg3 "(12345)") "peg thru 1")
(assert (not (peg/match peg3 " (12345)")) "peg thru 2")
(assert (not (peg/match peg3 "(12345")) "peg thru 3")
(assert (= "abc" (0 (peg/match peg4 "123(abc)"))) "peg thru/to 1")
(assert (= "abc" (0 (peg/match peg4 "(abc)"))) "peg thru/to 2")
(assert (not (peg/match peg4 "123(abc")) "peg thru/to 3")
(def peg5 (peg/compile [3 "abc"]))
(assert (:match peg5 "abcabcabc") "repeat alias 1")
(assert (:match peg5 "abcabcabcac") "repeat alias 2")
(assert (not (:match peg5 "abcabc")) "repeat alias 3")
(end-suite)

Binary file not shown.

BIN
tools/msi/JanetDialog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
tools/msi/LICENSE.rtf Normal file

Binary file not shown.

200
tools/msi/janet.wxs Normal file
View File

@@ -0,0 +1,200 @@
<?xml version="1.0" encoding="UTF-8"?>
<?define Name = "Janet" ?>
<?define Description = "The Janet Programming Language" ?>
<?define Manufacturer = "Janet-Lang.org" ?>
<?define WebPage = "https://janet-lang.org" ?>
<?ifdef env.JANET_VERSION ?>
<?define Version = "$(env.JANET_VERSION)" ?>
<?else?>
<?define Version = "0.0.0" ?>
<?endif?>
<?if $(sys.BUILDARCH)="x64" ?>
<?define UpgradeCode="712CACD6-09AA-430A-831C-80FDFFE3F9ED" ?>
<?define ProgramFilesFolder="ProgramFiles64Folder" ?>
<?define Win64="yes" ?>
<?define Arch="(x64)" ?>
<?elseif $(sys.BUILDARCH)="x86" ?>
<?define UpgradeCode="0411837a-82c4-4dc7-872b-134d0c1b0228" ?>
<?define ProgramFilesFolder="ProgramFilesFolder" ?>
<?define Win64="no" ?>
<?define Arch="(x86)" ?>
<?else ?>
<?error Unsupported value of sys.BUILDARCH=$(sys.BUILDARCH)?>
<?endif?>
<?define BaseRegKey="Software\Microsoft\$(var.Manufacturer)\$(var.Name)" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="$(var.Name)"
Language="1033"
Version="$(var.Version)"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="$(var.UpgradeCode)">
<Package Compressed="yes"
InstallScope="perUser"
Manufacturer="$(var.Manufacturer)"
Description="$(var.Description)" />
<MajorUpgrade DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit."/>
<MediaTemplate EmbedCab="yes" />
<Property Id="DISABLEADVTSHORTCUTS" Value="1" />
<!-- Set UI images (use the -b option to light.exe to set where these files are) -->
<WixVariable Id="WixUIBannerBmp" Value="JanetTopBanner.png" />
<WixVariable Id="WixUIDialogBmp" Value="JanetDialog.png" />
<WixVariable Id="WixUILicenseRtf" Value="LICENSE.rtf" />
<Icon Id="Janet.ico" SourceFile="assets\icon.ico" />
<!-- Add some details to Add/Remove Programs entry -->
<Property Id="ARPPRODUCTICON" Value="Janet.ico" />
<Property Id='ARPCOMMENTS'>$(var.Description)</Property>
<Property Id='ARPURLINFOABOUT'>$(var.WebPage)</Property>
<Property Id='COMPANY'>$(var.Manufacturer)</Property>
<!-- Default to per-user installs -->
<Property Id="WixAppFolder" Value="WixPerUserFolder" />
<Property Id="ApplicationFolderName" Value="$(var.Name)" />
<!-- Fix WixUI_Advanced to work with x64 -->
<CustomAction Id="WixSetDefaultPerMachineFolderPerArch"
Property="WixPerMachineFolder"
Value="[$(var.ProgramFilesFolder)][ApplicationFolderName]"
Execute="immediate"/>
<InstallExecuteSequence>
<Custom Action="WixSetDefaultPerMachineFolderPerArch" Before="WixSetPerMachineFolder" />
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="WixSetDefaultPerMachineFolderPerArch" Before="WixSetPerMachineFolder" />
</InstallUISequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.ProgramFilesFolder)">
<Directory Id="APPLICATIONFOLDER" Name="$(var.Name)">
<Directory Id="BinDir" Name="bin"/>
<Directory Id="CDir" Name="C"/>
<Directory Id="DocsDir" Name="docs"/>
<Directory Id="LibraryDir" Name="Library"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="$(var.Name)" />
</Directory>
</Directory>
<!--
Define the files to be installed.
File/@Source is relative to where this file is compiled, the root of the repository in this case.
File/@Name is the destination file name, if not set it defaults to the file name part of Source.
Component/@Directory is the Id of the destination directory - where the directory name and
hierarchy is set in the section above
-->
<ComponentGroup Id="Files">
<Component Directory="APPLICATIONFOLDER">
<File Source="README.md"/>
<RemoveFolder Id="RemoveRootDir" On="uninstall" />
</Component>
<Component Directory="APPLICATIONFOLDER">
<File Source="LICENSE"/>
</Component>
<Component Directory="APPLICATIONFOLDER">
<File Source="assets\icon.ico"/>
</Component>
<Component Directory="BinDir">
<File Source="dist\janet.exe" KeyPath="yes">
<Shortcut Id="JanetExeShortcut"
Directory="ApplicationProgramsFolder"
Name="$(var.Name)"
Description="$(var.Description)"
Icon="Janet.ico"
Advertise="yes"
WorkingDirectory="INSTALLFOLDER" />
</File>
<RemoveFolder Id="RemoveBinDir" On="uninstall" />
</Component>
<Component Directory="BinDir">
<File Source="jpm" Name="jpm.janet"/>
</Component>
<Component Directory="BinDir">
<File Source="tools\jpm.bat"/>
</Component>
<Component Directory="CDir">
<File Source="dist\janet.h"/>
<RemoveFolder Id="RemoveCDir" On="uninstall" />
</Component>
<Component Directory="CDir">
<File Source="dist\janetconf.h"/>
</Component>
<Component Directory="CDir">
<File Source="dist\janet.lib"/>
</Component>
<Component Directory="CDir">
<File Source="dist\janet.exp"/>
</Component>
<Component Directory="CDir">
<File Source="dist\janet.c"/>
</Component>
<Component Directory="CDir">
<File Source="dist\libjanet.lib"/>
</Component>
<Component Id="LibraryComponent" Directory="LibraryDir" Guid="3860e981-5f94-4002-b5d5-2d9ec0d2792d" KeyPath="yes">
<RemoveFolder Id="RemoveLibraryDir" On="uninstall" />
</Component>
<Component Id="DocsComponent" Directory="DocsDir">
<File Source="dist\doc.html" Name="docs.html" KeyPath="yes">
<Shortcut Id="JanetDocsShortcut"
Directory="ApplicationProgramsFolder"
Name="$(var.Name) Documentation"
Description="$(var.Description)"
Advertise="yes"/>
</File>
<RemoveFolder Id="RemoveDocsDir" On="uninstall" />
</Component>
</ComponentGroup>
<Component Id="StartMenu" Directory="ApplicationProgramsFolder">
<RegistryValue Root="HKMU" Key="$(var.BaseRegKey)" Name="installed" Type="integer" Value="1" KeyPath="yes" />
<RemoveFolder Id="RemoveApplicationProgramsFolder" On="uninstall" />
</Component>
<!-- This component is duplicated with different conditions so that we can set system or user environment variables -->
<Component Id="SetEnvVarsPerMachine" Directory="ApplicationProgramsFolder" Guid="57b1e1ef-89c8-4ce4-9f0f-37618677c5a4" KeyPath="yes">
<Condition>ALLUSERS=1</Condition>
<Environment Id="PATH_PERMACHINE" Name="PATH" Value="[BinDir]" Action="set" Permanent="no" System="yes" Part="last"/>
<Environment Id="JANET_BINPATH_PERMACHINE" Name="JANET_BINPATH" Value="[BinDir]" Action="set" Permanent="no" System="yes"/>
<Environment Id="JANET_PATH_PERMACHINE" Name="JANET_PATH" Value="[LibraryDir]" Action="set" Permanent="no" System="yes" />
<Environment Id="JANET_HEADERPATH_PERMACHINE" Name="JANET_HEADERPATH" Value="[CDir]" Action="set" Permanent="no" System="yes"/>
<Environment Id="JANET_LIBPATH_PERMACHINE" Name="JANET_LIBPATH" Value="[CDir]" Action="set" Permanent="no" System="yes"/>
</Component>
<Component Id="SetEnvVarsPerUser" Directory="ApplicationProgramsFolder" Guid="128be307-488b-49aa-971a-d2ae00a1a584" KeyPath="yes">
<Condition>NOT ALLUSERS=1</Condition>
<Environment Id="PATH_PERUSER" Name="PATH" Value="[BinDir]" Action="set" Permanent="no" System="no" Part="last"/>
<Environment Id="JANET_BINPATH_PERUSER" Name="JANET_BINPATH" Value="[BinDir]" Action="set" Permanent="no" System="no"/>
<Environment Id="JANET_PATH_PERUSER" Name="JANET_PATH" Value="[LibraryDir]" Action="set" Permanent="no" System="no" />
<Environment Id="JANET_HEADERPATH_PERUSER" Name="JANET_HEADERPATH" Value="[CDir]" Action="set" Permanent="no" System="no"/>
<Environment Id="JANET_LIBPATH_PERUSER" Name="JANET_LIBPATH" Value="[CDir]" Action="set" Permanent="no" System="no"/>
</Component>
<Feature Id="MainFeature" Title="$(var.Name) $(var.Version)"
Level="1" Absent="disallow" AllowAdvertise="no" InstallDefault="local"
Description="$(var.Description)">
<ComponentGroupRef Id="Files" />
<ComponentRef Id="StartMenu" />
<ComponentRef Id="SetEnvVarsPerMachine" />
<ComponentRef Id="SetEnvVarsPerUser" />
</Feature>
<UI>
<UIRef Id="WixUI_Advanced"/>
<!-- FindRelatedProducts runs before the user select the install scope, so we ask it to run again if the have changed the scope
-->
<Publish Dialog="InstallScopeDlg" Control="Next" Order="8" Event="DoAction" Value="FindRelatedProducts">WixAppFolder = "WixPerMachineFolder"</Publish>
</UI>
</Product>
</Wix>

Binary file not shown.

33
tools/patch-jpm.janet Normal file
View File

@@ -0,0 +1,33 @@
# Patch jpm to have the correct paths for the current install.
# usage: janet patch-jpm.janet output --libdir=/usr/local/lib/x64-linux/ --binpath
(def- argpeg
(peg/compile
'(* "--" '(to "=") "=" '(any 1))))
(def- args (tuple/slice (dyn :args) 3))
(def- len (length args))
(var i :private 0)
(def install-paths @{})
# Get flags
(each a args
(if-let [m (peg/match argpeg a)]
(let [[key value] m]
(put install-paths (keyword key) value))))
(def- replace-peg
(peg/compile
~(% (* '(to "###START###")
(constant ,(string/format "# Inserted by tools/patch-jpm.janet\n(def install-paths %j)" install-paths))
(thru "###END###")
'(any 1)))))
(def source (slurp ((dyn :args) 1)))
(def newsource (0 (peg/match replace-peg source)))
(spit ((dyn :args) 2) newsource)
(unless (= :windows (os/which))
(os/shell (string `chmod +x "` ((dyn :args) 2) `"`)))

View File

@@ -230,53 +230,53 @@
<key>name</key>
<string>punctuation.other.janet</string>
</dict>
<!-- string>(?&lt;![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*]) token match here (?![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])</string -->
<!-- string>(?&lt;![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*]) token match here (?![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])</string -->
<key>literal</key>
<dict>
<key>match</key>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])(true|false|nil)(?![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])</string>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])(true|false|nil)(?![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])</string>
<key>name</key>
<string>constant.language.janet</string>
</dict>
<key>corelib</key>
<dict>
<key>match</key>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])(%ALLSYMBOLS%)(?![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])</string>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])(%ALLSYMBOLS%)(?![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])</string>
<key>name</key>
<string>keyword.control.janet</string>
</dict>
<key>keysym</key>
<dict>
<key>match</key>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*]):[\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*]*</string>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*]):[\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*]*</string>
<key>name</key>
<string>constant.keyword.janet</string>
</dict>
<key>symbol</key>
<dict>
<key>match</key>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])[\.a-zA-Z_\-=!@\$%^&amp;?|\\/&lt;&gt;*][\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*]*</string>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])[\.a-zA-Z_\-=!@\$%^&amp;?/&lt;&gt;*][\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*]*</string>
<key>name</key>
<string>variable.other.janet</string>
</dict>
<key>hex-number</key>
<dict>
<key>match</key>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])[-+]?0x([_\da-fA-F]+|[_\da-fA-F]+\.[_\da-fA-F]*|\.[_\da-fA-F]+)(&amp;[+-]?[\da-fA-F]+)?(?![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])</string>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])[-+]?0x([_\da-fA-F]+|[_\da-fA-F]+\.[_\da-fA-F]*|\.[_\da-fA-F]+)(&amp;[+-]?[\da-fA-F]+)?(?![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])</string>
<key>name</key>
<string>constant.numeric.hex.janet</string>
</dict>
<key>dec-number</key>
<dict>
<key>match</key>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])[-+]?([_\d]+|[_\d]+\.[_\d]*|\.[_\d]+)([eE&amp;][+-]?[\d]+)?(?![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])</string>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])[-+]?([_\d]+|[_\d]+\.[_\d]*|\.[_\d]+)([eE&amp;][+-]?[\d]+)?(?![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])</string>
<key>name</key>
<string>constant.numeric.decimal.janet</string>
</dict>
<key>r-number</key>
<dict>
<key>match</key>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])[-+]?\d\d?r([_\w]+|[_\w]+\.[_\w]*|\.[_\w]+)(&amp;[+-]?[\w]+)?(?![\.:\w_\-=!@\$%^&amp;?|\\/&lt;&gt;*])</string>
<string>(?&lt;![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])[-+]?\d\d?r([_\w]+|[_\w]+\.[_\w]*|\.[_\w]+)(&amp;[+-]?[\w]+)?(?![\.:\w_\-=!@\$%^&amp;?/&lt;&gt;*])</string>
<key>name</key>
<string>constant.numeric.decimal.janet</string>
</dict>