sweet-moon 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|