sweet-moon 0.0.6 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46891cd3e8103176f3f909415432df155df1bd33cbed89a80f0042f5d303a2b7
4
- data.tar.gz: af7617e43eacc588135285dbd652f644d9bda8b87735c86ff89a7719ce6bfe1a
3
+ metadata.gz: 8379598305aeea20b37c0cb52a34a4ef4ff635ff6143cdda8aab84288f40a7f7
4
+ data.tar.gz: '092d9ec246616bc4e2fee6be1a851527cff3364c5576b9843bfc74d32de8cd31'
5
5
  SHA512:
6
- metadata.gz: 1949e5f83c00dd65cdf78e2e8ebd4f66654dc24df1769add99ad8f01e75cc97bcb090e9d0dc0cf5d10dcdd4d1d338252b4ad78894bd3d4cef40b91ae31aab3d0
7
- data.tar.gz: 9a09f1231c7e02250f232e368abd95b7bb1b4d5e366ef2614ce9871248c49201fb480b8b698833df66d769e7688602e8c3415a454366ef5ad3ede02163e1c5a4
6
+ metadata.gz: fe2d22239f861ddf25b645cf74bfe8a90f6481e00782c9f2170048e0bc92a91600517da2b62a9a609e70d7012ed1c2d20c427bdd717fce7ff06b7d31c02aba6c
7
+ data.tar.gz: a28579915ffb58a1f16ddd8ea60bf55c1e370ff818a1a16c698a2efe4780bd0497c628d4cc49d3befd7b9a8ab098a344692bbe5218211a505c890d747bc67436
data/.rubocop.yml CHANGED
@@ -1,7 +1,10 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.5.0
2
+ TargetRubyVersion: 3.1.0
3
3
  NewCops: enable
4
4
 
5
+ require:
6
+ - rubocop-rspec
7
+
5
8
  Style/Documentation:
6
9
  Enabled: false
7
10
 
@@ -19,7 +22,7 @@ Metrics/ModuleLength:
19
22
  Enabled: false
20
23
 
21
24
  Metrics/BlockLength:
22
- IgnoredMethods: ['describe', 'context', 'it']
25
+ AllowedMethods: ['describe', 'context', 'it']
23
26
 
24
27
  Style/DocumentDynamicEvalDefinition:
25
28
  Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.0
data/Gemfile CHANGED
@@ -1,12 +1,12 @@
1
- ruby '2.5.0'
1
+ ruby '3.1.0'
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- gem 'ffi', '~> 1.15', '>= 1.15.5'
5
+ gemspec
6
6
 
7
7
  group :test, :development do
8
- gem 'pry', '~> 0.14.1'
9
- gem 'rspec', '~> 3.11'
10
- gem 'rubocop', '~> 1.26'
11
- gem 'rubocop-rspec', '~> 2.9'
8
+ gem 'pry', '~> 0.14.2'
9
+ gem 'rspec', '~> 3.13'
10
+ gem 'rubocop', '~> 1.64', '>= 1.64.1'
11
+ gem 'rubocop-rspec', '~> 3.0', '>= 3.0.1'
12
12
  end
data/Gemfile.lock CHANGED
@@ -1,61 +1,75 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sweet-moon (1.0.0)
5
+ ffi (~> 1.17)
6
+
1
7
  GEM
2
8
  remote: https://rubygems.org/
3
9
  specs:
4
10
  ast (2.4.2)
5
11
  coderay (1.1.3)
6
- diff-lcs (1.5.0)
7
- ffi (1.15.5)
8
- method_source (1.0.0)
9
- parallel (1.21.0)
10
- parser (3.1.1.0)
12
+ diff-lcs (1.5.1)
13
+ ffi (1.17.0)
14
+ json (2.7.2)
15
+ language_server-protocol (3.17.0.3)
16
+ method_source (1.1.0)
17
+ parallel (1.25.1)
18
+ parser (3.3.3.0)
11
19
  ast (~> 2.4.1)
12
- pry (0.14.1)
20
+ racc
21
+ pry (0.14.2)
13
22
  coderay (~> 1.1)
14
23
  method_source (~> 1.0)
24
+ racc (1.8.0)
15
25
  rainbow (3.1.1)
16
- regexp_parser (2.2.1)
17
- rexml (3.2.5)
18
- rspec (3.11.0)
19
- rspec-core (~> 3.11.0)
20
- rspec-expectations (~> 3.11.0)
21
- rspec-mocks (~> 3.11.0)
22
- rspec-core (3.11.0)
23
- rspec-support (~> 3.11.0)
24
- rspec-expectations (3.11.0)
26
+ regexp_parser (2.9.2)
27
+ rexml (3.3.0)
28
+ strscan
29
+ rspec (3.13.0)
30
+ rspec-core (~> 3.13.0)
31
+ rspec-expectations (~> 3.13.0)
32
+ rspec-mocks (~> 3.13.0)
33
+ rspec-core (3.13.0)
34
+ rspec-support (~> 3.13.0)
35
+ rspec-expectations (3.13.1)
25
36
  diff-lcs (>= 1.2.0, < 2.0)
