dtr_core 0.10.0 → 0.11.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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec65bed75c4955e0c231146f532fd7d1c35ed2e7617966681dce5718076ba0be
|
4
|
+
data.tar.gz: a192a2cc58e2b4dbdd6bae900751675236d1532fc869676badc0b79a043a33e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 703ec3bd6c1ffd80d0f872bd13351467819daa7dfd42737c33f90402fd66f11026e1d902e4e186449cdd913d4ee2db8489ccdb4b7afcb691f43c7c4cb4c2156e
|
7
|
+
data.tar.gz: 5a7fc13e8418ea5917ffa8aa70855922f920750e8b9ee6bde1b0d910daecbb567cf058ce3b819f2cdae4fff8ecd41858a89936c207693456e46b17a7db404386
|
@@ -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.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Durst
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-13 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
|