Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ Base Docker image: Debian GNU/Linux trixie/sid
| Go/gccgo | 14.2.0 |
| Haskell | 9.10.2 |
| Idris 2 | 0.7.0 |
| Janet | 1.40.1-1449ad8 |
| Java | 24.0.2 |
| Julia | v"1.11.6" |
| Kotlin | 2.2.0 |
Expand Down
6 changes: 5 additions & 1 deletion brainfuck/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ all_runners := $(fast_runners) \
run[bf.lua] \
run[bf.tcl] \
run[bf_oo.tcl] \
run[bf.php]
run[bf.php] \
run[bf.janet]

# Build

Expand Down Expand Up @@ -243,6 +244,9 @@ run[bf.jl]:: run[%]: % | $(julia_fmt)
run[bf.php]:: run[%]: %
$(PHP_RUN) $(BF_SRC)

run[bf.janet]:: run[%]: %
$(JANET_RUN) $(BF_SRC)

# Utilities

.PHONY: clean
Expand Down
110 changes: 110 additions & 0 deletions brainfuck/bf.janet
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
(def OP_INC 0)
(def OP_MOVE 1)
(def OP_LOOP 2)
(def OP_PRINT 3)

(defn read-file [file-name]
(with [f (file/open file-name)]
(map string/from-bytes (file/read f :all))))

(defn parse-text [code & [pos]]
(var res @[])
(var idx (or pos 0))
(def len (length code))
(label result
(while (< idx len)
(let [c (get code idx)]
(++ idx)
(case c
"+" (array/push res [OP_INC 1])
"-" (array/push res [OP_INC -1])
">" (array/push res [OP_MOVE 1])
"<" (array/push res [OP_MOVE -1])
"." (array/push res [OP_PRINT 0])
"[" (let [[sub-res sub-idx] (parse-text code idx)]
(array/push res [OP_LOOP sub-res])
(set idx sub-idx))
"]" (return result [res idx])
nil))))
[res idx])

(defn make-tape []
@{:tape @[0] :pos 0})

(defn tape-get [tape]
(get (tape :tape) (tape :pos)))

(defn tape-inc [tape x]
(let [t (tape :tape)
p (tape :pos)]
(+= (t p) x)))

(defn tape-move [tape x]
(let [t (tape :tape)
len (length t)]
(+= (tape :pos) x)
(when (>= (tape :pos) len)
(array/join t (array/new-filled (* 2 len) 0)))))

(defn make-printer [quiet]
@{:sum1 0 :sum2 0 :quiet quiet})

(defn tape-print [printer n]
(if (printer :quiet)
(do
(set (printer :sum1)
(% (+ (printer :sum1) n) 255))
(set (printer :sum2)
(% (+ (printer :sum1) (printer :sum2)) 255)))
(do
(file/write stdout (string/from-bytes n))
(file/flush stdout))))

(defn tape-checksum [printer]
(let [sum1 (printer :sum1)
sum2 (printer :sum2)]
(bor (blshift sum2 8) sum1)))

(defn run [ops tape printer]
(each [op val] ops
(case op
OP_INC (tape-inc tape val)
OP_MOVE (tape-move tape val)
OP_LOOP (while (> (tape-get tape) 0)
(run val tape printer))
OP_PRINT (tape-print printer (tape-get tape))
nil)))

(defn notify [msg]
(try
(with [s (net/connect "localhost" 9001)]
(net/write s msg))
([err] (eprint "Connection failed: " err))))

(defn verify []
(def text "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>
---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.")

(def p-left (make-printer true))
(var tape (make-tape))
(run (first (parse-text (map string/from-bytes text))) tape p-left)
(def left (tape-checksum p-left))

(def p-right (make-printer true))
(each c "Hello World!\n"
(tape-print p-right c))
(def right (tape-checksum p-right))
(when (not= left right)
(eprintf "%d != %d" left right)
(os/exit 1)))

(verify)
(def text (first (parse-text (read-file (get (dyn :args) 1)))))
(def printer (make-printer (not (empty? (or (os/getenv "QUIET") "")))))

(notify (string/format "Janet\t%d" (os/getpid)))
(run text (make-tape) printer)
(notify "stop")

(when (printer :quiet)
(print "Output checksum: " (tape-checksum printer)))
1 change: 1 addition & 0 deletions common/commands.mk
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ TRUBY_NATIVE_RUN = $(XTIME) truffleruby $^
SCHEME_RUN = $(XTIME) scheme --optimize-level 3 --program $^
JULIA_RUN = $(XTIME) julia --optimize=3 --check-bounds=no $^
PHP_RUN = $(XTIME) php $^
JANET_RUN = $(XTIME) janet $^

GIT_CLONE = git clone --depth 1 -q
DOTNET_CLEAN = -dotnet clean --nologo -v q -c Release
Expand Down
7 changes: 7 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,13 @@ RUN cabal update \
&& cabal install hlint
ENV GHC_PACKAGE_PATH="~/.cabal/store/ghc-${GHC_VER}/package.db:"

# https://github.com/janet-lang/janet/releases
ARG JANET=v1.40.1
RUN curl -LO \
https://github.com/janet-lang/janet/releases/download/$JANET/janet-$JANET-linux-x64.tar.gz \
&& tar xf janet-$JANET-linux-x64.tar.gz
ENV PATH="/root/bin/janet-$JANET-linux/bin/:${PATH}"

ARG SCRIPTS_VER=unknown
COPY *.rb ./

Expand Down
1 change: 1 addition & 0 deletions docker/versions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class Test {
'Idris 2' => -> { `idris2 --version`.split[-1] },
'Odin' => -> { `odin version`.split[-1] },
'C3' => -> { `c3c --version`.lines.first[/C3 Compiler Version:\s+(\d+\.\d+\.\d+)/, 1] },
'Janet' => -> { `janet --version` },
}.freeze

def pad(num, str, padstr)
Expand Down