kapusta 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/README.md +30 -4
- data/examples/best-time-to-buy-sell-stock.kap +12 -0
- data/examples/majority-element.kap +11 -0
- data/examples/plus-one.kap +14 -0
- data/examples/reverse-integer.kap +13 -0
- data/examples/roman-to-integer.kap +17 -0
- data/examples/zoo-animal-1.kap +5 -0
- data/examples/zoo-animal-inheritance-2.kap +8 -0
- data/lib/kapusta/compiler/emitter/control_flow.rb +11 -3
- data/lib/kapusta/version.rb +1 -1
- data/spec/examples_spec.rb +31 -2
- metadata +8 -2
- data/examples/inheritance.kap +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ee9b062de9860ef3b9f3cfcbac8503e69c1549f0f09af35b41e5eb13303c1ddb
|
|
4
|
+
data.tar.gz: daa87e0b3b65dfc82f21ff47e88b41652d05f087e46320ca1c3f49bac2457b71
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 564c441ea9395cd4f28daaa631de6022e39125eede47032bf32bbc2a45f18979b7376f264b5302459b78403ef039ef8aca93e6f469cc0666b033f6e6717894a2
|
|
7
|
+
data.tar.gz: 38479cb8d38b81df15697a56c1a14e63d4dda7a0dd793db4e121e06126395339d9c7676a4bb14411a6b43398b64196f877ce3126990eb07d24f2a0c769a577e2
|
data/README.md
CHANGED
|
@@ -41,6 +41,36 @@ account = BankAccount.new('Ada', 100)
|
|
|
41
41
|
|
|
42
42
|
See `examples/bank-account.kap` and `examples/use_bank_account.rb`.
|
|
43
43
|
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
See [`examples/`](https://github.com/evmorov/kapusta/tree/main/examples).
|
|
47
|
+
|
|
48
|
+
```fennel
|
|
49
|
+
(fn ack [m n]
|
|
50
|
+
(if (= m 0) (+ n 1)
|
|
51
|
+
(= n 0) (ack (- m 1) 1)
|
|
52
|
+
(ack (- m 1) (ack m (- n 1)))))
|
|
53
|
+
|
|
54
|
+
(print (ack 2 3))
|
|
55
|
+
(print (ack 3 3))
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Compiles to:
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
def ack(m, n)
|
|
62
|
+
if m == 0
|
|
63
|
+
n + 1
|
|
64
|
+
elsif n == 0
|
|
65
|
+
ack(m - 1, 1)
|
|
66
|
+
else
|
|
67
|
+
ack(m - 1, ack(m, n - 1))
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
p(ack(2, 3))
|
|
71
|
+
p(ack(3, 3))
|
|
72
|
+
```
|
|
73
|
+
|
|
44
74
|
## Comparison with Fennel
|
|
45
75
|
|
|
46
76
|
Kapusta keeps most core Fennel forms. The main differences come from Ruby's runtime and object model.
|
|
@@ -65,10 +95,6 @@ Kapusta-specific additions:
|
|
|
65
95
|
- a trailing symbol-keyed hash is emitted as Ruby keyword arguments
|
|
66
96
|
- a final function literal argument is emitted as a Ruby block
|
|
67
97
|
|
|
68
|
-
## Examples
|
|
69
|
-
|
|
70
|
-
See `examples/`.
|
|
71
|
-
|
|
72
98
|
## Formatting
|
|
73
99
|
|
|
74
100
|
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
(fn max-profit [prices]
|
|
2
|
+
(var min-price (. prices 0))
|
|
3
|
+
(var best 0)
|
|
4
|
+
(for [i 1 (- (length prices) 1)]
|
|
5
|
+
(let [p (. prices i)]
|
|
6
|
+
(when (< p min-price) (set min-price p))
|
|
7
|
+
(when (> (- p min-price) best) (set best (- p min-price)))))
|
|
8
|
+
best)
|
|
9
|
+
|
|
10
|
+
(print (max-profit [7 1 5 3 6 4]))
|
|
11
|
+
(print (max-profit [7 6 4 3 1]))
|
|
12
|
+
(print (max-profit [2 4 1]))
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
(fn majority [nums]
|
|
2
|
+
(var candidate nil)
|
|
3
|
+
(var count 0)
|
|
4
|
+
(each [n nums]
|
|
5
|
+
(when (= count 0) (set candidate n))
|
|
6
|
+
(if (= n candidate) (set count (+ count 1)) (set count (- count 1))))
|
|
7
|
+
candidate)
|
|
8
|
+
|
|
9
|
+
(print (majority [3 2 3]))
|
|
10
|
+
(print (majority [2 2 1 1 1 2 2]))
|
|
11
|
+
(print (majority [1]))
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
(fn plus-one [digits]
|
|
2
|
+
(var i (- (length digits) 1))
|
|
3
|
+
(var carry 1)
|
|
4
|
+
(while (and (>= i 0) (> carry 0))
|
|
5
|
+
(let [total (+ (. digits i) carry)]
|
|
6
|
+
(tset digits i (% total 10))
|
|
7
|
+
(set carry (: (/ total 10) :floor)))
|
|
8
|
+
(set i (- i 1)))
|
|
9
|
+
(if (> carry 0) (: digits :unshift carry) digits))
|
|
10
|
+
|
|
11
|
+
(print (plus-one [1 2 3]))
|
|
12
|
+
(print (plus-one [4 3 2 1]))
|
|
13
|
+
(print (plus-one [9]))
|
|
14
|
+
(print (plus-one [9 9]))
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
(fn reverse-integer [x]
|
|
2
|
+
(let [sign (if (< x 0) -1 1)]
|
|
3
|
+
(var remaining (* x sign))
|
|
4
|
+
(var result 0)
|
|
5
|
+
(while (> remaining 0)
|
|
6
|
+
(set result (+ (* result 10) (% remaining 10)))
|
|
7
|
+
(set remaining (: (/ remaining 10) :floor)))
|
|
8
|
+
(* result sign)))
|
|
9
|
+
|
|
10
|
+
(print (reverse-integer 123))
|
|
11
|
+
(print (reverse-integer -123))
|
|
12
|
+
(print (reverse-integer 120))
|
|
13
|
+
(print (reverse-integer 0))
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
(fn roman-to-integer [s]
|
|
2
|
+
(let [values {"I" 1 "V" 5 "X" 10 "L" 50 "C" 100 "D" 500 "M" 1000}
|
|
3
|
+
chars (s.chars)
|
|
4
|
+
n (length chars)]
|
|
5
|
+
(var total 0)
|
|
6
|
+
(var i 0)
|
|
7
|
+
(while (< i n)
|
|
8
|
+
(let [curr (. values (. chars i))
|
|
9
|
+
ahead (if (< (+ i 1) n) (. values (. chars (+ i 1))) 0)
|
|
10
|
+
subtract? (< curr ahead)]
|
|
11
|
+
(set total (+ total (if subtract? (- ahead curr) curr)))
|
|
12
|
+
(set i (+ i (if subtract? 2 1)))))
|
|
13
|
+
total))
|
|
14
|
+
|
|
15
|
+
(print (roman-to-integer "III"))
|
|
16
|
+
(print (roman-to-integer "LVIII"))
|
|
17
|
+
(print (roman-to-integer "MCMXCIV"))
|
|
@@ -15,7 +15,7 @@ module Kapusta
|
|
|
15
15
|
return emit_expr(args[0], env, current_scope) if args.length == 1
|
|
16
16
|
|
|
17
17
|
cond = emit_expr(args[0], env, current_scope)
|
|
18
|
-
truthy =
|
|
18
|
+
truthy = emit_if_branch(args[1], env, current_scope)
|
|
19
19
|
lines = ["if #{cond}", indent(truthy)]
|
|
20
20
|
append_else_lines(lines, args[2..], env, current_scope)
|
|
21
21
|
lines << 'end'
|
|
@@ -31,7 +31,7 @@ module Kapusta
|
|
|
31
31
|
append_elsif_lines(lines, args, env, current_scope)
|
|
32
32
|
else
|
|
33
33
|
lines << 'else'
|
|
34
|
-
lines << indent(
|
|
34
|
+
lines << indent(emit_if_branch(args[0], env, current_scope))
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -39,10 +39,18 @@ module Kapusta
|
|
|
39
39
|
return append_else_lines(lines, args, env, current_scope) if args.length < 2
|
|
40
40
|
|
|
41
41
|
lines << "elsif #{emit_expr(args[0], env, current_scope)}"
|
|
42
|
-
lines << indent(
|
|
42
|
+
lines << indent(emit_if_branch(args[1], env, current_scope))
|
|
43
43
|
append_else_lines(lines, args[2..], env, current_scope)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
def emit_if_branch(form, env, current_scope)
|
|
47
|
+
return emit_expr(form, env, current_scope) unless do_form?(form)
|
|
48
|
+
|
|
49
|
+
emit_sequence(form.rest, env, current_scope,
|
|
50
|
+
allow_method_definitions: false,
|
|
51
|
+
result: true).first
|
|
52
|
+
end
|
|
53
|
+
|
|
46
54
|
def if_form?(form)
|
|
47
55
|
form.is_a?(List) && form.head.is_a?(Sym) && form.head.name == 'if'
|
|
48
56
|
end
|
data/lib/kapusta/version.rb
CHANGED
data/spec/examples_spec.rb
CHANGED
|
@@ -239,8 +239,12 @@ RSpec.describe 'examples' do
|
|
|
239
239
|
expect(run_example('hashfn.kap')).to eq("5\n21\n")
|
|
240
240
|
end
|
|
241
241
|
|
|
242
|
-
it '
|
|
243
|
-
expect(run_example('
|
|
242
|
+
it 'zoo-animal-1.kap' do
|
|
243
|
+
expect(run_example('zoo-animal-1.kap')).to eq('')
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it 'zoo-animal-inheritance-2.kap' do
|
|
247
|
+
expect(run_example('zoo-animal-inheritance-2.kap')).to eq(<<~OUT)
|
|
244
248
|
true
|
|
245
249
|
"animalia"
|
|
246
250
|
"Poppy the dog"
|
|
@@ -455,4 +459,29 @@ RSpec.describe 'examples' do
|
|
|
455
459
|
"draw"
|
|
456
460
|
OUT
|
|
457
461
|
end
|
|
462
|
+
|
|
463
|
+
it 'reverse-integer.kap' do
|
|
464
|
+
expect(run_example('reverse-integer.kap')).to eq("321\n-321\n21\n0\n")
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it 'roman-to-integer.kap' do
|
|
468
|
+
expect(run_example('roman-to-integer.kap')).to eq("3\n58\n1994\n")
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
it 'best-time-to-buy-sell-stock.kap' do
|
|
472
|
+
expect(run_example('best-time-to-buy-sell-stock.kap')).to eq("5\n0\n2\n")
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
it 'majority-element.kap' do
|
|
476
|
+
expect(run_example('majority-element.kap')).to eq("3\n2\n1\n")
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
it 'plus-one.kap' do
|
|
480
|
+
expect(run_example('plus-one.kap')).to eq(<<~OUT)
|
|
481
|
+
[1, 2, 4]
|
|
482
|
+
[4, 3, 2, 2]
|
|
483
|
+
[1, 0]
|
|
484
|
+
[1, 0, 0]
|
|
485
|
+
OUT
|
|
486
|
+
end
|
|
458
487
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kapusta
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Evgenii Morozov
|
|
@@ -29,6 +29,7 @@ files:
|
|
|
29
29
|
- examples/anonymous-greeter.kap
|
|
30
30
|
- examples/bank-account.kap
|
|
31
31
|
- examples/baseball-game.kap
|
|
32
|
+
- examples/best-time-to-buy-sell-stock.kap
|
|
32
33
|
- examples/binary-search.kap
|
|
33
34
|
- examples/binary-to-decimal.kap
|
|
34
35
|
- examples/block-sort.kap
|
|
@@ -52,10 +53,10 @@ files:
|
|
|
52
53
|
- examples/greet.kap
|
|
53
54
|
- examples/happy-number.kap
|
|
54
55
|
- examples/hashfn.kap
|
|
55
|
-
- examples/inheritance.kap
|
|
56
56
|
- examples/kwargs.kap
|
|
57
57
|
- examples/leap-year.kap
|
|
58
58
|
- examples/length-of-last-word.kap
|
|
59
|
+
- examples/majority-element.kap
|
|
59
60
|
- examples/match.kap
|
|
60
61
|
- examples/maximum-subarray.kap
|
|
61
62
|
- examples/min-max.kap
|
|
@@ -67,11 +68,14 @@ files:
|
|
|
67
68
|
- examples/pangram.kap
|
|
68
69
|
- examples/pcall.kap
|
|
69
70
|
- examples/pipeline.kap
|
|
71
|
+
- examples/plus-one.kap
|
|
70
72
|
- examples/points.kap
|
|
71
73
|
- examples/primes.kap
|
|
72
74
|
- examples/raindrops.kap
|
|
73
75
|
- examples/record.kap
|
|
74
76
|
- examples/regex.kap
|
|
77
|
+
- examples/reverse-integer.kap
|
|
78
|
+
- examples/roman-to-integer.kap
|
|
75
79
|
- examples/ruby-eval.kap
|
|
76
80
|
- examples/safe-lookup.kap
|
|
77
81
|
- examples/scopes.kap
|
|
@@ -88,6 +92,8 @@ files:
|
|
|
88
92
|
- examples/use_bank_account.rb
|
|
89
93
|
- examples/valid-parentheses-1.kap
|
|
90
94
|
- examples/valid-parentheses-2.kap
|
|
95
|
+
- examples/zoo-animal-1.kap
|
|
96
|
+
- examples/zoo-animal-inheritance-2.kap
|
|
91
97
|
- exe/kapfmt
|
|
92
98
|
- exe/kapusta
|
|
93
99
|
- kapusta.gemspec
|
data/examples/inheritance.kap
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
(let [animal-class (class Zoo.Animal
|
|
2
|
-
(fn initialize [name] (set (ivar name) name))
|
|
3
|
-
(fn name [] (ivar name))
|
|
4
|
-
(fn kingdom [] "animalia")
|
|
5
|
-
(fn label [] (.. (self.name) " the animal")))
|
|
6
|
-
dog-class (class Zoo.Dog [Zoo.Animal]
|
|
7
|
-
(fn label [] (.. (self.name) " the dog"))
|
|
8
|
-
(fn bark [] "woof"))
|
|
9
|
-
dog (dog-class.new "Poppy")]
|
|
10
|
-
(print (= dog-class.superclass animal-class)
|
|
11
|
-
(dog.kingdom)
|
|
12
|
-
(dog.label)
|
|
13
|
-
(dog.bark)))
|