Skip to content

Commit 391be22

Browse files
committed
yamlscript: WIP
Passing first 3 steps with no skipped tests. To test, run `make -C yamlscript test`. The Makefile will auto-install the ys binary under the impls/yamlscript/.cache/ directory.
1 parent 9eb7bea commit 391be22

File tree

13 files changed

+373
-1
lines changed

13 files changed

+373
-1
lines changed

IMPLS.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ IMPL:
112112
#- {IMPL: wasm, wasm_MODE: wace_libc, NO_SELF_HOST_PERF: 1} # Hangs on GH Actions
113113
- {IMPL: wren}
114114
- {IMPL: xslt, NO_SELF_HOST: 1} # step1 fail: "Too many nested template ..."
115+
- {IMPL: yamlscript}
115116
- {IMPL: yorick}
116117
- {IMPL: zig}
117118

Makefile.impls

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ IMPLS = ada ada.2 awk bash basic bbc-basic c c.2 chuck clojure coffee common-lis
3737
guile hare haskell haxe hy io janet java java-truffle js jq julia kotlin latex3 livescript logo lua make mal \
3838
matlab miniMAL nasm nim objc objpascal ocaml perl perl6 php picolisp pike plpgsql \
3939
plsql powershell prolog ps purs python2 python3 r racket rexx rpython ruby ruby.2 rust scala scheme skew sml \
40-
swift swift3 swift4 swift6 tcl ts vala vb vbs vhdl vimscript wasm wren yorick xslt zig
40+
swift swift3 swift4 swift6 tcl ts vala vb vbs vhdl vimscript wasm wren yamlscript yorick xslt zig
4141

