Class: Q_Device

Inherits:
Object
  • Object
show all
Defined in:
lib/q-language/device.rb

Overview

Copyright © 2010-2011 Jesse Sielaff

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(script) ⇒ Q_Device

Returns a new instance of Q_Device.



7
8
9
10
11
12
13
14
15
16
17
# File 'lib/q-language/device.rb', line 7

def initialize (script)
  @script = script
  parse_script_into_nodes
  
  @max_nodes ||= 3000
  @max_method_nodes ||= 3000
  
  @max_array_length ||= 100_000
  @max_hash_length ||= 100_000
  @max_string_length ||= 100_000
end

Instance Attribute Details

#max_array_lengthObject

Returns the value of attribute max_array_length.



20
21
22
# File 'lib/q-language/device.rb', line 20

def max_array_length
  @max_array_length
end

#max_hash_lengthObject

Returns the value of attribute max_hash_length.



20
21
22
# File 'lib/q-language/device.rb', line 20

def max_hash_length
  @max_hash_length
end

#max_method_nodesObject

Returns the value of attribute max_method_nodes.



19
20
21
# File 'lib/q-language/device.rb', line 19

def max_method_nodes
  @max_method_nodes
end

#max_nodesObject

Returns the value of attribute max_nodes.



19
20
21
# File 'lib/q-language/device.rb', line 19

def max_nodes
  @max_nodes
end

#max_string_lengthObject

Returns the value of attribute max_string_length.



20
21
22
# File 'lib/q-language/device.rb', line 20

def max_string_length
  @max_string_length
end

#scriptObject (readonly)

Returns the value of attribute script.



21
22
23
# File 'lib/q-language/device.rb', line 21

def script
  @script
end

Instance Method Details

#delete_node(target_type = :all) ⇒ Object

• User method Removes a Node of the given target type from the Q_Device’s tree, rewrites the Q script based on the new tree, then returns the removed Node. All Nodes of the given type will be targeted with equal probability. If no target type is given, Node may be of any type. If no Node of the given type is found, returns nil.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/q-language/device.rb', line 30

def delete_node (target_type = :all)
  parse_script_into_nodes if @nodes_need_reloading
  
  candidate_nodes = nodes(target_type) - [@tree]
  return nil unless target_node = candidate_nodes.sample
  
  target_node.block.nodes.delete(target_node)
  nodes.delete(target_node)
  nodes(target_node.node_type).delete(target_node)
  
  rewrite_script
  
  target_node
end

#execute(variables = {}, *implicit) ⇒ Object

Executes the script in a new Q_Environment with the given variables and implicit receivers, then returns the Q_Environment.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/q-language/device.rb', line 48

def execute (variables = {}, *implicit)
  parse_script_into_nodes if @nodes_need_reloading
  
  object = Class.new.new
  object.class.send(:define_method, :to_q) { QDynamic.new(self) }
  
begin
  options = [@max_nodes, @max_method_nodes, @max_array_length, @max_hash_length, @max_string_length]
  env = Q_Environment.new(variables, *implicit, object, options)
  env.evaluate(@tree)
rescue Q_Environment::TooManyNodes
end
  
  env
end

#get_node(target_type = :all) ⇒ Object

• User method Returns a Node of the given type. All Nodes may be chosen with equal probability. If no node of the given is found, returns nil.



68
69
70
71
# File 'lib/q-language/device.rb', line 68

def get_node (target_type = :all)
  parse_script_into_nodes if @nodes_need_reloading
  nodes(target_type).sample
end

#insert_node(new_node) ⇒ Object

• User method Inserts the given Node into a random position in a random block in the tree, rewrites the Q script based on the new tree, then returns the Node. All blocks in the tree will be targeted with equal probability.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/q-language/device.rb', line 78

def insert_node (new_node)
  parse_script_into_nodes if @nodes_need_reloading
  
  if new_node.is_a? String
    new_node = Q_Parser.new(new_node).parse.first
  end
  
  nodes_in_target_block = nodes(:block).sample.nodes
  node_position = rand(nodes_in_target_block.length + 1)
  
  nodes_in_target_block.insert(node_position, new_node)
  nodes.push(new_node)
  nodes(new_node.node_type).push(new_node)
  
  rewrite_script
  
  new_node
end

#modifyObject

• User method Executes the given block, rewrites the Q script to reflect any changes to the tree, then returns the result of the block.



101
102
103
104
105
106
107
108
109
110
# File 'lib/q-language/device.rb', line 101

def modify
  parse_script_into_nodes if @nodes_need_reloading
  
  result = yield
  
  rewrite_script
  @nodes_need_reloading = true
  
  result
end

#nodes(type = :all) ⇒ Object

• User method Returns the Array containing all Nodes of the given type.



115
116
117
118
# File 'lib/q-language/device.rb', line 115

def nodes (type = :all)
  parse_script_into_nodes if @nodes_need_reloading
  instance_variable_get :"@#{type}_nodes"
end

#parse_script_into_nodesObject

Parses the Q script, then stores the resulting tree and all its Nodes.



122
123
124
125
126
# File 'lib/q-language/device.rb', line 122

def parse_script_into_nodes
  @tree, @block_nodes, @literal_nodes, @method_nodes, @variable_nodes = Q_Parser.new(@script).parse
  @all_nodes = @block_nodes + @literal_nodes + @method_nodes + @variable_nodes
  @nodes_need_reloading = false
end

#replace_node(new_node, target_type = :all) ⇒ Object

• User method Replaces a Node of the given target type from the Q_Device’s tree with the given Node, rewrites the Q script based on the new tree, then returns the removed Node. All Nodes of the given type will be targeted with equal probability. If no target type is given, removed Node may be of any type. If no target Node of the given type is found, returns nil.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/q-language/device.rb', line 135

def replace_node (new_node, target_type = :all)
  parse_script_into_nodes if @nodes_need_reloading
  
  candidate_nodes = nodes(target_type) - [@tree]
  return nil unless target_node = candidate_nodes.sample
  
  if new_node.is_a? String
    new_node = Q_Parser.new(new_node).parse.first
  end
  
  nodes_in_parent_block = target_node.block.nodes
  node_position = nodes_in_parent_block.index(target_node)
  
  nodes_in_parent_block[node_position] = new_node
  
  nodes.delete(target_node)
  nodes.push(new_node)
  
  nodes(target_node.node_type).delete(target_node)
  nodes(new_node.node_type).push(new_node)
  
  rewrite_script
  
  target_node
end

#rewrite_scriptObject

Converts the tree into script form, then stores the script.



163
164
165
# File 'lib/q-language/device.rb', line 163

def rewrite_script
  @script = @tree.to_script
end