mirror of
https://github.com/janet-lang/janet
synced 2026-04-06 15:01:28 +00:00
Compare commits
57 Commits
v0.5.0
...
configchec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c304ddc35 | ||
|
|
ce9cd4fcef | ||
|
|
698e89aba4 | ||
|
|
4c8dd4b96c | ||
|
|
11998b3913 | ||
|
|
840610facf | ||
|
|
0280deccae | ||
|
|
4d5a95784a | ||
|
|
b43d93cf55 | ||
|
|
3f137ed0b1 | ||
|
|
5deb13d73e | ||
|
|
82a1c8635e | ||
|
|
010e2e4652 | ||
|
|
ddedae6831 | ||
|
|
6c63c4f129 | ||
|
|
802686e3df | ||
|
|
3be79e8735 | ||
|
|
a303704a7d | ||
|
|
b5e6c0b8fc | ||
|
|
98c46fcfb1 | ||
|
|
409da697dd | ||
|
|
91c3685705 | ||
|
|
411fc77ecf | ||
|
|
0378ba78cc | ||
|
|
55d8e8b56b | ||
|
|
97ad4c4f89 | ||
|
|
8de999c8f7 | ||
|
|
f444bd25ef | ||
|
|
43c0db4b0e | ||
|
|
8f168c600d | ||
|
|
ec43afb426 | ||
|
|
880049c0ee | ||
|
|
2b7ac16784 | ||
|
|
56d903d75b | ||
|
|
7054e878fb | ||
|
|
dde5351d11 | ||
|
|
7d49e3e6f1 | ||
|
|
30cb01e2f0 | ||
|
|
018e836ef5 | ||
|
|
7b25125431 | ||
|
|
0aa2f68793 | ||
|
|
516e031f67 | ||
|
|
3331f2fa02 | ||
|
|
dd1a199ebd | ||
|
|
f35b5765d6 | ||
|
|
8359044408 | ||
|
|
9f3dde3cc7 | ||
|
|
ad0f7d9b0d | ||
|
|
f647ac5631 | ||
|
|
e4c5eb4c76 | ||
|
|
dc9fc9c3f5 | ||
|
|
3b6a51df24 | ||
|
|
f2313b9959 | ||
|
|
805b3bbb88 | ||
|
|
232ea22dc5 | ||
|
|
3388acd2db | ||
|
|
52ab9fb475 |
@@ -9,3 +9,4 @@ tasks:
|
||||
gmake test CC=gcc
|
||||
sudo gmake install CC=gcc
|
||||
gmake test-install CC=gcc
|
||||
gmake test-amalg CC=gcc
|
||||
|
||||
11
.builds/.openbsd.yaml
Normal file
11
.builds/.openbsd.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
image: openbsd/6.5
|
||||
packages:
|
||||
- gmake
|
||||
tasks:
|
||||
- build: |
|
||||
cd janet
|
||||
gmake
|
||||
gmake test
|
||||
doas gmake install
|
||||
gmake test-install
|
||||
gmake test-amalg
|
||||
@@ -4,6 +4,7 @@ script:
|
||||
- make test
|
||||
- sudo make install
|
||||
- make test-install
|
||||
- make test-amalg
|
||||
- make build/janet-${TRAVIS_TAG}-${TRAVIS_OS_NAME}.tar.gz
|
||||
compiler:
|
||||
- clang
|
||||
|
||||
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,6 +1,24 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 1.0.0 - ??
|
||||
|
||||
- Add optional filters to `module/paths` to further refine import methods.
|
||||
- Add keyword arguments via `&keys` in parameter list.
|
||||
- Add `-k` flag for flychecking source.
|
||||
- Change signature to `compile` function.
|
||||
- Add `module/loaders` for custom loading functions.
|
||||
- Add external unification to `match` macro.
|
||||
- Add static library to main build.
|
||||
- Add `janet/*headerpath*` and change location of installed headers.
|
||||
- Let `partition` take strings.
|
||||
- Haiku OS support
|
||||
- Add `string/trim`, `string/trimr`, and `string/triml`.
|
||||
- Add `dofile` function.
|
||||
- Numbers require at least 1 significant digit.
|
||||
- `file/read` will return nil on end of file.
|
||||
- Fix various bugs.
|
||||
|
||||
## 0.5.0 - 2019-05-09
|
||||
- Fix some bugs with buffers.
|
||||
- Add `trace` and `untrace` to the core library.
|
||||
|
||||
88
Makefile
88
Makefile
@@ -31,8 +31,10 @@ JANET_BUILD?="\"$(shell git log --pretty=format:'%h' -n 1)\""
|
||||
CLIBS=-lm
|
||||
JANET_TARGET=build/janet
|
||||
JANET_LIBRARY=build/libjanet.so
|
||||
JANET_STATIC_LIBRARY=build/libjanet.a
|
||||
JANET_PATH?=$(PREFIX)/lib/janet
|
||||
MANPATH?=$(PREFIX)/share/man/man1/
|
||||
PKG_CONFIG_PATH?=$(PREFIX)/lib/pkgconfig
|
||||
DEBUGGER=gdb
|
||||
|
||||
CFLAGS=-std=c99 -Wall -Wextra -Isrc/include -fpic -O2 -fvisibility=hidden \
|
||||
@@ -47,9 +49,12 @@ else ifeq ($(UNAME), Linux)
|
||||
CLIBS:=$(CLIBS) -lrt -ldl
|
||||
endif
|
||||
# For other unix likes, add flags here!
|
||||
ifeq ($(UNAME),Haiku)
|
||||
LDFLAGS=-Wl,--export-dynamic
|
||||
endif
|
||||
|
||||
$(shell mkdir -p build/core build/mainclient build/webclient build/boot)
|
||||
all: $(JANET_TARGET) $(JANET_LIBRARY)
|
||||
all: $(JANET_TARGET) $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY)
|
||||
|
||||
######################
|
||||
##### Name Files #####
|
||||
@@ -130,7 +135,7 @@ build/janet_boot: $(JANET_BOOT_OBJECTS)
|
||||
|
||||
# Now the reason we bootstrap in the first place
|
||||
build/core_image.c: build/janet_boot
|
||||
build/janet_boot $@ JANET_PATH $(JANET_PATH)
|
||||
build/janet_boot $@ JANET_PATH $(JANET_PATH) JANET_HEADERPATH $(INCLUDEDIR)/janet
|
||||
|
||||
##########################################################
|
||||
##### The main interpreter program and shared object #####
|
||||
@@ -152,6 +157,9 @@ $(JANET_TARGET): $(JANET_CORE_OBJECTS) $(JANET_MAINCLIENT_OBJECTS)
|
||||
$(JANET_LIBRARY): $(JANET_CORE_OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -shared -o $@ $^ $(CLIBS)
|
||||
|
||||
$(JANET_STATIC_LIBRARY): $(JANET_CORE_OBJECTS)
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
######################
|
||||
##### Emscripten #####
|
||||
######################
|
||||
@@ -245,7 +253,7 @@ dist: build/janet-dist.tar.gz
|
||||
|
||||
build/janet-%.tar.gz: $(JANET_TARGET) \
|
||||
src/include/janet.h src/include/janetconf.h \
|
||||
janet.1 LICENSE CONTRIBUTING.md $(JANET_LIBRARY) \
|
||||
janet.1 LICENSE CONTRIBUTING.md $(JANET_LIBRARY) $(JANET_STATIC_LIBRARY) \
|
||||
build/doc.html README.md build/janet.c
|
||||
tar -czvf $@ $^
|
||||
|
||||
@@ -258,6 +266,46 @@ docs: build/doc.html
|
||||
build/doc.html: $(JANET_TARGET) tools/gendoc.janet
|
||||
$(JANET_TARGET) tools/gendoc.janet > build/doc.html
|
||||
|
||||
########################
|
||||
##### Installation #####
|
||||
########################
|
||||
|
||||
SONAME=libjanet.so.1
|
||||
|
||||
.PHONY: $(PKG_CONFIG_PATH)/janet.pc
|
||||
$(PKG_CONFIG_PATH)/janet.pc: $(JANET_TARGET)
|
||||
mkdir -p $(PKG_CONFIG_PATH)
|
||||
echo 'prefix=$(PREFIX)' > $@
|
||||
echo 'exec_prefix=$${prefix}' >> $@
|
||||
echo 'includedir=$(INCLUDEDIR)/janet' >> $@
|
||||
echo 'libdir=$(LIBDIR)' >> $@
|
||||
echo "" >> $@
|
||||
echo "Name: janet" >> $@
|
||||
echo "Url: https://janet-lang.org" >> $@
|
||||
echo "Description: Library for the Janet programming language." >> $@
|
||||
$(JANET_TARGET) -e '(print "Version: " janet/version)' >> $@
|
||||
echo 'Cflags: -I$${includedir}' >> $@
|
||||
echo 'Libs: -L$${libdir} -ljanet $(LDFLAGS)' >> $@
|
||||
echo 'Libs.private: $(CLIBS)' >> $@
|
||||
|
||||
install: $(JANET_TARGET) $(PKG_CONFIG_PATH)/janet.pc
|
||||
mkdir -p $(BINDIR)
|
||||
cp $(JANET_TARGET) $(BINDIR)/janet
|
||||
mkdir -p $(INCLUDEDIR)/janet
|
||||
cp -rf $(JANET_HEADERS) $(INCLUDEDIR)/janet
|
||||
mkdir -p $(JANET_PATH)
|
||||
mkdir -p $(LIBDIR)
|
||||
cp $(JANET_LIBRARY) $(LIBDIR)/libjanet.so.$(shell $(JANET_TARGET) -e '(print janet/version)')
|
||||
cp $(JANET_STATIC_LIBRARY) $(LIBDIR)/libjanet.a
|
||||
ln -sf $(SONAME) $(LIBDIR)/libjanet.so
|
||||
ln -sf libjanet.so.$(shell $(JANET_TARGET) -e '(print janet/version)') $(LIBDIR)/$(SONAME)
|
||||
cp tools/cook.janet $(JANET_PATH)
|
||||
cp tools/highlight.janet $(JANET_PATH)
|
||||
cp tools/bars.janet $(JANET_PATH)
|
||||
mkdir -p $(MANPATH)
|
||||
cp janet.1 $(MANPATH)
|
||||
-ldconfig $(LIBDIR)
|
||||
|
||||
#################
|
||||
##### Other #####
|
||||
#################
|
||||
@@ -272,33 +320,19 @@ build/janet.tmLanguage: tools/tm_lang_gen.janet $(JANET_TARGET)
|
||||
clean:
|
||||
-rm -rf build vgcore.* callgrind.*
|
||||
|
||||
build/version.txt: $(JANET_TARGET)
|
||||
$(JANET_TARGET) -e '(print janet/version)' > $@
|
||||
|
||||
SONAME=libjanet.so.0
|
||||
install: $(JANET_TARGET) build/version.txt
|
||||
mkdir -p $(BINDIR)
|
||||
cp $(JANET_TARGET) $(BINDIR)/janet
|
||||
mkdir -p $(INCLUDEDIR)
|
||||
cp $(JANET_HEADERS) $(INCLUDEDIR)
|
||||
mkdir -p $(LIBDIR)
|
||||
cp $(JANET_LIBRARY) $(LIBDIR)/libjanet.so.$(shell cat build/version.txt)
|
||||
ln -sf $(SONAME) $(LIBDIR)/libjanet.so
|
||||
ln -sf libjanet.so.$(shell cat build/version.txt) $(LIBDIR)/$(SONAME)
|
||||
mkdir -p $(INCLUDEDIR)/janet
|
||||
mkdir -p $(JANET_PATH)
|
||||
ln -sf $(INCLUDEDIR)/janet.h $(JANET_PATH)/janet.h
|
||||
ln -sf $(INCLUDEDIR)/janetconf.h $(JANET_PATH)/janetconf.h
|
||||
cp tools/cook.janet $(JANET_PATH)
|
||||
cp tools/highlight.janet $(JANET_PATH)
|
||||
cp tools/bars.janet $(JANET_PATH)
|
||||
mkdir -p $(MANPATH)
|
||||
cp janet.1 $(MANPATH)
|
||||
-ldconfig $(LIBDIR)
|
||||
|
||||
test-install:
|
||||
cd test/install && rm -rf build && janet build && janet build
|
||||
|
||||
build/embed_janet.o: build/janet.c $(JANET_HEADERS)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
build/embed_main.o: test/amalg/main.c $(JANET_HEADERS)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
build/embed_test: build/embed_janet.o build/embed_main.o
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(CLIBS)
|
||||
|
||||
test-amalg: build/embed_test
|
||||
./build/embed_test
|
||||
|
||||
uninstall:
|
||||
-rm $(BINDIR)/../$(JANET_TARGET)
|
||||
-rm -rf $(INCLUDEDIR)
|
||||
|
||||
34
README.md
34
README.md
@@ -3,6 +3,7 @@
|
||||
[](https://ci.appveyor.com/project/bakpakin/janet/branch/master)
|
||||
[](https://travis-ci.org/janet-lang/janet)
|
||||
[](https://builds.sr.ht/~bakpakin/janet/.freebsd.yaml?)
|
||||
[](https://builds.sr.ht/~bakpakin/janet/.openbsd.yaml?)
|
||||
|
||||
<img src="https://raw.githubusercontent.com/janet-lang/janet/master/assets/janet-w200.png" alt="Janet logo" width=200 align="left">
|
||||
|
||||
@@ -79,15 +80,28 @@ make test
|
||||
make repl
|
||||
```
|
||||
|
||||
### FreeBSD
|
||||
### 32-bit Haiku
|
||||
|
||||
FreeBSD build instructions are the same as the unix-like build instuctions,
|
||||
but you need `gmake` and `gcc` to compile.
|
||||
32-bit Haiku build instructions are the same as the unix-like build instructions,
|
||||
but you need to specify an alternative compiler, such as `gcc-x86`.
|
||||
|
||||
```
|
||||
cd somewhere/my/projects/janet
|
||||
gmake CC=gcc
|
||||
gmake test CC=gcc
|
||||
make CC=gcc-x86
|
||||
make test
|
||||
make repl
|
||||
```
|
||||
|
||||
### FreeBSD
|
||||
|
||||
FreeBSD build instructions are the same as the unix-like build instuctions,
|
||||
but you need `gmake` to compile. Alternatively, install directly from
|
||||
packages, using `pkg install lang/janet`.
|
||||
|
||||
```
|
||||
cd somewhere/my/projects/janet
|
||||
gmake
|
||||
gmake test
|
||||
gmake repl
|
||||
```
|
||||
|
||||
@@ -172,6 +186,16 @@ See the examples directory for some example janet code.
|
||||
Feel free to ask questions and join discussion on the [Janet Gitter Channel](https://gitter.im/janet-language/community).
|
||||
Alternatively, check out [the #janet channel on Freenode](https://webchat.freenode.net/)
|
||||
|
||||
## FAQ
|
||||
|
||||
### Why is my terminal is 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
|
||||
will not. If your terminal does not support ANSI escape codes, run the repl with
|
||||
the `-n` flag, which disables color output. You can also try the `-s` if further issues
|
||||
ensue.
|
||||
|
||||
## Why Janet
|
||||
|
||||
Janet is named after the almost omniscient and friendly artificial being in [The Good Place](https://en.wikipedia.org/wiki/The_Good_Place).
|
||||
|
||||
@@ -75,6 +75,14 @@ for %%f in (src\mainclient\*.c) do (
|
||||
%JANET_LINK% /out:janet.exe build\core\*.obj build\mainclient\*.obj build\core_image.obj
|
||||
@if errorlevel 1 goto :BUILDFAIL
|
||||
|
||||
@rem Gen amlag
|
||||
setlocal enabledelayedexpansion
|
||||
set "amalg_files="
|
||||
for %%f in (src\core\*.c) do (
|
||||
set "amalg_files=!amalg_files! %%f"
|
||||
)
|
||||
janet.exe tools\amalg.janet src\core\util.h src\core\state.h src\core\gc.h src\core\vector.h src\core\fiber.h src\core\regalloc.h src\core\compile.h src\core\emit.h src\core\symcache.h %amalg_files% build\core_image.c > build\janet.c
|
||||
|
||||
echo === Successfully built janet.exe for Windows ===
|
||||
echo === Run 'build_win test' to run tests. ==
|
||||
echo === Run 'build_win clean' to delete build artifacts. ===
|
||||
@@ -113,13 +121,7 @@ exit /b 0
|
||||
mkdir dist
|
||||
janet.exe tools\gendoc.janet > dist\doc.html
|
||||
|
||||
@rem Gen amlag
|
||||
setlocal enabledelayedexpansion
|
||||
set "amalg_files="
|
||||
for %%f in (src\core\*.c) do (
|
||||
set "amalg_files=!amalg_files! %%f"
|
||||
)
|
||||
janet.exe tools\amalg.janet src\core\util.h src\core\state.h src\core\gc.h src\core\vector.h src\core\fiber.h src\core\regalloc.h src\core\compile.h src\core\emit.h src\core\symcache.h %amalg_files% build\core_image.c > dist\janet.c
|
||||
copy build\janet.c dist\janet.c
|
||||
copy janet.exe dist\janet.exe
|
||||
copy LICENSE dist\LICENSE
|
||||
copy README.md dist\README.md
|
||||
|
||||
@@ -13,4 +13,4 @@
|
||||
(if isprime? (array/push list i)))
|
||||
list)
|
||||
|
||||
(print (string/pretty (primes 100)))
|
||||
(pp (primes 100))
|
||||
|
||||
29
examples/urlloader.janet
Normal file
29
examples/urlloader.janet
Normal file
@@ -0,0 +1,29 @@
|
||||
# An example of using Janet's extensible module system
|
||||
# to import files from URL. To try this, run `janet -l examples/urlloader.janet`
|
||||
# from the repl, and then:
|
||||
#
|
||||
# (import https://raw.githubusercontent.com/janet-lang/janet/master/examples/colors.janet :as c)
|
||||
#
|
||||
# This will import a file using curl. You can then try
|
||||
#
|
||||
# (print (c/color :green "Hello!"))
|
||||
#
|
||||
# This is a bit of a toy example (it just shells out to curl), but it is very
|
||||
# powerful and will work well in many cases.
|
||||
|
||||
(defn- load-url
|
||||
[url args]
|
||||
(def f (file/popen (string "curl " url)))
|
||||
(def res (dofile f :source url ;args))
|
||||
(try (file/close f) ([err] nil))
|
||||
res)
|
||||
|
||||
(defn- check-http-url
|
||||
[path]
|
||||
(if (or (string/has-prefix? "http://" path)
|
||||
(string/has-prefix? "https://" path))
|
||||
path))
|
||||
|
||||
# Add the module loader and path tuple to right places
|
||||
(array/push module/paths [check-http-url :janet-http])
|
||||
(put module/loaders :janet-http load-url)
|
||||
6
janet.1
6
janet.1
@@ -3,7 +3,7 @@
|
||||
janet \- run the Janet language abstract machine
|
||||
.SH SYNOPSIS
|
||||
.B janet
|
||||
[\fB\-hvsrpnq\fR]
|
||||
[\fB\-hvsrpnqk\fR]
|
||||
[\fB\-e\fR \fISOURCE\fR]
|
||||
[\fB\-l\fR \fIMODULE\fR]
|
||||
[\fB\-m\fR \fIPATH\fR]
|
||||
@@ -67,6 +67,10 @@ after an error. Persistent mode can be good for debugging and testing.
|
||||
.BR \-q
|
||||
Quiet output. Don't print a repl prompt or expression results to stdout.
|
||||
|
||||
.TP
|
||||
.BR \-k
|
||||
Don't execute a script, only compile it to check for errors. Useful for linting scripts.
|
||||
|
||||
.TP
|
||||
.BR \-m\ syspath
|
||||
Set the variable module/*syspath* to the string syspath so that Janet will load system modules
|
||||
|
||||
@@ -22,6 +22,7 @@ project('janet', 'c', default_options : ['c_std=c99'])
|
||||
|
||||
# Global settings
|
||||
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
|
||||
header_path = join_paths(get_option('prefix'), get_option('includedir'), 'janet')
|
||||
|
||||
# Link math library on all systems
|
||||
cc = meson.get_compiler('c')
|
||||
@@ -29,7 +30,7 @@ m_dep = cc.find_library('m', required : false)
|
||||
dl_dep = cc.find_library('dl', required : false)
|
||||
|
||||
# Some options
|
||||
add_project_arguments('-DJANET_BUILD="meson"', language : 'c')
|
||||
add_project_link_arguments('-rdynamic', language : 'c')
|
||||
|
||||
# Include directories
|
||||
incdir = include_directories('src/include')
|
||||
@@ -119,7 +120,7 @@ janet_boot = executable('janet-boot', core_src, boot_src, boot_gen,
|
||||
core_image = custom_target('core_image',
|
||||
input : [janet_boot],
|
||||
output : 'core_image.gen.c',
|
||||
command : [janet_boot, '@OUTPUT@', 'JANET_PATH', janet_path])
|
||||
command : [janet_boot, '@OUTPUT@', 'JANET_PATH', janet_path, 'JANET_HEADERPATH', header_path])
|
||||
|
||||
libjanet = shared_library('janet', core_src, core_image,
|
||||
include_directories : incdir,
|
||||
@@ -169,10 +170,8 @@ run_target('repl', command : [janet_mainclient])
|
||||
|
||||
# Installation
|
||||
install_man('janet.1')
|
||||
install_headers('src/include/janet.h', 'src/include/janetconf.h')
|
||||
install_headers('src/include/janet.h', 'src/include/janetconf.h', subdir: 'janet')
|
||||
janet_libs = [
|
||||
'src/include/janet.h',
|
||||
'src/include/janetconf.h',
|
||||
'tools/bars.janet',
|
||||
'tools/cook.janet',
|
||||
'tools/highlight.janet'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# The core janet library
|
||||
# Copyright 2019 (C) Calvin Rose
|
||||
# Copyright 2019 © Calvin Rose
|
||||
|
||||
###
|
||||
###
|
||||
@@ -136,12 +136,12 @@
|
||||
|
||||
(defmacro comment
|
||||
"Ignores the body of the comment."
|
||||
[])
|
||||
[&])
|
||||
|
||||
(defmacro if-not
|
||||
"Shorthand for (if (not ... "
|
||||
[condition exp-1 &opt exp-2]
|
||||
~(if ,condition ,exp-2 ,exp-1))
|
||||
"Shorthand for (if (not condition) else then)."
|
||||
[condition then &opt else]
|
||||
~(if ,condition ,else ,then))
|
||||
|
||||
(defmacro when
|
||||
"Evaluates the body when the condition is true. Otherwise returns nil."
|
||||
@@ -149,7 +149,7 @@
|
||||
~(if ,condition (do ,;body)))
|
||||
|
||||
(defmacro unless
|
||||
"Shorthand for (when (not ... "
|
||||
"Shorthand for (when (not condition) ;body). "
|
||||
[condition & body]
|
||||
~(if ,condition nil (do ,;body)))
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
(defmacro case
|
||||
"Select the body that equals the dispatch value. When pairs
|
||||
has an odd number of arguments, the last is the default expression.
|
||||
If no match is found, returns nil"
|
||||
If no match is found, returns nil."
|
||||
[dispatch & pairs]
|
||||
(def atm (idempotent? dispatch))
|
||||
(def sym (if atm dispatch (gensym)))
|
||||
@@ -416,7 +416,7 @@
|
||||
~(fiber/new (fn [] (loop ,head (yield (do ,;body)))) :yi))
|
||||
|
||||
(defmacro coro
|
||||
"A wrapper for making fibers. Same as (fiber/new (fn [] ...body) :yi)."
|
||||
"A wrapper for making fibers. Same as (fiber/new (fn [] ;body) :yi)."
|
||||
[& body]
|
||||
(tuple fiber/new (tuple 'fn '[] ;body) :yi))
|
||||
|
||||
@@ -678,7 +678,7 @@
|
||||
|
||||
(defn find
|
||||
"Find the first value in an indexed collection that satisfies a predicate. Returns
|
||||
nil if not found. Note their is no way to differentiate a nil from the indexed collection
|
||||
nil if not found. Note there is no way to differentiate a nil from the indexed collection
|
||||
and a not found. Consider find-index if this is an issue."
|
||||
[pred ind]
|
||||
(def i (find-index pred ind))
|
||||
@@ -1047,11 +1047,12 @@
|
||||
(var i 0) (var nextn n)
|
||||
(def len (length ind))
|
||||
(def ret (array/new (math/ceil (/ len n))))
|
||||
(def slicer (if (bytes? ind) string/slice tuple/slice))
|
||||
(while (<= nextn len)
|
||||
(array/push ret (tuple/slice ind i nextn))
|
||||
(array/push ret (slicer ind i nextn))
|
||||
(set i nextn)
|
||||
(+= nextn n))
|
||||
(if (not= i len) (array/push ret (tuple/slice ind i)))
|
||||
(if (not= i len) (array/push ret (slicer ind i)))
|
||||
ret)
|
||||
|
||||
###
|
||||
@@ -1126,10 +1127,13 @@
|
||||
~(if (= nil (def ,pattern ,expr)) ,sentinel ,(onmatch))))
|
||||
|
||||
(tuple? pattern)
|
||||
(match-1
|
||||
(get pattern 0) expr
|
||||
(fn []
|
||||
~(if (and ,;(tuple/slice pattern 1)) ,(onmatch) ,sentinel)) seen)
|
||||
(if (and (= (pattern 0) 'quote) (symbol? (pattern 1)))
|
||||
# Unification with external values
|
||||
~(if (= ,(pattern 1) ,expr) ,(onmatch) ,sentinel)
|
||||
(match-1
|
||||
(get pattern 0) expr
|
||||
(fn []
|
||||
~(if (and ,;(tuple/slice pattern 1)) ,(onmatch) ,sentinel)) seen))
|
||||
|
||||
(array? pattern)
|
||||
(do
|
||||
@@ -1454,6 +1458,7 @@
|
||||
:env - the environment to compile against - default is the current env\n\t
|
||||
:source - string path of source for better errors - default is \"<anonymous>\"\n\t
|
||||
:on-compile-error - callback when compilation fails - default is bad-compile\n\t
|
||||
:compile-only - only compile the souce, do not execute it - default is false\n\t
|
||||
:on-status - callback when a value is evaluated - default is debug/stacktrace\n\t
|
||||
:fiber-flags - what flags to wrap the compilation fiber with. Default is :ia."
|
||||
[opts]
|
||||
@@ -1464,9 +1469,11 @@
|
||||
:on-compile-error on-compile-error
|
||||
:on-parse-error on-parse-error
|
||||
:fiber-flags guard
|
||||
:compile-only compile-only
|
||||
:source where} opts)
|
||||
(default env (fiber/getenv (fiber/current)))
|
||||
(default chunks getline)
|
||||
(default chunks (fn [buf p] (getline "" buf)))
|
||||
(default compile-only false)
|
||||
(default onstatus debug/stacktrace)
|
||||
(default on-compile-error bad-compile)
|
||||
(default on-parse-error bad-parse)
|
||||
@@ -1486,7 +1493,7 @@
|
||||
(fn []
|
||||
(def res (compile source env where))
|
||||
(if (= (type res) :function)
|
||||
(res)
|
||||
(unless compile-only (res))
|
||||
(do
|
||||
(set good false)
|
||||
(def {:error err :start start :end end :fiber errf} res)
|
||||
@@ -1578,8 +1585,13 @@
|
||||
:native: becomes the dynamic library file extension, usually dll
|
||||
or so. Each element is a two element tuple, containing the path
|
||||
template and a keyword :source, :native, or :image indicating how
|
||||
require should load files found at these paths."
|
||||
@[[":all:" :source]
|
||||
require should load files found at these paths.\n\nA tuple can also
|
||||
contain a third element, specifying a filter that prevents module/find
|
||||
from searching that path template if the filter doesn't match the input
|
||||
path. The filter is often a file extension, including the period."
|
||||
@[[":all:" :native (if (= (os/which) :windows) ".dll" ".so")]
|
||||
[":all:" :image ".jimage"]
|
||||
[":all:" :source]
|
||||
["./:all:.janet" :source]
|
||||
["./:all:/init.janet" :source]
|
||||
[":sys:/:all:.janet" :source]
|
||||
@@ -1596,6 +1608,11 @@
|
||||
on Windows is C:/Janet/Library."
|
||||
(or (process/opts "JANET_PATH") ""))
|
||||
|
||||
(var module/*headerpath*
|
||||
"The path where the janet headers are installed. Useful for building
|
||||
native modules or compiling code at runtime."
|
||||
(process/opts "JANET_HEADERPATH"))
|
||||
|
||||
# Version of fexists that works even with a reduced OS
|
||||
(if-let [has-stat (_env 'os/stat)]
|
||||
(let [stat (has-stat :value)]
|
||||
@@ -1610,6 +1627,21 @@
|
||||
(file/close f)
|
||||
res))))
|
||||
|
||||
(def nati (if (= :windows (os/which)) "dll" "so"))
|
||||
(defn- expand-path-name
|
||||
[template name path]
|
||||
(->> template
|
||||
(string/replace ":name:" name)
|
||||
(string/replace ":sys:" module/*syspath*)
|
||||
(string/replace ":native:" nati)
|
||||
(string/replace ":all:" path)))
|
||||
(defn- mod-filter
|
||||
[x path]
|
||||
(case (type x)
|
||||
:nil path
|
||||
:string (string/has-suffix? x path)
|
||||
(x path)))
|
||||
|
||||
(defn module/find
|
||||
"Try to match a module or path name from the patterns in module/paths.
|
||||
Returns a tuple (fullpath kind) where the kind is one of :source, :native,
|
||||
@@ -1617,25 +1649,32 @@
|
||||
an error message."
|
||||
[path]
|
||||
(def parts (string/split "/" path))
|
||||
(def name (get parts (- (length parts) 1)))
|
||||
(def nati (if (= :windows (os/which)) "dll" "so"))
|
||||
(defn make-full
|
||||
[[p mod-kind]]
|
||||
(def fullpath (->> p
|
||||
(string/replace ":name:" name)
|
||||
(string/replace ":sys:" module/*syspath*)
|
||||
(string/replace ":native:" nati)
|
||||
(string/replace ":all:" path)))
|
||||
[fullpath mod-kind])
|
||||
(defn check-path [x] (if (fexists (x 0)) x))
|
||||
(def paths (map make-full module/paths))
|
||||
(def res (find check-path paths))
|
||||
(if res res [nil (string "could not find module "
|
||||
path
|
||||
":\n "
|
||||
;(interpose "\n " (map 0 paths)))]))
|
||||
(def name (last parts))
|
||||
(var ret nil)
|
||||
(each [p mod-kind checker] module/paths
|
||||
(when (mod-filter checker path)
|
||||
(if (function? p)
|
||||
(when-let [res (p path)]
|
||||
(set ret [res mod-kind])
|
||||
(break))
|
||||
(do
|
||||
(def fullpath (expand-path-name p name path))
|
||||
(when (fexists fullpath)
|
||||
(set ret [fullpath mod-kind])
|
||||
(break))))))
|
||||
(if ret ret
|
||||
(let [expander (fn [[t _ chk]]
|
||||
(when (string? t)
|
||||
(when (mod-filter chk path)
|
||||
(expand-path-name t name path))))
|
||||
paths (filter identity (map expander module/paths))
|
||||
str-parts (interpose "\n " paths)]
|
||||
[nil (string "could not find module " path ":\n " ;str-parts)])))
|
||||
|
||||
(put _env 'fexists nil)
|
||||
(put _env 'nati nil)
|
||||
(put _env 'expand-path-name nil)
|
||||
(put _env 'mod-filter nil)
|
||||
|
||||
(def module/cache
|
||||
"Table mapping loaded module identifiers to their environments."
|
||||
@@ -1646,47 +1685,63 @@
|
||||
circular dependencies."
|
||||
@{})
|
||||
|
||||
(defn dofile
|
||||
"Evaluate a file in a new environment and return the new environment."
|
||||
[path & args]
|
||||
(def {:exit exit-on-error
|
||||
:source source
|
||||
:compile-only compile-only} (table ;args))
|
||||
(def f (if (= (type path) :core/file)
|
||||
path
|
||||
(file/open path)))
|
||||
(def newenv (make-env))
|
||||
(defn chunks [buf _] (file/read f 2048 buf))
|
||||
(defn bp [&opt x y]
|
||||
(def ret (bad-parse x y))
|
||||
(if exit-on-error (os/exit 1))
|
||||
ret)
|
||||
(defn bc [&opt x y z]
|
||||
(def ret (bad-compile x y z))
|
||||
(if exit-on-error (os/exit 1))
|
||||
ret)
|
||||
(run-context {:env newenv
|
||||
:chunks chunks
|
||||
:on-parse-error bp
|
||||
:on-compile-error bc
|
||||
:on-status (fn [f x]
|
||||
(when (not= (fiber/status f) :dead)
|
||||
(debug/stacktrace f x)
|
||||
(if exit-on-error (os/exit 1))))
|
||||
:compile-only compile-only
|
||||
:source (or source (if (= f path) "<anonymous>" path))})
|
||||
(when (not= f path) (file/close f))
|
||||
(table/setproto newenv nil))
|
||||
|
||||
(def module/loaders
|
||||
"A table of loading method names to loading functions.
|
||||
This table lets require and import load many different kinds
|
||||
of files as module."
|
||||
@{:native (fn [path &] (native path (make-env)))
|
||||
:source (fn [path args]
|
||||
(put module/loading path true)
|
||||
(def newenv (dofile path ;args))
|
||||
(put module/loading path nil)
|
||||
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, then the path as a raw file path. Returns the new environment
|
||||
returned from compiling and running the file."
|
||||
[path & args]
|
||||
(def {:exit exit-on-error} (table ;args))
|
||||
(if-let [check (get module/cache path)]
|
||||
check
|
||||
(do
|
||||
(def [fullpath mod-kind] (module/find path))
|
||||
(unless fullpath (error mod-kind))
|
||||
(def env
|
||||
(case mod-kind
|
||||
:source (do
|
||||
# Normal janet module
|
||||
(def f (file/open fullpath))
|
||||
(def newenv (make-env))
|
||||
(put module/loading fullpath true)
|
||||
(defn chunks [buf _] (file/read f 2048 buf))
|
||||
(defn bp [&opt x y]
|
||||
(def ret (bad-parse x y))
|
||||
(if exit-on-error (os/exit 1))
|
||||
ret)
|
||||
(defn bc [&opt x y z]
|
||||
(def ret (bad-compile x y z))
|
||||
(if exit-on-error (os/exit 1))
|
||||
ret)
|
||||
(run-context {:env newenv
|
||||
:chunks chunks
|
||||
:on-parse-error bp
|
||||
:on-compile-error bc
|
||||
:on-status (fn [f x]
|
||||
(when (not= (fiber/status f) :dead)
|
||||
(debug/stacktrace f x)
|
||||
(if exit-on-error (os/exit 1))))
|
||||
:source fullpath})
|
||||
(file/close f)
|
||||
(put module/loading fullpath nil)
|
||||
(table/setproto newenv nil))
|
||||
:native (native fullpath (make-env))
|
||||
:image (load-image (slurp fullpath))))
|
||||
(def loader (module/loaders mod-kind))
|
||||
(unless loader (error (string "module type " mod-kind " unknown")))
|
||||
(def env (loader fullpath args))
|
||||
(put module/cache fullpath env)
|
||||
(put module/cache path env)
|
||||
env)))
|
||||
@@ -1710,7 +1765,9 @@
|
||||
symbols into the current environment, prepending a given prefix as needed.
|
||||
(use the :as or :prefix option to set a prefix). If no prefix is provided,
|
||||
use the name of the module as a prefix. One can also use :export true
|
||||
to re-export the imported symbols."
|
||||
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."
|
||||
[path & args]
|
||||
(def argm (map (fn [x]
|
||||
(if (keyword? x)
|
||||
@@ -1727,6 +1784,11 @@
|
||||
[&opt chunks onsignal env]
|
||||
(def level (+ (dyn :debug-level 0) 1))
|
||||
(default env (make-env))
|
||||
(default chunks (fn [buf p] (getline (string "repl:"
|
||||
(parser/where p)
|
||||
":"
|
||||
(parser/state p) "> ")
|
||||
buf)))
|
||||
(default onsignal (fn [f x]
|
||||
(case (fiber/status f)
|
||||
:dead (do
|
||||
|
||||
@@ -266,7 +266,7 @@ static const JanetReg array_cfuns[] = {
|
||||
{
|
||||
"array/ensure", cfun_array_ensure,
|
||||
JDOC("(array/ensure arr capacity)\n\n"
|
||||
"Ensures that the memory backing the array has enough memory for capacity "
|
||||
"Ensures that the memory backing the array is large enough for capacity "
|
||||
"items. Capacity must be an integer. If the backing capacity is already enough, "
|
||||
"then this function does nothing. Otherwise, the backing memory will be reallocated "
|
||||
"so that there is enough space.")
|
||||
|
||||
@@ -26,6 +26,16 @@
|
||||
#include "fiber.h"
|
||||
#endif
|
||||
|
||||
static JanetBuildConfig *api_build_config = &(JanetBuildConfig){
|
||||
.api_version = JANET_API_VERSION,
|
||||
.single_threaded = JANET_SINGLE_THREADED_BIT,
|
||||
.nanbox = JANET_NANBOX_BIT
|
||||
};
|
||||
|
||||
const JanetBuildConfig *janet_build_config() {
|
||||
return api_build_config;
|
||||
}
|
||||
|
||||
void janet_panicv(Janet message) {
|
||||
if (janet_vm_return_reg != NULL) {
|
||||
*janet_vm_return_reg = message;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "emit.h"
|
||||
#include "vector.h"
|
||||
#include "util.h"
|
||||
#include "state.h"
|
||||
#endif
|
||||
|
||||
JanetFopts janetc_fopts_default(JanetCompiler *c) {
|
||||
@@ -716,8 +717,12 @@ JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *w
|
||||
|
||||
/* C Function for compiling */
|
||||
static Janet cfun(int32_t argc, Janet *argv) {
|
||||
janet_arity(argc, 2, 3);
|
||||
JanetTable *env = janet_gettable(argv, 1);
|
||||
janet_arity(argc, 1, 3);
|
||||
JanetTable *env = argc > 1 ? janet_gettable(argv, 1) : janet_vm_fiber->env;
|
||||
if (NULL == env) {
|
||||
env = janet_table(0);
|
||||
janet_vm_fiber->env = env;
|
||||
}
|
||||
const uint8_t *source = NULL;
|
||||
if (argc == 3) {
|
||||
source = janet_getstring(argv, 2);
|
||||
@@ -740,7 +745,7 @@ static Janet cfun(int32_t argc, Janet *argv) {
|
||||
static const JanetReg compile_cfuns[] = {
|
||||
{
|
||||
"compile", cfun,
|
||||
JDOC("(compile ast env [, source])\n\n"
|
||||
JDOC("(compile ast &opt env source)\n\n"
|
||||
"Compiles an Abstract Syntax Tree (ast) into a janet function. "
|
||||
"Pair the compile function with parsing functionality to implement "
|
||||
"eval. Returns a janet function and does not modify ast. Throws an "
|
||||
|
||||
@@ -653,7 +653,7 @@ static void make_apply(JanetTable *env) {
|
||||
"be an array-like. Each element in this last argument is then also pushed as an argument to "
|
||||
"f. For example:\n\n"
|
||||
"\t(apply + 1000 (range 10))\n\n"
|
||||
"sums the first 10 integers and 1000.)"));
|
||||
"sums the first 10 integers and 1000."));
|
||||
}
|
||||
|
||||
static const uint32_t error_asm[] = {
|
||||
|
||||
@@ -239,11 +239,11 @@ void janetc_copy(
|
||||
return;
|
||||
}
|
||||
/* Process: src -> near -> dest */
|
||||
int32_t near = janetc_allocnear(c, JANETC_REGTEMP_3);
|
||||
janetc_movenear(c, near, src);
|
||||
janetc_moveback(c, dest, near);
|
||||
int32_t nearreg = janetc_allocnear(c, JANETC_REGTEMP_3);
|
||||
janetc_movenear(c, nearreg, src);
|
||||
janetc_moveback(c, dest, nearreg);
|
||||
/* Cleanup */
|
||||
janetc_regalloc_freetemp(&c->scope->ra, near, JANETC_REGTEMP_3);
|
||||
janetc_regalloc_freetemp(&c->scope->ra, nearreg, JANETC_REGTEMP_3);
|
||||
|
||||
}
|
||||
/* Instruction templated emitters */
|
||||
|
||||
@@ -127,6 +127,16 @@ void janet_fiber_pushn(JanetFiber *fiber, const Janet *arr, int32_t n) {
|
||||
fiber->stacktop = newtop;
|
||||
}
|
||||
|
||||
/* Create a struct with n values. If n is odd, the last value is ignored. */
|
||||
static Janet make_struct_n(const Janet *args, int32_t n) {
|
||||
int32_t i = 0;
|
||||
JanetKV *st = janet_struct_begin(n & (~1));
|
||||
for (; i < n; i += 2) {
|
||||
janet_struct_put(st, args[i], args[i + 1]);
|
||||
}
|
||||
return janet_wrap_struct(janet_struct_end(st));
|
||||
}
|
||||
|
||||
/* Push a stack frame to a fiber */
|
||||
int janet_fiber_funcframe(JanetFiber *fiber, JanetFunction *func) {
|
||||
JanetStackFrame *newframe;
|
||||
@@ -164,12 +174,19 @@ int janet_fiber_funcframe(JanetFiber *fiber, JanetFunction *func) {
|
||||
/* Check varargs */
|
||||
if (func->def->flags & JANET_FUNCDEF_FLAG_VARARG) {
|
||||
int32_t tuplehead = fiber->frame + func->def->arity;
|
||||
int st = func->def->flags & JANET_FUNCDEF_FLAG_STRUCTARG;
|
||||
if (tuplehead >= oldtop) {
|
||||
fiber->data[tuplehead] = janet_wrap_tuple(janet_tuple_n(NULL, 0));
|
||||
fiber->data[tuplehead] = st
|
||||
? make_struct_n(NULL, 0)
|
||||
: janet_wrap_tuple(janet_tuple_n(NULL, 0));
|
||||
} else {
|
||||
fiber->data[tuplehead] = janet_wrap_tuple(janet_tuple_n(
|
||||
fiber->data[tuplehead] = st
|
||||
? make_struct_n(
|
||||
fiber->data + tuplehead,
|
||||
oldtop - tuplehead));
|
||||
oldtop - tuplehead)
|
||||
: janet_wrap_tuple(janet_tuple_n(
|
||||
fiber->data + tuplehead,
|
||||
oldtop - tuplehead));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,14 +237,21 @@ int janet_fiber_funcframe_tail(JanetFiber *fiber, JanetFunction *func) {
|
||||
/* Check varargs */
|
||||
if (func->def->flags & JANET_FUNCDEF_FLAG_VARARG) {
|
||||
int32_t tuplehead = fiber->stackstart + func->def->arity;
|
||||
int st = func->def->flags & JANET_FUNCDEF_FLAG_STRUCTARG;
|
||||
if (tuplehead >= fiber->stacktop) {
|
||||
if (tuplehead >= fiber->capacity) janet_fiber_setcapacity(fiber, 2 * (tuplehead + 1));
|
||||
for (i = fiber->stacktop; i < tuplehead; ++i) fiber->data[i] = janet_wrap_nil();
|
||||
fiber->data[tuplehead] = janet_wrap_tuple(janet_tuple_n(NULL, 0));
|
||||
fiber->data[tuplehead] = st
|
||||
? make_struct_n(NULL, 0)
|
||||
: janet_wrap_tuple(janet_tuple_n(NULL, 0));
|
||||
} else {
|
||||
fiber->data[tuplehead] = janet_wrap_tuple(janet_tuple_n(
|
||||
fiber->data[tuplehead] = st
|
||||
? make_struct_n(
|
||||
fiber->data + tuplehead,
|
||||
fiber->stacktop - tuplehead));
|
||||
fiber->stacktop - tuplehead)
|
||||
: janet_wrap_tuple(janet_tuple_n(
|
||||
fiber->data + tuplehead,
|
||||
fiber->stacktop - tuplehead));
|
||||
}
|
||||
stacksize = tuplehead - fiber->stackstart + 1;
|
||||
} else {
|
||||
|
||||
@@ -160,7 +160,7 @@ static Janet cfun_io_fopen(int32_t argc, Janet *argv) {
|
||||
return f ? makef(f, flags) : janet_wrap_nil();
|
||||
}
|
||||
|
||||
/* Read up to n bytes into buffer. Return error string if error. */
|
||||
/* Read up to n bytes into buffer. */
|
||||
static void read_chunk(IOFile *iof, JanetBuffer *buffer, int32_t nBytesMax) {
|
||||
if (!(iof->flags & (IO_READ | IO_UPDATE)))
|
||||
janet_panic("file is not readable");
|
||||
@@ -183,6 +183,7 @@ static Janet cfun_io_fread(int32_t argc, Janet *argv) {
|
||||
} else {
|
||||
buffer = janet_getbuffer(argv, 2);
|
||||
}
|
||||
int32_t bufstart = buffer->count;
|
||||
if (janet_checktype(argv[1], JANET_KEYWORD)) {
|
||||
const uint8_t *sym = janet_unwrap_keyword(argv[1]);
|
||||
if (!janet_cstrcmp(sym, "all")) {
|
||||
@@ -207,6 +208,8 @@ static Janet cfun_io_fread(int32_t argc, Janet *argv) {
|
||||
fseek(iof->file, 0, SEEK_SET);
|
||||
read_chunk(iof, buffer, (int32_t) fsize);
|
||||
}
|
||||
/* Never return nil for :all */
|
||||
return janet_wrap_buffer(buffer);
|
||||
} else if (!janet_cstrcmp(sym, "line")) {
|
||||
for (;;) {
|
||||
int x = fgetc(iof->file);
|
||||
@@ -221,6 +224,7 @@ static Janet cfun_io_fread(int32_t argc, Janet *argv) {
|
||||
if (len < 0) janet_panic("expected positive integer");
|
||||
read_chunk(iof, buffer, len);
|
||||
}
|
||||
if (bufstart == buffer->count) return janet_wrap_nil();
|
||||
return janet_wrap_buffer(buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -632,7 +632,7 @@ static const JanetReg os_cfuns[] = {
|
||||
#ifndef JANET_REDUCED_OS
|
||||
{
|
||||
"os/dir", os_dir,
|
||||
JDOC("(os/stat dir [, array])\n\n"
|
||||
JDOC("(os/dir dir [, array])\n\n"
|
||||
"Iterate over files and subdirectories in a directory. Returns an array of paths parts, "
|
||||
"with only the filename or directory name and no prefix.")
|
||||
},
|
||||
|
||||
@@ -928,7 +928,7 @@ static const JanetReg parse_cfuns[] = {
|
||||
},
|
||||
{
|
||||
"parser/eof", cfun_parse_eof,
|
||||
JDOC("(parser/insert parser)\n\n"
|
||||
JDOC("(parser/eof parser)\n\n"
|
||||
"Indicate that the end of file was reached to the parser. This puts the parser in the :dead state.")
|
||||
},
|
||||
{
|
||||
|
||||
@@ -197,16 +197,15 @@ void janet_description_b(JanetBuffer *buffer, Janet x) {
|
||||
case JANET_STRING:
|
||||
janet_escape_string_b(buffer, janet_unwrap_string(x));
|
||||
return;
|
||||
case JANET_BUFFER:
|
||||
{
|
||||
JanetBuffer *b = janet_unwrap_buffer(x);
|
||||
if (b == buffer) {
|
||||
/* Ensures buffer won't resize while escaping */
|
||||
janet_buffer_ensure(b, 5 * b->count + 3, 1);
|
||||
}
|
||||
janet_escape_buffer_b(buffer, b);
|
||||
return;
|
||||
case JANET_BUFFER: {
|
||||
JanetBuffer *b = janet_unwrap_buffer(x);
|
||||
if (b == buffer) {
|
||||
/* Ensures buffer won't resize while escaping */
|
||||
janet_buffer_ensure(b, 5 * b->count + 3, 1);
|
||||
}
|
||||
janet_escape_buffer_b(buffer, b);
|
||||
return;
|
||||
}
|
||||
case JANET_ABSTRACT: {
|
||||
void *p = janet_unwrap_abstract(x);
|
||||
const JanetAbstractType *at = janet_abstract_type(p);
|
||||
|
||||
@@ -174,7 +174,7 @@ static int destructure(JanetCompiler *c,
|
||||
/* Create a source map for definitions. */
|
||||
static const Janet *janetc_make_sourcemap(JanetCompiler *c) {
|
||||
Janet *tup = janet_tuple_begin(3);
|
||||
tup[0] = janet_wrap_string(c->source);
|
||||
tup[0] = c->source ? janet_wrap_string(c->source) : janet_wrap_nil();
|
||||
tup[1] = janet_wrap_integer(c->current_mapping.start);
|
||||
tup[2] = janet_wrap_integer(c->current_mapping.end);
|
||||
return janet_tuple_end(tup);
|
||||
@@ -652,6 +652,7 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
|
||||
/* Function flags */
|
||||
int vararg = 0;
|
||||
int structarg = 0;
|
||||
int allow_extra = 0;
|
||||
int selfref = 0;
|
||||
int seenamp = 0;
|
||||
@@ -712,6 +713,19 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
min_arity = i;
|
||||
arity--;
|
||||
seenopt = 1;
|
||||
} else if (!janet_cstrcmp(janet_unwrap_symbol(param), "&keys")) {
|
||||
if (seenamp) {
|
||||
errmsg = "&keys in unexpected location";
|
||||
goto error;
|
||||
} else if (i == paramcount - 2) {
|
||||
vararg = 1;
|
||||
structarg = 1;
|
||||
arity -= 2;
|
||||
} else {
|
||||
errmsg = "&keys in unexpected location";
|
||||
goto error;
|
||||
}
|
||||
seenamp = 1;
|
||||
} else {
|
||||
janetc_nameslot(c, janet_unwrap_symbol(param), janetc_farslot(c));
|
||||
}
|
||||
@@ -749,6 +763,7 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
||||
def->min_arity = min_arity;
|
||||
def->max_arity = max_arity;
|
||||
if (vararg) def->flags |= JANET_FUNCDEF_FLAG_VARARG;
|
||||
if (structarg) def->flags |= JANET_FUNCDEF_FLAG_STRUCTARG;
|
||||
|
||||
if (selfref) def->name = janet_unwrap_symbol(head);
|
||||
defindex = janetc_addfuncdef(c, def);
|
||||
|
||||
@@ -290,8 +290,8 @@ static Janet cfun_string_hassuffix(int32_t argc, Janet *argv) {
|
||||
return str.len < suffix.len
|
||||
? janet_wrap_false()
|
||||
: janet_wrap_boolean(memcmp(suffix.bytes,
|
||||
str.bytes + str.len - suffix.len,
|
||||
suffix.len) == 0);
|
||||
str.bytes + str.len - suffix.len,
|
||||
suffix.len) == 0);
|
||||
}
|
||||
|
||||
static Janet cfun_string_findall(int32_t argc, Janet *argv) {
|
||||
@@ -467,6 +467,60 @@ static Janet cfun_string_format(int32_t argc, Janet *argv) {
|
||||
return janet_stringv(buffer->data, buffer->count);
|
||||
}
|
||||
|
||||
static int trim_help_checkset(JanetByteView set, uint8_t x) {
|
||||
for (int32_t j = 0; j < set.len; j++)
|
||||
if (set.bytes[j] == x)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t trim_help_leftedge(JanetByteView str, JanetByteView set) {
|
||||
for (int32_t i = 0; i < str.len; i++)
|
||||
if (!trim_help_checkset(set, str.bytes[i]))
|
||||
return i;
|
||||
return str.len;
|
||||
}
|
||||
|
||||
static int32_t trim_help_rightedge(JanetByteView str, JanetByteView set) {
|
||||
for (int32_t i = str.len - 1; i >= 0; i--)
|
||||
if (!trim_help_checkset(set, str.bytes[i]))
|
||||
return i + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void trim_help_args(int32_t argc, Janet *argv, JanetByteView *str, JanetByteView *set) {
|
||||
janet_arity(argc, 1, 2);
|
||||
*str = janet_getbytes(argv, 0);
|
||||
if (argc >= 2) {
|
||||
*set = janet_getbytes(argv, 1);
|
||||
} else {
|
||||
set->bytes = (const uint8_t *)(" \t\r\n\v\f");
|
||||
set->len = 6;
|
||||
}
|
||||
}
|
||||
|
||||
static Janet cfun_string_trim(int32_t argc, Janet *argv) {
|
||||
JanetByteView str, set;
|
||||
trim_help_args(argc, argv, &str, &set);
|
||||
int32_t left_edge = trim_help_leftedge(str, set);
|
||||
int32_t right_edge = trim_help_rightedge(str, set);
|
||||
return janet_stringv(str.bytes + left_edge, right_edge - left_edge);
|
||||
}
|
||||
|
||||
static Janet cfun_string_triml(int32_t argc, Janet *argv) {
|
||||
JanetByteView str, set;
|
||||
trim_help_args(argc, argv, &str, &set);
|
||||
int32_t left_edge = trim_help_leftedge(str, set);
|
||||
return janet_stringv(str.bytes + left_edge, str.len - left_edge);
|
||||
}
|
||||
|
||||
static Janet cfun_string_trimr(int32_t argc, Janet *argv) {
|
||||
JanetByteView str, set;
|
||||
trim_help_args(argc, argv, &str, &set);
|
||||
int32_t right_edge = trim_help_rightedge(str, set);
|
||||
return janet_stringv(str.bytes, right_edge);
|
||||
}
|
||||
|
||||
static const JanetReg string_cfuns[] = {
|
||||
{
|
||||
"string/slice", cfun_string_slice,
|
||||
@@ -488,8 +542,8 @@ static const JanetReg string_cfuns[] = {
|
||||
},
|
||||
{
|
||||
"string/from-bytes", cfun_string_frombytes,
|
||||
JDOC("(string/from-bytes byte-array)\n\n"
|
||||
"Creates a string from an array of integers with byte values. All integers "
|
||||
JDOC("(string/from-bytes &byte-vals)\n\n"
|
||||
"Creates a string from integer params with byte values. All integers "
|
||||
"will be coerced to the range of 1 byte 0-255.")
|
||||
},
|
||||
{
|
||||
@@ -574,6 +628,24 @@ static const JanetReg string_cfuns[] = {
|
||||
"Similar to snprintf, but specialized for operating with janet. Returns "
|
||||
"a new string.")
|
||||
},
|
||||
{
|
||||
"string/trim", cfun_string_trim,
|
||||
JDOC("(string/trim str [,set])\n\n"
|
||||
"Trim leading and trailing whitespace from a byte sequence. If the argument "
|
||||
"set is provided, consider only characters in set to be whitespace.")
|
||||
},
|
||||
{
|
||||
"string/triml", cfun_string_triml,
|
||||
JDOC("(string/triml str [,set])\n\n"
|
||||
"Trim leading whitespace from a byte sequence. If the argument "
|
||||
"set is provided, consider only characters in set to be whitespace.")
|
||||
},
|
||||
{
|
||||
"string/trimr", cfun_string_trimr,
|
||||
JDOC("(string/trimr str [,set])\n\n"
|
||||
"Trim trailing whitespace from a byte sequence. If the argument "
|
||||
"set is provided, consider only characters in set to be whitespace.")
|
||||
},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -291,8 +291,9 @@ int janet_scan_number(
|
||||
if (*str == '.') {
|
||||
if (seenpoint) goto error;
|
||||
seenpoint = 1;
|
||||
} else {
|
||||
seenadigit = 1;
|
||||
}
|
||||
seenadigit = 1;
|
||||
str++;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,23 @@ static Janet cfun_tuple_type(int32_t argc, Janet *argv) {
|
||||
}
|
||||
}
|
||||
|
||||
static Janet cfun_tuple_sourcemap(int32_t argc, Janet *argv) {
|
||||
janet_fixarity(argc, 1);
|
||||
const Janet *tup = janet_gettuple(argv, 0);
|
||||
Janet contents[2];
|
||||
contents[0] = janet_wrap_integer(janet_tuple_head(tup)->sm_start);
|
||||
contents[1] = janet_wrap_integer(janet_tuple_head(tup)->sm_end);
|
||||
return janet_wrap_tuple(janet_tuple_n(contents, 2));
|
||||
}
|
||||
|
||||
static Janet cfun_tuple_setmap(int32_t argc, Janet *argv) {
|
||||
janet_fixarity(argc, 3);
|
||||
const Janet *tup = janet_gettuple(argv, 0);
|
||||
janet_tuple_head(tup)->sm_start = janet_getinteger(argv, 1);
|
||||
janet_tuple_head(tup)->sm_end = janet_getinteger(argv, 2);
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
static const JanetReg tuple_cfuns[] = {
|
||||
{
|
||||
"tuple/brackets", cfun_tuple_brackets,
|
||||
@@ -138,6 +155,20 @@ static const JanetReg tuple_cfuns[] = {
|
||||
"the time, but will print differently and be treated differently by "
|
||||
"the compiler.")
|
||||
},
|
||||
{
|
||||
"tuple/sourcemap", cfun_tuple_sourcemap,
|
||||
JDOC("(tuple/sourcemap tup)\n\n"
|
||||
"Returns the sourcemap metadata attached to a tuple. "
|
||||
"The mapping is represented by a pair of byte offsets into the "
|
||||
"the source code representing the start and end byte indices where "
|
||||
"the tuple is. ")
|
||||
},
|
||||
{
|
||||
"tuple/setmap", cfun_tuple_setmap,
|
||||
JDOC("(tuple/setmap tup start end)\n\n"
|
||||
"Set the sourcemap metadata on a tuple. start and end should "
|
||||
"be integers representing byte offsets into the file. Returns tup.")
|
||||
},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
149
src/core/vm.c
149
src/core/vm.c
@@ -57,83 +57,13 @@ JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf = NULL;
|
||||
/* How we dispatch instructions. By default, we use
|
||||
* a switch inside an infinite loop. For GCC/clang, we use
|
||||
* computed gotos. */
|
||||
#ifdef ____GNUC__
|
||||
#ifdef __GNUC__
|
||||
#define VM_START() { goto *op_lookup[first_opcode];
|
||||
#define VM_END() }
|
||||
#define VM_OP(op) label_##op :
|
||||
#define VM_DEFAULT() label_unknown_op:
|
||||
#define vm_next() goto *op_lookup[*pc & 0xFF]
|
||||
static void *op_lookup[255] = {
|
||||
&&label_JOP_NOOP,
|
||||
&&label_JOP_ERROR,
|
||||
&&label_JOP_TYPECHECK,
|
||||
&&label_JOP_RETURN,
|
||||
&&label_JOP_RETURN_NIL,
|
||||
&&label_JOP_ADD_IMMEDIATE,
|
||||
&&label_JOP_ADD,
|
||||
&&label_JOP_SUBTRACT,
|
||||
&&label_JOP_MULTIPLY_IMMEDIATE,
|
||||
&&label_JOP_MULTIPLY,
|
||||
&&label_JOP_DIVIDE_IMMEDIATE,
|
||||
&&label_JOP_DIVIDE,
|
||||
&&label_JOP_BAND,
|
||||
&&label_JOP_BOR,
|
||||
&&label_JOP_BXOR,
|
||||
&&label_JOP_BNOT,
|
||||
&&label_JOP_SHIFT_LEFT,
|
||||
&&label_JOP_SHIFT_LEFT_IMMEDIATE,
|
||||
&&label_JOP_SHIFT_RIGHT,
|
||||
&&label_JOP_SHIFT_RIGHT_IMMEDIATE,
|
||||
&&label_JOP_SHIFT_RIGHT_UNSIGNED,
|
||||
&&label_JOP_SHIFT_RIGHT_UNSIGNED_IMMEDIATE,
|
||||
&&label_JOP_MOVE_FAR,
|
||||
&&label_JOP_MOVE_NEAR,
|
||||
&&label_JOP_JUMP,
|
||||
&&label_JOP_JUMP_IF,
|
||||
&&label_JOP_JUMP_IF_NOT,
|
||||
&&label_JOP_GREATER_THAN,
|
||||
&&label_JOP_GREATER_THAN_IMMEDIATE,
|
||||
&&label_JOP_LESS_THAN,
|
||||
&&label_JOP_LESS_THAN_IMMEDIATE,
|
||||
&&label_JOP_EQUALS,
|
||||
&&label_JOP_EQUALS_IMMEDIATE,
|
||||
&&label_JOP_COMPARE,
|
||||
&&label_JOP_LOAD_NIL,
|
||||
&&label_JOP_LOAD_TRUE,
|
||||
&&label_JOP_LOAD_FALSE,
|
||||
&&label_JOP_LOAD_INTEGER,
|
||||
&&label_JOP_LOAD_CONSTANT,
|
||||
&&label_JOP_LOAD_UPVALUE,
|
||||
&&label_JOP_LOAD_SELF,
|
||||
&&label_JOP_SET_UPVALUE,
|
||||
&&label_JOP_CLOSURE,
|
||||
&&label_JOP_PUSH,
|
||||
&&label_JOP_PUSH_2,
|
||||
&&label_JOP_PUSH_3,
|
||||
&&label_JOP_PUSH_ARRAY,
|
||||
&&label_JOP_CALL,
|
||||
&&label_JOP_TAILCALL,
|
||||
&&label_JOP_RESUME,
|
||||
&&label_JOP_SIGNAL,
|
||||
&&label_JOP_GET,
|
||||
&&label_JOP_PUT,
|
||||
&&label_JOP_GET_INDEX,
|
||||
&&label_JOP_PUT_INDEX,
|
||||
&&label_JOP_LENGTH,
|
||||
&&label_JOP_MAKE_ARRAY,
|
||||
&&label_JOP_MAKE_BUFFER,
|
||||
&&label_JOP_MAKE_STRING,
|
||||
&&label_JOP_MAKE_STRUCT,
|
||||
&&label_JOP_MAKE_TABLE,
|
||||
&&label_JOP_MAKE_TUPLE,
|
||||
&&label_JOP_MAKE_BRACKET_TUPLE,
|
||||
&&label_JOP_NUMERIC_LESS_THAN,
|
||||
&&label_JOP_NUMERIC_LESS_THAN_EQUAL,
|
||||
&&label_JOP_NUMERIC_GREATER_THAN,
|
||||
&&label_JOP_NUMERIC_GREATER_THAN_EQUAL,
|
||||
&&label_JOP_NUMERIC_EQUAL,
|
||||
&&label_unknown_op
|
||||
};
|
||||
#define opcode (*pc & 0xFF)
|
||||
#else
|
||||
#define VM_START() uint8_t opcode = first_opcode; for (;;) {switch(opcode) {
|
||||
#define VM_END() }}
|
||||
@@ -261,6 +191,81 @@ static Janet call_nonfn(JanetFiber *fiber, Janet callee) {
|
||||
/* Interpreter main loop */
|
||||
static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status) {
|
||||
|
||||
/* opcode -> label lookup if using clang/GCC */
|
||||
#ifdef __GNUC__
|
||||
static void *op_lookup[255] = {
|
||||
&&label_JOP_NOOP,
|
||||
&&label_JOP_ERROR,
|
||||
&&label_JOP_TYPECHECK,
|
||||
&&label_JOP_RETURN,
|
||||
&&label_JOP_RETURN_NIL,
|
||||
&&label_JOP_ADD_IMMEDIATE,
|
||||
&&label_JOP_ADD,
|
||||
&&label_JOP_SUBTRACT,
|
||||
&&label_JOP_MULTIPLY_IMMEDIATE,
|
||||
&&label_JOP_MULTIPLY,
|
||||
&&label_JOP_DIVIDE_IMMEDIATE,
|
||||
&&label_JOP_DIVIDE,
|
||||
&&label_JOP_BAND,
|
||||
&&label_JOP_BOR,
|
||||
&&label_JOP_BXOR,
|
||||
&&label_JOP_BNOT,
|
||||
&&label_JOP_SHIFT_LEFT,
|
||||
&&label_JOP_SHIFT_LEFT_IMMEDIATE,
|
||||
&&label_JOP_SHIFT_RIGHT,
|
||||
&&label_JOP_SHIFT_RIGHT_IMMEDIATE,
|
||||
&&label_JOP_SHIFT_RIGHT_UNSIGNED,
|
||||
&&label_JOP_SHIFT_RIGHT_UNSIGNED_IMMEDIATE,
|
||||
&&label_JOP_MOVE_FAR,
|
||||
&&label_JOP_MOVE_NEAR,
|
||||
&&label_JOP_JUMP,
|
||||
&&label_JOP_JUMP_IF,
|
||||
&&label_JOP_JUMP_IF_NOT,
|
||||
&&label_JOP_GREATER_THAN,
|
||||
&&label_JOP_GREATER_THAN_IMMEDIATE,
|
||||
&&label_JOP_LESS_THAN,
|
||||
&&label_JOP_LESS_THAN_IMMEDIATE,
|
||||
&&label_JOP_EQUALS,
|
||||
&&label_JOP_EQUALS_IMMEDIATE,
|
||||
&&label_JOP_COMPARE,
|
||||
&&label_JOP_LOAD_NIL,
|
||||
&&label_JOP_LOAD_TRUE,
|
||||
&&label_JOP_LOAD_FALSE,
|
||||
&&label_JOP_LOAD_INTEGER,
|
||||
&&label_JOP_LOAD_CONSTANT,
|
||||
&&label_JOP_LOAD_UPVALUE,
|
||||
&&label_JOP_LOAD_SELF,
|
||||
&&label_JOP_SET_UPVALUE,
|
||||
&&label_JOP_CLOSURE,
|
||||
&&label_JOP_PUSH,
|
||||
&&label_JOP_PUSH_2,
|
||||
&&label_JOP_PUSH_3,
|
||||
&&label_JOP_PUSH_ARRAY,
|
||||
&&label_JOP_CALL,
|
||||
&&label_JOP_TAILCALL,
|
||||
&&label_JOP_RESUME,
|
||||
&&label_JOP_SIGNAL,
|
||||
&&label_JOP_GET,
|
||||
&&label_JOP_PUT,
|
||||
&&label_JOP_GET_INDEX,
|
||||
&&label_JOP_PUT_INDEX,
|
||||
&&label_JOP_LENGTH,
|
||||
&&label_JOP_MAKE_ARRAY,
|
||||
&&label_JOP_MAKE_BUFFER,
|
||||
&&label_JOP_MAKE_STRING,
|
||||
&&label_JOP_MAKE_STRUCT,
|
||||
&&label_JOP_MAKE_TABLE,
|
||||
&&label_JOP_MAKE_TUPLE,
|
||||
&&label_JOP_MAKE_BRACKET_TUPLE,
|
||||
&&label_JOP_NUMERIC_LESS_THAN,
|
||||
&&label_JOP_NUMERIC_LESS_THAN_EQUAL,
|
||||
&&label_JOP_NUMERIC_GREATER_THAN,
|
||||
&&label_JOP_NUMERIC_GREATER_THAN_EQUAL,
|
||||
&&label_JOP_NUMERIC_EQUAL,
|
||||
&&label_unknown_op
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Interpreter state */
|
||||
register Janet *stack;
|
||||
register uint32_t *pc;
|
||||
|
||||
@@ -31,6 +31,8 @@ extern "C" {
|
||||
|
||||
#include "janetconf.h"
|
||||
|
||||
#define JANET_API_VERSION 1
|
||||
|
||||
#ifndef JANET_VERSION
|
||||
#define JANET_VERSION "latest"
|
||||
#endif
|
||||
@@ -51,6 +53,7 @@ extern "C" {
|
||||
|| defined(__FreeBSD__) || defined(__DragonFly__) \
|
||||
|| defined(__FreeBSD_kernel__) \
|
||||
|| defined(__GNU__) /* GNU/Hurd */ \
|
||||
|| defined(__HAIKU__) \
|
||||
|| defined(__linux__) \
|
||||
|| defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) \
|
||||
@@ -183,15 +186,26 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Alignment for pointers */
|
||||
#ifndef JANET_WALIGN
|
||||
#ifdef JANET_32
|
||||
#define JANET_WALIGN 4
|
||||
|
||||
/* Runtime config constants */
|
||||
#ifdef JANET_NO_NANBOX
|
||||
#define JANET_NANBOX_BIT 0
|
||||
#else
|
||||
#define JANET_WALIGN 8
|
||||
#define JANET_NANBOX_BIT 1
|
||||
#endif
|
||||
|
||||
#ifdef JANET_SINGLE_THREADED
|
||||
#define JANET_SINGLE_THREADED_BIT 1
|
||||
#else
|
||||
#define JANET_SINGLE_THREADED_BIT 0
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int api_version;
|
||||
int single_threaded : 1;
|
||||
int nanbox : 1;
|
||||
} JanetBuildConfig;
|
||||
|
||||
/***** END SECTION CONFIG *****/
|
||||
|
||||
/***** START SECTION TYPES *****/
|
||||
@@ -326,12 +340,12 @@ typedef enum JanetType {
|
||||
#define JANET_TFLAG_ABSTRACT (1 << JANET_ABSTRACT)
|
||||
#define JANET_TFLAG_POINTER (1 << JANET_POINTER)
|
||||
|
||||
/* Some abstractions */
|
||||
#define JANET_TFLAG_BYTES (JANET_TFLAG_STRING | JANET_TFLAG_SYMBOL | JANET_TFLAG_BUFFER | JANET_TFLAG_KEYWORD)
|
||||
#define JANET_TFLAG_INDEXED (JANET_TFLAG_ARRAY | JANET_TFLAG_TUPLE)
|
||||
#define JANET_TFLAG_DICTIONARY (JANET_TFLAG_TABLE | JANET_TFLAG_STRUCT)
|
||||
#define JANET_TFLAG_LENGTHABLE (JANET_TFLAG_BYTES | JANET_TFLAG_INDEXED | JANET_TFLAG_DICTIONARY)
|
||||
#define JANET_TFLAG_CALLABLE (JANET_TFLAG_FUNCTION | JANET_TFLAG_CFUNCTION)
|
||||
#define JANET_TFLAG_CALLABLE (JANET_TFLAG_FUNCTION | JANET_TFLAG_CFUNCTION | \
|
||||
JANET_TFLAG_LENGTHABLE | JANET_TFLAG_ABSTRACT)
|
||||
|
||||
/* We provide three possible implementations of Janets. The preferred
|
||||
* nanboxing approach, for 32 or 64 bits, and the standard C version. Code in the rest of the
|
||||
@@ -761,6 +775,7 @@ struct JanetAbstractHead {
|
||||
#define JANET_FUNCDEF_FLAG_HASDEFS 0x200000
|
||||
#define JANET_FUNCDEF_FLAG_HASENVS 0x400000
|
||||
#define JANET_FUNCDEF_FLAG_HASSOURCEMAP 0x800000
|
||||
#define JANET_FUNCDEF_FLAG_STRUCTARG 0x1000000
|
||||
#define JANET_FUNCDEF_FLAG_TAG 0xFFFF
|
||||
|
||||
/* Source mapping structure for a bytecode instruction */
|
||||
@@ -1262,6 +1277,15 @@ JANET_API void janet_register(const char *name, JanetCFunction cfun);
|
||||
/* New C API */
|
||||
|
||||
#define JANET_MODULE_ENTRY JANET_API void _janet_init
|
||||
|
||||
JANET_API int janet_api_version();
|
||||
JANET_API const JanetBuildConfig *janet_build_config();
|
||||
|
||||
#define janet_api_compatible() \
|
||||
((janet_api_build_config()->api_version == JANET_API_VERSION) \
|
||||
&& (janet_api_build_config()->nanbox == JANET_NANBOX_BIT) \
|
||||
&& (janet_api_build_config()->single_threaded == JANET_SINGLE_THREADED_BIT))
|
||||
|
||||
JANET_API void janet_panicv(Janet message);
|
||||
JANET_API void janet_panic(const char *message);
|
||||
JANET_API void janet_panics(const uint8_t *message);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef JANETCONF_H
|
||||
#define JANETCONF_H
|
||||
|
||||
#define JANET_VERSION "0.5.0"
|
||||
#define JANET_VERSION "1.0.0"
|
||||
|
||||
/* #define JANET_BUILD "local" */
|
||||
/* #define JANET_SINGLE_THREADED */
|
||||
@@ -42,6 +42,5 @@
|
||||
/* #define JANET_MAX_MACRO_EXPAND 200 */
|
||||
/* #define JANET_STACK_MAX 16384 */
|
||||
/* #define JANET_NO_NANBOX */
|
||||
/* #define JANET_WALIGN 8 */
|
||||
|
||||
#endif /* end of include guard: JANETCONF_H */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
(var *handleopts* true)
|
||||
(var *exit-on-error* true)
|
||||
(var *colorize* true)
|
||||
(var *compile-only* false)
|
||||
|
||||
(if-let [jp (os/getenv "JANET_PATH")] (set module/*syspath* jp))
|
||||
|
||||
@@ -25,6 +26,7 @@
|
||||
-r : Enter the repl after running all scripts
|
||||
-p : Keep on executing if there is a top level error (persistent)
|
||||
-q : Hide prompt, logo, and repl output (quiet)
|
||||
-k : Compile scripts but do not execute
|
||||
-m syspath : Set system path for loading global modules
|
||||
-c source output : Compile janet source code into an image
|
||||
-n : Disable ANSI color output in the repl
|
||||
@@ -37,6 +39,7 @@
|
||||
"r" (fn [&] (set *should-repl* true) 1)
|
||||
"p" (fn [&] (set *exit-on-error* false) 1)
|
||||
"q" (fn [&] (set *quiet* true) 1)
|
||||
"k" (fn [&] (set *compile-only* true) (set *exit-on-error* false) 1)
|
||||
"n" (fn [&] (set *colorize* false) 1)
|
||||
"m" (fn [i &] (set module/*syspath* (get process/args (+ i 1))) 2)
|
||||
"c" (fn [i &]
|
||||
@@ -67,10 +70,10 @@
|
||||
(+= i (dohandler (string/slice arg 1 2) i))
|
||||
(do
|
||||
(set *no-file* false)
|
||||
(import* arg :prefix "" :exit *exit-on-error*)
|
||||
(import* arg :prefix "" :exit *exit-on-error* :compile-only *compile-only*)
|
||||
(set i lenargs))))
|
||||
|
||||
(when (or *should-repl* *no-file*)
|
||||
(when (and (not *compile-only*) (or *should-repl* *no-file*))
|
||||
(if-not *quiet*
|
||||
(print "Janet " janet/version "-" janet/build " Copyright (C) 2017-2019 Calvin Rose"))
|
||||
(defn noprompt [_] "")
|
||||
|
||||
@@ -23,6 +23,13 @@
|
||||
#include <janet.h>
|
||||
#include "line.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern const unsigned char *janet_gen_init;
|
||||
extern int32_t janet_gen_init_size;
|
||||
|
||||
@@ -31,6 +38,15 @@ int main(int argc, char **argv) {
|
||||
JanetArray *args;
|
||||
JanetTable *env;
|
||||
|
||||
/* Enable color console on windows 10 console. */
|
||||
#ifdef _WIN32
|
||||
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD dwMode = 0;
|
||||
GetConsoleMode(hOut, &dwMode);
|
||||
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
SetConsoleMode(hOut, dwMode);
|
||||
#endif
|
||||
|
||||
/* Set up VM */
|
||||
janet_init();
|
||||
|
||||
|
||||
36
test/amalg/main.c
Normal file
36
test/amalg/main.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Calvin Rose
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* A simple client for checking if the amalgamated Janet source compiles
|
||||
* correctly. */
|
||||
|
||||
#include <janet.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
janet_init();
|
||||
JanetTable *env = janet_core_env(NULL);
|
||||
janet_dostring(env, "(print `hello, world!`)", "main", NULL);
|
||||
janet_deinit();
|
||||
return 0;
|
||||
}
|
||||
@@ -300,5 +300,8 @@
|
||||
(assert (= (length {1 2 3 nil}) 1) "nil value struct literal")
|
||||
(assert (= (length @{1 2 3 nil}) 1) "nil value table literal")
|
||||
|
||||
# Regression Test
|
||||
(assert (= 1 (((compile '(fn [] 1) @{})))) "regression test")
|
||||
|
||||
(end-suite)
|
||||
|
||||
|
||||
@@ -83,6 +83,16 @@
|
||||
(assert (= (string/join @["one" "two" "three"] ", ") "one, two, three") "string/join 2")
|
||||
(assert (= (string/join @["one" "two" "three"]) "onetwothree") "string/join 3")
|
||||
(assert (= (string/join @[] "hi") "") "string/join 4")
|
||||
(assert (= (string/trim " abcd ") "abcd") "string/trim 1")
|
||||
(assert (= (string/trim "abcd \t\t\r\f") "abcd") "string/trim 2")
|
||||
(assert (= (string/trim "\n\n\t abcd") "abcd") "string/trim 3")
|
||||
(assert (= (string/trim "") "") "string/trim 4")
|
||||
(assert (= (string/triml " abcd ") "abcd ") "string/triml 1")
|
||||
(assert (= (string/triml "\tabcd \t\t\r\f") "abcd \t\t\r\f") "string/triml 2")
|
||||
(assert (= (string/triml "abcd ") "abcd ") "string/triml 3")
|
||||
(assert (= (string/trimr " abcd ") " abcd") "string/trimr 1")
|
||||
(assert (= (string/trimr "\tabcd \t\t\r\f") "\tabcd") "string/trimr 2")
|
||||
(assert (= (string/trimr " abcd") " abcd") "string/trimr 3")
|
||||
(assert (deep= (string/split "," "one,two,three") @["one" "two" "three"]) "string/split 1")
|
||||
(assert (deep= (string/split "," "onetwothree") @["onetwothree"]) "string/split 2")
|
||||
(assert (deep= (string/find-all "e" "onetwothree") @[2 9 10]) "string/find-all 1")
|
||||
|
||||
@@ -96,4 +96,17 @@
|
||||
(setdyn :a 100)
|
||||
(assert (= 100 (dyn :a)) "dyn usage 4")
|
||||
|
||||
# Keyword arguments
|
||||
(defn myfn [x y z &keys {:a a :b b :c c}]
|
||||
(+ x y z a b c))
|
||||
|
||||
(assert (= (+ ;(range 6)) (myfn 0 1 2 :a 3 :b 4 :c 5)) "keyword args 1")
|
||||
(assert (= (+ ;(range 6)) (myfn 0 1 2 :a 1 :b 6 :c 5 :d 11)) "keyword args 2")
|
||||
|
||||
# Comment macro
|
||||
(comment 1)
|
||||
(comment 1 2)
|
||||
(comment 1 2 3)
|
||||
(comment 1 2 3 4)
|
||||
|
||||
(end-suite)
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
(if is-mac " -undefined dynamic_lookup" ""))))
|
||||
(def CFLAGS (string
|
||||
(if is-win "/I" "-I")
|
||||
module/*syspath*
|
||||
module/*headerpath*
|
||||
(if is-win " /O" " -std=c99 -Wall -Wextra -fpic -O")
|
||||
OPTIMIZE))
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
(def out (file/open dest :w))
|
||||
(def chunks (seq [b :in (file/read f :all)] (string b)))
|
||||
(file/write out
|
||||
"#include <janet/janet.h>\n"
|
||||
"#include <janet.h>\n"
|
||||
"static const unsigned char bytes[] = {"
|
||||
;(interpose ", " chunks)
|
||||
"};\n\n"
|
||||
|
||||
Reference in New Issue
Block a user