sbyc 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  module SByC
2
2
 
3
3
  # Version
4
- VERSION = "0.1.3".freeze
4
+ VERSION = "0.1.4".freeze
5
5
 
6
6
  # Provides tools around functional source code trees.
7
7
  module CodeTree
@@ -14,9 +14,5 @@ module SByC
14
14
  end # module CodeTree
15
15
 
16
16
  end # module SByC
17
-
18
- CodeTree = ::SByC::CodeTree
19
17
  require 'sbyc/codetree'
20
-
21
- TypeSystem = ::SByC::TypeSystem
22
18
  require 'sbyc/type_system'
@@ -1,81 +1,83 @@
1
- module CodeTree
2
-
3
- # Operator names
4
- OPERATOR_NAMES = {
5
- :'?' => :varref,
6
- :[] => :get,
7
- :[]= => :set,
8
- :** => :exponentiation,
9
- :~ => :complement,
10
- :== => :eq,
11
- #:!= => :neq,
12
- :-@ => :unary_minus,
13
- :+@ => :unary_plus,
14
- :- => :minus,
15
- :+ => :plus,
16
- :* => :times,
17
- :/ => :divide,
18
- :% => :modulo,
19
- :=~ => :match,
20
- :=== => :matches?,
21
- :& => :and,
22
- :| => :or,
23
- :> => :gt,
24
- :>= => :gte,
25
- :<= => :lte,
26
- :< => :lt,
27
- :>> => :right_shift,
28
- :<< => :left_shift,
29
- :'^' => :exclusive,
30
- :<=> => :compare
31
- }
32
- REVERSE_OPERATOR_NAMES = Hash[*OPERATOR_NAMES.to_a.collect{|c| c.reverse}.flatten]
33
-
34
- # Parses some code or block
35
- def parse(code = nil, options = nil, &block)
36
- code, options = nil, code if code.kind_of?(Hash) and options.nil?
37
- ProcParser::parse(code, options || {}, &block)
38
- end
39
- module_function :parse
40
-
41
- # Alias for _parse_
42
- def expr(code = nil, options = nil, &block)
43
- parse(code, options || {}, &block)
44
- end
45
- module_function :expr
46
-
47
- # Factors a CodeTree::Matcher instance
48
- def matcher(code = nil, &block)
49
- CodeTree::Matcher.new(parse(code, &block))
50
- end
51
- module_function :matcher
52
-
53
- # Factors a rewriter instance
54
- def rewriter(&definition)
55
- CodeTree::Rewriting::Rewriter.new(&definition)
56
- end
57
- module_function :rewriter
58
-
59
- # Factors a producer instance
60
- def producer(default_rules = true, &definition)
61
- CodeTree::Producing::Producer.new(default_rules, &definition)
62
- end
63
- module_function :producer
64
-
65
- # Converts an argument to an parse tree (an ASTNode instance)
66
- def coerce(arg)
67
- case arg
68
- when AstNode
69
- arg
70
- when Proc, String
71
- CodeTree::parse(arg)
72
- else
73
- raise "Unable to coerce #{arg.inspect} to a CodeTree::AstNode"
1
+ module SByC
2
+ module CodeTree
3
+
4
+ # Operator names
5
+ OPERATOR_NAMES = {
6
+ :'?' => :varref,
7
+ :[] => :get,
8
+ :[]= => :set,
9
+ :** => :exponentiation,
10
+ :~ => :complement,
11
+ :== => :eq,
12
+ #:!= => :neq,
13
+ :-@ => :unary_minus,
14
+ :+@ => :unary_plus,
15
+ :- => :minus,
16
+ :+ => :plus,
17
+ :* => :times,
18
+ :/ => :divide,
19
+ :% => :modulo,
20
+ :=~ => :match,
21
+ :=== => :matches?,
22
+ :& => :and,
23
+ :| => :or,
24
+ :> => :gt,
25
+ :>= => :gte,
26
+ :<= => :lte,
27
+ :< => :lt,
28
+ :>> => :right_shift,
29
+ :<< => :left_shift,
30
+ :'^' => :exclusive,
31
+ :<=> => :compare
32
+ }
33
+ REVERSE_OPERATOR_NAMES = Hash[*OPERATOR_NAMES.to_a.collect{|c| c.reverse}.flatten]
34
+
35
+ # Parses some code or block
36
+ def parse(code = nil, options = nil, &block)
37
+ code, options = nil, code if code.kind_of?(Hash) and options.nil?
38
+ ProcParser::parse(code, options || {}, &block)
74
39
  end
