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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e53ede493820fa8b4b1ab11144e85fdd24299dd5cbed9d81d28f84598431e3bb
4
- data.tar.gz: 58fb5680bfc4fcda2a064d4328288849e44e352eba01c6dcb4ba219e2af517dc
3
+ metadata.gz: 149908b637a12363b2de8ef8432c5348bb303756bf619e09ecd3530ca070973d
4
+ data.tar.gz: a4d642766c5e1bc759e87520de1f35288b6ef6920409a15238a4cdde60040a78
5
5
  SHA512:
6
- metadata.gz: 1ed541c5bd2d6cd8ba969867d78fb5b4977eae04b9fb9124ef3178b8255565302626bf88979013a9c84cfa93e98871ee1cdf5bd19cd1e280ca68c0461ace2e86
7
- data.tar.gz: 5456ed8bb4e25b422363a01a55f2c59465e83af83ca384ea5525d218009387402307256d6cfcf00e59ffca9992f29ac8cfdc79df2633fb7486f2cad2e03b11c0
6
+ metadata.gz: 4d81497276755f5d3921c40256864936be3d2b105091bf268a7f483e183668cb959c14d386672d8aad1118c1fc0c6564589893564e6eab203eadf4ac17f9ce62
7
+ data.tar.gz: 83771252da2ebc9d7cbdd15315aeaae226044de99be1cae842dc237db22cded37e027196f6eb57135fa34a67757dd451cf2de4bd53ff0e3e846d795248d99209
@@ -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 first_match_for_content(pattern)
15
- content.match(pattern)&.captures&.first
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)
@@ -3,31 +3,34 @@
3
3
  module DTRCore
4
4
  # Represents a contract in a DTR file.
5
5
  class Contract
6
- attr_reader :functions, :name, :state, :user_defined_types
6
+ attr_reader :helpers, :interface, :name, :state, :user_defined_types
7
7
 
8
- def initialize(name, state, functions, user_defined_types)
8
+ def initialize(name, state, interface, user_defined_types, helpers)
9
9
  @name = name
10
10
  @state = state
11
- @functions = functions
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.function_section, parser.user_defined_types_section)
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.function_section, parser.user_defined_types_section)
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
- functions == other.functions &&
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 += functions_to_s
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 functions_to_s
61
+ def interface_to_s
58
62
  return '' if @state.nil?
59
63
 
60
- "[InternalFunctions]:\n#{@functions&.map(&:to_s)&.join("\n")}\n:[InternalFunctions]\n"
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
- "[UserDefinedTypes]:\n#{@user_defined_types&.map(&:to_s)&.join("\n")}\n:[UserDefinedTypes]\n"
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
@@ -65,7 +65,8 @@ module DTRCore
65
65
  end
66
66
 
67
67
  def output_to_s
68
- return "" if output.nil?
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 += " #{single_instruction_to_s(x)}\n"
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: instruction[/instruction:\s*(?<all>[^\s,]+)/, 1],
104
- inputs: parse_function_instruction_input(instruction),
105
- assign: instruction[/\s*assign:\s*(?<all>[^\s\,]+)/, 1],
106
- scope: instruction[/\s*scope:\s*(?<all>[^\s\,]+)/, 1].to_i || 0
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
@@ -2,22 +2,13 @@
2
2
 
3
3
  module DTRCore
4
4
  module Number
5
- MIN_U32 = 0
6
- MAX_U32 = (2**32) - 1
5
+ MIN_Integer = -2**31
6
+ MAX_Integer = (2**31) - 1
7
7
 
8
- MIN_U64 = 0
9
- MAX_U64 = (2**64) - 1
8
+ MIN_BigInteger = -2**255
9
+ MAX_BigInteger = (2**255) - 1
10
10
 
11
- MIN_U256 = 0
12
- MAX_U256 = (2**256) - 1
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
@@ -23,7 +23,7 @@ module DTRCore
23
23
  def name_section
24
24
  return @name_section if @name_section
25
25
 
26
- name_section = first_match_for_content(/\[Contract\]:\s*(.+)/)
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 = first_match_for_content(/\[State\]:\s*((?:\s*\*\s*\[.+?\]\n(?:\s*\*.+\n?)*)*)/)
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 function_section
49
+ def interface_section
50
50
  return @function_definitions if @function_definitions
51
51
 
52
- function_section = first_match_for_content(/\[InternalFunctions\]:(?<all>.*):\[InternalFunctions\]/m)
52
+ interface_section = capture_section(/\[Interface\]:(?<all>.*):\[Interface\]/m)
53
53
 
54
- return nil if function_section.nil?
54
+ return nil if interface_section.nil?
55
55
 
56
- function_definitions = function_section.split('-()').map do |x|
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 function section.' if function_definitions.empty?
62
+ raise 'Empty interface section.' if function_definitions.empty?
63
63
 