26
- rspec-support (~> 3.11.0)
27
- rspec-mocks (3.11.0)
37
+ rspec-support (~> 3.13.0)
38
+ rspec-mocks (3.13.1)
28
39
  diff-lcs (>= 1.2.0, < 2.0)
29
- rspec-support (~> 3.11.0)
30
- rspec-support (3.11.0)
31
- rubocop (1.26.0)
40
+ rspec-support (~> 3.13.0)
41
+ rspec-support (3.13.1)
42
+ rubocop (1.64.1)
43
+ json (~> 2.3)
44
+ language_server-protocol (>= 3.17.0)
32
45
  parallel (~> 1.10)
33
- parser (>= 3.1.0.0)
46
+ parser (>= 3.3.0.2)
34
47
  rainbow (>= 2.2.2, < 4.0)
35
48
  regexp_parser (>= 1.8, < 3.0)
36
- rexml
37
- rubocop-ast (>= 1.16.0, < 2.0)
49
+ rexml (>= 3.2.5, < 4.0)
50
+ rubocop-ast (>= 1.31.1, < 2.0)
38
51
  ruby-progressbar (~> 1.7)
39
- unicode-display_width (>= 1.4.0, < 3.0)
40
- rubocop-ast (1.16.0)
41
- parser (>= 3.1.1.0)
42
- rubocop-rspec (2.9.0)
43
- rubocop (~> 1.19)
44
- ruby-progressbar (1.11.0)
45
- unicode-display_width (2.1.0)
52
+ unicode-display_width (>= 2.4.0, < 3.0)
53
+ rubocop-ast (1.31.3)
54
+ parser (>= 3.3.1.0)
55
+ rubocop-rspec (3.0.1)
56
+ rubocop (~> 1.61)
57
+ ruby-progressbar (1.13.0)
58
+ strscan (3.1.0)
59
+ unicode-display_width (2.5.0)
46
60
 
47
61
  PLATFORMS
48
62
  x86_64-linux
49
63
 
50
64
  DEPENDENCIES
51
- ffi (~> 1.15, >= 1.15.5)
52
- pry (~> 0.14.1)
53
- rspec (~> 3.11)
54
- rubocop (~> 1.26)
55
- rubocop-rspec (~> 2.9)
65
+ pry (~> 0.14.2)
66
+ rspec (~> 3.13)
67
+ rubocop (~> 1.64, >= 1.64.1)
68
+ rubocop-rspec (~> 3.0, >= 3.0.1)
69
+ sweet-moon!
56
70
 
57
71
  RUBY VERSION
58
- ruby 2.5.0p0
72
+ ruby 3.1.0p0
59
73
 
60
74
  BUNDLED WITH
61
75
  2.3.9