75
- end
76
- module_function :coerce
77
-
78
- end # module CodeTree
40
+ module_function :parse
41
+
42
+ # Alias for _parse_
43
+ def expr(code = nil, options = nil, &block)
44
+ parse(code, options || {}, &block)
45
+ end
46
+ module_function :expr
47
+
48
+ # Factors a CodeTree::Matcher instance
49
+ def matcher(code = nil, &block)
50
+ CodeTree::Matcher.new(parse(code, &block))
51
+ end
52
+ module_function :matcher
53
+
54
+ # Factors a rewriter instance
55
+ def rewriter(&definition)
56
+ CodeTree::Rewriting::Rewriter.new(&definition)
57
+ end
58
+ module_function :rewriter
59
+
60
+ # Factors a producer instance
61
+ def producer(default_rules = true, &definition)
62
+ CodeTree::Producing::Producer.new(default_rules, &definition)
63
+ end
64
+ module_function :producer
65
+
66
+ # Converts an argument to an parse tree (an ASTNode instance)
67
+ def coerce(arg)
68
+ case arg
69
+ when AstNode
70
+ arg
71
+ when Proc, String
72
+ CodeTree::parse(arg)
73
+ else
74
+ raise "Unable to coerce #{arg.inspect} to a CodeTree::AstNode"
75
+ end
76
+ end
77
+ module_function :coerce
78
+
79
+ end # module CodeTree
80
+ end # module SByC
79
81
  require 'sbyc/codetree/ast_node'
80
82
  require 'sbyc/codetree/proc_parser'
81
83
  require 'sbyc/codetree/eval'
@@ -1,140 +1,142 @@
1
- module CodeTree
2
- class AstNode
1
+ module SByC
2
+ module CodeTree
3
+ class AstNode
3
4
 
4
- # Name of the method call
5
- attr_accessor :name
6
- alias :function :name
5
+ # Name of the method call
6
+ attr_accessor :name
7
+ alias :function :name
7
8
 
8
- # Children nodes
9
- attr_reader :children
10
- alias :args :children
9
+ # Children nodes
10
+ attr_reader :children
11
+ alias :args :children
11
12
 
12
- # Operator found by type checking
13
- attr_reader :operator
13
+ # Operator found by type checking
14
+ attr_reader :operator
14
15
 
15
- # Creates an ASTNode instance
16
- def initialize(name, children)
17
- @name, @children = name, children
18
- end
16
+ # Creates an ASTNode instance
17
+ def initialize(name, children)
18
+ @name, @children = name, children
19
+ end
19
20
 
20
- # Delegated to the children array
21
- def [](*args, &block)
22
- children.[](*args, &block)
23
- end
21
+ # Delegated to the children array
22
+ def [](*args, &block)
23
+ children.[](*args, &block)
24
+ end
24
25
 
25
- # Recursively finds the first literal.
26
- def literal
27
- leaf? ? children[0] : children[0].literal
28
- end
26
+ # Recursively finds the first literal.
27
+ def literal
28
+ leaf? ? children[0] : children[0].literal
29
+ end
29
30
 
30
- # Returns false
31
- def leaf?
32
- (name == :_)
33
- end
31
+ # Returns false
32
+ def leaf?
33
+ (name == :_)
34
+ end
34
35
 
35
- # Negation of leaf?
36
- def branch?
37
- not(leaf?)
38
- end
36
+ # Negation of leaf?
37
+ def branch?
38
+ not(leaf?)
39
+ end
39
40
 
40
- # Yields block with each child in turn
41
- def each(&block)
42
- children.each(&block)
43
- end
41
+ # Yields block with each child in turn
42
+ def each(&block)
43
+ children.each(&block)
44
+ end
44
45
 
45
- # Makes a depth-first-search visit of the AST
46
- def visit(&block)
47
- yield(self, leaf? ? children : children.collect{|c| c.respond_to?(:visit) ? c.visit(&block) : c})
48
- end
46
+ # Makes a depth-first-search visit of the AST
47
+ def visit(&block)
48
+ yield(self, leaf? ? children : children.collect{|c| c.respond_to?(:visit) ? c.visit(&block) : c})
49
+ end
49
50
 
