dtr_core 0.10.0 → 0.11.1

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: ad7236ff8c846c7126d0d8e53f3d7cd5d6635eeefbca857dafdf22e85473cbe6
4
- data.tar.gz: d8741a66894615c02d59be5ba8884f165acdcfdb045c2243c07c57c3116cb699
3
+ metadata.gz: 63137198f11287cf84f4a62df74afb125146867e2379f59b73a6146840051748
4
+ data.tar.gz: d3967276a7b33fbd0e1db027754b22746e5e464a087445466417e79a1c4730e1
5
5
  SHA512:
6
- metadata.gz: 83a20837017ec8a60ae948918f6b1947332516248bac6f805bdfc12b7b2a5636d5f01157739c81167113a873218da6cf55b22c297e1903718c9913b29322f2f7
7
- data.tar.gz: 42b2bd3b5ef207d88fe3a955a9358ea54270979115df12e10d2318d6d230c80e8d858979d9d91df91bd2158153dd93f0d2e8efd15e0e27c4f261dee6432d660d
6
+ metadata.gz: 41066cf773aa89c5bcf005ca9306b5286f1c8a5d84e73d8a43feee2754c33c0f2228a8576c99d744a55e6d1e2554d55edace7d39494da3580f871e79ac4529a7
7
+ data.tar.gz: ca54b572bad2667dd337184ac9b5c74addcdf5290912e0efe8e707bc7cf545dc1ab098c0f9015b55f700aee46de5a5c8f8296e97333026840441ffe2f71250df
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DTRCore
4
+ module Graph
5
+ class LCPBT_Forrest
6
+ attr_accessor :trees
7
+
8
+ def initialize
9
+ @trees = []
10
+ end
11
+
12
+ def add_tree(tree)
13
+ @trees << tree
14
+ end
15
+
16
+ def traverse
17
+ @trees.map(&:traverse)
18
+ end
19
+
20
+ def traverse_with_indentation
21
+ @trees.map(&:traverse_with_indentation)
22
+ end
23
+
24
+ # This represents a traversal through a unique path, covering all trees in the forest
25
+ # only once. This is useful for code generation.
26
+ def traverse_to_ids
27
+ id_map = {}
28
+ result = []
29
+
30
+ traverse
31
+ .map { |x| x.map(&:id) }
32
+ .each do |x|
33
+ sub_result = []
34
+ x.each do |y|
35
+ next if id_map[y]
36
+
37
+ sub_result << y
38
+ id_map[y] = true
39
+ end
40
+ result << sub_result
41
+ end
42
+
43
+ result
44
+ end
45
+
46
+ def code_generator_traverse(&block)
47
+ traverse_with_indentation
48
+ .map { |tree| tree.reverse.uniq.reverse.map(&block) }
49
+ end
50
+
51
+ def size
52
+ @trees.size
53
+ end
54
+
55
+ def all_paths_to(instruction_id)
56
+ @trees.map { |x| x.all_paths_to(instruction_id) }.flatten(1).compact
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module DTRCore
6
+ module Graph
7
+ class LeftChildPreferentialBinaryTree
8
+ attr_accessor :value, :left_child, :right_child, :tree_id
9
+
10
+ def initialize(value, indentation: 0)
11
+ @tree_id = SecureRandom.uuid
12
+ @indentation = indentation
13
+ @value = value
14
+ @left_child = nil
15
+ @right_child = nil
16
+ end
17
+
18
+ def set_left_child(node)
19
+ raise 'Left child already exists' if @left_child
20
+
21
+ @left_child = node
22
+ end
23
+
24
+ def set_right_child(node)
25
+ raise 'Right child already exists' if @right_child
26
+
27
+ @right_child = node
28
+ end
29
+
30
+ def traverse
31
+ result = []
32
+ result << @value
33
+ result += @left_child.traverse if @left_child
34
+ result += @right_child.traverse if @right_child
35
+ result
36
+ end
37
+
38
+ def traverse_with_indentation
39
+ result = []
40
+ result << [@value, @indentation]
41
+ result += @left_child.traverse_with_indentation if @left_child
42
+ result += @right_child.traverse_with_indentation if @right_child
43
+ result
44
+ end
45
+
46
+ def all_paths_to(instruction_id, cur_result: [])
47
+ if value.id == instruction_id
48
+ return cur_result.empty? ? [[instruction_id]] : cur_result + [instruction_id]
49
+ end
50
+
51
+ result = nil
52
+
53
+ if @left_child
54
+ left_child_traverse = @left_child.all_paths_to(instruction_id, cur_result: cur_result + [value.id])
55
+ result = left_child_traverse unless left_child_traverse.nil?
56
+ end
57
+
58
+ if @right_child
59
+ right_child_traverse = @right_child.all_paths_to(instruction_id, cur_result: cur_result + [value.id])
60
+ result = result.nil? ? right_child_traverse : [result, right_child_traverse]
61
+ end
62
+
63
+ result
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DTRCore
4
+ module Graph
5
+ class Silviculturist
6
+ attr_accessor :forrest
7
+
8
+ def initialize(instructions)
9
+ @instructions = instructions
10
+ @forrest = LCPBT_Forrest.new
11
+ @seen_instructions = {}
12
+ end
13
+
14
+ def make_forrest
15
+ index = 0
16
+ while index < @instructions.size
17
+ instructions = @instructions[index..]
18
+ scope = 0
19
+ tree = plant_trees(scope, instructions)
20
+ @forrest.add_tree(tree)
21
+
22
+ seen = true
23
+ while seen && index < @instructions.size
24
+ index += 1
25
+ seen = @instructions[index].nil? || @seen_instructions[@instructions[index].id]
26
+ end
27
+ end
28
+ end
29
+
30
+ def plant_trees(scope, instructions, from_id: nil, indentation: 0)
31
+ cur_instruction = instructions[0]
32
+
33
+ return nil if cur_instruction.nil?
34
+
35
+ if cur_instruction.scope != scope
36
+ return plant_trees(scope, instructions[1..], from_id: cur_instruction.id,
37
+ indentation:)
38
+ end
39
+
40
+ return @seen_instructions[cur_instruction.id] if @seen_instructions[cur_instruction.id]
41
+
42
+ down_jump = cur_instruction.instruction == 'jump' && (
43
+ (cur_instruction.inputs.size == 1 && cur_instruction.inputs[0].to_i < scope) ||
44
+ (cur_instruction.inputs.size == 2 && cur_instruction.inputs[1].to_i < scope))
45
+
46
+ rest_of_instructions = instructions[1..]
47
+
48
+ tree = LeftChildPreferentialBinaryTree.new(cur_instruction,
49
+ indentation: if down_jump
50
+ indentation - 1
51
+ else
52
+ indentation
53
+ end)
54
+ @seen_instructions[cur_instruction.id] = tree
55
+
56
+ case cur_instruction.instruction
57
+ when 'jump'
58
+ case cur_instruction.inputs.size
59
+ # unconditional jump
60
+ when 1
61
+ new_scope = cur_instruction.inputs[0].to_i
62
+
63
+ # halt when going back to 0
64
+ return tree if new_scope.zero?
65
+
66
+ tree.set_left_child(plant_trees(new_scope, rest_of_instructions, from_id: cur_instruction.id,
67
+ indentation: down_jump ? indentation - 1 : indentation + 1))
68
+ # conditional jump
69
+ when 2
70
+ # detour
71
+ new_scope = cur_instruction.inputs[1].to_i
72
+
73
+ tree.set_left_child(plant_trees(new_scope, rest_of_instructions,
74
+ from_id: cur_instruction.id, indentation: down_jump ? indentation - 1 : indentation + 1))
75
+ # continue
76
+ tree.set_right_child(plant_trees(scope, rest_of_instructions, from_id: cur_instruction.id,
77
+ indentation:))
78
+ # if-let
79
+ when 3
80
+ raise 'We do not yet support if-let statements'
81
+ end
82
+ # the way a goto works is that you want to drop out of the loop back to the scope you were at
83
+ # when you started the loop
84
+ when 'goto'
85
+ goto_target_id = cur_instruction.inputs[0].to_i
86
+ return_scope = @instructions.find { |x| x.id == goto_target_id }.scope
87
+
88
+ return tree if return_scope.zero?
89
+
90
+ # TODO: fix indentation
91
+ tree.set_left_child(plant_trees(return_scope.to_i, rest_of_instructions, from_id: cur_instruction.id,
92
+ indentation:))
93
+ else
94
+ # left_child
95
+ tree.set_left_child(plant_trees(scope, rest_of_instructions, from_id: cur_instruction.id,
96
+ indentation:))
97
+ end
98
+
99
+ tree
100
+ end
101
+ end
102
+ end
103
+ end
data/lib/dtr_core.rb CHANGED
@@ -12,4 +12,11 @@ module DTRCore
12
12
  autoload :InstructionValidator, 'dtr_core/instruction_validator'
