dtr_core 0.5.6 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dtr_core/common.rb +8 -6
- data/lib/dtr_core/contract.rb +21 -11
- data/lib/dtr_core/function.rb +13 -14
- data/lib/dtr_core/instruction.rb +32 -0
- data/lib/dtr_core/instruction_validator.rb +77 -0
- data/lib/dtr_core/number.rb +6 -15
- data/lib/dtr_core/parser.rb +27 -9
- data/lib/dtr_core/supported_attributes.rb +62 -79
- data/lib/dtr_core/type_validator.rb +61 -13
- data/lib/dtr_core/user_defined_type.rb +1 -1
- data/lib/dtr_core.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 149908b637a12363b2de8ef8432c5348bb303756bf619e09ecd3530ca070973d
|
4
|
+
data.tar.gz: a4d642766c5e1bc759e87520de1f35288b6ef6920409a15238a4cdde60040a78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d81497276755f5d3921c40256864936be3d2b105091bf268a7f483e183668cb959c14d386672d8aad1118c1fc0c6564589893564e6eab203eadf4ac17f9ce62
|
7
|
+
data.tar.gz: 83771252da2ebc9d7cbdd15315aeaae226044de99be1cae842dc237db22cded37e027196f6eb57135fa34a67757dd451cf2de4bd53ff0e3e846d795248d99209
|
data/lib/dtr_core/common.rb
CHANGED
@@ -3,16 +3,18 @@
|
|
3
3
|
module DTRCore
|
4
4
|
# Common methods used by the DTRCore module.
|
5
5
|
module Common
|
6
|
-
def strip_and_remove_quotes(str)
|
7
|
-
str.strip.gsub(/['"]/, '')
|
8
|
-
end
|
9
|
-
|
10
6
|
def split_strip_select(some_list)
|
11
7
|
some_list&.split("\n")&.map(&:strip)&.select { |x| x.length.positive? }
|
12
8
|
end
|
13
9
|
|
14
|
-
def
|
15
|
-
content.match(pattern)&.captures
|
10
|
+
def capture_section(pattern)
|
11
|
+
captures = content.match(pattern)&.captures
|
12
|
+
|
13
|
+
if content.scan(pattern).length > 1
|
14
|
+
raise 'Multiple captures found for a section.'
|
15
|
+
elsif captures
|
16
|
+
captures&.first
|
17
|
+
end
|
16
18
|
end
|
17
19
|
|
18
20
|
def clean_name(definition)
|
data/lib/dtr_core/contract.rb
CHANGED
@@ -3,31 +3,34 @@
|
|
3
3
|
module DTRCore
|
4
4
|
# Represents a contract in a DTR file.
|
5
5
|
class Contract
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :helpers, :interface, :name, :state, :user_defined_types
|
7
7
|
|
8
|
-
def initialize(name, state,
|
8
|
+
def initialize(name, state, interface, user_defined_types, helpers)
|
9
9
|
@name = name
|
10
10
|
@state = state
|
11
|
-
@
|
11
|
+
@interface = interface
|
12
12
|
@user_defined_types = user_defined_types
|
13
|
+
@helpers = helpers
|
13
14
|
end
|
14
15
|
|
15
16
|
def self.from_dtr(filepath)
|
16
17
|
parser = DTRCore::Parser.new(filepath)
|
17
18
|
|
18
|
-
new(parser.name_section, parser.state_section, parser.
|
19
|
+
new(parser.name_section, parser.state_section, parser.interface_section, parser.user_defined_types_section,
|
20
|
+
parser.helpers_section)
|
19
21
|
end
|
20
22
|
|
21
23
|
def self.from_dtr_raw(content)
|
22
24
|
parser = DTRCore::Parser.new('', content:)
|
23
25
|
|
24
|
-
new(parser.name_section, parser.state_section, parser.
|
26
|
+
new(parser.name_section, parser.state_section, parser.interface_section, parser.user_defined_types_section,
|
27
|
+
parser.helpers_section)
|
25
28
|
end
|
26
29
|
|
27
30
|
def ==(other)
|
28
31
|
name == other.name &&
|
29
32
|
state == other.state &&
|
30
|
-
|
33
|
+
interface == other.interface &&
|
31
34
|
user_defined_types == other.user_defined_types
|
32
35
|
end
|
33
36
|
|
@@ -36,8 +39,9 @@ module DTRCore
|
|
36
39
|
|
37
40
|
return_string += name_to_s
|
38
41
|
return_string += "#{state_to_s}\n"
|
39
|
-
return_string +=
|
42
|
+
return_string += interface_to_s
|
40
43
|
return_string += user_defined_types_to_s
|
44
|
+
return_string += helpers_to_s
|
41
45
|
|
42
46
|
return_string
|
43
47
|
end
|
@@ -51,19 +55,25 @@ module DTRCore
|
|
51
55
|
def state_to_s
|
52
56
|
return '' if @state.nil?
|
53
57
|
|
54
|
-
"[State]:\n#{@state&.map(&:to_s)&.join("\n")}\n"
|
58
|
+
"[State]:\n#{@state&.map(&:to_s)&.join("\n")}\n:[State]\n"
|
55
59
|
end
|
56
60
|
|
57
|
-
def
|
61
|
+
def interface_to_s
|
58
62
|
return '' if @state.nil?
|
59
63
|
|
60
|
-
"[
|
64
|
+
"[Interface]:\n#{@interface&.map(&:to_s)&.join("\n")}\n:[Interface]\n"
|
61
65
|
end
|
62
66
|
|
63
67
|
def user_defined_types_to_s
|
64
68
|
return '' if @user_defined_types.nil?
|
65
69
|
|
66
|
-
"[
|
70
|
+
"[User Defined Types]:\n#{@user_defined_types&.map(&:to_s)&.join("\n")}\n:[User Defined Types]\n"
|
71
|
+
end
|
72
|
+
|
73
|
+
def helpers_to_s
|
74
|
+
return '' if @helpers.nil?
|
75
|
+
|
76
|
+
"[Helpers]:\n#{@helpers&.map(&:to_s)&.join("\n")}\n:[Helpers]\n"
|
67
77
|
end
|
68
78
|
end
|
69
79
|
end
|
data/lib/dtr_core/function.rb
CHANGED
@@ -65,7 +65,8 @@ module DTRCore
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def output_to_s
|
68
|
-
return
|
68
|
+
return '' if output.nil?
|
69
|
+
|
69
70
|
" * Output: #{output}\n"
|
70
71
|
end
|
71
72
|
|
@@ -75,19 +76,13 @@ module DTRCore
|
|
75
76
|
return_string += " * Instructions:\n"
|
76
77
|
return_string += " $\n"
|
77
78
|
@instructions.each do |x|
|
78
|
-
return_string += " #{
|
79
|
+
return_string += " #{x}\n"
|
79
80
|
end
|
80
81
|
return_string += " $\n"
|
81
82
|
|
82
83
|
return_string
|
83
84
|
end
|
84
85
|
|
85
|
-
def single_instruction_to_s(ins)
|
86
|
-
"{ instruction: #{ins[:instruction]}," \
|
87
|
-
"input: (#{ins[:inputs]&.join(', ')}), " \
|
88
|
-
"assign: #{ins[:assign]}, scope: #{ins[:scope]} }\n"
|
89
|
-
end
|
90
|
-
|
91
86
|
def format_function_inputs(inputs)
|
92
87
|
return [] if inputs.nil?
|
93
88
|
|
@@ -99,12 +94,16 @@ module DTRCore
|
|
99
94
|
end
|
100
95
|
|
101
96
|
def parse_function_instruction(instruction)
|
102
|
-
|
103
|
-
instruction
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
97
|
+
instruction = DTRCore::Instruction.new(
|
98
|
+
instruction[/instruction:\s*(?<all>[^\s,]+)/, 1],
|
99
|
+
parse_function_instruction_input(instruction),
|
100
|
+
instruction[/\s*assign:\s*(?<all>[^\s\,]+)/, 1],
|
101
|
+
instruction[/\s*scope:\s*(?<all>[^\s\,]+)/, 1].to_i || 0
|
102
|
+
)
|
103
|
+
|
104
|
+
raise "Invalid instruction: #{instruction}" unless instruction.valid?
|
105
|
+
|
106
|
+
instruction
|
108
107
|
end
|
109
108
|
|
110
109
|
def parse_function_instruction_input(definition)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DTRCore
|
4
|
+
# Instruction class
|
5
|
+
class Instruction
|
6
|
+
attr_reader :instruction, :inputs, :assign, :scope
|
7
|
+
|
8
|
+
def initialize(instruction, inputs, assign, scope)
|
9
|
+
@instruction = instruction
|
10
|
+
@inputs = inputs
|
11
|
+
@assign = assign
|
12
|
+
@scope = scope
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
instruction == other.instruction &&
|
17
|
+
inputs == other.inputs &&
|
18
|
+
assign == other.assign &&
|
19
|
+
scope == other.scope
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"{ instruction: #{instruction}," \
|
24
|
+
"input: (#{inputs&.join(', ')}), " \
|
25
|
+
"assign: #{assign}, scope: #{scope} }"
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid?
|
29
|
+
DTRCore::InstructionValidator.new(self).valid?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dtr_core/common'
|
4
|
+
|
5
|
+
module DTRCore
|
6
|
+
# Instruction validator for DTR types.
|
7
|
+
class InstructionValidator
|
8
|
+
include ::DTRCore::Common
|
9
|
+
|
10
|
+
def initialize(instruction)
|
11
|
+
@instruction = instruction
|
12
|
+
|
13
|
+
validate_input!
|
14
|
+
end
|
15
|
+
|
16
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
18
|
+
def valid?
|
19
|
+
return false unless scope_valid?
|
20
|
+
|
21
|
+
case @instruction.instruction
|
22
|
+
when 'assign', 'evaluate', 'print'
|
23
|
+
validate_basic_operation!
|
24
|
+
when 'exit_with_message', 'return'
|
25
|
+
validate_terminating_operation!
|
26
|
+
when 'and', 'or'
|
27
|
+
validate_logical_operation!
|
28
|
+
when 'goto', 'jump', 'end_of_iteration_check', 'label'
|
29
|
+
validate_control_flow_operation!
|
30
|
+
when 'field', 'instantiate_object'
|
31
|
+
validate_object_operation!
|
32
|
+
when 'add', 'subtract', 'multiply', 'divide'
|
33
|
+
validate_binary_operation!
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
# rubocop:enable Metrics/MethodLength
|
39
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def validate_input!
|
44
|
+
raise 'Missing Instruction.' if @instruction.nil?
|
45
|
+
raise 'Instruction name missing.' if @instruction.instruction.nil?
|
46
|
+
raise 'Instruction missing scope.' if @instruction.scope.nil?
|
47
|
+
end
|
48
|
+
|
49
|
+
def scope_valid?
|
50
|
+
@instruction.scope >= 0
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate_basic_operation!
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
def validate_terminating_operation!
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate_logical_operation!
|
62
|
+
@instruction.inputs&.length == 2
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate_control_flow_operation!
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_object_operation!
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
def validate_binary_operation!
|
74
|
+
@instruction.inputs&.length == 2
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/dtr_core/number.rb
CHANGED
@@ -2,22 +2,13 @@
|
|
2
2
|
|
3
3
|
module DTRCore
|
4
4
|
module Number
|
5
|
-
|
6
|
-
|
5
|
+
MIN_Integer = -2**31
|
6
|
+
MAX_Integer = (2**31) - 1
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
MIN_BigInteger = -2**255
|
9
|
+
MAX_BigInteger = (2**255) - 1
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
MIN_I32 = -2**31
|
15
|
-
MAX_I32 = (2**31) - 1
|
16
|
-
|
17
|
-
MIN_I64 = -2**63
|
18
|
-
MAX_I64 = (2**63) - 1
|
19
|
-
|
20
|
-
MIN_I256 = -2**255
|
21
|
-
MAX_I256 = (2**255) - 1
|
11
|
+
MIN_Float = -2**31
|
12
|
+
MAX_Float = (2**31) - 1
|
22
13
|
end
|
23
14
|
end
|
data/lib/dtr_core/parser.rb
CHANGED
@@ -23,7 +23,7 @@ module DTRCore
|
|
23
23
|
def name_section
|
24
24
|
return @name_section if @name_section
|
25
25
|
|
26
|
-
name_section =
|
26
|
+
name_section = capture_section(/\[Contract\]:\s*(.+)/)
|
27
27
|
|
28
28
|
raise 'Missing contract name.' if name_section.nil?
|
29
29
|
|
@@ -33,7 +33,7 @@ module DTRCore
|
|
33
33
|
def state_section
|
34
34
|
return @state_definitions if @state_definitions
|
35
35
|
|
36
|
-
state_section =
|
36
|
+
state_section = capture_section(/\[State\]:\s*((?:\s*\*\s*\[.+?\]\n(?:\s*\*.+\n?)*)*)\s*:\[State\]/)
|
37
37
|
|
38
38
|
return nil if state_section.nil?
|
39
39
|
|
@@ -46,29 +46,29 @@ module DTRCore
|
|
46
46
|
@state_section ||= state_definitions
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
49
|
+
def interface_section
|
50
50
|
return @function_definitions if @function_definitions
|
51
51
|
|
52
|
-
|
52
|
+
interface_section = capture_section(/\[Interface\]:(?<all>.*):\[Interface\]/m)
|
53
53
|
|
54
|
-
return nil if
|
54
|
+
return nil if interface_section.nil?
|
55
55
|
|
56
|
-
function_definitions =
|
56
|
+
function_definitions = interface_section.split('-()').map do |x|
|
57
57
|
DTRCore::Function.from_definition(x.strip.to_s)
|
58
58
|
end
|
59
59
|
|
60
60
|
function_definitions.reject! { |x| x.name.nil? }
|
61
61
|
|
62
|
-
raise 'Empty
|
62
|
+
raise 'Empty interface section.' if function_definitions.empty?
|
63
63
|
|
64
|
-
@
|
64
|
+
@interface_section ||= function_definitions
|
65
65
|
end
|
66
66
|
|
67
67
|
def user_defined_types_section
|
68
68
|
return @user_defined_types if @user_defined_types
|
69
69
|
|
70
70
|
user_defined_types_regex = /\[User Defined Types\]:([\s\S]*?)\s*:\[User Defined Types\]/
|
71
|
-
user_defined_types_section_parsed_out =
|
71
|
+
user_defined_types_section_parsed_out = capture_section(user_defined_types_regex)
|
72
72
|
|
73
73
|
return nil if user_defined_types_section_parsed_out.nil?
|
74
74
|
|
@@ -79,5 +79,23 @@ module DTRCore
|
|
79
79
|
|
80
80
|
@user_defined_types_section ||= user_defined_types
|
81
81
|
end
|
82
|
+
|
83
|
+
def helpers_section
|
84
|
+
return @function_definitions if @function_definitions
|
85
|
+
|
86
|
+
helpers_section = capture_section(/\[Helpers\]:(?<all>.*)\s*:\[Helpers\]/m)
|
87
|
+
|
88
|
+
return nil if helpers_section.nil?
|
89
|
+
|
90
|
+
function_definitions = helpers_section.split('-()').map do |x|
|
91
|
+
DTRCore::Function.from_definition(x.strip.to_s)
|
92
|
+
end
|
93
|
+
|
94
|
+
function_definitions.reject! { |x| x.name.nil? }
|
95
|
+
|
96
|
+
raise 'Empty helpers section.' if function_definitions.empty?
|
97
|
+
|
98
|
+
@helpers_section ||= function_definitions
|
99
|
+
end
|
82
100
|
end
|
83
101
|
end
|
@@ -1,98 +1,81 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Layout/LineLength
|
3
4
|
module DTRCore
|
4
5
|
module SupportedAttributes
|
5
6
|
# Supported Instructions for DTR.
|
6
7
|
## Instruction Categories ##
|
7
8
|
INSTRUCTION_CATEGORY_BASIC = 'basic'
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
INSTRUCTION_CATEGORY_STRING = 'string'
|
12
|
-
INSTRUCTION_CATEGORY_ENVIRONMENT = 'environment'
|
13
|
-
INSTRUCTION_CATEGORY_METHODS = 'methods'
|
14
|
-
INSTRUCTION_CATEGORY_OBJECTS = 'objects'
|
15
|
-
INSTRUCTION_CATEGORY_CONDITIONAL = 'conditional'
|
9
|
+
INSTRUCTION_CATEGORY_BINARY = 'binary'
|
10
|
+
INSTRUCTION_CATEGORY_CONTROL_FLOW = 'control_flow'
|
11
|
+
INSTRUCTION_CATEGORY_TERMINATING = 'terminating'
|
16
12
|
INSTRUCTION_CATEGORY_LOGICAL = 'logical'
|
13
|
+
INSTRUCTION_CATEGORY_OBJECT = 'object'
|
17
14
|
INSTRUCTION_CATEGORIES = [
|
18
15
|
INSTRUCTION_CATEGORY_BASIC,
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
INSTRUCTION_CATEGORY_METHODS,
|
25
|
-
INSTRUCTION_CATEGORY_OBJECTS,
|
26
|
-
INSTRUCTION_CATEGORY_CONDITIONAL,
|
27
|
-
INSTRUCTION_CATEGORY_LOGICAL
|
16
|
+
INSTRUCTION_CATEGORY_BINARY,
|
17
|
+
INSTRUCTION_CATEGORY_CONTROL_FLOW,
|
18
|
+
INSTRUCTION_CATEGORY_TERMINATING,
|
19
|
+
INSTRUCTION_CATEGORY_LOGICAL,
|
20
|
+
INSTRUCTION_CATEGORY_OBJECT
|
28
21
|
].freeze
|
29
22
|
## Instructions ##
|
30
23
|
INSTRUCTIONS = [
|
31
|
-
|
32
|
-
|
33
|
-
{ name: '
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
{ name: '
|
41
|
-
|
42
|
-
|
43
|
-
{ name: '
|
44
|
-
category:
|
45
|
-
{ name: '
|
46
|
-
category:
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
{ name: '
|
51
|
-
|
52
|
-
{ name: '
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
{ name: '
|
58
|
-
category:
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
{ name: '
|
65
|
-
|
66
|
-
{ name: '
|
67
|
-
category:
|
68
|
-
{ name: '
|
69
|
-
category:
|
70
|
-
# logical operations
|
71
|
-
{ name: 'and', description: 'Logical AND.', category: INSTRUCTION_CATEGORY_LOGICAL },
|
72
|
-
{ name: 'or', description: 'Logical OR.', category: INSTRUCTION_CATEGORY_LOGICAL }
|
24
|
+
{ name: 'assign', description: 'given some input value, assign to ASSIGN_NAME',
|
25
|
+
category: INSTRUCTION_CATEGORY_BASIC },
|
26
|
+
{ name: 'evaluate',
|
27
|
+
description: 'given a method name and 0 or more inputs, execute method. At this time, evaluate is a fairly loose catch-all for not explicitly defined operations', category: INSTRUCTION_CATEGORY_BASIC },
|
28
|
+
{ name: 'print', description: 'given some value, print it to standard out',
|
29
|
+
category: INSTRUCTION_CATEGORY_BASIC },
|
30
|
+
|
31
|
+
{ name: 'exit_with_message', description: 'immediately end execution, returning message',
|
32
|
+
category: INSTRUCTION_CATEGORY_TERMINATING },
|
33
|
+
{ name: 'return', description: 'return from function with input value',
|
34
|
+
category: INSTRUCTION_CATEGORY_TERMINATING },
|
35
|
+
|
36
|
+
{ name: 'and', description: 'lassign to ASSIGN_NAME result of “and-ing” two values',
|
37
|
+
category: INSTRUCTION_CATEGORY_LOGICAL },
|
38
|
+
{ name: 'or', description: 'assign to ASSIGN_NAME result of “or-ing” two values',
|
39
|
+
category: INSTRUCTION_CATEGORY_LOGICAL },
|
40
|
+
|
41
|
+
{ name: 'goto',
|
42
|
+
description: 'conditional if two inputs. In this case, first input is the condition to evaluate. If that is true, or there is only one input, move in code to the first input (a label name)', category: INSTRUCTION_CATEGORY_CONTROL_FLOW },
|
43
|
+
{ name: 'jump',
|
44
|
+
description: 'conditional if two inputs. In this case, first input is the condition to evaluate. If that is true, or there is only one input, jump to scope level', category: INSTRUCTION_CATEGORY_CONTROL_FLOW },
|
45
|
+
{ name: 'end_of_iteration_check',
|
46
|
+
description: 'check on input to see if at end of iteration. Return result to ASSIGN_NAME', category: INSTRUCTION_CATEGORY_CONTROL_FLOW },
|
47
|
+
{ name: 'label', description: 'a named location within the instruction set for a given function',
|
48
|
+
category: INSTRUCTION_CATEGORY_CONTROL_FLOW },
|
49
|
+
|
50
|
+
{ name: 'field', description: 'access a field on an object and assign result to ASSIGN_NAME',
|
51
|
+
category: INSTRUCTION_CATEGORY_OBJECT },
|
52
|
+
{ name: 'instantiate_object',
|
53
|
+
description: 'initialize an object by first passing in the type of object and the passing in each initial values for its fields. Supported types here include: Dictionary, List, Range, Tuple, and UDT. For UDTs, the second input is the name of the UDT.', category: INSTRUCTION_CATEGORY_OBJECT },
|
54
|
+
|
55
|
+
{ name: 'add', description: 'assign to ASSIGN_NAME result of adding two value',
|
56
|
+
category: INSTRUCTION_CATEGORY_BINARY },
|
57
|
+
{ name: 'subtract', description: 'assign to ASSIGN_NAME result of subtracting two value',
|
58
|
+
category: INSTRUCTION_CATEGORY_BINARY },
|
59
|
+
{ name: 'multiply', description: 'assign to ASSIGN_NAME result of multiplying two value',
|
60
|
+
category: INSTRUCTION_CATEGORY_BINARY },
|
61
|
+
{ name: 'divide', description: 'assign to ASSIGN_NAME result of dividing two value',
|
62
|
+
category: INSTRUCTION_CATEGORY_BINARY }
|
73
63
|
].freeze
|
74
64
|
|
75
65
|
# Supported Types for DTR.
|
76
|
-
TYPES = [
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
'i64',
|
89
|
-
'i128',
|
90
|
-
'i256',
|
91
|
-
## unsigned
|
92
|
-
'u32',
|
93
|
-
'u64',
|
94
|
-
'u128',
|
95
|
-
'u256'
|
66
|
+
TYPES = %w[
|
67
|
+
Dictionary
|
68
|
+
List
|
69
|
+
Range
|
70
|
+
Tuple
|
71
|
+
UDT
|
72
|
+
Address
|
73
|
+
BigInteger
|
74
|
+
Boolean
|
75
|
+
Float
|
76
|
+
Integer
|
77
|
+
String
|
96
78
|
].freeze
|
97
79
|
end
|
98
80
|
end
|
81
|
+
# rubocop:enable Layout/LineLength
|
@@ -13,31 +13,79 @@ module DTRCore
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def validate_then_coerce_initial_value!
|
16
|
+
validate_input!
|
17
|
+
|
18
|
+
return validate_integer! if %w[Integer BigInteger Float].include?(@type_name)
|
19
|
+
return validate_string! if ['String'].include?(@type_name)
|
20
|
+
return validate_address! if ['Address'].include?(@type_name)
|
21
|
+
return validate_boolean! if ['Boolean'].include?(@type_name)
|
22
|
+
|
23
|
+
raise 'Missing Invalid Type Name.'
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def validate_input!
|
16
29
|
raise 'Missing Type Name.' if @type_name.nil?
|
17
30
|
raise 'Missing Initial Value.' if @initial_value.nil?
|
31
|
+
end
|
18
32
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
33
|
+
# TODO: implement deeper validation for Address type
|
34
|
+
# TODO: confirm this works for non-Stellar addresses
|
35
|
+
def validate_address!
|
36
|
+
raise "Invalid initial value for Address: #{@initial_value}. Wrong type." unless @initial_value.length == 56
|
37
|
+
|
38
|
+
@initial_value
|
39
|
+
end
|
40
|
+
|
41
|
+
def validate_string!
|
42
|
+
unless @initial_value.is_a?(String) && @initial_value.match(/".*"/)
|
43
|
+
raise "Invalid initial value for String: #{@initial_value}. Wrong type."
|
28
44
|
end
|
45
|
+
|
46
|
+
@initial_value.strip
|
29
47
|
end
|
30
48
|
|
31
|
-
|
49
|
+
def validate_boolean!
|
50
|
+
unless %w[true
|
51
|
+
false].include?(@initial_value)
|
52
|
+
raise "Invalid initial value for Boolean: #{@initial_value}. Wrong type."
|
53
|
+
end
|
32
54
|
|
33
|
-
|
34
|
-
|
55
|
+
@initial_value == 'true'
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_integer!
|
59
|
+
unless @initial_value =~ (/^[\-\.\d]\d*(\.?\d*)*/)
|
60
|
+
raise "Invalid initial value for #{@type_name}: #{@initial_value}. Wrong type."
|
61
|
+
end
|
35
62
|
|
36
63
|
raise "Invalid initial value for type #{@type_name}. Out of range." unless @initial_value.to_i.between?(
|
37
64
|
DTRCore::Number.const_get(:"MIN_#{@type_name}"), DTRCore::Number.const_get(:"MAX_#{@type_name}")
|
38
65
|
)
|
39
66
|
|
40
|
-
|
67
|
+
handle_each_numeric_type!
|
68
|
+
end
|
69
|
+
|
70
|
+
def handle_each_numeric_type!
|
71
|
+
case @type_name
|
72
|
+
when 'Integer', 'BigInteger'
|
73
|
+
raise "Invalid initial value for #{@type_name}: #{@initial_value}. Wrong type." unless non_float_integer?
|
74
|
+
|
75
|
+
@initial_value.to_i
|
76
|
+
when 'Float'
|
77
|
+
raise "Invalid initial value for #{@type_name}: #{@initial_value}. Wrong type." unless floaty_float?
|
78
|
+
|
79
|
+
@initial_value.to_f
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def non_float_integer?
|
84
|
+
@initial_value =~ (/^[\-\.\d]\d*(\.?\d*)*/) && !@initial_value.include?('.')
|
85
|
+
end
|
86
|
+
|
87
|
+
def floaty_float?
|
88
|
+
@initial_value =~ (/^[\-\.\d]\d*(\.?\d*)*/) && @initial_value.include?('.')
|
41
89
|
end
|
42
90
|
end
|
43
91
|
end
|
data/lib/dtr_core.rb
CHANGED
@@ -9,5 +9,7 @@ module DTRCore
|
|
9
9
|
autoload :State, 'dtr_core/state'
|
10
10
|
autoload :SupportedAttributes, 'dtr_core/supported_attributes'
|
11
11
|
autoload :TypeValidator, 'dtr_core/type_validator'
|
12
|
+
autoload :InstructionValidator, 'dtr_core/instruction_validator'
|
13
|
+
autoload :Instruction, 'dtr_core/instruction'
|
12
14
|
autoload :UserDefinedType, 'dtr_core/user_defined_type'
|
13
15
|
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.6.2
|
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-06-
|
11
|
+
date: 2024-06-17 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,8 @@ 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/instruction.rb
|
26
|
+
- lib/dtr_core/instruction_validator.rb
|
25
27
|
- lib/dtr_core/number.rb
|
26
28
|
- lib/dtr_core/parser.rb
|
27
29
|
- lib/dtr_core/state.rb
|