50
- # Renames some nodes, given a name2name map.
51
- def rename!(map = nil, &block)
52
- map = CodeTree::Name2X::Delegate.coerce(map || block)
53
- visit{|node, collected|
54
- newname = map.name2name(node.name)
55
- node.send(:name=, newname) if newname
56
- nil
57
- }
58
- self
59
- end
51
+ # Renames some nodes, given a name2name map.
52
+ def rename!(map = nil, &block)
53
+ map = CodeTree::Name2X::Delegate.coerce(map || block)
54
+ visit{|node, collected|
55
+ newname = map.name2name(node.name)
56
+ node.send(:name=, newname) if newname
57
+ nil
58
+ }
59
+ self
60
+ end
60
61
 
61
- # Inject code through module mapped to function names
62
- def code_inject!(map = nil, &block)
63
- map = CodeTree::Name2X::Delegate.coerce(map || block)
64
- visit{|node, collected|
65
- ext = map.name2module(node.function)
66
- node.extend(ext) if ext
67
- nil
68
- }
69
- self
70
- end
62
+ # Inject code through module mapped to function names
63
+ def code_inject!(map = nil, &block)
64
+ map = CodeTree::Name2X::Delegate.coerce(map || block)
65
+ visit{|node, collected|
66
+ ext = map.name2module(node.function)
67
+ node.extend(ext) if ext
68
+ nil
69
+ }
70
+ self
71
+ end
71
72
 
72
- # Create class instances
73
- def digest(map = nil, &block)
74
- map = CodeTree::Name2X::Delegate.coerce(map || block)
75
- visit{|node, collected|
76
- if node.leaf?
77
- node.literal
78
- else
79
- ext = map.name2class(node.function)
80
- raise "Unexpected node function: #{node.function}" unless ext
81
- ext.new(*collected)
82
- end
83
- }
84
- end
73
+ # Create class instances
74
+ def digest(map = nil, &block)
75
+ map = CodeTree::Name2X::Delegate.coerce(map || block)
76
+ visit{|node, collected|
77
+ if node.leaf?
78
+ node.literal
79
+ else
80
+ ext = map.name2class(node.function)
81
+ raise "Unexpected node function: #{node.function}" unless ext
82
+ ext.new(*collected)
83
+ end
84
+ }
85
+ end
85
86
 
86
- # Inspection
87
- def inspect
88
- "(#{name} #{children.collect{|c| c.inspect}.join(', ')})"
89
- end
87
+ # Inspection
88
+ def inspect
89
+ "(#{name} #{children.collect{|c| c.inspect}.join(', ')})"
90
+ end
90
91
 
91
- # Returns a short string representation
92
- def to_s
93
- case function
94
- when :'_'
95
- literal.inspect
96
- when :'?'
97
- literal.to_s
98
- else
99
- "(#{name} #{children.collect{|c| c.to_s}.join(', ')})"
92
+ # Returns a short string representation
93
+ def to_s
94
+ case function
95
+ when :'_'
96
+ literal.inspect
97
+ when :'?'
98
+ literal.to_s
99
+ else
100
+ "(#{name} #{children.collect{|c| c.to_s}.join(', ')})"
101
+ end
100
102
  end
101
- end
102
103
 
103
- # Returns an array version of this ast
104
- def to_a
105
- visit{|node, collected| [node.name, collected]}
106
- end
104
+ # Returns an array version of this ast
105
+ def to_a
106
+ visit{|node, collected| [node.name, collected]}
107
+ end
107
108
 
108
- # Checks tree equality with another node
109
- def ==(other)
110
- return false unless other.kind_of?(AstNode)
111
- return false unless (function == other.function)
112
- return false unless args.size == other.args.size
113
- return false unless args.zip(other.args).all?{|v1, v2| v1 == v2}
114
- true
115
- end
109
+ # Checks tree equality with another node
110
+ def ==(other)
111
+ return false unless other.kind_of?(AstNode)
112
+ return false unless (function == other.function)
113
+ return false unless args.size == other.args.size
114
+ return false unless args.zip(other.args).all?{|v1, v2| v1 == v2}
115
+ true
116
+ end
116
117
 