13
13
  autoload :Instruction, 'dtr_core/instruction'
14
14
  autoload :UserDefinedType, 'dtr_core/user_defined_type'
15
+
16
+ # A graph is a collection of nodes and edges representing the structure of a DTR file.
17
+ module Graph
18
+ autoload :LCPBT_Forrest, 'dtr_core/graph/lcpbt_forrest'
19
+ autoload :LeftChildPreferentialBinaryTree, 'dtr_core/graph/left_child_preferential_binary_tree'
20
+ autoload :Silviculturist, 'dtr_core/graph/silviculturist'
21
+ end
15
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dtr_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Durst
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-09 00:00:00.000000000 Z
11
+ date: 2024-07-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Core smart contract intermediate language (Digicus Textual Representation)
14
14
  parser.
@@ -22,6 +22,9 @@ files:
22
22
  - lib/dtr_core/common.rb
23
23
  - lib/dtr_core/contract.rb
24
24
  - lib/dtr_core/function.rb
25
+ - lib/dtr_core/graph/lcpbt_forrest.rb
26
+ - lib/dtr_core/graph/left_child_preferential_binary_tree.rb
27
+ - lib/dtr_core/graph/silviculturist.rb
25
28
  - lib/dtr_core/instruction.rb
26
29
  - lib/dtr_core/instruction_validator.rb
27
30
  - lib/dtr_core/number.rb
@@ -35,7 +38,7 @@ licenses:
35
38
  - MIT
36
39
  metadata:
37
40
  rubygems_mfa_required: 'true'
38
- post_install_message:
41
+ post_install_message:
39
42
  rdoc_options: []
40
43
  require_paths:
41
44
  - lib
@@ -50,8 +53,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
50
53
  - !ruby/object:Gem::Version
51
54
  version: '0'
52
55
  requirements: []
53
- rubygems_version: 3.5.13
54
- signing_key:
56
+ rubygems_version: 3.4.10
57
+ signing_key:
55
58
  specification_version: 4
56
59
  summary: Core smart contract intermediate language (Digicus Textual Representation)
57
60
  parser.