Class: SByC::CodeTree::AstNode

Inherits:
Object
  • Object
show all
Defined in:
lib/sbyc/codetree/ast_node.rb,
lib/sbyc/codetree/eval/ast_node_ext.rb,
lib/sbyc/codetree/matching/ast_node_ext.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, children) ⇒ AstNode

Creates an ASTNode instance



17
18
19
# File 'lib/sbyc/codetree/ast_node.rb', line 17

def initialize(name, children)
  @name, @children = name, children
end

Instance Attribute Details

#childrenObject (readonly) Also known as: args

Children nodes



10
11
12
# File 'lib/sbyc/codetree/ast_node.rb', line 10

def children
  @children
end

#nameObject Also known as: function

Name of the method call



6
7
8
# File 'lib/sbyc/codetree/ast_node.rb', line 6

def name
  @name
end

#operatorObject (readonly)

Operator found by type checking



14
15
16
# File 'lib/sbyc/codetree/ast_node.rb', line 14

def operator
  @operator
end

Class Method Details

.coerce(arg) ⇒ Object

Coercion



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/sbyc/codetree/ast_node.rb', line 119

def self.coerce(arg)
  case arg
    when AstNode
      arg
    when Array
      name, children = arg
      if name.kind_of?(Symbol) and children.kind_of?(Array)
        if name == :_ and children.size == 1
          AstNode.new(:_, children)
        else
          AstNode.new(name, children.collect{|c| AstNode.coerce(c)})
        end
      else
        AstNode.new(:_, [ arg ])
      end
    else
      AstNode.new(:_, [ arg ])
  end
end

Instance Method Details

#==(other) ⇒ Object

Checks tree equality with another node



110
111
112
113
114
115
116
# File 'lib/sbyc/codetree/ast_node.rb', line 110

def ==(other)
  return false unless other.kind_of?(AstNode)
  return false unless (function == other.function)
  return false unless args.size == other.args.size
  return false unless args.zip(other.args).all?{|v1, v2| v1 == v2}
  true
end

#===(other) ⇒ Object

Applies ast node matching



6
7
8
9
10
11
12
# File 'lib/sbyc/codetree/matching/ast_node_ext.rb', line 6

def ===(other)
  if other.kind_of?(CodeTree::AstNode)
    CodeTree::Matcher.new(self) === other
  else
    super
  end
end

#[](*args, &block) ⇒ Object

Delegated to the children array



22
23
24
# File 'lib/sbyc/codetree/ast_node.rb', line 22

def [](*args, &block)
  children.[](*args, &block)
end

#branch?Boolean

Negation of leaf?

Returns:

  • (Boolean)


37
38
39
# File 'lib/sbyc/codetree/ast_node.rb', line 37

def branch?
  not(leaf?)
end

#code_inject!(map = nil, &block) ⇒ Object

Inject code through module mapped to function names



63
64
65
66
67
68
69
70
71
# File 'lib/sbyc/codetree/ast_node.rb', line 63

def code_inject!(map = nil, &block)
  map = CodeTree::Name2X::Delegate.coerce(map || block)
  visit{|node, collected| 
    ext = map.name2module(node.function)
    node.extend(ext) if ext
    nil
  }
  self
end

#digest(map = nil, &block) ⇒ Object

Create class instances



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/sbyc/codetree/ast_node.rb', line 74

def digest(map = nil, &block)
  map = CodeTree::Name2X::Delegate.coerce(map || block)
  visit{|node, collected| 
    if node.leaf?
      node.literal
    else
      ext = map.name2class(node.function)
      raise "Unexpected node function: #{node.function}" unless ext
      ext.new(*collected)
    end
  }
end

#each(&block) ⇒ Object

Yields block with each child in turn



42
43
44
# File 'lib/sbyc/codetree/ast_node.rb', line 42

def each(&block)
  children.each(&block)
end

#functional_compile(receiver_object = "receiver", scope_object = "scope", scope_method = :[]) ⇒ Object

Generates the code of an functional evaluation



23
24
25
# File 'lib/sbyc/codetree/eval/ast_node_ext.rb', line 23