64
- @function_section ||= function_definitions
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 = first_match_for_content(user_defined_types_regex)
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
- INSTRUCTION_CATEGORY_STATE = 'state'
9
- INSTRUCTION_CATEGORY_UNTYPED = 'untyped'
10
- INSTRUCTION_CATEGORY_NUMERIC = 'numeric'
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
- INSTRUCTION_CATEGORY_STATE,
20
- INSTRUCTION_CATEGORY_UNTYPED,
21
- INSTRUCTION_CATEGORY_NUMERIC,
22
- INSTRUCTION_CATEGORY_STRING,
23
- INSTRUCTION_CATEGORY_ENVIRONMENT,
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
- # basic operations
32
- { name: 'return', description: 'Return a value from a function.', category: INSTRUCTION_CATEGORY_BASIC },
33
- { name: 'assign', description: 'Assign a value to a variable.', category: INSTRUCTION_CATEGORY_BASIC },
34
- { name: 'panic', description: 'Exit, quickly, and loudly.', category: INSTRUCTION_CATEGORY_BASIC },
35
- # state operations
36
- { name: 'fetch_state', description: 'Fetch a value from the state.', category: INSTRUCTION_CATEGORY_STATE },
37
- { name: 'save_state', description: 'Save a value to the state.', category: INSTRUCTION_CATEGORY_STATE },
38
- # untyped operations
39
- { name: 'add', description: 'Add two things of unknown types together.', category: INSTRUCTION_CATEGORY_UNTYPED },
40
- { name: 'add_and_assign',
41
- description: 'Add two things of unknown types together and then assign to the first one.',
42
- category: INSTRUCTION_CATEGORY_UNTYPED },
43
- { name: 'subtract', description: 'Subtract two things of unknown types together.',
44
- category: INSTRUCTION_CATEGORY_UNTYPED },
45
- { name: 'divide', description: 'Divide two things of unknown types together.',
46
- category: INSTRUCTION_CATEGORY_UNTYPED },
47
- { name: 'multiply', description: 'Multiply two things of unknown types together.',
48
- category: INSTRUCTION_CATEGORY_UNTYPED },
49
- # numeric operations
50
- { name: 'add_numbers', description: 'Add two numbers.', category: INSTRUCTION_CATEGORY_NUMERIC },
51
- { name: 'subtract_numbers', description: 'Subtract two numbers.', category: INSTRUCTION_CATEGORY_NUMERIC },
52
- { name: 'multiply_numbers', description: 'Multiply two numbers.', category: INSTRUCTION_CATEGORY_NUMERIC },
53
- { name: 'divide_numbers', description: 'Divide two numbers.', category: INSTRUCTION_CATEGORY_NUMERIC },
54
- # string operations
55
- { name: 'add_strings', description: 'Concatenate two strings.', category: INSTRUCTION_CATEGORY_STRING },
56
- # environment operations
57
- { name: 'contract_address', description: 'Get the contract address.',
58
- category: INSTRUCTION_CATEGORY_ENVIRONMENT },
59
- # method operations
60
- { name: 'evaluate', description: 'Evaluate a method. Method name is the first input and arguments follow',
61
- category: INSTRUCTION_CATEGORY_METHODS },
62
- # object operations
63
- { name: 'field', description: 'Reference an object field.', category: INSTRUCTION_CATEGORY_OBJECTS },
64
- { name: 'initialize_udt', description: 'Instantiate UDT object.', category: INSTRUCTION_CATEGORY_OBJECTS },
65
- # conditional operations
66
- { name: 'conditional_jump', description: 'Jump to a label if first input is true.',
67
- category: INSTRUCTION_CATEGORY_CONDITIONAL },
68
- { name: 'unconditional_jump', description: 'Jump to a no matter what.',
69
- category: INSTRUCTION_CATEGORY_CONDITIONAL },
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
- # basic types
78
- 'address',
79
- 'boolean',
80
- # string types
81
- 'symbol',
82
- # collection types
83
- 'array',
84
- 'map',
85
- # numeric types
86
- ## signed
87
- 'i32',
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
- case @type_name
20
- when 'I32', 'I64', 'I256', 'U32', 'U64', 'U256'
21
- validate_numeric!
22
-
23
- # TODO: check type
24
- when 'Symbol', 'String'
25
- strip_and_remove_quotes(@initial_value)
26
- else
27
- raise 'Missing Invalid Type Name.'
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
- private
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
- def validate_numeric!
34
- raise 'Invalid initial value for type. Wrong type.' unless @initial_value =~ (/^[\-\.\d]\d*(\.?\d*)*/)
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
- @initial_value.to_i
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
@@ -38,7 +38,7 @@ module DTRCore
38
38
  end
39
39
 
40
40
  def to_s
41
- "#{name} { #{attributes.map { |x| "#{x[:name]}: #{x[:type]}" }.join("\n")} }"
41
+ "\t* (#{name})\n\t{\n#{@attributes.map { |x| "\t\t#{x[:name]}: #{x[:type]}" }.join("\n")}\n\t}"
42
42
  end
43
43
 
44
44
  def ==(other)
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.5.6
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-07 00:00:00.000000000 Z
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