4242
step5_EXCLUDES += bash # never completes at 10,000
4343
step5_EXCLUDES += basic # too slow, and limited to ints of 2^16
@@ -199,6 +199,7 @@ vhdl_STEP_TO_PROG = impls/vhdl/$($(1))
199199
vimscript_STEP_TO_PROG = impls/vimscript/$($(1)).vim
200200
wasm_STEP_TO_PROG = impls/wasm/$($(1)).wasm
201201
wren_STEP_TO_PROG = impls/wren/$($(1)).wren
202+
yamlscript_STEP_TO_PROG = impls/yamlscript/$($(1)).ys
202203
yorick_STEP_TO_PROG = impls/yorick/$($(1)).i
203204
xslt_STEP_TO_PROG = impls/xslt/$($(1))
204205
zig_STEP_TO_PROG = impls/zig/$($(1))

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ FAQ](docs/FAQ.md) where I attempt to answer some common questions.
139139
| [WebAssembly](#webassembly-wasm) (wasm) | [Joel Martin](https://github.com/kanaka) |
140140
| [Wren](#wren) | [Dov Murik](https://github.com/dubek) |
141141
| [XSLT](#xslt) | [Ali MohammadPur](https://github.com/alimpfard) |
142+
| [YAMLScript](#yamlscript) | [Ingy döt Net](https://github.com/ingydotnet) |
142143
| [Yorick](#yorick) | [Dov Murik](https://github.com/dubek) |
143144
| [Zig](#zig) | [Josh Tobin](https://github.com/rjtobin) |
144145

@@ -1296,6 +1297,19 @@ cd impls/wren
12961297
wren ./stepX_YYY.wren
12971298
```
12981299

1300+
### YS (YAMLScript)
1301+
1302+
The YS (YAMLScript) implementation of mal was tested on YS 0.2.2.
1303+
1304+
```
1305+
cd impls/yamlscript
1306+
make test
1307+
```
1308+
1309+
The Makefile will install `ys` locally so there are no prerequisites.
1310+
1311+
Note: The YS language owes its origin to the "mal" project!
1312+
12991313
### Yorick
13001314

13011315
The Yorick implementation of mal was tested on Yorick 2.2.04.

impls/yamlscript/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/.cache/

impls/yamlscript/Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
FROM ubuntu:jammy
2+
LABEL maintainer="Ingy döt Net <[email protected]>"
3+
4+
##########################################################
5+
# General requirements for testing or common across many
6+
# implementations
7+
##########################################################
8+
9+
RUN apt-get -y update
10+
11+
# Required for running tests
12+
RUN apt-get -y install make python3
13+
14+
# Some typical implementation and test requirements
15+
RUN apt-get -y install curl libreadline-dev libedit-dev
16+
17+
RUN mkdir -p /mal
18+
WORKDIR /mal
19+
20+
##########################################################
21+
# Specific implementation requirements
22+
##########################################################
23+
24+
RUN apt-get -y install xz-utils
25+
26+
RUN ln -s python3 /usr/bin/python
27+
28+
RUN curl -s https://getys.org/ys | VERSION=0.2.2 bash
29+
30+
ENV YSPATH=/mal/impls/yamlscript/lib

impls/yamlscript/Makefile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
M := $(or $(MAKES_REPO_DIR),.cache/makes)
2+
$(shell [ -d $M ] || git clone -q https://github.com/makeplus/makes $M)
3+
include $M/init.mk
4+
include $M/clean.mk
5+
include $M/ys.mk
6+
include $M/shell.mk
7+
8+
ROOT := $(shell cd ../.. && pwd)
9+
10+
ifndef BASIC
11+
export DEFERRABLE := 1
12+
export OPTIONAL := 1
13+
endif
14+
15+
IMPL := yamlscript
16+
17+
STEPS := $(shell for f in step*; do echo $${f%%_*}; done)
18+
STEPS := $(STEPS:step%=%)
19+
ALL-TESTS := $(STEPS:%=test-%)
20+
21+
GREP-RESULTS := grep -E '(^TEST RESULTS|: .* tests$$)'
22+
23+
export YSPATH := lib
24+
25+
26+
test:
27+
time $(MAKE) test-all BASIC=$(BASIC) |& $(GREP-RESULTS)
28+
echo
29+
30+
test-all: $(ALL-TESTS)
31+
32+
test-docker: docker-build
33+
$(MAKE) -C $(ROOT) DOCKERIZE=1 test^$(IMPL)
34+
35+
test-self-host: docker-build
36+
time $(MAKE) -C $(ROOT) MAL_IMPL=$(IMPL) test^mal^step{0..2} |& \
37+
$(GREP-RESULTS)
38+
39+
$(ALL-TESTS): $(YS)
40+
time $(MAKE) --no-print-directory -C ../.. \
41+
test^$(IMPL)^step$(@:test-%=%) \
42+
MAL_IMPL=$(IMPL) \
43+
DEFERRABLE=$(DEFERRABLE) \
44+
OPTIONAL=$(OPTIONAL) || \
45+
[[ $@ == test-6 ]]
46+
47+
docker-build:
48+
$(MAKE) -C $(ROOT) docker-build^$(IMPL)
49+
@echo

impls/yamlscript/lib/printer.ys

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
!YS-v0
2+
ns: printer
3+
4+
defn pr-str(ast):
5+
cond:
6+
nil?(ast): 'nil'
7+
map?(ast):
8+
type value =: ast:seq:first
9+
condp eq type:
10+
'list':
11+
"($(joins(value.map(pr-str))))"
12+
'vector':
13+
"[$(joins(value.map(pr-str)))]"
14+
'hash-map':
15+
"{$(joins(value.map(pr-str)))}"
16+
'quote':
17+
"(quote $(value:pr-str))"
18+
'quasiquote':
19+
"(quasiquote $(value:pr-str))"
20+
'unquote':
21+
"(unquote $(value:pr-str))"
22+
'splice-unquote':
23+
"(splice-unquote $(value:pr-str))"
24+
'deref':
25+
"(deref $(value:pr-str))"
26+
'with-meta':
27+
"(with-meta $(value.0:pr-str)
28+
$(value.1:pr-str))"
29+
string?(ast): str('"' ast '"')
30+
else: str(ast)

impls/yamlscript/lib/reader.ys

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
!YS-v0
2+
ns: reader
3+
4+
tokens =: atom()
5+
6+
re-tokenize =:
7+
qr:: |
8+
(?x)
9+
[\s,]*
10+
(
11+
~@ |
12+
[\[\]{}()'`~^@] |
13+
"(?:\\.|[^\\"])*"? |
14+
;.* |
15+
[^\s\[\]{}()'"`,;]*
16+
)
17+
18+
defn read-str(string):
19+
reset tokens: tokenize(string)
20+
=>: read-form()
21+
22+
defn tokenize(string):
23+
remove empty?:
24+
map second:
25+
re-seq re-tokenize: string
26+
27+
defn peek():
28+
first: tokens.@
29+
30+
defn next():
31+
token =: peek()
32+
reset tokens:
33+
rest: tokens.@
34+
=>: token
35+
36+
defn read-form():
37+
token =: peek()
38+
condp eq token:
39+
'(': read-list('list' ')')
40+
'[': read-list('vector' ']')
41+
'{': read-list('hash-map' '}')
42+
"'": read-quote('quote')
43+
'`': read-quote('quasiquote')
44+
'~': read-quote('unquote')
45+
'~@': read-quote('splice-unquote')
46+
'@': read-quote('deref')
47+
'^': with-meta()
48+
else: read-atom()
49+
50+
defn read-list(type end):
51+
next:
52+
hash-map type:
53+
loop list []:
54+
token =: peek()
55+
when-not token:
56+
die: "Reached end of input in 'read_list'"
57+
if token != end:
58+
recur: list.conj(read-form())
59+
else: next() && list
60+
61+
defn read-quote(type):
62+
next:
63+
hash-map: type read-form()
64+
65+
defn with-meta():
66+
next:
67+
meta =: read-form()
68+
form =: read-form()
69+
hash-map: +
70+
'with-meta' [form meta]
71+
72+
re-string =:
73+
qr:: |
74+
(?x)
75+
"
76+
(?:
77+
\\. |
78+
[^\\"]
79+
)*
80+
"
81+
82+
defn read-atom():
83+
atom =: next()
84+
condp re-find atom:
85+
/^nil$/: nil
86+
/^"/:
87+
if atom =~ re-string:
88+
str: atom.subs(1 atom.#.--)
89+
die: "Reached end of input looking for '\"'"
90+
/^:\w/:
91+
atom.subs(1):keyword
92+
/^-?\d/:
93+
atom:to-num
94+
/^(?:\w|[-+*\/])/:
95+
atom:symbol
96+
else:
97+
die: "Unknown atom '$atom'"

impls/yamlscript/lib/readline.ys

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
!YS-v0
2+
ns: readline
3+
4+
defn readline(prompt):
5+
print: prompt
6+
read-line:

impls/yamlscript/run

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
set -eu
4+
5+
exec ys "$(dirname "${BASH_SOURCE[0]}")/${STEP:-stepA_mal}.ys" "$@"

0 commit comments

Comments
 (0)