kapusta 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -2
  3. data/bin/check-all +17 -0
  4. data/bin/compile-examples +70 -0
  5. data/bin/fennel-parity +4 -38
  6. data/examples/account-lockout.kap +11 -0
  7. data/examples/accumulator.kap +2 -0
  8. data/examples/bank-account.kap +2 -0
  9. data/examples/bst-iterator.kap +52 -0
  10. data/examples/circle.kap +18 -0
  11. data/examples/convert-temperature.kap +14 -0
  12. data/examples/count-effects.kap +13 -0
  13. data/examples/counter.kap +2 -0
  14. data/examples/falling-drops.kap +12 -0
  15. data/examples/fennel-parity-examples.txt +40 -0
  16. data/examples/hit-counter.kap +2 -0
  17. data/examples/max-achievable.kap +8 -0
  18. data/examples/module-header.kap +4 -2
  19. data/examples/mruby-runtime-examples.txt +92 -0
  20. data/examples/number-of-1-bits.kap +13 -0
  21. data/examples/number-of-steps.kap +15 -0
  22. data/examples/parking-system.kap +2 -0
  23. data/examples/recent-counter.kap +17 -0
  24. data/examples/scopes.kap +2 -0
  25. data/examples/signal-harvest.kap +16 -0
  26. data/examples/stack.kap +2 -0
  27. data/examples/two-sum-hash.kap +11 -14
  28. data/examples/underscore-patterns.kap +1 -1
  29. data/examples/valid-parentheses-1.kap +2 -0
  30. data/lib/kapusta/cli.rb +11 -6
  31. data/lib/kapusta/compiler/emitter/bindings.rb +27 -2
  32. data/lib/kapusta/compiler/emitter/control_flow.rb +97 -14
  33. data/lib/kapusta/compiler/emitter/expressions.rb +1 -0
  34. data/lib/kapusta/compiler/emitter/interop.rb +4 -2
  35. data/lib/kapusta/compiler/emitter/patterns.rb +125 -0
  36. data/lib/kapusta/compiler/emitter/support.rb +63 -24
  37. data/lib/kapusta/compiler/emitter.rb +2 -1
  38. data/lib/kapusta/compiler/normalizer.rb +6 -0
  39. data/lib/kapusta/compiler.rb +15 -6
  40. data/lib/kapusta/errors.rb +6 -0
  41. data/lib/kapusta/formatter.rb +1 -2
  42. data/lib/kapusta/lsp/definition.rb +17 -0
  43. data/lib/kapusta/lsp/rename.rb +3 -1
  44. data/lib/kapusta/lsp/scope_walker.rb +40 -11
  45. data/lib/kapusta/lsp.rb +2 -1
  46. data/lib/kapusta/version.rb +1 -1
  47. data/lib/kapusta.rb +2 -2
  48. data/spec/cli_spec.rb +35 -0
  49. data/spec/examples_errors_spec.rb +20 -0
  50. data/spec/examples_spec.rb +136 -0
  51. data/spec/lsp_spec.rb +71 -3
  52. data/spec/spec_helper.rb +9 -0
  53. metadata +14 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 520158590f1244ac17f70b58ded945f66be00060f6da89cebb366fefaf27b62e
4
- data.tar.gz: 6773e0faa320f23cb15106e710f380a39093c9fc6e56cead8941c28e0ccf16c5
3
+ metadata.gz: 326afa9f8872d9d92bf4c3ca32fa5c15f78559691aa447a23472a4042a4f3a4c
4
+ data.tar.gz: 625c013cad69a7e2229ea99a64796c2de90f9fd9665152c74cbd6753c67319f0
5
5
  SHA512:
