Skip to content

Commit 9107dc2

Browse files
authored
Merge pull request #37 from ArkScript-lang/v4
V4
2 parents 4fa96f9 + c3520e8 commit 9107dc2

18 files changed

+464
-414
lines changed

.github/workflows/ci.yml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ on:
66
pull_request:
77
branches: [ master ]
88

9+
env:
10+
ARTIFACT_NAME: "linux-clang-15.zip"
11+
CLANG_VERSION: 15
12+
913
jobs:
1014
build:
1115
runs-on: ubuntu-latest
@@ -14,29 +18,29 @@ jobs:
1418
- name: Checkout std
1519
uses: actions/checkout@v2
1620

17-
- uses: robinraju/release-downloader@v1.5
21+
- uses: robinraju/release-downloader@v1.9
1822
with:
1923
latest: true
24+
preRelease: true
2025
repository: ArkScript-lang/Ark
21-
fileName: "linux-clang-11.zip"
26+
fileName: ${{ env.ARTIFACT_NAME }}
2227

2328
- name: Set up files
2429
shell: bash
2530
run: |
26-
unzip linux-clang-11.zip
31+
unzip $ARTIFACT_NAME
2732
chmod u+x arkscript *.so lib/*.arkm
2833
cp lib/*.arkm ./
2934
3035
- name: Update LLVM compilers
3136
shell: bash
3237
run: |
33-
version=11
34-
sudo apt-get install -y clang-${version} lld-${version} libc++-${version}-dev libc++abi-${version}-dev clang-tools-${version}
38+
sudo apt-get install -y clang-${CLANG_VERSION} lld-${CLANG_VERSION} \
39+
libc++-${CLANG_VERSION}-dev libc++abi-${CLANG_VERSION}-dev \
40+
clang-tools-${CLANG_VERSION}
3541
3642
- name: Tests
3743
shell: bash
3844
run: |
3945
./arkscript --version
40-
for f in tests/*.ark; do
41-
./arkscript $f -L ./
42-
done
46+
./arkscript tests/all.ark -L ./

Events.ark

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(import "List.ark")
1+
(import std.List)
22

33
# @brief Allows to register events listeners and emit events
44
# =begin

List.ark

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# @param _func the function to call on each element
44
# @details The original list is left unmodified.
55
# =begin
6-
# (import "List.ark")
6+
# (import std.List)
77
# (let collection [1 2 5 12])
88
# (list:forEach collection (fun (element) {
99
# (print element)
@@ -21,7 +21,7 @@
2121
# @param _L the list to iterate over
2222
# @details The original list is left unmodified.
2323
# =begin
24-
# (import "List.ark")
24+
# (import std.List)
2525
# (let collection [1 2 5 12])
2626
# (let p (list:product collection)) # => 120
2727
# =end
@@ -38,7 +38,7 @@
3838
# @param _L the list to iterate over
3939
# @details The original list is left unmodified.
4040
# =begin
41-
# (import "List.ark")
41+
# (import std.List)
4242
# (let collection [1 2 5 12])
4343
# (let p (list:sum collection)) # => 20
4444
# =end
@@ -51,7 +51,7 @@
5151
(set _index (+ 1 _index))})
5252
_output }))
5353

54-
(import "Math.ark") # needed for math:min, math:max
54+
(import std.Math :min :max)
5555

5656
# @brief Drop the first n elements of a list
5757
# @param _L the list to work on
@@ -101,7 +101,7 @@
101101
# @param _f the predicate
102102
# @details The original list is left unmodified.
103103
# =begin
104-
# (import "Math.ark")
104+
# (import std.Math)
105105
# (print (list:filter [1 2 3 4 5 6 7 8 9] math:even)) # [2 4 6 8]
106106
# =end
107107
# @author https://github.com/rstefanic

Macros.ark

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
!{-> (arg fn1 ...fn) {
2-
!{if (> (len fn) 0)
1+
($ -> (arg fn1 ...fn) {
2+
($if (> (len fn) 0)
33
(-> (fn1 arg) ...fn)
4-
(fn1 arg)}}}
4+
(fn1 arg))})
55

66
# internal, do not use
7-
!{__suffix-dup (sym x) {
8-
!{if (> x 1)
9-
(__suffix-dup sym (- x 1))}
10-
(symcat sym x)}}
7+
($ __suffix-dup (sym x) {
8+
($if (> x 1)
9+
(__suffix-dup sym (- x 1)))
10+
(symcat sym x)})
1111

12-
!{partial (func ...defargs) {
13-
!{bloc (__suffix-dup a (- (argcount func) (len defargs)))}
12+
($ partial (func ...defargs) {
13+
($ bloc (__suffix-dup a (- (argcount func) (len defargs))))
1414
(fun (bloc) (func ...defargs bloc))
15-
!{undef bloc}}}
15+
($undef bloc)})

String.ark

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,15 @@
135135
(let _pattern_sz (len _pattern))
136136

137137
(while (!= -1 _idx) {
138+
(mut _first_segment (str:slice _out 0 _idx))
139+
(mut _next_segment (str:slice _out (+ _idx _pattern_sz) (- (len _out) (+ _idx _pattern_sz))))
138140
(set _out (+
139-
(str:slice _out 0 _idx)
141+
_first_segment
140142
_new
141-
(str:slice _out (+ _idx _pattern_sz) (- (len _out) (+ _idx _pattern_sz)))))
142-
(set _idx (str:find _out _pattern))})
143+
_next_segment))
144+
(set _idx (str:find _next_segment _pattern))
145+
(if (!= -1 _idx)
146+
(set _idx (+ _idx (len _first_segment) (len _new))))})
143147
_out }))
144148

145149
# @brief Join a list of elements with a given string delimiter

Testing.ark

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# internal, do not use
2+
(let _runner (fun (_name _callable) {
3+
(mut _passed 0)
4+
(mut _failed 0)
5+
(mut _failures [])
6+
(let _case_desc "")
7+
(mut _cases [])
8+
(mut _case_pointer 0)
9+
(mut display_cases_success false)
10+
11+
(let _start_time (time))
12+
# run test
13+
(_callable)
14+
(let _end_time (time))
15+
16+
# no newline, yet
17+
(puts _name)
18+
(if (> _passed 0)
19+
(puts (str:format " - {} ✅" _passed)))
20+
(if (> _failed 0)
21+
(puts (str:format ", {} ❌" _failed)))
22+
23+
(puts (str:format " in {:2.3f}ms\n" (* 1000 (- _end_time _start_time))))
24+
25+
(mut _i 0)
26+
(let _failures_count (len _failures))
27+
(while (< _i _failures_count) {
28+
(print " " (@ _failures _i))
29+
(set _i (+ 1 _i))})
30+
31+
[_passed _failed]}))
32+
33+
(let _test_desc (fun (_desc)
34+
(if (empty? _desc)
35+
""
36+
(str:format " for test '{}'" (head _desc)))))
37+
38+
# internal, do not use
39+
# Has a _case_desc which also exists (empty) inside _runner so that tests without a
40+
# case won't crash the testing library when trying to access the case name.
41+
# Add the test name to a pile so that we can nicely print all the case names later.
42+
# Update the pointer to current case to its old value later on
43+
(let _case (fun (_case_desc _callable) {
44+
(let _old_pointer _case_pointer)
45+
(append! _cases _case_desc)
46+
(_callable)
47+
(pop! _cases -1)
48+
(set _case_pointer _old_pointer)}))
49+
50+
# @brief Create a test case with a label to help with debugging when one or more tests fail
51+
# @details Test cases can be nested.
52+
# @param _desc a description for the test, a string
53+
# @param _body test to execute
54+
# =begin
55+
# (test:suite name {
56+
# (test:expect (my_function 1 2 3))
57+
# (test:case "a description" {
58+
# (test:expect (return_true) "return true"})
59+
# (test:eq 1 2 "1 is 2, this should fail")})
60+
# =end
61+
# @author https://github.com/SuperFola
62+
($ test:case (_desc _body)
63+
(_case _desc (fun () {_body})))
64+
65+
# internal, do not use
66+
# Until _case_pointer isn't at the end of the pile (where our failing test case's is),
67+
# iterate on the list, writing the case name in a cascade pattern.
68+
# This way if we have CASE A>CASE B>CASE C and no test crashed in A nor in A>B,
69+
# we are still able to display the cascade A>B>C with the correct indentation.
70+
(let _add_case (fun () {
71+
(let _target_len (len _cases))
72+
(while (< _case_pointer _target_len) {
73+
(mut _indent (* 2 _case_pointer))
74+
(mut _fmt (if (> _indent 0) (+ "{: <" (toString _indent) "}{}") "{}{}"))
75+
(append! _failures (str:format _fmt "" (@ _cases _case_pointer)))
76+
(set _case_pointer (+ 1 _case_pointer))})}))
77+
78+
# internal, do not use
79+
# This can only be used within a (nested or not) call to test:suite
80+
# because it updates _failed and _failures, which are defined by
81+
# test:suite call to _runner
82+
(let _report_error (fun (_lhs _rhs _lhs_repr _rhs_repr _desc) {
83+
(set _failed (+ 1 _failed))
84+
85+
# If we have a case description AND the pointer isn't up to date, display the case(s)' names
86+
(if (and (not (empty? _case_desc)) (!= _case_pointer (len _cases)))
87+
(_add_case))
88+
89+
# Compute global indent for the failing test resume
90+
(let _indent_case_len (* 2 (len _cases)))
91+
(let _indent (if (> _indent_case_len 0)
92+
(str:format (+ "{: <" (toString _indent_case_len) "}") "")
93+
""))
94+
# Add the error message
95+
(append! _failures (str:format "{}expected '{}' but got '{}'{}" _indent _lhs_repr _rhs_repr (_test_desc _desc)))
96+
97+
(let _rhs_start (+ (len _lhs_repr) (len "expected ''")))
98+
(let _lhs_align (len _lhs_repr))
99+
(let _rhs_align (len _rhs_repr))
100+
(let _show_expected (!= _lhs_repr (toString _lhs)))
101+
(let _show_real (!= _rhs_repr (toString _rhs)))
102+
103+
(if _show_real
104+
(append! _failures
105+
(str:format
106+
(+ "{}{: <" (toString (len "expected ")) "}" "{: <" (toString _rhs_start) "}{:~<" (toString _rhs_align) "} {}")
107+
_indent
108+
# to position one char before the first ' surrounding the expected value
109+
""
110+
# writes the | right under the first ' surrounding the expected value
111+
(if _show_expected "|" "")
112+
# begins the \~~~~ under the real value
113+
(if _show_real "\\" "")
114+
(if _show_real _rhs ""))))
115+
(if _show_expected
116+
(append! _failures
117+
(str:format
118+
(+ "{}{: <" (toString (len "expected ")) "}\\ {}")
119+
_indent
120+
""
121+
_lhs)))}))
122+
123+
# internal, do not use
124+
# This can only be used within a (nested or not) call to test:suite
125+
# because it updates _passed, which is defined by test:suite call to _runner
126+
(let _report_success (fun () {
127+
(set _passed (+ 1 _passed))
128+
(if display_cases_success
129+
(_add_case))
130+
}))
131+
132+
# @brief Given a value or function call returning a boolean, generate a test case
133+
# @param _cond the value to test for truthiness
134+
# @param _desc an optional description (string) for the test
135+
# =begin
136+
# (test:suite name {
137+
# (test:expect (my_function 1 2 3))
138+
# (test:expect (return_true) "return true"})
139+
# =end
140+
# @author https://github.com/SuperFola
141+
($ test:expect (_cond ..._desc) {
142+
(if (!= true _cond)
143+
{
144+
(set _failed (+ 1 _failed))
145+
(append! _failures (str:format "{} returned {}{}" ($repr _cond) _cond) (_test_desc _desc))}
146+
(_report_success))})
147+
148+
# @brief Compare two values that should be equal and generate a test case
149+
# @param _expected expected value
150+
# @param _expr computed value to test
151+
# @param _desc an optional description (string) for the test
152+
# =begin
153+
# (test:suite name {
154+
# (test:eq 6 (my_function 1 2 3))
155+
# (test:eq 5 (foo) "foo should return 5")})
156+
# =end
157+
# @author https://github.com/SuperFola
158+
($ test:eq (_expected _expr ..._desc) {
159+
(if (= _expected _expr)
160+
(_report_success)
161+
(_report_error _expected _expr ($repr _expected) ($repr _expr) _desc))})
162+
163+
# @brief Compare two values that should **not** be equal and generate a test case
164+
# @param _unexpected the value we don't want
165+
# @param _value tested value
166+
# @param _desc an optional description (string) for the test
167+
# =begin
168+
# (test:suite name {
169+
# (test:neq 0 (my_function 1 2 3))})
170+
# =end
171+
# @author https://github.com/SuperFola
172+
($ test:neq (_unexpected _value ..._desc) {
173+
(if (!= _unexpected _value)
174+
(_report_success)
175+
(_report_error _unexpected _value ($repr _unexpected) ($repr _value) _desc))})
176+
177+
# @brief Generate the code for a test suite
178+
# @details Create two variables: _name-output (a list: [successes, failures]) and _name-status (boolean, true on success)
179+
# @param _name test name, as an identifier
180+
# @param _body body of the test, a begin block
181+
# =begin
182+
# (test:suite name {
183+
# (set display_cases_success true) # default: false, when true, display all the cases names on success and failures
184+
# (test:eq 6 (my_function 1 2 3))
185+
# (test:eq 128 (* 8 16))})
186+
# =end
187+
# @author https://github.com/SuperFola
188+
($ test:suite (_name _body) {
189+
(let (symcat _name "-output") (_runner ($repr _name) (fun () {_body})))
190+
(let (symcat _name "-status") (= 0 (@ (symcat _name "-output") 1)))})

tests/all.ark

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(import events-tests)
2+
(import exceptions-tests)
3+
(import functional-tests)
4+
(import lazy-tests)
5+
(import list-tests)
6+
(import macros-tests)
7+
(import math-tests)
8+
(import range-tests)
9+
(import string-tests)
10+
(import switch-tests)

0 commit comments

Comments
 (0)