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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53512e4cdebbb07a50f1bff53338574994140e5b16ddc5c1fd05e27b8cbc8a20
4
- data.tar.gz: c7907d4901ecfb193c4df0c0b09bca2869babab65f6327d542c59a88a9edff51
3
+ metadata.gz: ee9b062de9860ef3b9f3cfcbac8503e69c1549f0f09af35b41e5eb13303c1ddb
4
+ data.tar.gz: daa87e0b3b65dfc82f21ff47e88b41652d05f087e46320ca1c3f49bac2457b71
5
5
  SHA512:
6
- metadata.gz: c185f6d33f64071522cef35498fb7310f47d4091d3873868361294ff40edb51e836cdb2c0168dac1f599bc9ccd7c230d34d276fa6ab1a3fca479a4a4c40b9025
7
- data.tar.gz: dcf0acd60680784bb38685305f5454466e4c36358d08a2994e2ca988e5fa19d32fa6eafdb48bb1054681e5699daaddc4b9ebf73477f0450d8dc78482cfad0147
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"))
@@ -0,0 +1,5 @@
1
+ (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")))
@@ -0,0 +1,8 @@
1
+ (require "./zoo-animal-1")
2
+
3
+ (class Zoo.Dog [Zoo.Animal]
4
+ (fn label [] (.. (self.name) " the dog"))
5
+ (fn bark [] "woof"))
6
+
7
+ (let [dog (Zoo.Dog.new "Poppy")]
8
+ (print (= Zoo.Dog.superclass Zoo.Animal) (dog.kingdom) (dog.label) (dog.bark)))
@@ -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 = emit_expr(args[1], env, current_scope)
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(emit_expr(args[0], env, current_scope))
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(emit_expr(args[1], env, current_scope))
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kapusta
4
- VERSION = '0.2.0'
4
+ VERSION = '0.2.1'
5
5
  end
@@ -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 'inheritance.kap' do
243
- expect(run_example('inheritance.kap')).to eq(<<~OUT)
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.0
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
@@ -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)))