sweet-moon 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bc6ba34912c2d5c9e26b95b385e4a992b186b6adbe81e40e0e6068cc363a948
4
- data.tar.gz: 751f266193c94b533cf8f0b38f99745870688a2efd01e5277bb25d0aafe4b314
3
+ metadata.gz: 79d7b00c236a8ce4b85d6cb4230d7e4e9714b0e537199fa3445254c0577b5bfa
4
+ data.tar.gz: befd1ae3a4bcec8a274a256b5aab3c690cf876df1167531a896650b956e7dc58
5
5
  SHA512:
6
- metadata.gz: 1fac3cd35cc1afd5cf1918f98326237203f9e12c631ccde66946a6496d24d90e69cf06a43413b1f58527c486f81f50098d7d866547389936becac5b6ba8eda84
7
- data.tar.gz: e14b5c3eecbdeefa68747f4b2cf8377c0b99289783bfd5dd3eec5c295368bea65eca70be594f4272777cbd811ecdb6a3fef36ce73103349831072d44851a51bb
6
+ metadata.gz: 05ff924f37bab331deb03a55e21b968384fd7755cc38d8b4780b45ec5a14d21487df64df1dea2122c41ad4dedfb4e8013964e926a826537e713aa253b923be90
7
+ data.tar.gz: 8d1266390a693ef67f8bf5209eb5b2cf2b997bddb1e9f90ba5e2030fadd9ddf5819f2411099173b7a4528eafdcd09b7157675bcff77e3ca864fe600018085355
data/README.md CHANGED
@@ -69,7 +69,7 @@ gem install sweet-moon
69
69
  > **Disclaimer:** It's an early-stage project, and you should expect breaking changes.
70
70
 
71
71
  ```ruby
72
- gem 'sweet-moon', '~> 0.0.2'
72
+ gem 'sweet-moon', '~> 0.0.3'
73
73
  ```
74
74
 