6
- metadata.gz: 814d37c473287d2d1e54568c7d21c22d88703cd89da761100c1f20950e47cb18eb2ac4807aa596878ded72eb7049a6083d2b9de46bc76ce2ea55787f6993f61f
7
- data.tar.gz: 3a15fc05522e617cf46e8709a55dc8497252503f2b995dffaa4f8995fc34a54e9bcc2a711cd501884203bf0113c7924f159377459de8f2524e9c371c018d8238
6
+ metadata.gz: 2768ae288a6011b651f7e084af68717a3cf6486a45483985fe8eeb7ed9fa9ea3f2ce18c6db77b94e74b130cc10c84c486970569eee760fb82ae858070486049b
7
+ data.tar.gz: 04245b8c5e76773abe1f6c9efde7c64242eaec147e8f07c3d91239a893c25cf2477e4e2b7cec518aa2e82ee948238088d37f68731f41f807aebb6c911c2d03e8
data/README.md CHANGED
@@ -4,7 +4,7 @@ Kapusta is a Lisp for the Ruby runtime.
4
4
 
5
5
  It is inspired by [Fennel](https://fennel-lang.org). It is not intended to be production-ready like Clojure: that would be a lot of work, and Ruby is already a rich, elegant language.
6
6
 
7
- Instead, Kapusta aims to bring some of the simplicity and joy of Lisp to Ruby. Where Lua is intentionally minimal, and Fennel follows that design for good reason, Kapusta exists mostly for fun. You can use it for small apps, LeetCode, DragonRuby, or maybe even Rails.
7
+ Instead, Kapusta aims to bring some of the simplicity and joy of Lisp to Ruby. Where Fennel uses Lua's stdlib and runtime, Kapusta uses Ruby's. You can use it for small apps, LeetCode, DragonRuby, or maybe even Rails.
8
8
 
9
9
  For more information about Kapusta, see the official Fennel documentation and tutorials.
10
10
 
@@ -45,6 +45,12 @@ exe/kapusta --compile examples/fizzbuzz.kap > examples/fizzbuzz.rb
45
45
  ruby examples/fizzbuzz.rb
46
46
  ```
47
47
 
48
+ For mruby-compatible output, such as DragonRuby, use:
49
+
50
+ ```
51
+ exe/kapusta --compile --target=mruby examples/match.kap > examples/match-mruby.rb
52
+ ```
53
+
48
54
  ## Use from Ruby
49
55
 
50
56
  Ruby can require a `.kap` file and use it directly.
@@ -104,7 +110,9 @@ Kapusta keeps most core Fennel forms. The main differences come from Ruby's runt
104
110
  Kapusta-specific additions:
105
111
 
106
112
  - `module` and `class` for Ruby host structure, including file-header forms
107
- - `ivar` or `@var`) / `cvar` or `@@var` / `gvar` or `$var`
113
+ - `(end)` closes a bodyless file-header
114
+ - `(defn name ...)` or `(fn class.name ..)`
115
+ - `ivar` or `@var` / `cvar` or `@@var` / `gvar` or `$var`
108
116
  - `try` / `catch` / `finally` plus `raise` for exceptions
109
117
  - `(ruby "...")` raw host escape hatch
110
118
  - a trailing symbol-keyed hash is emitted as Ruby keyword arguments
data/bin/check-all CHANGED
@@ -16,4 +16,21 @@ bin/fennel-parity
16
16
  echo "== compile examples =="
17
17
  bin/compile-examples
18
18
 
19
+ echo "== run mruby-compatible examples on mruby =="
20
+ MRUBY_RUNTIME_EXAMPLES=()
21
+ while IFS= read -r example || [[ -n "$example" ]]; do
22
+ [[ -n "$example" ]] && MRUBY_RUNTIME_EXAMPLES+=("$example")
23
+ done < examples/mruby-runtime-examples.txt
24
+
25
+ for example in "${MRUBY_RUNTIME_EXAMPLES[@]}"; do
26
+ ruby_file="examples-compiled/$example.rb"
27
+ file="examples-compiled/$example-mruby.rb"
28
+ if [[ ! -f "$file" ]]; then
29
+ file="$ruby_file"
30
+ fi
31
+
32
+ ruby "$ruby_file" >/dev/null
33
+ mruby "$file" >/dev/null
34
+ done
35
+
19
36
  echo "== Success! =="
data/bin/compile-examples CHANGED
@@ -4,6 +4,61 @@ set -euo pipefail
4
4
  ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
5
  SOURCE_DIR="$ROOT_DIR/examples"
6
6
  TARGET_DIR="$ROOT_DIR/examples-compiled"
7
+ tmp_files=()
8
+ MRUBY_RUNTIME_EXAMPLES=()
9
+
10
+ while IFS= read -r example || [[ -n "$example" ]]; do
11
+ [[ -n "$example" ]] && MRUBY_RUNTIME_EXAMPLES+=("$example")
12
+ done < "$SOURCE_DIR/mruby-runtime-examples.txt"
13
+
14
+ cleanup() {
15
+ rm -f "${tmp_files[@]}"
16
+ }
17
+ trap cleanup EXIT
18
+
19
+ is_mruby_runtime_example() {
20
+ local name="$1"
21
+
22
+ for example in "${MRUBY_RUNTIME_EXAMPLES[@]}"; do
23
+ [[ "$name" == "$example" ]] && return 0
24
+ done
25
+
26
+ return 1
27
+ }
28
+
29
+ needs_mruby_artifact() {
30
+ local name="$1"
31
+ local ruby_file="$2"
32
+ local ruby_stdout
33
+ local ruby_stderr
34
+ local mruby_stdout
35
+ local mruby_stderr
36
+
37
+ is_mruby_runtime_example "$name" || return 1
38
+
39
+ ruby_stdout="$(mktemp)"
40
+ ruby_stderr="$(mktemp)"
41
+ mruby_stdout="$(mktemp)"
42
+ mruby_stderr="$(mktemp)"
43
+ tmp_files+=("$ruby_stdout" "$ruby_stderr" "$mruby_stdout" "$mruby_stderr")
44
+
45
+ if ! ruby "$ruby_file" > "$ruby_stdout" 2> "$ruby_stderr"; then
46
+ printf 'Compiled example failed under ruby: %s\n' "$ruby_file" >&2
47
+ cat "$ruby_stderr" >&2
48
+ exit 1
49
+ fi
50
+
51
+ if ! mruby "$ruby_file" > "$mruby_stdout" 2> "$mruby_stderr"; then
52
+ return 0
53
+ fi
54
+
55
+ ! cmp -s "$ruby_stdout" "$mruby_stdout"
56
+ }
57
+
58
+ if (($# > 0)); then
59
+ printf 'usage: bin/compile-examples\n' >&2
60
+ exit 1
61
+ fi
7
62
 
8
63
  mkdir -p "$TARGET_DIR"
9
64
 
@@ -18,7 +73,22 @@ fi
18
73
  for kap_file in "${kap_files[@]}"; do
19
74
  name="$(basename "$kap_file" .kap)"
20
75
  ruby_file="$TARGET_DIR/$name.rb"
76
+ mruby_file="$TARGET_DIR/$name-mruby.rb"
21
77
 
22
78
  "$ROOT_DIR/exe/kapusta" --compile "$kap_file" > "$ruby_file"
23
79
  printf 'Compiled %s -> %s\n' "$kap_file" "$ruby_file"
80
+
81
+ if needs_mruby_artifact "$name" "$ruby_file"; then
82
+ tmp_mruby="$(mktemp)"
83
+ tmp_files+=("$tmp_mruby")
84
+ "$ROOT_DIR/exe/kapusta" --compile --target=mruby "$kap_file" > "$tmp_mruby"
85
+ if cmp -s "$ruby_file" "$tmp_mruby"; then
86
+ rm -f "$mruby_file"
87
+ else
88
+ mv "$tmp_mruby" "$mruby_file"
89
+ printf 'Compiled %s -> %s\n' "$kap_file" "$mruby_file"
90
+ fi
91
+ else
92
+ rm -f "$mruby_file"
93
+ fi
24
94
  done
data/bin/fennel-parity CHANGED
@@ -9,44 +9,10 @@ EXAMPLES_ERRORS = File.join(ROOT, 'examples-errors')
9
9
  KAPUSTA = File.join(ROOT, 'exe', 'kapusta')
10
10
  KAPFMT = File.join(ROOT, 'exe', 'kapfmt')
11
11
 
12
- COMPATIBLE = %w[
13
- ackermann.kap
14
- anonymous-greeter.kap
15
- classify-wallet.kap
16
- climbing-stairs.kap
17
- describe.kap
18
- destructure.kap
19
- even-squares.kap
20
- factorial.kap
21
- fib.kap
22
- fizzbuzz.kap
23
- gcd.kap
24
- hashfn.kap
25
- leap-year.kap
26
- macros-dbg.kap
27
- macros-import-helpers.kap
28
- macros-import-whole.kap
29
- macros-import.kap
30
- macros-multi.kap
31
- macros-swap.kap
32
- macros-thrice-if.kap
33
- macros-unless.kap
34
- macros-when-let.kap
35
- match.kap
36
- min-max.kap
37
- or-patterns.kap
38
- power-of-three.kap
39
- packet-router.kap
40
- points.kap
41
- primes.kap
42
- safe-lookup.kap
43
- shapes.kap
44
- squares.kap
45
- sum.kap
46
- thread-styles.kap
47
- tic-tac-toe.kap
48
- underscore-patterns.kap
49
- ].freeze
12
+ COMPATIBLE = File.readlines(File.join(EXAMPLES, 'fennel-parity-examples.txt'), chomp: true)
13
+ .reject(&:empty?)
14
+ .map { |name| "#{name}.kap" }
15
+ .freeze
50
16
 
51
17
  def run(cmd, file, chdir: EXAMPLES, env: {})
52
18
  out, err, status = Open3.capture3(env, cmd, file, chdir:)
@@ -0,0 +1,11 @@
1
+ (local max-missed 3)
2
+
3
+ (fn classify [guesses]
4
+ (var missed 0)
5
+ (each [_ g (ipairs guesses)]
6
+ (when (= g 1) (set missed (+ missed 1))))
7
+ (if (< missed max-missed) :ok :locked))
8
+
9
+ (print (classify [0 1 0 1]))
10
+ (print (classify [1 1 1]))
11
+ (print (classify [1 1 1 0]))
@@ -10,6 +10,8 @@
10
10
  (fn value []
11
11
  (ivar total))
12
12
 
13
+ (end)
14
+
13
15
  (let [acc (Accumulator.new 10)]
14
16
  (acc.add! 5)
15
17
  (acc.add! 7)
@@ -19,3 +19,5 @@
19
19
  (set (ivar balance)
20
20
  (- (ivar balance) amount))
21
21
  self)
22
+
23
+ (end)
@@ -0,0 +1,52 @@
1
+ (class TreeNode)
2
+
3
+ (fn initialize [val left right]
4
+ (set @val val)
5
+ (set @left left)
6
+ (set @right right))
7
+
8
+ (fn val [] @val)
9
+ (fn left [] @left)
10
+ (fn right [] @right)
11
+
12
+ (end)
13
+
14
+ (class BSTIterator)
15
+
16
+ (fn initialize [root]
17
+ (set @stack [])
18
+ (self.push-left root))
19
+
20
+ (fn push-left [node]
21
+ (var n node)
22
+ (while n
23
+ (let [stack @stack]
24
+ (stack.push n))
25
+ (set n (n.left))))
26
+
27
+ (fn next []
28
+ (let [stack @stack
29
+ node (stack.pop)]
30
+ (self.push-left (node.right))
31
+ (node.val)))
32
+
33
+ (fn has-next? []
34
+ (let [stack @stack]
35
+ (not (stack.empty?))))
36
+
37
+ (end)
38
+
39
+ (let [root (TreeNode.new 7
40
+ (TreeNode.new 3 nil nil)
41
+ (TreeNode.new 15
42
+ (TreeNode.new 9 nil nil)
43
+ (TreeNode.new 20 nil nil)))
44
+ it (BSTIterator.new root)]
45
+ (print (it.next))
46
+ (print (it.next))
47
+ (print (it.has-next?))
48
+ (print (it.next))
49
+ (print (it.has-next?))
50
+ (print (it.next))
51
+ (print (it.next))
52
+ (print (it.has-next?)))
@@ -0,0 +1,18 @@
1
+ (class Circle)
2
+
3
+ (local pi 3.14159)
4
+
5
+ (fn initialize [radius]
6
+ (set @radius radius))
7
+
8
+ (fn area []
9
+ (* pi @radius @radius))
10
+
11
+ (fn circumference []
12
+ (* 2 pi @radius))
13
+
14
+ (end)
15
+
16
+ (let [c (Circle.new 5)]
17
+ (print (c.area))
18
+ (print (c.circumference)))
@@ -0,0 +1,14 @@
1
+ (local KELVIN-OFFSET 273.15)
2
+ (local FAHRENHEIT-SCALE 1.8)
3
+ (local FAHRENHEIT-OFFSET 32.0)
4
+
5
+ (fn convert-temperature [celsius]
6
+ (let [k (+ celsius KELVIN-OFFSET)
7
+ f (+ (* celsius FAHRENHEIT-SCALE) FAHRENHEIT-OFFSET)]
8
+ [k f]))
9
+
10
+ (let [[k f] (convert-temperature 36.5)]
11
+ (print k f))
12
+
13
+ (let [[k f] (convert-temperature 122.11)]
14
+ (print k f))
@@ -0,0 +1,13 @@
1
+ (fn count-by-kind [effects]
2
+ (var quits 0)
3
+ (var moves 0)
4
+ (each [_ effect (ipairs effects)]
5
+ (case (. effect :kind)
6
+ :quit (set quits (+ quits 1))
7
+ :move (set moves (+ moves 1))
8
+ _ nil))
9
+ [quits moves])
10
+
11
+ (let [effects [{:kind :move} {:kind :quit} {:kind :move} {:kind :other}]
12
+ [q m] (count-by-kind effects)]
13
+ (print q m))
data/examples/counter.kap CHANGED
@@ -12,6 +12,8 @@
12
12
  (fn self.zero []
13
13
  (Counter.new 0))
14
14
 
15
+ (end)
16
+
15
17
  (let [c (Counter.new 10)]
16
18
  (c.tick)
17
19
  (c.tick)
@@ -0,0 +1,12 @@
1
+ (fn step [drops]
2
+ (each [_ drop (ipairs drops)]
3
+ (let [falling {:kind (. drop :kind)
4
+ :x (. drop :x)
5
+ :y (+ (. drop :y) (. drop :speed))
6
+ :w (. drop :w)
7
+ :h (. drop :h)
8
+ :speed (. drop :speed)}]
9
+ (print (. falling :kind) (. falling :x) (. falling :y)))))
10
+
11
+ (step [{:kind "rain" :x 0 :y 0 :w 1 :h 1 :speed 2}
12
+ {:kind "snow" :x 5 :y 1 :w 1 :h 1 :speed 1}])
@@ -0,0 +1,40 @@
1
+ ackermann
2
+ anonymous-greeter
3
+ classify-wallet
4
+ climbing-stairs
5
+ convert-temperature
6
+ count-effects
7
+ describe
8
+ destructure
9
+ even-squares
10
+ factorial
11
+ falling-drops
12
+ fib
13
+ fizzbuzz
14
+ gcd
15
+ hashfn
16
+ leap-year
17
+ macros-dbg
18
+ macros-import-helpers
19
+ macros-import-whole
20
+ macros-import
21
+ macros-multi
22
+ macros-swap
23
+ macros-thrice-if
24
+ macros-unless
25
+ macros-when-let
26
+ match
27
+ max-achievable
28
+ min-max
29
+ or-patterns
30
+ power-of-three
31
+ packet-router
32
+ points
33
+ primes
34
+ safe-lookup
35
+ shapes
36
+ squares
37
+ sum
38
+ thread-styles
39
+ tic-tac-toe
40
+ underscore-patterns
@@ -9,6 +9,8 @@
9
9
  (set $last-hitter @name)
10
10
  @@total)
11
11
 
12
+ (end)
13
+
12
14
  (let [a (HitCounter.new "alice")
13
15
  b (HitCounter.new "bob")]
14
16
  (print (a.hit))
@@ -0,0 +1,8 @@
1
+ (local steps 2)
2
+
3
+ (fn max-achievable [num t]
4
+ (+ num (* steps t)))
5
+
6
+ (print (max-achievable 4 1))
7
+ (print (max-achievable 3 2))
8
+ (print (max-achievable 0 5))
@@ -1,7 +1,9 @@
1
1
  ; File header forms map directly to Ruby modules.
2
2
  (module HeaderDemo)
3
3
 
4
- (fn self.greet [name]
4
+ (defn greet [name]
5
5
  (.. "Hello, " name "!"))
6
6
 
7
- (print (self.greet "Ada"))
7
+ (end)
8
+
9
+ (print (HeaderDemo.greet "Ada"))
@@ -0,0 +1,92 @@
1
+ account-lockout
2
+ accumulator
3
+ ackermann
4
+ anagram
5
+ anonymous-greeter
6
+ bank-account
7
+ baseball-game
8
+ best-time-to-buy-sell-stock
9
+ binary-search
10
+ binary-to-decimal
11
+ block-sort
12
+ bst-iterator
13
+ calc
14
+ circle
15
+ classify-wallet
16
+ climbing-stairs
17
+ contains-duplicate
18
+ convert-temperature
19
+ count-effects
20
+ counter
21
+ describe
22
+ destructure
23
+ doto-hygiene
24
+ doto
25
+ egg-count
26
+ even-squares
27
+ exceptions
28
+ factorial
29
+ falling-drops
30
+ fib
31
+ fizzbuzz
32
+ gcd
33
+ greet
34
+ happy-number
35
+ hashfn
36
+ hit-counter
37
+ kwargs
38
+ leap-year
39
+ length-of-last-word
40
+ macros-dbg
41
+ macros-import-helpers
42
+ macros-import-whole
43
+ macros-import
44
+ macros-multi
45
+ macros-swap
46
+ macros-thrice-if
47
+ macros-unless
48
+ macros-when-let
49
+ majority-element
50
+ manhattan-distance
51
+ match
52
+ max-achievable
53
+ maximum-subarray
54
+ min-max
55
+ module-header
56
+ move-zeroes
57
+ number-of-1-bits
58
+ number-of-steps
59
+ or-patterns
60
+ packet-router
61
+ parking-system
62
+ pipeline
63
+ pivot-index
64
+ plus-one
65
+ points
66
+ power-of-three
67
+ primes
68
+ raindrops
69
+ recent-counter
70
+ record
71
+ reverse-integer
72
+ roman-to-integer
73
+ ruby-eval
74
+ safe-lookup
75
+ scopes
76
+ shapes
77
+ signal-harvest
78
+ single-number
79
+ squares
80
+ stack
81
+ subtract-product-sum
82
+ sum
83
+ thread-styles
84
+ threading
85
+ tic-tac-toe
86
+ tset
87
+ two-sum-hash
88
+ two-sum
89
+ ugly-number
90
+ underscore-patterns
91
+ valid-parentheses-1
92
+ zoo-animal-1
@@ -0,0 +1,13 @@
1
+ (local BIT-WIDTH 32)
2
+
3
+ (fn hamming-weight [n]
4
+ (var x n)
5
+ (var count 0)
6
+ (for [_ 1 BIT-WIDTH]
7
+ (set count (+ count (% x 2)))
8
+ (set x (: (/ x 2) :floor)))
9
+ count)
10
+
11
+ (print (hamming-weight 11))
12
+ (print (hamming-weight 128))
13
+ (print (hamming-weight 4294967293))
@@ -0,0 +1,15 @@
1
+ (local target 0)
2
+
3
+ (fn steps-to-zero [n]
4
+ (var x n)
5
+ (var steps 0)
6
+ (while (not= x target)
7
+ (if (= 0 (% x 2))
8
+ (set x (: (/ x 2) :floor))
9
+ (set x (- x 1)))
10
+ (set steps (+ steps 1)))
11
+ steps)
12
+
13
+ (print (steps-to-zero 14))
14
+ (print (steps-to-zero 8))
15
+ (print (steps-to-zero 123))
@@ -11,6 +11,8 @@
11
11
  (and (= car-type 3) (> @small 0)) (do (set @small (- @small 1)) true)
12
12
  false))
13
13
 
14
+ (end)
15
+
14
16
  (let [parking (ParkingSystem.new 1 1 0)]
15
17
  (print (parking.add-car 1))
16
18
  (print (parking.add-car 2))
@@ -0,0 +1,17 @@
1
+ (class RecentCounter)
2
+ (fn initialize [] (set @pings []))
3
+ (fn ping [t]
4
+ (let [pings @pings]
5
+ (pings.push t)
6
+ (while (< (. pings 0) (- t 3000))
7
+ (pings.shift))
8
+ (length pings)))
9
+ (defn warm [history]
10
+ (let [c (RecentCounter.new)]
11
+ (each [_ t (ipairs history)] (c.ping t))
12
+ c))
13
+ (end)
14
+
15
+ (let [c (RecentCounter.warm [100 200 300])]
16
+ (print (c.ping 3001))
17
+ (print (c.ping 3002)))
data/examples/scopes.kap CHANGED
@@ -10,6 +10,8 @@
10
10
  (fn self.total []
11
11
  (cvar total))
12
12
 
13
+ (end)
14
+
13
15
  (let [a (ScopeCounter.new)
14
16
  b (ScopeCounter.new)]
15
17
  (print (a.add! 5))
@@ -0,0 +1,16 @@
1
+ (module SignalHarvest)
2
+
3
+ (local SCREEN-W 1280)
4
+ (local TARGET-SCORE 36)
5
+
6
+ (defn cell-width [columns]
7
+ (/ SCREEN-W columns))
8
+
9
+ (defn win? [score]
10
+ (>= score TARGET-SCORE))
11
+
12
+ (end)
13
+
14
+ (print (SignalHarvest.cell-width 32))
15
+ (print (SignalHarvest.win? 40))
16
+ (print (SignalHarvest.win? 12))
data/examples/stack.kap CHANGED
@@ -24,6 +24,8 @@
24
24
  (fn get-min []
25
25
  (. (ivar mins) -1))
26
26
 
27
+ (end)
28
+
27
29
  (let [s (MinStack.new)]
28
30
  (s.push -2)
29
31
  (s.push 0)
@@ -1,17 +1,14 @@
1
- (let [
2
- two-sum-hash
3
- (fn [nums target seen]
4
- (var i 0)
5
- (var answer nil)
6
- (while (and (< i (length nums)) (= answer nil))
7
- (let [n (. nums i)
8
- complement (- target n)]
9
- (if (seen.key? complement)
10
- (set answer [(. seen complement) i])
11
- (tset seen n i)))
12
- (set i (+ i 1)))
13
- answer)
14
- ]
1
+ (let [two-sum-hash (fn [nums target seen]
2
+ (var i 0)
3
+ (var answer nil)
4
+ (while (and (< i (length nums)) (= answer nil))
5
+ (let [n (. nums i)
6
+ complement (- target n)]
7
+ (if (seen.key? complement)
8
+ (set answer [(. seen complement) i])
9
+ (tset seen n i)))
10
+ (set i (+ i 1)))
11
+ answer)]
15
12
  (print (two-sum-hash [2 7 11 15] 9 {}))
16
13
  (print (two-sum-hash [3 2 4] 6 {}))
17
14
  (print (two-sum-hash [1 2 3] 10 {})))
@@ -1,7 +1,7 @@
1
1
  (fn loose [v]
2
2
  (case v
3
3
  _x _x
4
- _ "fallback"))
4
+ _ "not-reachable"))
5
5
 
6
6
  (fn strict [v]
7
7
  (case v
@@ -17,3 +17,5 @@
17
17
  (stack.push ch)))
18
18
  (set i (+ i 1)))
19
19
  (and ok (stack.empty?))))
20
+
21
+ (end)