data/README.md CHANGED
@@ -28,6 +28,7 @@ _Sweet Moon_ is a resilient solution that makes working with [Lua](https://www.l
28
28
  - [Fennel](#fennel)
29
29
  - [Fennel Usage](#fennel-usage)
30
30
  - [Fennel Global vs Local Variables](#fennel-global-vs-local-variables)
31
+ - [allowedGlobals and options](#allowedglobals-and-options)
31
32
  - [Fennel Setup](#fennel-setup)
32
33
  - [Integration with fnx](#integration-with-fnx)
33
34
  - [Fennel REPL](#fennel-repl)
@@ -47,6 +48,7 @@ _Sweet Moon_ is a resilient solution that makes working with [Lua](https://www.l
47
48
  - [Development](#development)
48
49
  - [Tests Setup](#tests-setup)
49
50
  - [Running](#running)
51
+ - [Publish to RubyGems](#publish-to-rubygems)
50
52
  - [Supporting New Versions](#supporting-new-versions)
51
53
 
52
54
  ## Supported Versions
@@ -74,7 +76,7 @@ gem install sweet-moon
74
76
  > **Disclaimer:** It's an early-stage project, and you should expect breaking changes.
75
77
 
76
78
  ```ruby
77
- gem 'sweet-moon', '~> 0.0.6'
79
+ gem 'sweet-moon', '~> 1.0.0'
78
80
  ```
79
81
 
80
82
  ```ruby
@@ -445,6 +447,16 @@ second = state.get(:second)
445
447
  second.([%w[a b c]]) # => 'b'
446
448
  ```
447
449
 
450
+ Alternatively, you can send the `outputs` parameter:
451
+
452
+ ```ruby
453
+ require 'sweet-moon'
454
+
455
+ state = SweetMoon::State.new
456
+
457
+ state.eval('return "a", "b"', { outputs: 2 }) # => ['a', 'b']
458
+ ```
459
+
448
460
  You can call Ruby _Lambdas_ from _Lua_ as well:
449
461
 
450
462
  ```ruby
@@ -821,6 +833,71 @@ fennel.eval('var-b') # => nil
821
833
  fennel.eval('_G.var-b') # => 35
822
834
  ```
823
835
 
836
+ ### allowedGlobals and options
837
+
838
+ As Lua, Fennel functions may return [multiple results](https://www.lua.org/pil/5.1.html), so `eval` and `load` accept a second parameter to indicate the expected number of outputs:
839
+
840
+ ```fnl
841
+ ; source.fnl
842
+
843
+ (fn multi [] (values "c" "d"))
844
+
845
+ (multi)
846
+ ```
847
+
848
+ ```ruby
849
+ require 'sweet-moon'
850
+
851
+ fennel = SweetMoon::State.new.fennel
852
+
853
+ fennel.eval('(values "a" "b")', 2) # => ['a', 'b']
854
+ fennel.load('source.fnl', 2) # => ['c', 'd']
855
+ ```
856
+
857
+ The Fennel API offers [some options](https://fennel-lang.org/api) that `eval` and `load` accept as a third parameter:
858
+
859
+ ```ruby
860
+ require 'sweet-moon'
861
+
862
+ fennel = SweetMoon::State.new.fennel
863
+
864
+ fennel.eval('(print (+ 2 3))', 1, { allowedGlobals: ['print'] }) # => 5
865
+
866
+ fennel.eval('(print (+ 2 3))', 1, { allowedGlobals: [] })
867
+ # Compile error in unknown:1 (SweetMoon::Errors::LuaRuntimeError)
868
+ # unknown identifier in strict mode: print
869
+
870
+ # (print (+ 2 3))
871
+ # ^^^^^
872
+ # * Try looking to see if there's a typo.
873
+ # * Try using the _G table instead, eg. _G.print if you really want a global.
874
+ # * Try moving this code to somewhere that print is in scope.
875
+ # * Try binding print as a local in the scope of this code.
876
+ ```
877
+
878
+ Alternatively, you can use the second parameter for options as well:
879
+
880
+ ```ruby
881
+ require 'sweet-moon'
882
+
883
+ fennel = SweetMoon::State.new.fennel
884
+
885
+ fennel.eval('(print (+ 2 3))', { allowedGlobals: ['print'] }) # => 5
886
+ ```
887
+
888
+ You can also specify the expected outputs in the options parameter (it will be removed and not forwarded to Fennel):
889
+
890
+ ```ruby
891
+ require 'sweet-moon'
892
+
893
+ fennel = SweetMoon::State.new.fennel
894
+
895
+ fennel.eval(
896
+ '(values "a" "b")',
897
+ { allowedGlobals: ['values'], outputs: 2 }
898
+ ) # => ['a', 'b']
899
+ ```
900
+
824
901
  ### Fennel Setup
825
902
 
826
903
  To ensure that the Fennel module is available, you can set up the [_LuaRocks_](#integration-withluarocks) integration or manually add the `package_path` for the module.
@@ -1462,6 +1539,16 @@ bundle exec sweet-moon signatures /lua/lib/542 542.rb
1462
1539
  bundle exec ruby some/file.rb
1463
1540
  ```
1464
1541
 
1542
+ ### Publish to RubyGems
1543
+
1544
+ ```bash
1545
+ gem build sweet-moon.gemspec
1546
+
1547
+ gem signin
1548
+
1549
+ gem push sweet-moon-1.0.0.gem
1550
+ ```
1551
+
1465
1552
  ### Supporting New Versions
1466
1553
 
1467
1554
  Download both the source code and the libraries.
data/components/api.rb CHANGED
@@ -80,7 +80,7 @@ module Component
80
80
  }
81
81
  end
82
82
 
83
- { api: api, signatures: signatures }
83
+ { api:, signatures: }
84
84
  }
85
85
  }
86
86
  end
@@ -26,18 +26,18 @@ module Component
26
26
 
27
27
  api.lua_settop(state[:lua], -7 - 1)
28
28
 
29
- { state: state }
29
+ { state: }
30
30
  },
31
31
 
32
32
  load_file_and_push_chunck!: ->(api, state, path) {
33
33
  result = api.luaL_loadfile(state[:lua], path)
34
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
34
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
35
35
  },
36
36
 
37
37
  push_chunk!: ->(api, state, value) {
38
38
  result = api.luaL_loadbuffer(state[:lua], value, value.size, value)
39
39
 
40
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
40
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
41
41
  },
42
42
 
43
43
  set_table!: ->(api, state) {
@@ -45,20 +45,20 @@ module Component
45
45
 
46
46
  api.lua_settop(state[:lua], -2)
47
47
 
48
- { state: state,
48
+ { state:,
49
49
  error: Interpreter[:_error].(api, state, result, pull: false) }
50
50
  },
51
51
 
52
52
  push_value!: ->(api, state, value) {
53
53
  Writer[:push!].(api, state, Component::V50, value)
54
- { state: state }
54
+ { state: }
55
55
  },
56
56
 
57
57
  pop_and_set_as!: ->(api, state, variable) {
58
58
  api.lua_pushstring(state[:lua], variable)
59
59
  api.lua_insert(state[:lua], -2)
60
60
  api.lua_settable(state[:lua], Logic::V50::Interpreter[:LUA_GLOBALSINDEX])
61
- { state: state }
61
+ { state: }
62
62
  },
63
63
 
64
64
  get_variable_and_push!: ->(api, state, variable, key = nil) {
@@ -77,12 +77,12 @@ module Component
77
77
  -1)
78
78
  end
79
79
 
80
- { state: state, extra_pop: extra_pop }
80
+ { state:, extra_pop: }
81
81
  },
82
82
 
83
83
  call!: ->(api, state, inputs = 0, outputs = 1) {
84
84
  result = api.lua_pcall(state[:lua], inputs, outputs, 0)
85
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
85
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
86
86
  },
87
87
 
88
88
  read_and_pop!: ->(api, state, stack_index = -1, extra_pop: false) {
@@ -92,13 +92,13 @@ module Component
92
92
  api.lua_settop(state[:lua], -2) if result[:pop]
93
93
  api.lua_settop(state[:lua], -2) if extra_pop
94
94
 
95
- { state: state, output: result[:value] }
95
+ { state:, output: result[:value] }
96
96
  },
97
97
 
98
98
  read_all!: ->(api, state) {
99
99
  result = Reader[:read_all!].(api, state, Component::V50)
100
100
 
101
- { state: state, output: result }
101
+ { state:, output: result }
102
102
  },
103
103
 
104
104
  destroy_state!: ->(api, state) {
@@ -116,9 +116,9 @@ module Component
116
116
  ] || :error
117
117
 
118
118
  if code.is_a?(Numeric) && code >= 1
119
- return { status: status } unless options[:pull] && state
119
+ return { status: } unless options[:pull] && state
120
120
 
121
- { status: status,
121
+ { status:,
122
122
  value: Interpreter[:read_and_pop!].(api, state, -1)[:output] }
123
123
  end
124
124
  }
@@ -19,17 +19,17 @@ module Component
19
19
 
20
20
  open_standard_libraries!: ->(api, state) {
21
21
  api.luaL_openlibs(state[:lua])
22
- { state: state }
22
+ { state: }
23
23
  },
24
24
 
25
25
  load_file_and_push_chunck!: ->(api, state, path) {
26
26
  result = api.luaL_loadfile(state[:lua], path)
27
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
27
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
28
28
  },
29
29
 
30
30
  push_chunk!: ->(api, state, value) {
31
31
  result = api.luaL_loadstring(state[:lua], value)
32
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
32
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
33
33
  },
34
34
 
35
35
  set_table!: ->(api, state) {
@@ -37,20 +37,20 @@ module Component
37
37
 
38
38
  api.lua_settop(state[:lua], -2)
39
39
 
40
- { state: state,
40
+ { state:,
41
41
  error: Interpreter[:_error].(api, state, result, pull: false) }
42
42
  },
43
43
 
44
44
  push_value!: ->(api, state, value) {
45
45
  Writer[:push!].(api, state, Component::V51, value)
46
- { state: state }
46
+ { state: }
47
47
  },
48
48
 
49
49
  pop_and_set_as!: ->(api, state, variable) {
50
50
  api.lua_pushstring(state[:lua], variable)
51
51
  api.lua_insert(state[:lua], -2)
52
52
  api.lua_settable(state[:lua], Logic::V51::Interpreter[:LUA_GLOBALSINDEX])
53
- { state: state }
53
+ { state: }
54
54
  },
55
55
 
56
56
  get_variable_and_push!: ->(api, state, variable, key = nil) {
@@ -66,12 +66,12 @@ module Component
66
66
  end
67
67
  end
68
68
 
69
- { state: state, extra_pop: true }
69
+ { state:, extra_pop: true }
70
70
  },
71
71
 
72
72
  call!: ->(api, state, inputs = 0, outputs = 1) {
73
73
  result = api.lua_pcall(state[:lua], inputs, outputs, 0)
74
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
74
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
75
75
  },
76
76
 
77
77
  read_and_pop!: ->(api, state, stack_index = -1, extra_pop: false) {
@@ -80,13 +80,13 @@ module Component
80
80
  api.lua_settop(state[:lua], -2) if result[:pop]
81
81
  api.lua_settop(state[:lua], -2) if extra_pop
82
82
 
83
- { state: state, output: result[:value] }
83
+ { state:, output: result[:value] }
84
84
  },
85
85
 
86
86
  read_all!: ->(api, state) {
87
87
  result = Reader[:read_all!].(api, state, Component::V51)
88
88
 
89
- { state: state, output: result }
89
+ { state:, output: result }
90
90
  },
91
91
 
92
92
  destroy_state!: ->(api, state) {
@@ -104,9 +104,9 @@ module Component
104
104
  ] || :error
105
105
 
106
106
  if code.is_a?(Numeric) && code >= 2
107
- return { status: status } unless options[:pull] && state
107
+ return { status: } unless options[:pull] && state
108
108
 
109
- { status: status,
109
+ { status:,
110
110
  value: Interpreter[:read_and_pop!].(api, state, -1)[:output] }
111
111
  end
112
112
  }
@@ -50,7 +50,7 @@ module Component
50
50
  }
51
51
  )
52
52
  end
53
- return 1
53
+ 1
54
54
  }
55
55
  },
56
56
 
@@ -19,17 +19,17 @@ module Component
19
19
 
20
20
  open_standard_libraries!: ->(api, state) {
21
21
  api.luaL_openlibs(state[:lua])
22
- { state: state }
22
+ { state: }
23
23
  },
24
24
 
25
25
  load_file_and_push_chunck!: ->(api, state, path) {
26
26
  result = api.luaL_loadfile(state[:lua], path)
27
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
27
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
28
28
  },
29
29
 
30
30
  push_chunk!: ->(api, state, value) {
31
31
  result = api.luaL_loadstring(state[:lua], value)
32
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
32
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
33
33
  },
34
34
 
35
35
  set_table!: ->(api, state) {
@@ -37,18 +37,18 @@ module Component
37
37
 
38
38
  api.lua_settop(state[:lua], -2)
39
39
 
40
- { state: state,
40
+ { state:,
41
41
  error: Interpreter[:_error].(api, state, result, pull: false) }
42
42
  },
43
43
 
44
44
  push_value!: ->(api, state, value) {
45
45
  Writer[:push!].(api, state, Component::V54, value)
46
- { state: state }
46
+ { state: }
47
47
  },
48
48
 
49
49
  pop_and_set_as!: ->(api, state, variable) {
50
50
  api.lua_setglobal(state[:lua], variable)
51
- { state: state }
51
+ { state: }
52
52
  },
53
53
 
54
54
  get_variable_and_push!: ->(api, state, variable, key = nil) {
@@ -63,12 +63,12 @@ module Component
63
63
  end
64
64
  end
65
65
 
66
- { state: state, extra_pop: true }
66
+ { state:, extra_pop: true }
67
67
  },
68
68
 
69
69
  call!: ->(api, state, inputs = 0, outputs = 1) {
70
70
  result = api.lua_pcall(state[:lua], inputs, outputs, 0)
71
- { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
71
+ { state:, error: Interpreter[:_error].(api, state, result, pull: true) }
72
72
  },
73
73
 
74
74
  read_and_pop!: ->(api, state, stack_index = -1, extra_pop: false) {
@@ -78,13 +78,13 @@ module Component
78
78
  api.lua_settop(state[:lua], -2) if result[:pop]
79
79
  api.lua_settop(state[:lua], -2) if extra_pop
80
80
 
81
- { state: state, output: result[:value] }
81
+ { state:, output: result[:value] }
82
82
  },
83
83
 
84
84
  read_all!: ->(api, state) {
85
85
  result = Reader[:read_all!].(api, state, Component::V54)
86
86
 
87
- { state: state, output: result }
87
+ { state:, output: result }
88
88
  },
89
89
 
90
90
  destroy_state!: ->(api, state) {
@@ -102,9 +102,9 @@ module Component
102
102
  ] || :error
103
103
 
104
104
  if code.is_a?(Numeric) && code >= 2
105
- return { status: status } unless options[:pull] && state
105
+ return { status: } unless options[:pull] && state
106
106
 
107
- { status: status,
107
+ { status:,
108
108
  value: Interpreter[:read_and_pop!].(api, state, -1)[:output] }
109
109
  end
110
110
  }
@@ -26,7 +26,7 @@ module Component
26
26
  when 'number'
27
27
  component::Reader[:read_number!].(api, state, stack_index)
28
28
  when 'no value'
29
- { value: nil, pop: true, type: type }
29
+ { value: nil, pop: true, type: }
30
30
  when 'nil'
31
31
  { value: nil, pop: true }
32
32
  when 'boolean'
@@ -40,7 +40,7 @@ module Component
40
40
  # string table function userdata thread
41
41
  { value:
42
42
  "#{type}: 0x#{api.lua_topointer(state[:lua], stack_index).address}",
43
- type: type, pop: true }
43
+ type:, pop: true }
44
44
  end
45
45
  },
46
46
 
@@ -38,7 +38,8 @@ module Component
38
38
  return 'number' if value.is_a? Float
39
39
  return 'table' if value.is_a?(Hash) || value.is_a?(Array)
40
40
  return 'string' if value.is_a?(String) || value.instance_of?(Symbol)
41
- return 'boolean' if [true, false].include? value
41
+
42
+ 'boolean' if [true, false].include? value
42
43
  }
43
44
  }
44
45
  end
@@ -1,6 +1,6 @@
1
1
  # Available at https://github.com/gbaptista/sweet-moon-test
2
2
 
3
- fennel-dev: '/home/me/sweet-moon-test/fennel/dev/?.lua'
3
+ fennel-dev: '/home/gbaptista/Fennel/?.lua'
4
4
 
5
5
  luarocks:
6
6
  expected: ['dkjson', 'supernova', 'readline']
data/controllers/api.rb CHANGED
@@ -31,7 +31,7 @@ module Controller
31
31
  component = Component::API[:attach!].(api, api_reference, injections)
32
32
 
33
33
  component[:meta] = {
34
- options: options,
34
+ options:,
35
35
  elected: {
36
36
  shared_objects: shared_objects.map { |o| o[:path] },
37
37
  api_reference: api_reference[:version]
@@ -49,15 +49,15 @@ module Controller
49
49
  candidates = paths
50
50
 
51
51
  shared_objects = Component::IO[:reject_non_existent!].(paths).map do |path|
52
- { path: path }
52
+ { path: }
53
53
  end
54
54
  else
55
55
  bases = %w[/usr/lib /usr/lib/* /usr/local/lib /opt/local/lib]
56
56
 
57
57
  # XDG
58
- if ENV['HOME']
59
- bases << "#{ENV['HOME']}/.local/lib"
60
- bases << "#{ENV['HOME']}/.local/lib/*"
58
+ if Dir.home
59
+ bases << "#{Dir.home}/.local/lib"
60
+ bases << "#{Dir.home}/.local/lib/*"
61
61
  end
62
62
 
63
63
  bases.each do |base|
@@ -70,7 +70,7 @@ module Controller
70
70
  shared_objects = Logic::SharedObject[:choose].(candidates)
71
71
  end
72
72
 
73
- if shared_objects.size.zero?
73
+ if shared_objects.empty?
74
74
  raise SweetMoon::Errors::SweetMoonError,
75
75
  "Lua shared object (liblua.so) not found: #{candidates}"
76
76
  end
@@ -86,7 +86,7 @@ module Controller
86
86
  candidate[:version] == api_reference
87
87
  end
88
88
 
89
- if availabe_candidates.size.zero?
89
+ if availabe_candidates.empty?
90
90
  raise SweetMoon::Errors::SweetMoonError,
91
91
  "API Reference #{api_reference} not available."
92
92
  end
@@ -7,15 +7,15 @@ module Controller
7
7
  handle!: -> {
8
8
  Port::Out::Shell[:dispatch!].(
9
9
  "\n#{Logic::Spec[:command]} #{Logic::Spec[:version]}\n\n" \
10
- "usage:\n" \
11
- " #{Logic::Spec[:command]} version\n"\
12
- " #{Logic::Spec[:command]} signatures /lua/source [output.rb]\n"\
13
- " #{Logic::Spec[:command]} lua -i\n"\
14
- " #{Logic::Spec[:command]} lua file.lua [-o]\n"\
15
- " #{Logic::Spec[:command]} lua -e \"print(1 + 2);\" [-o]\n"\
16
- " #{Logic::Spec[:command]} fennel -i\n"\
17
- " #{Logic::Spec[:command]} fennel file.fnl [-o]\n"\
18
- " #{Logic::Spec[:command]} fennel -e \"(+ 1 2)\" [-o]"\
10
+ "usage:\n " \
11
+ "#{Logic::Spec[:command]} version\n " \
12
+ "#{Logic::Spec[:command]} signatures /lua/source [output.rb]\n " \
13
+ "#{Logic::Spec[:command]} lua -i\n " \
14
+ "#{Logic::Spec[:command]} lua file.lua [-o]\n " \
15
+ "#{Logic::Spec[:command]} lua -e \"print(1 + 2);\" [-o]\n " \
16
+ "#{Logic::Spec[:command]} fennel -i\n " \
17
+ "#{Logic::Spec[:command]} fennel file.fnl [-o]\n " \
18
+ "#{Logic::Spec[:command]} fennel -e \"(+ 1 2)\" [-o]" \
19
19
  "\n\n"
20
20
  )
21
21
  }
@@ -69,7 +69,7 @@ module Controller
69
69
 
70
70
  Port::Out::Shell[:dispatch!].("\n#{primitives.size} primitives:\n")
71
71
  Port::Out::Shell[:dispatch!].(
72
- YAML.dump(primitives).lines[1..-1].map { |line| " #{line}" }
72
+ YAML.dump(primitives).lines[1..].map { |line| " #{line}" }
73
73
  )
74
74
  },
75
75
 
@@ -126,7 +126,7 @@ module Controller
126
126
  missing << function unless attachables[function.to_sym]
127
127
  end
128
128
 
129
- { attachables: attachables, macros: macros, missing: missing }
129
+ { attachables:, macros:, missing: }
130
130
  },
131
131
 
132
132
  functions_from_shared_objects!: ->(path) {
@@ -20,7 +20,7 @@ module Controller
20
20
 
21
21
  build_meta!: ->(component, options) {
22
22
  component[:meta] = {
23
- options: options,
23
+ options:,
24
24
  elected: {
25
25
  interpreter: component[:interpreter][:version]
26
26
  },
@@ -62,7 +62,7 @@ module Controller
62
62
  result[:error]
63
63
  end
64
64
 
65
- return Component::Interpreters[result[:version]][:interpreter]
65
+ Component::Interpreters[result[:version]][:interpreter]
66
66
  }
67
67
  }
68
68
  end
data/dsl/fennel.rb CHANGED
@@ -20,12 +20,16 @@ module DSL
20
20
  build_meta
21
21
  end
22
22
 
23
- def eval(input, outputs = 1)
24
- @eval.([input], outputs)
23
+ def eval(input, first = nil, second = nil)
24
+ options = _build_options(first, second)
25
+
26
+ @eval.([input, options[:options]], options[:outputs])
25
27
  end
26
28
 
27
- def load(path, outputs = 1)
28
- @dofile.([path], outputs)
29
+ def load(path, first = nil, second = nil)
30
+ options = _build_options(first, second)
31
+
32
+ @dofile.([path, options[:options]], options[:outputs])
29
33
  end
30
34
 
31
35
  def build_meta
@@ -42,8 +46,8 @@ module DSL
42
46
  @state.respond_to? method_name
43
47
  end
44
48
 
45
- def method_missing(method_name, *arguments, &block)
46
- @state.public_send(method_name, *arguments, &block)
49
+ def method_missing(method_name, ...)
50
+ @state.public_send(method_name, ...)
47
51
  end
48
52
  end
49
53
  end
data/dsl/state.rb CHANGED
@@ -28,11 +28,19 @@ module DSL
28
28
  end
29
29
 
30
30
  def eval(input, outputs = 1)
31
- @controller[:eval!].(@api, @interpreter, state, input, outputs)[:output]
31
+ options = _build_options(outputs, nil)
32
+
33
+ @controller[:eval!].(
34
+ @api, @interpreter, state, input, options[:outputs]
35
+ )[:output]
32
36
  end
33
37
 
34
38
  def load(path, outputs = 1)
35
- @controller[:load!].(@api, @interpreter, state, path, outputs)[:output]
39
+ options = _build_options(outputs, nil)
40
+
41
+ @controller[:load!].(
42
+ @api, @interpreter, state, path, options[:outputs]
43
+ )[:output]
36
44
  end
37
45
 
38
46
  def get(variable, key = nil)
@@ -56,6 +64,22 @@ module DSL
56
64
  nil
57
65
  end
58
66
 
67
+ def _build_options(first, second)
68
+ options = { outputs: 1 }
69
+
70
+ options = options.merge(first) if first.is_a? Hash
71
+ options = options.merge(second) if second.is_a? Hash
72
+
73
+ options[:outputs] = first if first.is_a? Numeric
74
+ options[:outputs] = second if second.is_a? Numeric
75
+
76
+ outputs = options[:outputs] if options[:outputs]
77
+
78
+ options.delete(:outputs)
79
+
80
+ { options:, outputs: }
81
+ end
82
+
59
83
  def _ensure_min_version!(purpose, lua, jit = nil)
60
84
  version = lua
61
85
  version = jit if meta.interpreter[/jit/] && jit
@@ -98,7 +122,7 @@ module DSL
98
122
  {
99
123
  api_reference: api_component[:meta][:elected][:api_reference],
100
124
  shared_objects: api_component[:meta][:elected][:shared_objects],
101
- global_ffi: global_ffi
125
+ global_ffi:
102
126
  }
103
127
  end
104
128
 
@@ -113,8 +137,7 @@ module DSL
113
137
 
114
138
  def state
115
139
  unless @state
116
- raise SweetMoon::Errors::SweetMoonError,
117
- 'The state no longer exists.'
140
+ raise SweetMoon::Errors::SweetMoonError, 'The state no longer exists.'
118
141
  end
119
142
 
120
143
  @state
data/logic/interpreter.rb CHANGED
@@ -18,7 +18,7 @@ module Logic
18
18
  interpreter[:version].to_s == options[:interpreter]
19
19
  end
20
20
 
21
- if interpreters.size.zero?
21
+ if interpreters.empty?
22
22
  return {
23
23
  compatible: false,
24
24
  error: "Interpreter #{options[:interpreter]} not available."
@@ -1,4 +1,4 @@
1
- require_relative './io'
1
+ require_relative 'io'
2
2
 
3
3
  module Logic
4
4
  SharedObject = {
@@ -23,7 +23,9 @@ module Logic
23
23
  end
24
24
  end
25
25
 
26
- elected = candidates.max_by do |candidate|
26
+ elected = candidates.filter do |candidate|
27
+ candidate[:path] !~ /\+\+/ # Exclude C++ Shared Objects
28
+ end.max_by do |candidate|
27
29
  Gem::Version.new(candidate[:inferences][:version] || '0')
28
30
  end
29
31
 
@@ -45,7 +47,7 @@ module Logic
45
47
  Gem::Version.new(raw_inferred_version || '0')
46
48
  end
47
49
 
48
- { path: path,
50
+ { path:,
49
51
  inferences: { jit: !path[/jit/].nil?, version: inferred_version } }
50
52
  }
51
53
  }
data/logic/signature.rb CHANGED
@@ -66,7 +66,7 @@ module Logic
66
66
  primitive = parts[base_index].gsub(';', '')
67
67
  type = parts[base_index + 1].gsub(';', '')
68
68
 
69
- { type: type, primitive: primitive }
69
+ { type:, primitive: }
70
70
  },
71
71
 
72
72
  extract_types_from_header: ->(source, types = {}) {
@@ -104,7 +104,7 @@ module Logic
104
104
 
105
105
  buffer = 100
106
106
 
107
- while signature.scan(/\(/).size != signature.scan(/\)/).size &&
107
+ while signature.scan('(').size != signature.scan(')').size &&
108
108
  buffer.positive?
109
109
 
110
110
  signature = "#{signature} #{source.lines[current_index]}"
@@ -113,7 +113,7 @@ module Logic
113
113
  buffer -= 1
114
114
  end
115
115
 
116
- signature = signature.gsub(/\n/, ' ').gsub(/\s+/, ' ').strip
116
+ signature = signature.gsub("\n", ' ').gsub(/\s+/, ' ').strip
117
117
 
118
118
  signatures << signature
119
119
  end
@@ -226,8 +226,8 @@ module Logic
226
226
 
227
227
  parameter[:type] = parts.pop
228
228
 
229
- parameter[:name] = parameter[:name].sub(/\*/, '') if parameter[:name]
230
- parameter[:type] = parameter[:type].sub(/\*/, '') if parameter[:type]
229
+ parameter[:name] = parameter[:name].sub('*', '') if parameter[:name]
230
+ parameter[:type] = parameter[:type].sub('*', '') if parameter[:type]
231
231
 
232
232
  parameter[:primitive] = parameter[:type]
233
233
 
@@ -252,7 +252,7 @@ module Logic
252
252
 
253
253
  return nil if function_name.nil? || output[:type].nil?
254
254
 
255
- { name: function_name, output: output }
255
+ { name: function_name, output: }
256
256
  }
257
257
  }
258
258
  end
data/logic/spec.rb CHANGED
@@ -2,7 +2,7 @@ module Logic
2
2
  Spec = {
3
3
  name: 'sweet-moon',
4
4
  command: 'sweet-moon',
5
- version: '0.0.6',
5
+ version: '1.0.0',
6
6
  author: 'gbaptista',
7
7
  summary: 'Lua / Fennel from Ruby and vice versa. Support to LuaJIT, Lua 5.0, ' \
8
8
  'and 5.1. Lua C API for Lua 5, 4, and 3. LuaRocks and fnx integration.',
data/ports/in/shell.rb CHANGED
@@ -11,8 +11,8 @@ module Port
11
11
  when 'version' then Controller::CLI::Version[:handle!].()
12
12
  when 'signatures' then Controller::CLI::Signatures[:handle!].(ARGV[1],
13
13
  ARGV[2])
14
- when 'lua' then Controller::CLI::CLI[:handle!].(ARGV[1..-1])
15
- when 'fennel' then Controller::CLI::CLI[:handle!].(ARGV[1..-1], true)
14
+ when 'lua' then Controller::CLI::CLI[:handle!].(ARGV[1..])
15
+ when 'fennel' then Controller::CLI::CLI[:handle!].(ARGV[1..], true)
16
16
  else; Controller::CLI::Help[:handle!].()
17
17
  end
18
18
  }
data/sweet-moon.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
 
13
13
  spec.license = Logic::Spec[:license]
14
14
 
15
- spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.1.0')
16
16
 
17
17
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
18
 
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.bindir = 'ports/in/shell'
30
30
  spec.executables = %w[sweet-moon]
31
31
 
32
- spec.add_dependency 'ffi', '~> 1.15', '>= 1.15.5'
32
+ spec.add_dependency 'ffi', '~> 1.17'
33
33
 
34
34
  spec.metadata['rubygems_mfa_required'] = 'true'
35
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sweet-moon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - gbaptista
8
8
  autorequire:
9
9
  bindir: ports/in/shell
10
10
  cert_chain: []
11
- date: 2022-03-27 00:00:00.000000000 Z
11
+ date: 2024-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -16,20 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.15'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 1.15.5
19
+ version: '1.17'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '1.15'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 1.15.5
26
+ version: '1.17'
33
27
  description: |-
34
28
  A resilient solution that makes working with Lua / Fennel from Ruby and vice versa a delightful experience.
35
29
 
@@ -43,6 +37,7 @@ files:
43
37
  - ".gitignore"
44
38
  - ".rspec"
45
39
  - ".rubocop.yml"
40
+ - ".ruby-version"
46
41
  - Gemfile
47
42
  - Gemfile.lock
48
43
  - LICENSE
@@ -127,14 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
127
122
  requirements:
128
123
  - - ">="
129
124
  - !ruby/object:Gem::Version
130
- version: 2.5.0
125
+ version: 3.1.0
131
126
  required_rubygems_version: !ruby/object:Gem::Requirement
132
127
  requirements:
133
128
  - - ">="
134
129
  - !ruby/object:Gem::Version
135
130
  version: '0'
136
131
  requirements: []
137
- rubygems_version: 3.2.3
132
+ rubygems_version: 3.3.3
138
133
  signing_key:
139
134
  specification_version: 4
140
135
  summary: Lua / Fennel from Ruby and vice versa. Support to LuaJIT, Lua 5.0, and 5.1.