sweet-moon 0.0.2 → 0.0.5
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/.rubocop.yml +3 -0
- data/README.md +197 -16
- data/components/injections/injections_503.rb +2 -1
- data/components/injections/injections_514.rb +2 -1
- data/components/injections/injections_542.rb +2 -1
- data/components/interpreters/50/function.rb +14 -47
- data/components/interpreters/50/interpreter.rb +50 -28
- data/components/interpreters/50/reader.rb +2 -60
- data/components/interpreters/50/table.rb +19 -54
- data/components/interpreters/50/writer.rb +2 -40
- data/components/interpreters/51/function.rb +3 -46
- data/components/interpreters/51/interpreter.rb +37 -26
- data/components/interpreters/51/reader.rb +2 -60
- data/components/interpreters/51/table.rb +2 -55
- data/components/interpreters/51/writer.rb +2 -40
- data/components/interpreters/54/function.rb +82 -23
- data/components/interpreters/54/interpreter.rb +35 -22
- data/components/interpreters/54/reader.rb +20 -17
- data/components/interpreters/54/table.rb +25 -19
- data/components/interpreters/54/writer.rb +11 -11
- data/config/tests.sample.yml +13 -9
- data/controllers/state.rb +47 -12
- data/dsl/errors.rb +9 -1
- data/dsl/fennel.rb +2 -0
- data/dsl/state.rb +9 -3
- data/logic/interpreters/interpreter_50.rb +1 -0
- data/logic/interpreters/interpreter_54.rb +5 -5
- data/logic/spec.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e216a8bf96c191f08675bad6b2d4d9a1dceb9649a5e856ce4d6b4894e09b35e
|
4
|
+
data.tar.gz: b807eb9b92df1e53a0e0011f6132724c95b11a76dafab1073a46d2c5bf35c6ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 538a7a773c11fe66a13c0be49efeb1f8d37da83f52a85d32fe8a7c52b3b590d155b0cdfb50efec3755181947db6a7b67a238b31c10bc382362b70301594949fb
|
7
|
+
data.tar.gz: 95d84ea3cf24919e4646c766f66302308f22392434ba5f76b0ae7743d4ef9ad3868d90b13b3d4bf26d58d7500d276b88be7ee26393818cf00950f08f4e6c4fc6
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -21,15 +21,18 @@ _Sweet Moon_ is a resilient solution that makes working with [Lua](https://www.l
|
|
21
21
|
- [Tables, Arrays, and Hashes](#tables-arrays-and-hashes)
|
22
22
|
- [Functions](#functions)
|
23
23
|
- [Other Types](#other-types)
|
24
|
+
- [Lua Global vs Local Variables](#lua-global-vs-local-variables)
|
24
25
|
- [_destroy_ and _clear_](#destroy-and-clear)
|
25
26
|
- [Modules, Packages and LuaRocks](#modules-packages-and-luarocks)
|
26
27
|
- [Integration with LuaRocks](#integration-with-luarocks)
|
27
28
|
- [Fennel](#fennel)
|
28
29
|
- [Fennel Usage](#fennel-usage)
|
30
|
+
- [Fennel Global vs Local Variables](#fennel-global-vs-local-variables)
|
29
31
|
- [Fennel Setup](#fennel-setup)
|
30
32
|
- [Integration with fnx](#integration-with-fnx)
|
31
33
|
- [Global vs Isolated](#global-vs-isolated)
|
32
34
|
- [Error Handling](#error-handling)
|
35
|
+
- [Ruby feat. Lua Errors](#ruby-feat-lua-errors)
|
33
36
|
- [Where can I find .so files?](#where-can-i-find-so-files)
|
34
37
|
- [Low-Level C API](#low-level-c-api)
|
35
38
|
- [The API](#the-api)
|
@@ -69,7 +72,7 @@ gem install sweet-moon
|
|
69
72
|
> **Disclaimer:** It's an early-stage project, and you should expect breaking changes.
|
70
73
|
|
71
74
|
```ruby
|
72
|
-
gem 'sweet-moon', '~> 0.0.
|
75
|
+
gem 'sweet-moon', '~> 0.0.5'
|
73
76
|
```
|
74
77
|
|
75
78
|
```ruby
|
@@ -209,6 +212,7 @@ Compared to: [rufus-lua](https://github.com/jmettraux/rufus-lua), [YAML](https:/
|
|
209
212
|
- [Tables, Arrays, and Hashes](#tables-arrays-and-hashes)
|
210
213
|
- [Functions](#functions)
|
211
214
|
- [Other Types](#other-types)
|
215
|
+
- [Lua Global vs Local Variables](#lua-global-vs-local-variables)
|
212
216
|
- [_destroy_ and _clear_](#destroy-and-clear)
|
213
217
|
|
214
218
|
### Setup
|
@@ -389,6 +393,20 @@ state.eval('lua_value = {a = "text", b = 1.5, c = true}') # => nil
|
|
389
393
|
state.get(:lua_value, :b) # => 1.5
|
390
394
|
```
|
391
395
|
|
396
|
+
With `set`, you can use a second parameter to set a field:
|
397
|
+
|
398
|
+
```ruby
|
399
|
+
require 'sweet-moon'
|
400
|
+
|
401
|
+
state = SweetMoon::State.new
|
402
|
+
|
403
|
+
state.set(:myTable, {}) # => nil
|
404
|
+
|
405
|
+
state.set(:myTable, :a, 3) # => nil
|
406
|
+
|
407
|
+
state.eval('return myTable["a"]') # => 3
|
408
|
+
```
|
409
|
+
|
392
410
|
Caveats:
|
393
411
|
|
394
412
|
- Ruby `Symbol` (e.g. `:value`) is converted to Lua `string`.
|
@@ -512,6 +530,24 @@ fennel_eval = state.get(:fennel_eval)
|
|
512
530
|
fennel_eval.(['(+ 1 1)']) # => 2
|
513
531
|
```
|
514
532
|
|
533
|
+
#### Lua Global vs Local Variables
|
534
|
+
|
535
|
+
You can't exchange _local_ variables, only [_global_](https://www.lua.org/pil/1.2.html) ones:
|
536
|
+
|
537
|
+
```ruby
|
538
|
+
require 'sweet-moon'
|
539
|
+
|
540
|
+
state = SweetMoon::State.new
|
541
|
+
|
542
|
+
state.eval('lua_value = "Lua Text"') # => nil
|
543
|
+
|
544
|
+
state.get('lua_value') # => 'Lua Text'
|
545
|
+
|
546
|
+
state.eval('local lua_b = "b"') # => nil
|
547
|
+
|
548
|
+
state.get('lua_b') # => nil
|
549
|
+
```
|
550
|
+
|
515
551
|
## _destroy_ and _clear_
|
516
552
|
|
517
553
|
You can destroy a state:
|
@@ -577,21 +613,21 @@ state.add_package_path('/home/me/my-lua-modules/?/init.lua')
|
|
577
613
|
|
578
614
|
state.add_package_cpath('/home/me/my-lua-modules/?.so')
|
579
615
|
|
580
|
-
state.add_package_path('/home/me/fennel
|
616
|
+
state.add_package_path('/home/me/fennel/?.lua')
|
581
617
|
|
582
|
-
state.add_package_cpath('/home/me
|
618
|
+
state.add_package_cpath('/home/me/?.so')
|
583
619
|
|
584
620
|
state.package_path
|
585
621
|
# => ['./?.lua',
|
586
622
|
# './?/init.lua',
|
587
623
|
# '/home/me/my-lua-modules/?.lua',
|
588
624
|
# '/home/me/my-lua-modules/?/init.lua',
|
589
|
-
# '/home/me/fennel
|
625
|
+
# '/home/me/fennel/?.lua']
|
590
626
|
|
591
627
|
state.package_cpath
|
592
628
|
# => ['./?.so',
|
593
629
|
# '/home/me/my-lua-modules/?.so',
|
594
|
-
# '/home/me
|
630
|
+
# '/home/me/?.so']
|
595
631
|
```
|
596
632
|
|
597
633
|
Requiring a module:
|
@@ -611,8 +647,8 @@ You can set packages in State constructors:
|
|
611
647
|
require 'sweet-moon'
|
612
648
|
|
613
649
|
SweetMoon::State.new(
|
614
|
-
package_path: '/folder/lib
|
615
|
-
package_cpath: '/lib/lib
|
650
|
+
package_path: '/folder/lib/?.lua',
|
651
|
+
package_cpath: '/lib/lib/?.so',
|
616
652
|
)
|
617
653
|
```
|
618
654
|
|
@@ -622,8 +658,8 @@ Also, you can add packages through the global config:
|
|
622
658
|
require 'sweet-moon'
|
623
659
|
|
624
660
|
SweetMoon.global.config(
|
625
|
-
package_path: '/folder/lib
|
626
|
-
package_cpath: '/lib/lib
|
661
|
+
package_path: '/folder/lib/?.lua',
|
662
|
+
package_cpath: '/lib/lib/?.so',
|
627
663
|
)
|
628
664
|
```
|
629
665
|
|
@@ -714,8 +750,8 @@ state = SweetMoon::State.new
|
|
714
750
|
|
715
751
|
state.fennel.eval('(+ 1 2)') # => 3
|
716
752
|
|
717
|
-
state.fennel.eval('(
|
718
|
-
state.fennel.eval('(mySum 2 3)') # => 5
|
753
|
+
state.fennel.eval('(set _G.mySum (fn [a b] (+ a b)))')
|
754
|
+
state.fennel.eval('(_G.mySum 2 3)') # => 5
|
719
755
|
|
720
756
|
mySum = state.fennel.get(:mySum)
|
721
757
|
|
@@ -725,7 +761,7 @@ sum_list = -> (list) { list.sum }
|
|
725
761
|
|
726
762
|
state.set('sumList', sum_list) # => nil
|
727
763
|
|
728
|
-
state.fennel.eval('(sumList [2 3 5])') # => 10
|
764
|
+
state.fennel.eval('(_G.sumList [2 3 5])') # => 10
|
729
765
|
|
730
766
|
state.fennel.load('file.fnl')
|
731
767
|
```
|
@@ -740,6 +776,49 @@ state = SweetMoon::State.new.fennel
|
|
740
776
|
state.eval('(+ 1 2)') # => 3
|
741
777
|
```
|
742
778
|
|
779
|
+
### Fennel Global vs Local Variables
|
780
|
+
|
781
|
+
Fennel encourages you to explicitly use the [_`_G`_](https://www.lua.org/manual/5.4/manual.html#pdf-_G) table to access global variables:
|
782
|
+
|
783
|
+
```ruby
|
784
|
+
require 'sweet-moon'
|
785
|
+
|
786
|
+
fennel = SweetMoon::State.new.fennel
|
787
|
+
|
788
|
+
fennel.eval('(set _G.a? 2)')
|
789
|
+
|
790
|
+
fennel.get('a?') # => 2
|
791
|
+
fennel.get('_G', 'a?') # => 2
|
792
|
+
|
793
|
+
fennel.set('b', 3)
|
794
|
+
|
795
|
+
fennel.eval('(print _G.b)') # => 3
|
796
|
+
```
|
797
|
+
|
798
|
+
Although older versions have the expression `(global name "value")`, it's deprecated, and you should avoid using that. _Sweet Moon_ has no commitments in supporting this deprecated expression, and you should prefer the `_G` way.
|
799
|
+
|
800
|
+
As is [true for Lua](#lua-global-vs-local-variables), you can't exchange _local_ variables, only [_global_](https://www.lua.org/pil/1.2.html) ones:
|
801
|
+
|
802
|
+
```ruby
|
803
|
+
require 'sweet-moon'
|
804
|
+
|
805
|
+
fennel = SweetMoon::State.new.fennel
|
806
|
+
|
807
|
+
fennel.eval('(local name "value")')
|
808
|
+
|
809
|
+
fennel.get('name') # => nil
|
810
|
+
|
811
|
+
fennel.eval('(set _G.name "value")')
|
812
|
+
|
813
|
+
fennel.get('name') # => "value"
|
814
|
+
|
815
|
+
fennel.set('var-b', 35) # => nil
|
816
|
+
|
817
|
+
fennel.eval('var-b') # => nil
|
818
|
+
|
819
|
+
fennel.eval('_G.var-b') # => 35
|
820
|
+
```
|
821
|
+
|
743
822
|
### Fennel Setup
|
744
823
|
|
745
824
|
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.
|
@@ -753,7 +832,7 @@ require 'sweet-moon'
|
|
753
832
|
|
754
833
|
state = SweetMoon::State.new
|
755
834
|
|
756
|
-
state.add_package_path('/folder/fennel
|
835
|
+
state.add_package_path('/folder/fennel/?.lua')
|
757
836
|
|
758
837
|
state.fennel.eval('(+ 1 1)') # => 2
|
759
838
|
```
|
@@ -763,7 +842,7 @@ With the constructor:
|
|
763
842
|
```ruby
|
764
843
|
require 'sweet-moon'
|
765
844
|
|
766
|
-
fennel = SweetMoon::State.new(package_path: '/folder/fennel
|
845
|
+
fennel = SweetMoon::State.new(package_path: '/folder/fennel/?.lua').fennel
|
767
846
|
|
768
847
|
fennel.eval('(+ 1 1)') # => 2
|
769
848
|
```
|
@@ -773,7 +852,7 @@ With global:
|
|
773
852
|
```ruby
|
774
853
|
require 'sweet-moon'
|
775
854
|
|
776
|
-
SweetMoon.global.state.add_package_path('/folder/fennel
|
855
|
+
SweetMoon.global.state.add_package_path('/folder/fennel/?.lua')
|
777
856
|
|
778
857
|
SweetMoon.global.state.fennel.eval('(+ 1 1)') # => 2
|
779
858
|
```
|
@@ -783,7 +862,7 @@ Alternatively:
|
|
783
862
|
```ruby
|
784
863
|
require 'sweet-moon'
|
785
864
|
|
786
|
-
SweetMoon.global.config(package_path: '/folder/fennel
|
865
|
+
SweetMoon.global.config(package_path: '/folder/fennel/?.lua')
|
787
866
|
|
788
867
|
SweetMoon.global.state.fennel.eval('(+ 1 1)') # => 2
|
789
868
|
```
|
@@ -929,6 +1008,108 @@ rescue LuaRuntimeError => error
|
|
929
1008
|
end
|
930
1009
|
```
|
931
1010
|
|
1011
|
+
### Ruby feat. Lua Errors
|
1012
|
+
|
1013
|
+
Lua errors can be rescued inside Ruby:
|
1014
|
+
|
1015
|
+
```lua
|
1016
|
+
-- source.lua
|
1017
|
+
error('error from lua')
|
1018
|
+
```
|
1019
|
+
|
1020
|
+
```ruby
|
1021
|
+
require 'sweet-moon'
|
1022
|
+
require 'sweet-moon/errors'
|
1023
|
+
|
1024
|
+
state = SweetMoon::State.new
|
1025
|
+
|
1026
|
+
begin
|
1027
|
+
state.load('source.lua')
|
1028
|
+
rescue LuaRuntimeError => e
|
1029
|
+
puts e.message
|
1030
|
+
# => source.lua:2: error from lua
|
1031
|
+
end
|
1032
|
+
```
|
1033
|
+
|
1034
|
+
Ruby errors can be handled inside Lua:
|
1035
|
+
|
1036
|
+
```ruby
|
1037
|
+
require 'sweet-moon'
|
1038
|
+
|
1039
|
+
state = SweetMoon::State.new
|
1040
|
+
|
1041
|
+
state.set(:rubyFn, -> { raise 'error from ruby' })
|
1042
|
+
|
1043
|
+
state.load('source.lua')
|
1044
|
+
```
|
1045
|
+
|
1046
|
+
```lua
|
1047
|
+
-- source.lua
|
1048
|
+
local status, err = pcall(rubyFn)
|
1049
|
+
|
1050
|
+
print(status) -- => false
|
1051
|
+
|
1052
|
+
print(err)
|
1053
|
+
-- [string " return function (...)..."]:5: RuntimeError: error from ruby stack traceback:
|
1054
|
+
-- [string " return function (...)..."]:5: in function 'rubyFn'
|
1055
|
+
-- [C]: in function 'pcall'
|
1056
|
+
-- source.lua:2: in main chunk
|
1057
|
+
```
|
1058
|
+
|
1059
|
+
Ruby errors not handled inside Lua can be rescued inside Ruby again, with an additional Lua backtrace:
|
1060
|
+
|
1061
|
+
```lua
|
1062
|
+
-- source.lua
|
1063
|
+
a = 1
|
1064
|
+
|
1065
|
+
rubyFn()
|
1066
|
+
```
|
1067
|
+
|
1068
|
+
```ruby
|
1069
|
+
require 'sweet-moon'
|
1070
|
+
|
1071
|
+
state = SweetMoon::State.new
|
1072
|
+
|
1073
|
+
state.set(:rubyFn, -> { raise 'error from ruby' })
|
1074
|
+
|
1075
|
+
begin
|
1076
|
+
state.load('source.lua')
|
1077
|
+
rescue RuntimeError => e
|
1078
|
+
puts e.message # => error from ruby
|
1079
|
+
|
1080
|
+
puts e.backtrace.last
|
1081
|
+
# => source.lua:4: in main chunk
|
1082
|
+
end
|
1083
|
+
```
|
1084
|
+
|
1085
|
+
Lua errors inside Lua functions can be rescued inside Ruby:
|
1086
|
+
|
1087
|
+
```lua
|
1088
|
+
-- source.lua
|
1089
|
+
function luaFn()
|
1090
|
+
error('lua function error')
|
1091
|
+
end
|
1092
|
+
```
|
1093
|
+
|
1094
|
+
```ruby
|
1095
|
+
require 'sweet-moon'
|
1096
|
+
require 'sweet-moon/errors'
|
1097
|
+
|
1098
|
+
state = SweetMoon::State.new
|
1099
|
+
|
1100
|
+
state.load('source.lua')
|
1101
|
+
|
1102
|
+
lua_fn = state.get(:luaFn)
|
1103
|
+
|
1104
|
+
begin
|
1105
|
+
lua_fn.()
|
1106
|
+
rescue LuaRuntimeError => e
|
1107
|
+
puts e.message # => "source.lua:3: lua function error"
|
1108
|
+
end
|
1109
|
+
```
|
1110
|
+
|
1111
|
+
For Fennel, all the examples above are equally true, with additional stack traceback as well.
|
1112
|
+
|
932
1113
|
## Where can I find .so files?
|
933
1114
|
|
934
1115
|
Due to the Lua's popularity, you likely have it already on your system, and _Sweet Moon_ will be able to find the files by itself.
|
@@ -6,7 +6,8 @@ module Component
|
|
6
6
|
ffi: [:cfunction, [:pointer], :int],
|
7
7
|
overwrite: {
|
8
8
|
lua_pushcclosure: [%i[pointer cfunction int], :void],
|
9
|
-
lua_tocfunction: [%i[pointer int], :cfunction]
|
9
|
+
lua_tocfunction: [%i[pointer int], :cfunction],
|
10
|
+
lua_atpanic: [%i[pointer cfunction], :cfunction]
|
10
11
|
}
|
11
12
|
}
|
12
13
|
],
|
@@ -6,7 +6,8 @@ module Component
|
|
6
6
|
ffi: [:cfunction, [:pointer], :int],
|
7
7
|
overwrite: {
|
8
8
|
lua_pushcclosure: [%i[pointer cfunction int], :void],
|
9
|
-
lua_tocfunction: [%i[pointer int], :cfunction]
|
9
|
+
lua_tocfunction: [%i[pointer int], :cfunction],
|
10
|
+
lua_atpanic: [%i[pointer cfunction], :cfunction]
|
10
11
|
}
|
11
12
|
}
|
12
13
|
],
|
@@ -6,7 +6,8 @@ module Component
|
|
6
6
|
ffi: [:cfunction, [:pointer], :int],
|
7
7
|
overwrite: {
|
8
8
|
lua_pushcclosure: [%i[pointer cfunction int], :void],
|
9
|
-
lua_tocfunction: [%i[pointer int], :cfunction]
|
9
|
+
lua_tocfunction: [%i[pointer int], :cfunction],
|
10
|
+
lua_atpanic: [%i[pointer cfunction], :cfunction]
|
10
11
|
}
|
11
12
|
}
|
12
13
|
],
|
@@ -1,52 +1,19 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '../../../dsl/errors'
|
3
|
-
|
4
|
-
require_relative 'writer'
|
5
|
-
require_relative 'reader'
|
1
|
+
require_relative '../54/function'
|
6
2
|
|
7
3
|
module Component
|
8
4
|
module V50
|
9
|
-
Function =
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
reference = api.luaL_ref(
|
23
|
-
state, Logic::V50::Interpreter[:LUA_REGISTRYINDEX]
|
24
|
-
)
|
25
|
-
|
26
|
-
{ value: ->(input = [], output = 1) {
|
27
|
-
api.lua_rawgeti(
|
28
|
-
state, Logic::V50::Interpreter[:LUA_REGISTRYINDEX], reference
|
29
|
-
)
|
30
|
-
|
31
|
-
input.each do |value|
|
32
|
-
Writer[:push!].(api, state, value)
|
33
|
-
end
|
34
|
-
|
35
|
-
result = Interpreter[:call!].(api, state, input.size, output)
|
36
|
-
|
37
|
-
if result[:error]
|
38
|
-
raise SweetMoon::Errors::SweetMoonErrorHelper.for(
|
39
|
-
result[:error][:status]
|
40
|
-
), result[:error][:value]
|
41
|
-
end
|
42
|
-
|
43
|
-
result = Reader[:read_all!].(api, state)
|
44
|
-
|
45
|
-
return result.first if output == 1
|
46
|
-
|
47
|
-
result
|
48
|
-
}, pop: false }
|
49
|
-
}
|
50
|
-
}
|
5
|
+
Function = Component::V54::Function
|
6
|
+
|
7
|
+
LUA_HANDLER = <<LUA
|
8
|
+
return function (...)
|
9
|
+
result = _ruby(unpack(arg))
|
10
|
+
|
11
|
+
if result['error'] then
|
12
|
+
error(result['output'])
|
13
|
+
else
|
14
|
+
return result['output']
|
15
|
+
end
|
16
|
+
end
|
17
|
+
LUA
|
51
18
|
end
|
52
19
|
end
|
@@ -1,91 +1,113 @@
|
|
1
1
|
require_relative '../../../logic/interpreters/interpreter_50'
|
2
2
|
|
3
|
+
require_relative 'function'
|
3
4
|
require_relative 'reader'
|
4
|
-
require_relative 'writer'
|
5
5
|
require_relative 'table'
|
6
|
+
require_relative 'writer'
|
6
7
|
|
7
8
|
module Component
|
8
9
|
module V50
|
9
10
|
Interpreter = {
|
10
11
|
version: Logic::V50::Interpreter[:version],
|
12
|
+
logic: Logic::V50,
|
11
13
|
|
12
14
|
create_state!: ->(api) {
|
13
15
|
state = api.lua_open
|
14
|
-
{ state:
|
16
|
+
{ state: { lua: state, avoid_gc: [], ruby_error_info: nil },
|
17
|
+
error: state ? nil : :MemoryAllocation }
|
15
18
|
},
|
16
19
|
|
17
20
|
open_standard_libraries!: ->(api, state) {
|
18
|
-
api.luaopen_base(state)
|
19
|
-
api.luaopen_table(state)
|
20
|
-
api.luaopen_io(state)
|
21
|
-
api.luaopen_string(state)
|
22
|
-
api.luaopen_math(state)
|
21
|
+
api.luaopen_base(state[:lua])
|
22
|
+
api.luaopen_table(state[:lua])
|
23
|
+
api.luaopen_io(state[:lua])
|
24
|
+
api.luaopen_string(state[:lua])
|
25
|
+
api.luaopen_math(state[:lua])
|
23
26
|
|
24
|
-
api.lua_settop(state, -7 - 1)
|
27
|
+
api.lua_settop(state[:lua], -7 - 1)
|
25
28
|
|
26
29
|
{ state: state }
|
27
30
|
},
|
28
31
|
|
29
32
|
load_file_and_push_chunck!: ->(api, state, path) {
|
30
|
-
result = api.luaL_loadfile(state, path)
|
33
|
+
result = api.luaL_loadfile(state[:lua], path)
|
31
34
|
{ state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
|
32
35
|
},
|
33
36
|
|
34
37
|
push_chunk!: ->(api, state, value) {
|
35
|
-
result = api.luaL_loadbuffer(state, value, value.size, value)
|
38
|
+
result = api.luaL_loadbuffer(state[:lua], value, value.size, value)
|
36
39
|
|
37
40
|
{ state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
|
38
41
|
},
|
39
42
|
|
40
|
-
set_table!: ->(api, state
|
41
|
-
|
43
|
+
set_table!: ->(api, state) {
|
44
|
+
result = api.lua_settable(state[:lua], -3)
|
45
|
+
|
46
|
+
api.lua_settop(state[:lua], -2)
|
47
|
+
|
48
|
+
{ state: state,
|
49
|
+
error: Interpreter[:_error].(api, state, result, pull: false) }
|
42
50
|
},
|
43
51
|
|
44
52
|
push_value!: ->(api, state, value) {
|
45
|
-
Writer[:push!].(api, state, value)
|
53
|
+
Writer[:push!].(api, state, Component::V50, value)
|
46
54
|
{ state: state }
|
47
55
|
},
|
48
56
|
|
49
57
|
pop_and_set_as!: ->(api, state, variable) {
|
50
|
-
api.lua_pushstring(state, variable)
|
51
|
-
api.lua_insert(state, -2)
|
52
|
-
api.lua_settable(state, Logic::V50::Interpreter[:LUA_GLOBALSINDEX])
|
58
|
+
api.lua_pushstring(state[:lua], variable)
|
59
|
+
api.lua_insert(state[:lua], -2)
|
60
|
+
api.lua_settable(state[:lua], Logic::V50::Interpreter[:LUA_GLOBALSINDEX])
|
53
61
|
{ state: state }
|
54
62
|
},
|
55
63
|
|
56
64
|
get_variable_and_push!: ->(api, state, variable, key = nil) {
|
57
|
-
|
58
|
-
|
65
|
+
extra_pop = true
|
66
|
+
if variable == '_G'
|
67
|
+
variable = key
|
68
|
+
key = nil
|
69
|
+
extra_pop = false
|
70
|
+
end
|
59
71
|
|
60
|
-
|
72
|
+
api.lua_pushstring(state[:lua], variable.to_s)
|
73
|
+
api.lua_gettable(state[:lua], Logic::V50::Interpreter[:LUA_GLOBALSINDEX])
|
61
74
|
|
62
|
-
|
75
|
+
unless key.nil?
|
76
|
+
Table[:read_field_and_push!].(api, state, Component::V50, key,
|
77
|
+
-1)
|
78
|
+
end
|
79
|
+
|
80
|
+
{ state: state, extra_pop: extra_pop }
|
63
81
|
},
|
64
82
|
|
65
83
|
call!: ->(api, state, inputs = 0, outputs = 1) {
|
66
|
-
result = api.lua_pcall(state, inputs, outputs, 0)
|
84
|
+
result = api.lua_pcall(state[:lua], inputs, outputs, 0)
|
67
85
|
{ state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
|
68
86
|
},
|
69
87
|
|
70
88
|
read_and_pop!: ->(api, state, stack_index = -1, extra_pop: false) {
|
71
|
-
result = Component::V50::Reader[:read!].(api, state,
|
89
|
+
result = Component::V50::Reader[:read!].(api, state, Component::V50,
|
90
|
+
stack_index)
|
72
91
|
|
73
|
-
api.lua_settop(state, -2) if result[:pop]
|
74
|
-
api.lua_settop(state, -2) if extra_pop
|
92
|
+
api.lua_settop(state[:lua], -2) if result[:pop]
|
93
|
+
api.lua_settop(state[:lua], -2) if extra_pop
|
75
94
|
|
76
95
|
{ state: state, output: result[:value] }
|
77
96
|
},
|
78
97
|
|
79
98
|
read_all!: ->(api, state) {
|
80
|
-
result = Reader[:read_all!].(api, state)
|
99
|
+
result = Reader[:read_all!].(api, state, Component::V50)
|
81
100
|
|
82
101
|
{ state: state, output: result }
|
83
102
|
},
|
84
103
|
|
85
104
|
destroy_state!: ->(api, state) {
|
86
|
-
result = api.lua_close(state)
|
105
|
+
result = api.lua_close(state[:lua])
|
106
|
+
|
107
|
+
state.delete(:lua)
|
108
|
+
state.delete(:avoid_gc)
|
87
109
|
|
88
|
-
{ state: nil, error: Interpreter[:_error].(api,
|
110
|
+
{ state: nil, error: Interpreter[:_error].(api, nil, result) }
|
89
111
|
},
|
90
112
|
|
91
113
|
_error: ->(api, state, code, options = {}) {
|
@@ -94,7 +116,7 @@ module Component
|
|
94
116
|
] || :error
|
95
117
|
|
96
118
|
if code.is_a?(Numeric) && code >= 1
|
97
|
-
return { status: status } unless options[:pull]
|
119
|
+
return { status: status } unless options[:pull] && state
|
98
120
|
|
99
121
|
{ status: status,
|
100
122
|
value: Interpreter[:read_and_pop!].(api, state, -1)[:output] }
|
@@ -1,65 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative 'interpreter'
|
4
|
-
require_relative 'function'
|
5
|
-
require_relative 'table'
|
1
|
+
require_relative '../54/reader'
|
6
2
|
|
7
3
|
module Component
|
8
4
|
module V50
|
9
|
-
Reader =
|
10
|
-
read_all!: ->(api, state) {
|
11
|
-
(1..api.lua_gettop(state)).map do
|
12
|
-
Interpreter[:read_and_pop!].(api, state)[:output]
|
13
|
-
end.reverse
|
14
|
-
},
|
15
|
-
|
16
|
-
read!: ->(api, state, stack_index = -1) {
|
17
|
-
stack_index = api.lua_gettop(state) if stack_index == -1
|
18
|
-
|
19
|
-
type = api.lua_typename(state, api.lua_type(state, stack_index)).read_string
|
20
|
-
|
21
|
-
case type
|
22
|
-
when 'string'
|
23
|
-
Reader[:read_string!].(api, state, stack_index)
|
24
|
-
when 'number'
|
25
|
-
Reader[:read_number!].(api, state, stack_index)
|
26
|
-
when 'no value'
|
27
|
-
{ value: nil, pop: true, type: type }
|
28
|
-
when 'nil'
|
29
|
-
{ value: nil, pop: true }
|
30
|
-
when 'boolean'
|
31
|
-
Reader[:read_boolean!].(api, state, stack_index)
|
32
|
-
when 'table'
|
33
|
-
Table[:read!].(api, state, stack_index)
|
34
|
-
when 'function'
|
35
|
-
Function[:read!].(api, state, stack_index)
|
36
|
-
else
|
37
|
-
# none nil boolean lightuserdata number
|
38
|
-
# string table function userdata thread
|
39
|
-
{ value: "#{type}: 0x#{api.lua_topointer(state, stack_index).address}",
|
40
|
-
type: type, pop: true }
|
41
|
-
end
|
42
|
-
},
|
43
|
-
|
44
|
-
read_string!: ->(api, state, stack_index) {
|
45
|
-
{ value: api.lua_tostring(state, stack_index).read_string,
|
46
|
-
pop: true }
|
47
|
-
},
|
48
|
-
|
49
|
-
read_number!: ->(api, state, stack_index) {
|
50
|
-
if api.respond_to?(:lua_isinteger) &&
|
51
|
-
api.respond_to?(:lua_tointeger) &&
|
52
|
-
api.lua_isinteger(state, stack_index) == 1
|
53
|
-
|
54
|
-
return { value: api.lua_tointeger(state, stack_index), pop: true }
|
55
|
-
end
|
56
|
-
|
57
|
-
{ value: api.lua_tonumber(state, stack_index), pop: true }
|
58
|
-
},
|
59
|
-
|
60
|
-
read_boolean!: ->(api, state, stack_index) {
|
61
|
-
{ value: api.lua_toboolean(state, stack_index) == 1, pop: true }
|
62
|
-
}
|
63
|
-
}
|
5
|
+
Reader = Component::V54::Reader
|
64
6
|
end
|
65
7
|
end
|