75
75
  ```ruby
@@ -9,23 +9,26 @@ module Component
9
9
  Function = {
10
10
  push!: ->(api, state, closure) {
11
11
  handler = ->(current_state) {
12
- input = Reader[:read_all!].(api, current_state)
12
+ updated_state = state.merge(lua: current_state)
13
+ input = Reader[:read_all!].(api, updated_state)
13
14
  result = closure.(*input)
14
- Writer[:push!].(api, current_state, result)
15
+ Writer[:push!].(api, updated_state, result)
15
16
  return 1
16
17
  }
17
18
 
18
- api.lua_pushcclosure(state, handler, 0)
19
+ state[:avoid_gc] << handler
20
+
21
+ api.lua_pushcclosure(state[:lua], handler, 0)
19
22
  },
20
23
 
21
24
  read!: ->(api, state, _stack_index) {
22
25
  reference = api.luaL_ref(
23
- state, Logic::V50::Interpreter[:LUA_REGISTRYINDEX]
26
+ state[:lua], Logic::V50::Interpreter[:LUA_REGISTRYINDEX]
24
27
  )
25
28
 
26
29
  { value: ->(input = [], output = 1) {
27
30
  api.lua_rawgeti(
28
- state, Logic::V50::Interpreter[:LUA_REGISTRYINDEX], reference
31
+ state[:lua], Logic::V50::Interpreter[:LUA_REGISTRYINDEX], reference
29
32
  )
30
33
 
31
34
  input.each do |value|
@@ -11,28 +11,29 @@ module Component
11
11
 
12
12
  create_state!: ->(api) {
13
13
  state = api.lua_open
14
- { state: state, error: state ? nil : :MemoryAllocation }
14
+ { state: { lua: state, avoid_gc: [] },
15
+ error: state ? nil : :MemoryAllocation }
15
16
  },
16
17
 
17
18
  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)
19
+ api.luaopen_base(state[:lua])
20
+ api.luaopen_table(state[:lua])
21
+ api.luaopen_io(state[:lua])
22
+ api.luaopen_string(state[:lua])
23
+ api.luaopen_math(state[:lua])
23
24
 
24
- api.lua_settop(state, -7 - 1)
25
+ api.lua_settop(state[:lua], -7 - 1)
25
26
 
26
27
  { state: state }
27
28
  },
28
29
 
29
30
  load_file_and_push_chunck!: ->(api, state, path) {
30
- result = api.luaL_loadfile(state, path)
31
+ result = api.luaL_loadfile(state[:lua], path)
31
32
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
32
33
  },
33
34
 
34
35
  push_chunk!: ->(api, state, value) {
35
- result = api.luaL_loadbuffer(state, value, value.size, value)
36
+ result = api.luaL_loadbuffer(state[:lua], value, value.size, value)
36
37
 
37
38
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
38
39
  },
@@ -47,15 +48,15 @@ module Component
47
48
  },
48
49
 
49
50
  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])
51
+ api.lua_pushstring(state[:lua], variable)
52
+ api.lua_insert(state[:lua], -2)
53
+ api.lua_settable(state[:lua], Logic::V50::Interpreter[:LUA_GLOBALSINDEX])
53
54
  { state: state }
54
55
  },
55
56
 
56
57
  get_variable_and_push!: ->(api, state, variable, key = nil) {
57
- api.lua_pushstring(state, variable.to_s)
58
- api.lua_gettable(state, Logic::V50::Interpreter[:LUA_GLOBALSINDEX])
58
+ api.lua_pushstring(state[:lua], variable.to_s)
59
+ api.lua_gettable(state[:lua], Logic::V50::Interpreter[:LUA_GLOBALSINDEX])
59
60
 
60
61
  Table[:read_field_and_push!].(api, state, key, -1) unless key.nil?
61
62
 
@@ -63,15 +64,15 @@ module Component
63
64
  },
64
65
 
65
66
  call!: ->(api, state, inputs = 0, outputs = 1) {
66
- result = api.lua_pcall(state, inputs, outputs, 0)
67
+ result = api.lua_pcall(state[:lua], inputs, outputs, 0)
67
68
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
68
69
  },
69
70
 
70
71
  read_and_pop!: ->(api, state, stack_index = -1, extra_pop: false) {
71
72
  result = Component::V50::Reader[:read!].(api, state, stack_index)
72
73
 
73
- api.lua_settop(state, -2) if result[:pop]
74
- api.lua_settop(state, -2) if extra_pop
74
+ api.lua_settop(state[:lua], -2) if result[:pop]
75
+ api.lua_settop(state[:lua], -2) if extra_pop
75
76
 
76
77
  { state: state, output: result[:value] }
77
78
  },
@@ -83,9 +84,12 @@ module Component
83
84
  },
84
85
 
85
86
  destroy_state!: ->(api, state) {
86
- result = api.lua_close(state)
87
+ result = api.lua_close(state[:lua])
87
88
 
88
- { state: nil, error: Interpreter[:_error].(api, state, result) }
89
+ state.delete(:lua)
90
+ state.delete(:avoid_gc)
91
+
92
+ { state: nil, error: Interpreter[:_error].(api, nil, result) }
89
93
  },
90
94
 
91
95
  _error: ->(api, state, code, options = {}) {
@@ -94,7 +98,7 @@ module Component
94
98
  ] || :error
95
99
 
96
100
  if code.is_a?(Numeric) && code >= 1
97
- return { status: status } unless options[:pull]
101
+ return { status: status } unless options[:pull] && state
98
102
 
99
103
  { status: status,
100
104
  value: Interpreter[:read_and_pop!].(api, state, -1)[:output] }
@@ -8,15 +8,16 @@ module Component
8
8
  module V50
9
9
  Reader = {
10
10
  read_all!: ->(api, state) {
11
- (1..api.lua_gettop(state)).map do
11
+ (1..api.lua_gettop(state[:lua])).map do
12
12
  Interpreter[:read_and_pop!].(api, state)[:output]
13
13
  end.reverse
14
14
  },
15
15
 
16
16
  read!: ->(api, state, stack_index = -1) {
17
- stack_index = api.lua_gettop(state) if stack_index == -1
17
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
18
18
 
19
- type = api.lua_typename(state, api.lua_type(state, stack_index)).read_string
19
+ type = api.lua_typename(state[:lua],
20
+ api.lua_type(state[:lua], stack_index)).read_string
20
21
 
21
22
  case type
22
23
  when 'string'
@@ -36,29 +37,30 @@ module Component
36
37
  else
37
38
  # none nil boolean lightuserdata number
38
39
  # string table function userdata thread
39
- { value: "#{type}: 0x#{api.lua_topointer(state, stack_index).address}",
40
+ { value:
41
+ "#{type}: 0x#{api.lua_topointer(state[:lua], stack_index).address}",
40
42
  type: type, pop: true }
41
43
  end
42
44
  },
43
45
 
44
46
  read_string!: ->(api, state, stack_index) {
45
- { value: api.lua_tostring(state, stack_index).read_string,
47
+ { value: api.lua_tostring(state[:lua], stack_index).read_string,
46
48
  pop: true }
47
49
  },
48
50
 
49
51
  read_number!: ->(api, state, stack_index) {
50
52
  if api.respond_to?(:lua_isinteger) &&
51
53
  api.respond_to?(:lua_tointeger) &&
52
- api.lua_isinteger(state, stack_index) == 1
54
+ api.lua_isinteger(state[:lua], stack_index) == 1
53
55
 
54
- return { value: api.lua_tointeger(state, stack_index), pop: true }
56
+ return { value: api.lua_tointeger(state[:lua], stack_index), pop: true }
55
57
  end
56
58
 
57
- { value: api.lua_tonumber(state, stack_index), pop: true }
59
+ { value: api.lua_tonumber(state[:lua], stack_index), pop: true }
58
60
  },
59
61
 
60
62
  read_boolean!: ->(api, state, stack_index) {
61
- { value: api.lua_toboolean(state, stack_index) == 1, pop: true }
63
+ { value: api.lua_toboolean(state[:lua], stack_index) == 1, pop: true }
62
64
  }
63
65
  }
64
66
  end
@@ -7,40 +7,41 @@ module Component
7
7
  module V50
8
8
  Table = {
9
9
  push!: ->(api, state, list, stack_index = -1) {
10
- stack_index = api.lua_gettop(state) if stack_index == -1
10
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
11
11
 
12
- api.lua_newtable(state)
12
+ api.lua_newtable(state[:lua])
13
13
 
14
14
  if list.is_a? Hash
15
15
  list.each_key do |key|
16
16
  Writer[:push!].(api, state, key)
17
17
  Writer[:push!].(api, state, list[key])
18
- api.lua_settable(state, stack_index + 1)
18
+ api.lua_settable(state[:lua], stack_index + 1)
19
19
  end
20
20
  else
21
21
  list.each_with_index do |value, index|
22
22
  Writer[:push!].(api, state, index + 1)
23
23
  Writer[:push!].(api, state, value)
24
- api.lua_settable(state, stack_index + 1)
24
+ api.lua_settable(state[:lua], stack_index + 1)
25
25
  end
26
26
  end
27
27
  },
28
28
 
29
29
  read!: ->(api, state, stack_index) {
30
- stack_index = api.lua_gettop(state) if stack_index == -1
30
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
31
31
 
32
- type = api.lua_typename(state, api.lua_type(state, stack_index)).read_string
32
+ type = api.lua_typename(state[:lua],
33
+ api.lua_type(state[:lua], stack_index)).read_string
33
34
 
34
- api.lua_pushnil(state)
35
+ api.lua_pushnil(state[:lua])
35
36
 
36
37
  return nil if type != 'table'
37
38
 
38
39
  tuples = []
39
40
 
40
- while api.lua_next(state, stack_index).positive?
41
+ while api.lua_next(state[:lua], stack_index).positive?
41
42
  value = Reader[:read!].(api, state, stack_index + 2)
42
43
  key = Reader[:read!].(api, state, stack_index + 1)
43
- api.lua_settop(state, -2) if value[:pop]
44
+ api.lua_settop(state[:lua], -2) if value[:pop]
44
45
 
45
46
  tuples << [key[:value], value[:value]]
46
47
 
@@ -51,24 +52,25 @@ module Component
51
52
  },
52
53
 
53
54
  read_field_and_push!: ->(api, state, expected_key, stack_index) {
54
- stack_index = api.lua_gettop(state) if stack_index == -1
55
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
55
56
 
56
- type = api.lua_typename(state, api.lua_type(state, stack_index)).read_string
57
+ type = api.lua_typename(state[:lua],
58
+ api.lua_type(state[:lua], stack_index)).read_string
57
59
 
58
- api.lua_pushnil(state)
60
+ api.lua_pushnil(state[:lua])
59
61
 
60
62
  return nil if type != 'table'
61
63
 
62
64
  result = nil
63
65
 
64
- while api.lua_next(state, stack_index).positive?
66
+ while api.lua_next(state[:lua], stack_index).positive?
65
67
  value = Reader[:read!].(api, state, stack_index + 2)
66
68
  key = Reader[:read!].(api, state, stack_index + 1)
67
69
 
68
- api.lua_settop(state, -2) if value[:pop]
70
+ api.lua_settop(state[:lua], -2) if value[:pop]
69
71
 
70
72
  key_type = api.lua_typename(
71
- state, api.lua_type(state, stack_index + 1)
73
+ state[:lua], api.lua_type(state[:lua], stack_index + 1)
72
74
  ).read_string
73
75
 
74
76
  if Table[:is_same_key].(key_type, key[:value], expected_key)
@@ -79,7 +81,7 @@ module Component
79
81
  break if value[:type] == 'no value'
80
82
  end
81
83
 
82
- api.lua_settop(state, -2)
84
+ api.lua_settop(state[:lua], -2)
83
85
 
84
86
  Writer[:push!].(api, state, result)
85
87
  },
@@ -7,26 +7,26 @@ module Component
7
7
  push!: ->(api, state, value) {
8
8
  case Writer[:_to_lua_type].(value)
9
9
  when 'string'
10
- api.lua_pushstring(state, value.to_s)
10
+ api.lua_pushstring(state[:lua], value.to_s)
11
11
  when 'number'
12
- api.lua_pushnumber(state, value)
12
+ api.lua_pushnumber(state[:lua], value)
13
13
  when 'integer'
14
14
  if api.respond_to? :lua_pushinteger
15
- api.lua_pushinteger(state, value)
15
+ api.lua_pushinteger(state[:lua], value)
16
16
  else
17
- api.lua_pushnumber(state, value)
17
+ api.lua_pushnumber(state[:lua], value)
18
18
  end
19
19
  when 'nil'
20
- api.lua_pushnil(state)
20
+ api.lua_pushnil(state[:lua])
21
21
  when 'boolean'
22
- api.lua_pushboolean(state, value ? 1 : 0)
22
+ api.lua_pushboolean(state[:lua], value ? 1 : 0)
23
23
  when 'table'
24
24
  Table[:push!].(api, state, value)
25
25
  when 'function'
26
26
  Function[:push!].(api, state, value)
27
27
  else
28
28
  api.lua_pushstring(
29
- state, "#<#{value.class}:0x#{format('%016x', value.object_id)}>"
29
+ state[:lua], "#<#{value.class}:0x#{format('%016x', value.object_id)}>"
30
30
  )
31
31
  end
32
32
  },
@@ -9,23 +9,26 @@ module Component
9
9
  Function = {
10
10
  push!: ->(api, state, closure) {
11
11
  handler = ->(current_state) {
12
- input = Reader[:read_all!].(api, current_state)
12
+ updated_state = state.merge(lua: current_state)
13
+ input = Reader[:read_all!].(api, updated_state)
13
14
  result = closure.(*input)
14
- Writer[:push!].(api, current_state, result)
15
+ Writer[:push!].(api, updated_state, result)
15
16
  return 1
16
17
  }
17
18
 
18
- api.lua_pushcclosure(state, handler, 0)
19
+ state[:avoid_gc] << handler
20
+
21
+ api.lua_pushcclosure(state[:lua], handler, 0)
19
22
  },
20
23
 
21
24
  read!: ->(api, state, _stack_index) {
22
25
  reference = api.luaL_ref(
23
- state, Logic::V51::Interpreter[:LUA_REGISTRYINDEX]
26
+ state[:lua], Logic::V51::Interpreter[:LUA_REGISTRYINDEX]
24
27
  )
25
28
 
26
29
  { value: ->(input = [], output = 1) {
27
30
  api.lua_rawgeti(
28
- state, Logic::V51::Interpreter[:LUA_REGISTRYINDEX], reference
31
+ state[:lua], Logic::V51::Interpreter[:LUA_REGISTRYINDEX], reference
29
32
  )
30
33
 
31
34
  input.each do |value|
@@ -11,22 +11,23 @@ module Component
11
11
 
12
12
  create_state!: ->(api) {
13
13
  state = api.luaL_newstate
14
- { state: state, error: state ? nil : :MemoryAllocation }
14
+ { state: { lua: state, avoid_gc: [] },
15
+ error: state ? nil : :MemoryAllocation }
15
16
  },
16
17
 
17
18
  open_standard_libraries!: ->(api, state) {
18
- api.luaL_openlibs(state)
19
+ api.luaL_openlibs(state[:lua])
19
20
 
20
21
  { state: state }
21
22
  },
22
23
 
23
24
  load_file_and_push_chunck!: ->(api, state, path) {
24
- result = api.luaL_loadfile(state, path)
25
+ result = api.luaL_loadfile(state[:lua], path)
25
26
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
26
27
  },
27
28
 
28
29
  push_chunk!: ->(api, state, value) {
29
- result = api.luaL_loadstring(state, value)
30
+ result = api.luaL_loadstring(state[:lua], value)
30
31
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
31
32
  },
32
33
 
@@ -40,21 +41,22 @@ module Component
40
41
  },
41
42
 
42
43
  pop_and_set_as!: ->(api, state, variable) {
43
- api.lua_pushstring(state, variable)
44
- api.lua_insert(state, -2)
45
- api.lua_settable(state, Logic::V51::Interpreter[:LUA_GLOBALSINDEX])
44
+ api.lua_pushstring(state[:lua], variable)
45
+ api.lua_insert(state[:lua], -2)
46
+ api.lua_settable(state[:lua], Logic::V51::Interpreter[:LUA_GLOBALSINDEX])
46
47
  { state: state }
47
48
  },
48
49
 
49
50
  get_variable_and_push!: ->(api, state, variable, key = nil) {
50
- api.lua_pushstring(state, variable.to_s)
51
- api.lua_gettable(state, Logic::V51::Interpreter[:LUA_GLOBALSINDEX])
51
+ api.lua_pushstring(state[:lua], variable.to_s)
52
+ api.lua_gettable(state[:lua], Logic::V51::Interpreter[:LUA_GLOBALSINDEX])
52
53
 
53
54
  unless key.nil?
54
- if api.lua_typename(state, api.lua_type(state, -1)).read_string == 'table'
55
+ if api.lua_typename(state[:lua],
56
+ api.lua_type(state[:lua], -1)).read_string == 'table'
55
57
  Table[:read_field!].(api, state, key, -1)
56
58
  else
57
- api.lua_pushnil(state)
59
+ api.lua_pushnil(state[:lua])
58
60
  end
59
61
  end
60
62
 
@@ -62,15 +64,15 @@ module Component
62
64
  },
63
65
 
64
66
  call!: ->(api, state, inputs = 0, outputs = 1) {
65
- result = api.lua_pcall(state, inputs, outputs, 0)
67
+ result = api.lua_pcall(state[:lua], inputs, outputs, 0)
66
68
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
67
69
  },
68
70
 
69
71
  read_and_pop!: ->(api, state, stack_index = -1, extra_pop: false) {
70
72
  result = Component::V51::Reader[:read!].(api, state, stack_index)
71
73
 
72
- api.lua_settop(state, -2) if result[:pop]
73
- api.lua_settop(state, -2) if extra_pop
74
+ api.lua_settop(state[:lua], -2) if result[:pop]
75
+ api.lua_settop(state[:lua], -2) if extra_pop
74
76
 
75
77
  { state: state, output: result[:value] }
76
78
  },
@@ -82,9 +84,12 @@ module Component
82
84
  },
83
85
 
84
86
  destroy_state!: ->(api, state) {
85
- result = api.lua_close(state)
87
+ result = api.lua_close(state[:lua])
86
88
 
87
- { state: nil, error: Interpreter[:_error].(api, state, result) }
89
+ state.delete(:lua)
90
+ state.delete(:avoid_gc)
91
+
92
+ { state: nil, error: Interpreter[:_error].(api, nil, result) }
88
93
  },
89
94
 
90
95
  _error: ->(api, state, code, options = {}) {
@@ -93,7 +98,7 @@ module Component
93
98
  ] || :error
94
99
 
95
100
  if code.is_a?(Numeric) && code >= 2
96
- return { status: status } unless options[:pull]
101
+ return { status: status } unless options[:pull] && state
97
102
 
98
103
  { status: status,
99
104
  value: Interpreter[:read_and_pop!].(api, state, -1)[:output] }
@@ -8,15 +8,16 @@ module Component
8
8
  module V51
9
9
  Reader = {
10
10
  read_all!: ->(api, state) {
11
- (1..api.lua_gettop(state)).map do
11
+ (1..api.lua_gettop(state[:lua])).map do
12
12
  Interpreter[:read_and_pop!].(api, state)[:output]
13
13
  end.reverse
14
14
  },
15
15
 
16
16
  read!: ->(api, state, stack_index = -1) {
17
- stack_index = api.lua_gettop(state) if stack_index == -1
17
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
18
18
 
19
- type = api.lua_typename(state, api.lua_type(state, stack_index)).read_string
19
+ type = api.lua_typename(state[:lua],
20
+ api.lua_type(state[:lua], stack_index)).read_string
20
21
 
21
22
  case type
22
23
  when 'string'
@@ -36,29 +37,30 @@ module Component
36
37
  else
37
38
  # none nil boolean lightuserdata number
38
39
  # string table function userdata thread
39
- { value: "#{type}: 0x#{api.lua_topointer(state, stack_index).address}",
40
+ { value:
41
+ "#{type}: 0x#{api.lua_topointer(state[:lua], stack_index).address}",
40
42
  type: type, pop: true }
41
43
  end
42
44
  },
43
45
 
44
46
  read_string!: ->(api, state, stack_index) {
45
- { value: api.lua_tostring(state, stack_index).read_string,
47
+ { value: api.lua_tostring(state[:lua], stack_index).read_string,
46
48
  pop: true }
47
49
  },
48
50
 
49
51
  read_number!: ->(api, state, stack_index) {
50
52
  if api.respond_to?(:lua_isinteger) &&
51
53
  api.respond_to?(:lua_tointeger) &&
52
- api.lua_isinteger(state, stack_index) == 1
54
+ api.lua_isinteger(state[:lua], stack_index) == 1
53
55
 
54
- return { value: api.lua_tointeger(state, stack_index), pop: true }
56
+ return { value: api.lua_tointeger(state[:lua], stack_index), pop: true }
55
57
  end
56
58
 
57
- { value: api.lua_tonumber(state, stack_index), pop: true }
59
+ { value: api.lua_tonumber(state[:lua], stack_index), pop: true }
58
60
  },
59
61
 
60
62
  read_boolean!: ->(api, state, stack_index) {
61
- { value: api.lua_toboolean(state, stack_index) == 1, pop: true }
63
+ { value: api.lua_toboolean(state[:lua], stack_index) == 1, pop: true }
62
64
  }
63
65
  }
64
66
  end
@@ -7,40 +7,41 @@ module Component
7
7
  module V51
8
8
  Table = {
9
9
  push!: ->(api, state, list, stack_index = -1) {
10
- stack_index = api.lua_gettop(state) if stack_index == -1
10
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
11
11
 
12
- api.lua_createtable(state, list.size, 0)
12
+ api.lua_createtable(state[:lua], list.size, 0)
13
13
 
14
14
  if list.is_a? Hash
15
15
  list.each_key do |key|
16
16
  Writer[:push!].(api, state, key)
17
17
  Writer[:push!].(api, state, list[key])
18
- api.lua_settable(state, stack_index + 1)
18
+ api.lua_settable(state[:lua], stack_index + 1)
19
19
  end
20
20
  else
21
21
  list.each_with_index do |value, index|
22
22
  Writer[:push!].(api, state, index + 1)
23
23
  Writer[:push!].(api, state, value)
24
- api.lua_settable(state, stack_index + 1)
24
+ api.lua_settable(state[:lua], stack_index + 1)
25
25
  end
26
26
  end
27
27
  },
28
28
 
29
29
  read!: ->(api, state, stack_index) {
30
- stack_index = api.lua_gettop(state) if stack_index == -1
30
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
31
31
 
32
- type = api.lua_typename(state, api.lua_type(state, stack_index)).read_string
32
+ type = api.lua_typename(state[:lua],
33
+ api.lua_type(state[:lua], stack_index)).read_string
33
34
 
34
- api.lua_pushnil(state)
35
+ api.lua_pushnil(state[:lua])
35
36
 
36
37
  return nil if type != 'table'
37
38
 
38
39
  tuples = []
39
40
 
40
- while api.lua_next(state, stack_index).positive?
41
+ while api.lua_next(state[:lua], stack_index).positive?
41
42
  value = Reader[:read!].(api, state, stack_index + 2)
42
43
  key = Reader[:read!].(api, state, stack_index + 1)
43
- api.lua_settop(state, -2) if value[:pop]
44
+ api.lua_settop(state[:lua], -2) if value[:pop]
44
45
 
45
46
  tuples << [key[:value], value[:value]]
46
47
 
@@ -53,7 +54,7 @@ module Component
53
54
  read_field!: ->(api, state, expected_key, stack_index) {
54
55
  expected_key = expected_key.to_s if expected_key.is_a? Symbol
55
56
 
56
- api.lua_getfield(state, stack_index, expected_key)
57
+ api.lua_getfield(state[:lua], stack_index, expected_key)
57
58
  }
58
59
  }
59
60
  end
@@ -7,26 +7,26 @@ module Component
7
7
  push!: ->(api, state, value) {
8
8
  case Writer[:_to_lua_type].(value)
9
9
  when 'string'
10
- api.lua_pushstring(state, value.to_s)
10
+ api.lua_pushstring(state[:lua], value.to_s)
11
11
  when 'number'
12
- api.lua_pushnumber(state, value)
12
+ api.lua_pushnumber(state[:lua], value)
13
13
  when 'integer'
14
14
  if api.respond_to? :lua_pushinteger
15
- api.lua_pushinteger(state, value)
15
+ api.lua_pushinteger(state[:lua], value)
16
16
  else
17
- api.lua_pushnumber(state, value)
17
+ api.lua_pushnumber(state[:lua], value)
18
18
  end
19
19
  when 'nil'
20
- api.lua_pushnil(state)
20
+ api.lua_pushnil(state[:lua])
21
21
  when 'boolean'
22
- api.lua_pushboolean(state, value ? 1 : 0)
22
+ api.lua_pushboolean(state[:lua], value ? 1 : 0)
23
23
  when 'table'
24
24
  Table[:push!].(api, state, value)
25
25
  when 'function'
26
26
  Function[:push!].(api, state, value)
27
27
  else
28
28
  api.lua_pushstring(
29
- state, "#<#{value.class}:0x#{format('%016x', value.object_id)}>"
29
+ state[:lua], "#<#{value.class}:0x#{format('%016x', value.object_id)}>"
30
30
  )
31
31
  end
32
32
  },
@@ -9,23 +9,26 @@ module Component
9
9
  Function = {
10
10
  push!: ->(api, state, closure) {
11
11
  handler = ->(current_state) {
12
- input = Reader[:read_all!].(api, current_state)
12
+ updated_state = state.merge(lua: current_state)
13
+ input = Reader[:read_all!].(api, updated_state)
13
14
  result = closure.(*input)
14
- Writer[:push!].(api, current_state, result)
15
+ Writer[:push!].(api, updated_state, result)
15
16
  return 1
16
17
  }
17
18
 
18
- api.lua_pushcclosure(state, handler, 0)
19
+ state[:avoid_gc] << handler
20
+
21
+ api.lua_pushcclosure(state[:lua], handler, 0)
19
22
  },
20
23
 
21
24
  read!: ->(api, state, _stack_index) {
22
25
  reference = api.luaL_ref(
23
- state, Logic::V54::Interpreter[:LUA_REGISTRYINDEX]
26
+ state[:lua], Logic::V54::Interpreter[:LUA_REGISTRYINDEX]
24
27
  )
25
28
 
26
29
  { value: ->(input = [], output = 1) {
27
30
  api.lua_rawgeti(
28
- state, Logic::V54::Interpreter[:LUA_REGISTRYINDEX], reference
31
+ state[:lua], Logic::V54::Interpreter[:LUA_REGISTRYINDEX], reference
29
32
  )
30
33
 
31
34
  input.each do |value|
@@ -11,21 +11,22 @@ module Component
11
11
 
12
12
  create_state!: ->(api) {
13
13
  state = api.luaL_newstate
14
- { state: state, error: state ? nil : :MemoryAllocation }
14
+ { state: { lua: state, avoid_gc: [] },
15
+ error: state ? nil : :MemoryAllocation }
15
16
  },
16
17
 
17
18
  open_standard_libraries!: ->(api, state) {
18
- api.luaL_openlibs(state)
19
+ api.luaL_openlibs(state[:lua])
19
20
  { state: state }
20
21
  },
21
22
 
22
23
  load_file_and_push_chunck!: ->(api, state, path) {
23
- result = api.luaL_loadfile(state, path)
24
+ result = api.luaL_loadfile(state[:lua], path)
24
25
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
25
26
  },
26
27
 
27
28
  push_chunk!: ->(api, state, value) {
28
- result = api.luaL_loadstring(state, value)
29
+ result = api.luaL_loadstring(state[:lua], value)
29
30
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
30
31
  },
31
32
 
@@ -39,18 +40,19 @@ module Component
39
40
  },
40
41
 
41
42
  pop_and_set_as!: ->(api, state, variable) {
42
- api.lua_setglobal(state, variable)
43
+ api.lua_setglobal(state[:lua], variable)
43
44
  { state: state }
44
45
  },
45
46
 
46
47
  get_variable_and_push!: ->(api, state, variable, key = nil) {
47
- api.lua_getglobal(state, variable.to_s)
48
+ api.lua_getglobal(state[:lua], variable.to_s)
48
49
 
49
50
  unless key.nil?
50
- if api.lua_typename(state, api.lua_type(state, -1)).read_string == 'table'
51
+ if api.lua_typename(state[:lua],
52
+ api.lua_type(state[:lua], -1)).read_string == 'table'
51
53
  Table[:read_field!].(api, state, key, -1)
52
54
  else
53
- api.lua_pushnil(state)
55
+ api.lua_pushnil(state[:lua])
54
56
  end
55
57
  end
56
58
 
@@ -58,15 +60,15 @@ module Component
58
60
  },
59
61
 
60
62
  call!: ->(api, state, inputs = 0, outputs = 1) {
61
- result = api.lua_pcall(state, inputs, outputs, 0)
63
+ result = api.lua_pcall(state[:lua], inputs, outputs, 0)
62
64
  { state: state, error: Interpreter[:_error].(api, state, result, pull: true) }
63
65
  },
64
66
 
65
67
  read_and_pop!: ->(api, state, stack_index = -1, extra_pop: false) {
66
68
  result = Component::V54::Reader[:read!].(api, state, stack_index)
67
69
 
68
- api.lua_settop(state, -2) if result[:pop]
69
- api.lua_settop(state, -2) if extra_pop
70
+ api.lua_settop(state[:lua], -2) if result[:pop]
71
+ api.lua_settop(state[:lua], -2) if extra_pop
70
72
 
71
73
  { state: state, output: result[:value] }
72
74
  },
@@ -78,9 +80,12 @@ module Component
78
80
  },
79
81
 
80
82
  destroy_state!: ->(api, state) {
81
- result = api.lua_close(state)
83
+ result = api.lua_close(state[:lua])
82
84
 
83
- { state: nil, error: Interpreter[:_error].(api, state, result) }
85
+ state.delete(:lua)
86
+ state.delete(:avoid_gc)
87
+
88
+ { state: nil, error: Interpreter[:_error].(api, nil, result) }
84
89
  },
85
90
 
86
91
  _error: ->(api, state, code, options = {}) {
@@ -89,7 +94,7 @@ module Component
89
94
  ] || :error
90
95
 
91
96
  if code.is_a?(Numeric) && code >= 2
92
- return { status: status } unless options[:pull]
97
+ return { status: status } unless options[:pull] && state
93
98
 
94
99
  { status: status,
95
100
  value: Interpreter[:read_and_pop!].(api, state, -1)[:output] }
@@ -8,15 +8,16 @@ module Component
8
8
  module V54
9
9
  Reader = {
10
10
  read_all!: ->(api, state) {
11
- (1..api.lua_gettop(state)).map do
11
+ (1..api.lua_gettop(state[:lua])).map do
12
12
  Interpreter[:read_and_pop!].(api, state)[:output]
13
13
  end.reverse
14
14
  },
15
15
 
16
16
  read!: ->(api, state, stack_index = -1) {
17
- stack_index = api.lua_gettop(state) if stack_index == -1
17
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
18
18
 
19
- type = api.lua_typename(state, api.lua_type(state, stack_index)).read_string
19
+ type = api.lua_typename(state[:lua],
20
+ api.lua_type(state[:lua], stack_index)).read_string
20
21
 
21
22
  case type
22
23
  when 'string'
@@ -36,29 +37,30 @@ module Component
36
37
  else
37
38
  # none nil boolean lightuserdata number
38
39
  # string table function userdata thread
39
- { value: "#{type}: 0x#{api.lua_topointer(state, stack_index).address}",
40
+ { value:
41
+ "#{type}: 0x#{api.lua_topointer(state[:lua], stack_index).address}",
40
42
  type: type, pop: true }
41
43
  end
42
44
  },
43
45
 
44
46
  read_string!: ->(api, state, stack_index) {
45
- { value: api.lua_tostring(state, stack_index).read_string,
47
+ { value: api.lua_tostring(state[:lua], stack_index).read_string,
46
48
  pop: true }
47
49
  },
48
50
 
49
51
  read_number!: ->(api, state, stack_index) {
50
52
  if api.respond_to?(:lua_isinteger) &&
51
53
  api.respond_to?(:lua_tointeger) &&
52
- api.lua_isinteger(state, stack_index) == 1
54
+ api.lua_isinteger(state[:lua], stack_index) == 1
53
55
 
54
- return { value: api.lua_tointeger(state, stack_index), pop: true }
56
+ return { value: api.lua_tointeger(state[:lua], stack_index), pop: true }
55
57
  end
56
58
 
57
- { value: api.lua_tonumber(state, stack_index), pop: true }
59
+ { value: api.lua_tonumber(state[:lua], stack_index), pop: true }
58
60
  },
59
61
 
60
62
  read_boolean!: ->(api, state, stack_index) {
61
- { value: api.lua_toboolean(state, stack_index) == 1, pop: true }
63
+ { value: api.lua_toboolean(state[:lua], stack_index) == 1, pop: true }
62
64
  }
63
65
  }
64
66
  end
@@ -7,40 +7,41 @@ module Component
7
7
  module V54
8
8
  Table = {
9
9
  push!: ->(api, state, list, stack_index = -1) {
10
- stack_index = api.lua_gettop(state) if stack_index == -1
10
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
11
11
 
12
- api.lua_createtable(state, list.size, 0)
12
+ api.lua_createtable(state[:lua], list.size, 0)
13
13
 
14
14
  if list.is_a? Hash
15
15
  list.each_key do |key|
16
16
  Writer[:push!].(api, state, key)
17
17
  Writer[:push!].(api, state, list[key])
18
- api.lua_settable(state, stack_index + 1)
18
+ api.lua_settable(state[:lua], stack_index + 1)
19
19
  end
20
20
  else
21
21
  list.each_with_index do |value, index|
22
22
  Writer[:push!].(api, state, index + 1)
23
23
  Writer[:push!].(api, state, value)
24
- api.lua_settable(state, stack_index + 1)
24
+ api.lua_settable(state[:lua], stack_index + 1)
25
25
  end
26
26
  end
27
27
  },
28
28
 
29
29
  read!: ->(api, state, stack_index) {
30
- stack_index = api.lua_gettop(state) if stack_index == -1
30
+ stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
31
31
 
32
- type = api.lua_typename(state, api.lua_type(state, stack_index)).read_string
32
+ type = api.lua_typename(state[:lua],
33
+ api.lua_type(state[:lua], stack_index)).read_string
33
34
 
34
- api.lua_pushnil(state)
35
+ api.lua_pushnil(state[:lua])
35
36
 
36
37
  return nil if type != 'table'
37
38
 
38
39
  tuples = []
39
40
 
40
- while api.lua_next(state, stack_index).positive?
41
+ while api.lua_next(state[:lua], stack_index).positive?
41
42
  value = Reader[:read!].(api, state, stack_index + 2)
42
43
  key = Reader[:read!].(api, state, stack_index + 1)
43
- api.lua_settop(state, -2) if value[:pop]
44
+ api.lua_settop(state[:lua], -2) if value[:pop]
44
45
 
45
46
  tuples << [key[:value], value[:value]]
46
47
 
@@ -53,7 +54,7 @@ module Component
53
54
  read_field!: ->(api, state, expected_key, stack_index) {
54
55
  expected_key = expected_key.to_s if expected_key.is_a? Symbol
55
56
 
56
- api.lua_getfield(state, stack_index, expected_key)
57
+ api.lua_getfield(state[:lua], stack_index, expected_key)
57
58
  }
58
59
  }
59
60
  end
@@ -7,26 +7,26 @@ module Component
7
7
  push!: ->(api, state, value) {
8
8
  case Writer[:_to_lua_type].(value)
9
9
  when 'string'
10
- api.lua_pushstring(state, value.to_s)
10
+ api.lua_pushstring(state[:lua], value.to_s)
11
11
  when 'number'
12
- api.lua_pushnumber(state, value)
12
+ api.lua_pushnumber(state[:lua], value)
13
13
  when 'integer'
14
14
  if api.respond_to? :lua_pushinteger
15
- api.lua_pushinteger(state, value)
15
+ api.lua_pushinteger(state[:lua], value)
16
16
  else
17
- api.lua_pushnumber(state, value)
17
+ api.lua_pushnumber(state[:lua], value)
18
18
  end
19
19
  when 'nil'
20
- api.lua_pushnil(state)
20
+ api.lua_pushnil(state[:lua])
21
21
  when 'boolean'
22
- api.lua_pushboolean(state, value ? 1 : 0)
22
+ api.lua_pushboolean(state[:lua], value ? 1 : 0)
23
23
  when 'table'
24
24
  Table[:push!].(api, state, value)
25
25
  when 'function'
26
26
  Function[:push!].(api, state, value)
27
27
  else
28
28
  api.lua_pushstring(
29
- state, "#<#{value.class}:0x#{format('%016x', value.object_id)}>"
29
+ state[:lua], "#<#{value.class}:0x#{format('%016x', value.object_id)}>"
30
30
  )
31
31
  end
32
32
  },
@@ -1,9 +1,11 @@
1
1
  # Available at https://github.com/gbaptista/sweet-moon-test
2
2
 
3
3
  luarocks:
4
- - /home/me/.luarocks/share/lua/5.4/?.lua
5
- - /home/me/.luarocks/share/lua/5.4/?/init.lua
6
- - /home/me/.luarocks/lib/lua/5.4/?.so
4
+ path:
5
+ - /home/me/.luarocks/share/lua/5.4/?.lua
6
+ - /home/me/.luarocks/share/lua/5.4/?/init.lua
7
+ - /home/me/.luarocks/lib/lua/5.4/?.so
8
+ expected: ['supernova', 'dkjson', 'lfs']
7
9
 
8
10
  jit:2.0.5:
9
11
  description: 'Lua Jit 2.0.5 + Fennel 1.0.0'
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.2',
5
+ version: '0.0.3',
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.',
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.2
4
+ version: 0.0.3
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-22 00:00:00.000000000 Z
11
+ date: 2022-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi