tataru 0.1.0 → 0.2.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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/bin/console +15 -0
  4. data/bin/setup +8 -0
  5. data/lib/tataru.rb +70 -12
  6. data/lib/tataru/base_resource.rb +49 -0
  7. data/lib/tataru/base_resource_desc.rb +35 -0
  8. data/lib/tataru/compiler.rb +100 -0
  9. data/lib/tataru/create_subroutines.rb +31 -0
  10. data/lib/tataru/delete_subroutines.rb +42 -0
  11. data/lib/tataru/flattener.rb +81 -0
  12. data/lib/tataru/init_hash_compiler.rb +41 -0
  13. data/lib/tataru/instruction.rb +52 -7
  14. data/lib/tataru/instruction_hash.rb +54 -0
  15. data/lib/tataru/instructions/call_instruction.rb +19 -0
  16. data/lib/tataru/instructions/check_create_instruction.rb +27 -0
  17. data/lib/tataru/instructions/check_delete_instruction.rb +20 -0
  18. data/lib/tataru/instructions/check_instruction.rb +26 -0
  19. data/lib/tataru/instructions/check_update_instruction.rb +27 -0
  20. data/lib/tataru/instructions/clear_instruction.rb +12 -0
  21. data/lib/tataru/instructions/compare_instruction.rb +16 -0
  22. data/lib/tataru/instructions/create_instruction.rb +20 -0
  23. data/lib/tataru/instructions/delete_instruction.rb +14 -0
  24. data/lib/tataru/instructions/end_instruction.rb +12 -0
  25. data/lib/tataru/instructions/goto_if_instruction.rb +26 -0
  26. data/lib/tataru/instructions/immediate_mode_instruction.rb +12 -0
  27. data/lib/tataru/instructions/init_instruction.rb +27 -0
  28. data/lib/tataru/instructions/key_instruction.rb +12 -0
  29. data/lib/tataru/instructions/mark_deletable_instruction.rb +13 -0
  30. data/lib/tataru/instructions/read_instruction.rb +28 -0
  31. data/lib/tataru/instructions/rescmp_instruction.rb +34 -0
  32. data/lib/tataru/instructions/resource_instruction.rb +15 -0
  33. data/lib/tataru/instructions/return_instruction.rb +16 -0
  34. data/lib/tataru/instructions/update_instruction.rb +16 -0
  35. data/lib/tataru/instructions/value_instruction.rb +15 -0
  36. data/lib/tataru/instructions/value_rom_instruction.rb +23 -0
  37. data/lib/tataru/instructions/value_update_instruction.rb +18 -0
  38. data/lib/tataru/memory.rb +16 -0
  39. data/lib/tataru/quest.rb +43 -0
  40. data/lib/tataru/representation.rb +22 -0
  41. data/lib/tataru/representations/array_representation.rb +18 -0
  42. data/lib/tataru/representations/hash_representation.rb +20 -0
  43. data/lib/tataru/representations/literal_representation.rb +9 -0
  44. data/lib/tataru/representations/output_representation.rb +19 -0
  45. data/lib/tataru/representations/resource_representation.rb +49 -0
  46. data/lib/tataru/resolver.rb +39 -0
  47. data/lib/tataru/resource_dsl.rb +21 -71
  48. data/lib/tataru/resource_type_pool.rb +22 -0
  49. data/lib/tataru/rom_reader.rb +47 -0
  50. data/lib/tataru/runner.rb +48 -0
  51. data/lib/tataru/sub_planner.rb +41 -0
  52. data/lib/tataru/subroutine_compiler.rb +52 -0
  53. data/lib/tataru/top_dsl.rb +35 -0
  54. data/lib/tataru/update_subroutines.rb +111 -0
  55. data/lib/tataru/version.rb +1 -1
  56. data/spec/compiler_spec.rb +181 -0
  57. data/spec/flattener_spec.rb +88 -0
  58. data/spec/init_hash_compiler_spec.rb +85 -0
  59. data/spec/instruction_hash_spec.rb +63 -0
  60. data/spec/instruction_spec.rb +36 -0
  61. data/spec/instructions/call_instruction_spec.rb +28 -0
  62. data/spec/instructions/check_create_instruction_spec.rb +67 -0
  63. data/spec/instructions/check_delete_instruction_spec.rb +47 -0
  64. data/spec/instructions/check_update_instruction_spec.rb +67 -0
  65. data/spec/instructions/clear_instruction_spec.rb +16 -0
  66. data/spec/instructions/compare_instruction_spec.rb +29 -0
  67. data/spec/instructions/create_instruction_spec.rb +62 -0
  68. data/spec/instructions/delete_instruction_spec.rb +20 -0
  69. data/spec/instructions/end_instruction_spec.rb +15 -0
  70. data/spec/instructions/goto_if_instruction_spec.rb +42 -0
  71. data/spec/instructions/init_instruction_spec.rb +16 -0
  72. data/spec/instructions/key_instruction_spec.rb +15 -0
  73. data/spec/instructions/mark_deletable_instruction_spec.rb +20 -0
  74. data/spec/instructions/read_instruction_spec.rb +34 -0
  75. data/spec/instructions/rescmp_instruction_spec.rb +113 -0
  76. data/spec/instructions/return_instruction_spec.rb +28 -0
  77. data/spec/instructions/update_instruction_spec.rb +39 -0
  78. data/spec/instructions/value_instruction_spec.rb +27 -0
  79. data/spec/instructions/value_rom_instruction_spec.rb +170 -0
  80. data/spec/instructions/value_update_instruction_spec.rb +35 -0
  81. data/spec/quest_spec.rb +9 -0
  82. data/spec/representations/array_representation_spec.rb +29 -0
  83. data/spec/representations/hash_representation_spec.rb +29 -0
  84. data/spec/representations/literal_representation_spec.rb +10 -0
  85. data/spec/representations/output_representation_spec.rb +11 -0
  86. data/spec/representations/resource_representation_spec.rb +50 -0
  87. data/spec/resource_dsl_spec.rb +71 -0
  88. data/spec/runner_spec.rb +99 -0
  89. data/spec/spec_helper.rb +401 -0
  90. data/spec/subroutine_compiler_spec.rb +39 -0
  91. data/spec/taru_spec.rb +616 -0
  92. data/spec/top_dsl_spec.rb +68 -0
  93. data/tataru.gemspec +45 -0
  94. metadata +145 -27
  95. data/Rakefile +0 -8
  96. data/lib/tataru/default_resource_finder.rb +0 -10
  97. data/lib/tataru/execution_step.rb +0 -79
  98. data/lib/tataru/planner.rb +0 -93
  99. data/lib/tataru/requirements.rb +0 -67
  100. data/lib/tataru/requirements_dsl.rb +0 -33
  101. data/lib/tataru/resource.rb +0 -52
  102. data/lib/tataru/state.rb +0 -64
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ # compiles the inithash
5
+ class InitHashCompiler
6
+ def initialize(dsl)
7
+ @dsl = dsl
8
+ end
9
+
10
+ def resolved_references(resource_name, references)
11
+ references.map do |field, refname|
12
+ [field, refname.to_s.sub(/^top/, resource_name)]
13
+ end.to_h
14
+ end
15
+
16
+ def generate_init_hash
17
+ rom = {}
18
+ @dsl.resources.each do |k, v|
19
+ # Expand all the values used to a big flat hash that
20
+ # is only one level deep for ease of use, then mark
21
+ # them for the vm to use
22
+ flattener = Flattener.new(v)
23
+ flattener.flattened.each do |key, value|
24
+ fixed = value.dup
25
+ if fixed[:references]
26
+ fixed[:references] = resolved_references(k, fixed[:references])
27
+ end
28
+ rom[key.to_s.sub(/^top/, k)] = fixed
29
+ end
30
+ end
31
+ {
32
+ rom: rom,
33
+ remote_ids: {}
34
+ }
35
+ end
36
+
37
+ def result
38
+ @result ||= generate_init_hash
39
+ end
40
+ end
41
+ end
@@ -1,15 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tataru
4
- # An instruction
4
+ # a thing to do
5
5
  class Instruction
6
- attr_reader :action, :id, :state, :requirements
6
+ class << self
7
+ attr_accessor :expected_params
7
8
 
8
- def initialize(action, id, state, requirements)
9
- @action = action
10
- @id = id
11
- @state = state
12
- @requirements = requirements
9
+ def expects(symbol)
10
+ @expected_params ||= []
11
+ @expected_params << symbol
12
+
13
+ define_method symbol do
14
+ return nil if @memory&.hash.nil?
15
+
16
+ memory.hash[:temp][symbol]
17
+ end
18
+ end
19
+ end
20
+
21
+ attr_accessor :memory
22
+
23
+ def execute(memory)
24
+ @memory = memory
25
+ self.class.expected_params&.each do |symbol|
26
+ unless memory.hash[:temp].key? symbol
27
+ raise "required param #{symbol} not found"
28
+ end
29
+ end
30
+
31
+ run
13
32
  end
33
+
34
+ def run; end
14
35
  end
15
36
  end
37
+
38
+ require 'tataru/instructions/immediate_mode_instruction'
39
+ require 'tataru/instructions/resource_instruction'
40
+ require 'tataru/instructions/check_instruction'
41
+ require 'tataru/instructions/check_delete_instruction'
42
+ require 'tataru/instructions/mark_deletable_instruction'
43
+ require 'tataru/instructions/clear_instruction'
44
+ require 'tataru/instructions/goto_if_instruction'
45
+ require 'tataru/instructions/key_instruction'
46
+ require 'tataru/instructions/value_rom_instruction'
47
+ require 'tataru/instructions/value_update_instruction'
48
+ require 'tataru/instructions/compare_instruction'
49
+ require 'tataru/instructions/delete_instruction'
50
+ require 'tataru/instructions/update_instruction'
51
+ require 'tataru/instructions/create_instruction'
52
+ require 'tataru/instructions/end_instruction'
53
+ require 'tataru/instructions/check_create_instruction'
54
+ require 'tataru/instructions/read_instruction'
55
+ require 'tataru/instructions/check_update_instruction'
56
+ require 'tataru/instructions/rescmp_instruction'
57
+ require 'tataru/instructions/call_instruction'
58
+ require 'tataru/instructions/value_instruction'
59
+ require 'tataru/instructions/return_instruction'
60
+ require 'tataru/instructions/init_instruction'
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ # representation of a set of instructions
5
+ class InstructionHash
6
+ def initialize(thehash)
7
+ @thehash = thehash
8
+ end
9
+
10
+ def instruction_list
11
+ @instruction_list ||= instructions
12
+ end
13
+
14
+ def to_h
15
+ @thehash
16
+ end
17
+
18
+ def instructions
19
+ return [] unless @thehash[:instructions]
20
+
21
+ @thehash[:instructions].map do |action|
22
+ if action == :init
23
+ init_instruction
24
+ elsif action.is_a? Hash
25
+ # immediate mode instruction
26
+ instruction_for(action.keys[0]).new(action.values[0])
27
+ else
28
+ instruction_for(action).new
29
+ end
30
+ end.to_a
31
+ end
32
+
33
+ def instruction_for(action)
34
+ instr_const = "#{action}_instruction".camelize
35
+ unless Tataru::Instructions.const_defined? instr_const
36
+ raise "Unknown instruction '#{action}'"
37
+ end
38
+
39
+ Tataru::Instructions.const_get(instr_const)
40
+ end
41
+
42
+ def init_instruction
43
+ init = Tataru::Instructions::InitInstruction.new
44
+
45
+ inithash = @thehash[:init]
46
+ if inithash
47
+ %i[remote_ids outputs deleted rom labels].each do |member|
48
+ init.send(:"#{member}=", inithash[member]) if inithash.key? member
49
+ end
50
+ end
51
+ init
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # pushes the callstack and branches
6
+ class CallInstruction < ImmediateModeInstruction
7
+ def run
8
+ labels = memory.hash[:labels]
9
+ unless labels.key? @param
10
+ memory.error = 'Label not found'
11
+ return
12
+ end
13
+
14
+ memory.call_stack.push(memory.program_counter)
15
+ memory.program_counter = labels[@param] - 1
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # instruction to check create
6
+ class CheckCreateInstruction < CheckInstruction
7
+ def initialize
8
+ super :create
9
+ end
10
+
11
+ def after_complete
12
+ memory.hash[:outputs][resource_name] = outputs
13
+ end
14
+
15
+ def outputs
16
+ return {} unless desc.output_fields.count
17
+
18
+ resource_class = desc.resource_class
19
+ resource = resource_class.new(memory.hash[:remote_ids][resource_name])
20
+ o = resource.outputs
21
+ raise "Output for '#{resource_name}' is not a hash" unless o.is_a? Hash
22
+
23
+ resource.outputs
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # check that delete is completed
6
+ class CheckDeleteInstruction < CheckInstruction
7
+ def initialize
8
+ super :delete
9
+ end
10
+
11
+ def after_complete
12
+ memory.hash[:deleted] << resource_name
13
+
14
+ return unless desc.needs_remote_id?
15
+
16
+ memory.hash[:remote_ids].delete(resource_name)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # General checking class
6
+ class CheckInstruction < ResourceInstruction
7
+ def initialize(check_type)
8
+ @check_type = check_type
9
+ end
10
+
11
+ def run
12
+ resource_class = desc.resource_class
13
+ resource = resource_class.new(memory.hash[:remote_ids][resource_name])
14
+
15
+ if resource.send(:"#{@check_type}_complete?")
16
+ after_complete
17
+ else
18
+ # repeat this instruction until its done
19
+ memory.program_counter -= 1
20
+ end
21
+ end
22
+
23
+ def after_complete(_memory); end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # check that update is completed
6
+ class CheckUpdateInstruction < CheckInstruction
7
+ def initialize
8
+ super :update
9
+ end
10
+
11
+ def after_complete
12
+ memory.hash[:outputs][resource_name] = outputs
13
+ end
14
+
15
+ def outputs
16
+ return {} unless desc.output_fields.count
17
+
18
+ resource_class = desc.resource_class
19
+ resource = resource_class.new(memory.hash[:remote_ids][resource_name])
20
+ o = resource.outputs
21
+ raise "Output for '#{resource_name}' is not a hash" unless o.is_a? Hash
22
+
23
+ resource.outputs
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # clears temp memory
6
+ class ClearInstruction < Instruction
7
+ def run
8
+ memory.hash[:temp] = {}
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # compares whats in temp result to param
6
+ class CompareInstruction < ImmediateModeInstruction
7
+ def run
8
+ memory.hash[:temp][:result] = if memory.hash[:temp][:result] == @param
9
+ 1
10
+ else
11
+ 0
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # instruction to create
6
+ class CreateInstruction < ResourceInstruction
7
+ expects :properties
8
+
9
+ def run
10
+ resource_class = desc.resource_class
11
+ resource = resource_class.new(nil)
12
+ resource.create(properties)
13
+
14
+ return unless desc.needs_remote_id?
15
+
16
+ memory.hash[:remote_ids][resource_name] = resource.remote_id
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # instruction to delete
6
+ class DeleteInstruction < ResourceInstruction
7
+ def run
8
+ resource_class = desc.resource_class
9
+ resource = resource_class.new(memory.hash[:remote_ids][resource_name])
10
+ resource.delete
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # ends the program
6
+ class EndInstruction < Instruction
7
+ def run
8
+ memory.end = true
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # goto if temp result is non zero
6
+ class GotoIfInstruction < ImmediateModeInstruction
7
+ def run
8
+ return if memory.hash[:temp][:result].zero?
9
+
10
+ memory.program_counter = if @param.is_a? Integer
11
+ @param - 1
12
+ else
13
+ label_branch!
14
+ end
15
+ end
16
+
17
+ def label_branch!
18
+ unless memory.hash[:labels]&.key?(@param)
19
+ raise "Label '#{@param}' not found"
20
+ end
21
+
22
+ memory.hash[:labels][@param] - 1
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # instruction that takes a parameter
6
+ class ImmediateModeInstruction < Instruction
7
+ def initialize(param)
8
+ @param = param
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # instruction to initialize the memory
6
+ class InitInstruction < Instruction
7
+ attr_accessor :remote_ids, :outputs, :rom, :labels, :deleted
8
+
9
+ def initialize
10
+ @remote_ids = {}
11
+ @outputs = {}
12
+ @rom = {}
13
+ @labels = {}
14
+ @deleted = []
15
+ end
16
+
17
+ def run
18
+ memory.hash[:remote_ids] = @remote_ids
19
+ memory.hash[:outputs] = @outputs
20
+ memory.hash[:labels] = @labels
21
+ memory.hash[:rom] = @rom.freeze
22
+ memory.hash[:deleted] = @deleted
23
+ memory.hash[:update_action] = {}
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tataru
4
+ module Instructions
5
+ # sets a key
6
+ class KeyInstruction < ImmediateModeInstruction
7
+ def run
8
+ memory.hash[:temp][:_key] = @param
9
+ end
10
+ end
11
+ end
12
+ end