def functional_compile(receiver_object = "receiver", scope_object = "scope", scope_method = :[])
  CodeTree::FunctionalEval.functional_compile(self, receiver_object, scope_object, scope_method)
end

#functional_eval(master_object, scope = {}, scope_method = :[]) ⇒ Object Also known as: apply

Executes functional evaluation of this ast



33
34
35
# File 'lib/sbyc/codetree/eval/ast_node_ext.rb', line 33

def functional_eval(master_object, scope = {}, scope_method = :[]) 
  CodeTree::FunctionalEval.functional_eval(self, master_object, scope)
end

#functional_proc(scope_method = :[]) ⇒ Object

Generates a lambda function for functional evaluation



28
29
30
# File 'lib/sbyc/codetree/eval/ast_node_ext.rb', line 28

def functional_proc(scope_method = :[])
  CodeTree::FunctionalEval.functional_proc(self, scope_method)
end

#inspectObject

Inspection



88
89
90
# File 'lib/sbyc/codetree/ast_node.rb', line 88

def inspect
  "(#{name} #{children.collect{|c| c.inspect}.join(', ')})"
end

#leaf?Boolean

Returns false

Returns:

  • (Boolean)


32
33
34
# File 'lib/sbyc/codetree/ast_node.rb', line 32

def leaf?
  (name == :_)
end

#literalObject

Recursively finds the first literal.



27
28
29
# File 'lib/sbyc/codetree/ast_node.rb', line 27

def literal
  leaf? ? children[0] : children[0].literal
end

#object_compile(scope_object = "scope", scope_method = :[]) ⇒ Object

Generates the code of an object evaluation



6
7
8
# File 'lib/sbyc/codetree/eval/ast_node_ext.rb', line 6

def object_compile(scope_object = "scope", scope_method = :[])
  CodeTree::ObjectEval.object_compile(self, scope_object, scope_method)
end

#object_eval(scope = {}, scope_method = :[]) ⇒ Object Also known as: call, eval

Executes object evaluation of this ast



16
17
18
# File 'lib/sbyc/codetree/eval/ast_node_ext.rb', line 16

def object_eval(scope = {}, scope_method = :[])
  CodeTree::ObjectEval.object_eval(self, scope)
end

#object_proc(scope_method = :[]) ⇒ Object

Generates a lambda function for object evaluation



11
12
13
# File 'lib/sbyc/codetree/eval/ast_node_ext.rb', line 11

def object_proc(scope_method = :[])
  CodeTree::ObjectEval.object_proc(self, scope_method)
end

#rename!(map = nil, &block) ⇒ Object

Renames some nodes, given a name2name map.



52
53
54
55
56
57
58
59
60
# File 'lib/sbyc/codetree/ast_node.rb', line 52

def rename!(map = nil, &block)
  map = CodeTree::Name2X::Delegate.coerce(map || block)
  visit{|node, collected|
    newname = map.name2name(node.name)
    node.send(:name=, newname) if newname
    nil
  }
  self
end

#to_aObject

Returns an array version of this ast



105
106
107
# File 'lib/sbyc/codetree/ast_node.rb', line 105

def to_a
  visit{|node, collected| [node.name, collected]}
end

#to_sObject

Returns a short string representation



93
94
95
96
97
98
99
100
101
102
# File 'lib/sbyc/codetree/ast_node.rb', line 93

def to_s
  case function
    when :'_'
      literal.inspect
    when :'?'
      literal.to_s
    else
      "(#{name} #{children.collect{|c| c.to_s}.join(', ')})"
  end
end

#visit {|_self, leaf? ? children : children.collect{|c| c.respond_to?(:visit) ? c.visit(&block) : c}| ... } ⇒ Object

Makes a depth-first-search visit of the AST

Yields:

Yield Parameters:



47
48
49
# File 'lib/sbyc/codetree/ast_node.rb', line 47

def visit(&block)
  yield(self, leaf? ? children : children.collect{|c| c.respond_to?(:visit) ? c.visit(&block) : c})
end