117
- # Coercion
118
- def self.coerce(arg)
119
- case arg
120
- when AstNode
121
- arg
122
- when Array
123
- name, children = arg
124
- if name.kind_of?(Symbol) and children.kind_of?(Array)
125
- if name == :_ and children.size == 1
126
- AstNode.new(:_, children)
118
+ # Coercion
119
+ def self.coerce(arg)
120
+ case arg
121
+ when AstNode
122
+ arg
123
+ when Array
124
+ name, children = arg
125
+ if name.kind_of?(Symbol) and children.kind_of?(Array)
126
+ if name == :_ and children.size == 1
127
+ AstNode.new(:_, children)
128
+ else
129
+ AstNode.new(name, children.collect{|c| AstNode.coerce(c)})
130
+ end
127
131
  else
128
- AstNode.new(name, children.collect{|c| AstNode.coerce(c)})
132
+ AstNode.new(:_, [ arg ])
129
133
  end
130
134
  else
131
135
  AstNode.new(:_, [ arg ])
132
- end
133
- else
134
- AstNode.new(:_, [ arg ])
136
+ end
135
137
  end
136
- end
137
138
 
138
- private :name=
139
- end # module AstNode
140
- end # module CodeTree
139
+ private :name=
140
+ end # module AstNode
141
+ end # module CodeTree
142
+ end # module SByC
@@ -1,38 +1,40 @@
1
- module CodeTree
2
- class AstNode
1
+ module SByC
2
+ module CodeTree
3
+ class AstNode
3
4
 
4
- # Generates the code of an object evaluation
5
- def object_compile(scope_object = "scope", scope_method = :[])
6
- CodeTree::ObjectEval.object_compile(self, scope_object, scope_method)
7
- end
5
+ # Generates the code of an object evaluation
6
+ def object_compile(scope_object = "scope", scope_method = :[])
7
+ CodeTree::ObjectEval.object_compile(self, scope_object, scope_method)
8
+ end
8
9
 
9
- # Generates a lambda function for object evaluation
10
- def object_proc(scope_method = :[])
11
- CodeTree::ObjectEval.object_proc(self, scope_method)
12
- end
10
+ # Generates a lambda function for object evaluation
11
+ def object_proc(scope_method = :[])
12
+ CodeTree::ObjectEval.object_proc(self, scope_method)
13
+ end
13
14
 
14
- # Executes object evaluation of this ast
15
- def object_eval(scope = {}, scope_method = :[])
16
- CodeTree::ObjectEval.object_eval(self, scope)
17
- end
18
- alias :call :object_eval
19
- alias :eval :object_eval
15
+ # Executes object evaluation of this ast
16
+ def object_eval(scope = {}, scope_method = :[])
17
+ CodeTree::ObjectEval.object_eval(self, scope)
18
+ end
19
+ alias :call :object_eval
20
+ alias :eval :object_eval
20
21
 
21
- # Generates the code of an functional evaluation
22
- def functional_compile(receiver_object = "receiver", scope_object = "scope", scope_method = :[])
23
- CodeTree::FunctionalEval.functional_compile(self, receiver_object, scope_object, scope_method)
24
- end
22
+ # Generates the code of an functional evaluation
23
+ def functional_compile(receiver_object = "receiver", scope_object = "scope", scope_method = :[])
24
+ CodeTree::FunctionalEval.functional_compile(self, receiver_object, scope_object, scope_method)
25
+ end
25
26
 
26
- # Generates a lambda function for functional evaluation
27
- def functional_proc(scope_method = :[])
28
- CodeTree::FunctionalEval.functional_proc(self, scope_method)
29
- end
27
+ # Generates a lambda function for functional evaluation
28
+ def functional_proc(scope_method = :[])
29
+ CodeTree::FunctionalEval.functional_proc(self, scope_method)
30
+ end
30
31
 
31
- # Executes functional evaluation of this ast
32
- def functional_eval(master_object, scope = {}, scope_method = :[])
33
- CodeTree::FunctionalEval.functional_eval(self, master_object, scope)
34
- end
35
- alias :apply :functional_eval
32
+ # Executes functional evaluation of this ast
33
+ def functional_eval(master_object, scope = {}, scope_method = :[])
34
+ CodeTree::FunctionalEval.functional_eval(self, master_object, scope)
35
+ end
36
+ alias :apply :functional_eval
36
37
 
37
- end # class AstNode
38
- end # module CodeTree
38
+ end # class AstNode
39
+ end # module CodeTree
40
+ end # module SByC