carbon-compiler 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +17 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +39 -0
  6. data/.travis.yml +5 -0
  7. data/CODE_OF_CONDUCT.md +49 -0
  8. data/Gemfile +11 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +41 -0
  11. data/Rakefile +9 -0
  12. data/Vagrantfile +84 -0
  13. data/carbon-compiler.gemspec +28 -0
  14. data/lib/carbon/compiler.rb +20 -0
  15. data/lib/carbon/compiler/directive.rb +48 -0
  16. data/lib/carbon/compiler/directive/import.rb +17 -0
  17. data/lib/carbon/compiler/errors.rb +7 -0
  18. data/lib/carbon/compiler/location.rb +136 -0
  19. data/lib/carbon/compiler/metanostic.rb +123 -0
  20. data/lib/carbon/compiler/metanostic/defaults.rb +41 -0
  21. data/lib/carbon/compiler/metanostic/defaults.yml +138 -0
  22. data/lib/carbon/compiler/metanostic/diagnostic.rb +112 -0
  23. data/lib/carbon/compiler/metanostic/list.rb +109 -0
  24. data/lib/carbon/compiler/metanostic/mode.rb +162 -0
  25. data/lib/carbon/compiler/metanostic/state.rb +174 -0
  26. data/lib/carbon/compiler/metanostic/template.erb +11 -0
  27. data/lib/carbon/compiler/node.rb +18 -0
  28. data/lib/carbon/compiler/node/base.rb +213 -0
  29. data/lib/carbon/compiler/node/definition.rb +19 -0
  30. data/lib/carbon/compiler/node/definition/class.rb +24 -0
  31. data/lib/carbon/compiler/node/definition/class/element.rb +18 -0
  32. data/lib/carbon/compiler/node/definition/directive.rb +22 -0
  33. data/lib/carbon/compiler/node/definition/directive/function.rb +18 -0
  34. data/lib/carbon/compiler/node/definition/enum.rb +20 -0
  35. data/lib/carbon/compiler/node/definition/enum/element.rb +17 -0
  36. data/lib/carbon/compiler/node/definition/function.rb +44 -0
  37. data/lib/carbon/compiler/node/definition/function/body.rb +17 -0
  38. data/lib/carbon/compiler/node/definition/function/name.rb +18 -0
  39. data/lib/carbon/compiler/node/definition/function/parameter.rb +18 -0
  40. data/lib/carbon/compiler/node/definition/function/parameters.rb +17 -0
  41. data/lib/carbon/compiler/node/definition/module.rb +23 -0
  42. data/lib/carbon/compiler/node/definition/struct.rb +24 -0
  43. data/lib/carbon/compiler/node/definition/struct/element.rb +18 -0
  44. data/lib/carbon/compiler/node/etype.rb +66 -0
  45. data/lib/carbon/compiler/node/etype/option.rb +25 -0
  46. data/lib/carbon/compiler/node/etype/star.rb +13 -0
  47. data/lib/carbon/compiler/node/expression.rb +18 -0
  48. data/lib/carbon/compiler/node/expression/assignment.rb +22 -0
  49. data/lib/carbon/compiler/node/expression/call.rb +22 -0
  50. data/lib/carbon/compiler/node/expression/call/access.rb +24 -0
  51. data/lib/carbon/compiler/node/expression/call/attribute.rb +23 -0
  52. data/lib/carbon/compiler/node/expression/call/enum.rb +25 -0
  53. data/lib/carbon/compiler/node/expression/call/module.rb +24 -0
  54. data/lib/carbon/compiler/node/expression/call/parameters.rb +17 -0
  55. data/lib/carbon/compiler/node/expression/call/self.rb +17 -0
  56. data/lib/carbon/compiler/node/expression/call/unified.rb +27 -0
  57. data/lib/carbon/compiler/node/expression/literal.rb +83 -0
  58. data/lib/carbon/compiler/node/expression/operation.rb +20 -0
  59. data/lib/carbon/compiler/node/expression/operation/and.rb +20 -0
  60. data/lib/carbon/compiler/node/expression/operation/neq.rb +21 -0
  61. data/lib/carbon/compiler/node/expression/operation/normal.rb +20 -0
  62. data/lib/carbon/compiler/node/expression/operation/or.rb +20 -0
  63. data/lib/carbon/compiler/node/expression/unit.rb +16 -0
  64. data/lib/carbon/compiler/node/name.rb +27 -0
  65. data/lib/carbon/compiler/node/root.rb +23 -0
  66. data/lib/carbon/compiler/node/statement.rb +24 -0
  67. data/lib/carbon/compiler/node/statement/catch.rb +20 -0
  68. data/lib/carbon/compiler/node/statement/condition.rb +14 -0
  69. data/lib/carbon/compiler/node/statement/else.rb +17 -0
  70. data/lib/carbon/compiler/node/statement/elsif.rb +18 -0
  71. data/lib/carbon/compiler/node/statement/finally.rb +17 -0
  72. data/lib/carbon/compiler/node/statement/for.rb +18 -0
  73. data/lib/carbon/compiler/node/statement/if.rb +18 -0
  74. data/lib/carbon/compiler/node/statement/let.rb +18 -0
  75. data/lib/carbon/compiler/node/statement/match.rb +14 -0
  76. data/lib/carbon/compiler/node/statement/return.rb +17 -0
  77. data/lib/carbon/compiler/node/statement/try.rb +19 -0
  78. data/lib/carbon/compiler/node/statement/while.rb +19 -0
  79. data/lib/carbon/compiler/parser.rb +63 -0
  80. data/lib/carbon/compiler/parser/common.rb +79 -0
  81. data/lib/carbon/compiler/parser/expressions.rb +39 -0
  82. data/lib/carbon/compiler/parser/expressions/precedence.rb +134 -0
  83. data/lib/carbon/compiler/parser/expressions/primary.rb +120 -0
  84. data/lib/carbon/compiler/parser/firsts.rb +74 -0
  85. data/lib/carbon/compiler/parser/helpers.rb +61 -0
  86. data/lib/carbon/compiler/parser/root.rb +57 -0
  87. data/lib/carbon/compiler/parser/root/class.rb +34 -0
  88. data/lib/carbon/compiler/parser/root/directive.rb +87 -0
  89. data/lib/carbon/compiler/parser/root/enum.rb +45 -0
  90. data/lib/carbon/compiler/parser/root/function.rb +90 -0
  91. data/lib/carbon/compiler/parser/root/struct.rb +34 -0
  92. data/lib/carbon/compiler/parser/root/trait.rb +44 -0
  93. data/lib/carbon/compiler/parser/statements.rb +86 -0
  94. data/lib/carbon/compiler/parser/statements/if.rb +50 -0
  95. data/lib/carbon/compiler/parser/statements/match.rb +39 -0
  96. data/lib/carbon/compiler/parser/statements/try.rb +49 -0
  97. data/lib/carbon/compiler/project.rb +37 -0
  98. data/lib/carbon/compiler/project/file.rb +64 -0
  99. data/lib/carbon/compiler/scanner.rb +82 -0
  100. data/lib/carbon/compiler/scanner/main.rb +76 -0
  101. data/lib/carbon/compiler/scanner/token.rb +58 -0
  102. data/lib/carbon/compiler/version.rb +8 -0
  103. data/lib/carbon/compiler/visitor.rb +13 -0
  104. data/lib/carbon/compiler/visitor/base.rb +52 -0
  105. data/lib/carbon/compiler/visitor/generation.rb +45 -0
  106. data/lib/carbon/compiler/visitor/generation/asserts.rb +30 -0
  107. data/lib/carbon/compiler/visitor/generation/class.rb +93 -0
  108. data/lib/carbon/compiler/visitor/generation/context.rb +75 -0
  109. data/lib/carbon/compiler/visitor/generation/expressions.rb +82 -0
  110. data/lib/carbon/compiler/visitor/generation/expressions/assignment.rb +105 -0
  111. data/lib/carbon/compiler/visitor/generation/expressions/calls.rb +89 -0
  112. data/lib/carbon/compiler/visitor/generation/function.rb +68 -0
  113. data/lib/carbon/compiler/visitor/generation/statements.rb +131 -0
  114. data/lib/carbon/compiler/visitor/generation/struct.rb +115 -0
  115. data/lib/carbon/compiler/visitor/preparation.rb +86 -0
  116. data/lib/carbon/compiler/visitor/preparation/expressions.rb +26 -0
  117. data/lib/carbon/compiler/visitor/preparation/function.rb +55 -0
  118. data/lib/carbon/compiler/visitor/preparation/statements.rb +73 -0
  119. data/lib/carbon/compiler/visitor/preparation/struct.rb +37 -0
  120. data/program.ca +16 -0
  121. data/test.rb +21 -0
  122. metadata +234 -0
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "carbon/compiler/visitor/generation/context"
5
+
6
+ module Carbon
7
+ module Compiler
8
+ module Visitor
9
+ class Generation
10
+ include Base
11
+
12
+ require "carbon/compiler/visitor/generation/asserts"
13
+ require "carbon/compiler/visitor/generation/expressions"
14
+ require "carbon/compiler/visitor/generation/function"
15
+ require "carbon/compiler/visitor/generation/statements"
16
+ require "carbon/compiler/visitor/generation/struct"
17
+
18
+ include Generation::Asserts
19
+ include Generation::Expressions
20
+ include Generation::Function
21
+ include Generation::Statements
22
+ include Generation::Struct
23
+
24
+ def initialize(file, index)
25
+ @index = index
26
+ @file = file
27
+ @name = @file.module
28
+ end
29
+
30
+ def call(node)
31
+ accept(node)
32
+ end
33
+
34
+ on Node::Root => :visit_root
35
+ def visit_root(node)
36
+ node.each { |c| accept(c) }
37
+ end
38
+
39
+ on Node::Definition::Directive => :visit_directive
40
+ def visit_directive(node)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Generation
8
+ module Asserts
9
+ def assert_type_equal(found, expected, location: Location.default)
10
+ return unless found != expected
11
+ @file.emit("Expression/Type/Mismatch", location, [found, expected])
12
+ end
13
+
14
+ def assert_type_void(found, location: Location.default)
15
+ assert_type_equal(found, Carbon::Void, location: location)
16
+ end
17
+
18
+ def assert_type_boolean(found, location: Location.default)
19
+ assert_type_equal(found, Carbon::Boolean, location: location)
20
+ end
21
+
22
+ def assert_nolocal(name, context, location: Location.default)
23
+ return unless context.key?(name)
24
+ @file.emit("Statement/Let/Redefine", location, [name])
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Generation
8
+ module Class
9
+ Generation.on Node::Definition::Class => :visit_class
10
+ def visit_class(node)
11
+ @index.define(class: @name) do |cl|
12
+ cl[:elements] = node.each
13
+ end
14
+
15
+ class_accessors(node)
16
+ class_allocate(node)
17
+ end
18
+
19
+ private
20
+
21
+ def class_allocate(node)
22
+ fname = @name.call("allocate", [])
23
+ @index.define(function: fname) do |function|
24
+ function[:return] = @name
25
+ class_allocate_definition(function[:definition])
26
+ end
27
+ end
28
+
29
+ def class_accessors(node)
30
+ node.each_with_index do |element, index|
31
+ class_read_accessor(element, index, node)
32
+ class_write_accessor(element, index, node)
33
+ end
34
+ end
35
+
36
+ def class_read_accessor(element, index, node)
37
+ fname = @name.call(element.name.value, [@name])
38
+ @index.define(function: fname) do |function|
39
+ function[:return] = element.type
40
+ class_read_accessor_definition(function[:definition], element,
41
+ index)
42
+ end
43
+
44
+ fname = @name.call("@#{element.name.value}", [@name])
45
+ @index.define(function: fname) do |function|
46
+ function[:return] = element.type
47
+ class_read_accessor_definition(function[:definition], element,
48
+ index)
49
+ end
50
+ end
51
+
52
+ def class_write_accessor(element, index, node)
53
+ fname = @name.call("#{element.name.value}=", [@name, element.type])
54
+ @index.define(function: fname) do |function|
55
+ function[:return] = element.type
56
+ class_write_accessor_definition(function[:definition], element,
57
+ index)
58
+ end
59
+
60
+ fname = @name.call("@#{element.name.value}=", [@name, element.type])
61
+ @index.define(function: fname) do |function|
62
+ function[:return] = element.type
63
+ class_write_accessor_definition(function[:definition], element,
64
+ index)
65
+ end
66
+ end
67
+
68
+ def class_read_accessor_definition(definition, element, index)
69
+ entry = definition.add("entry").build
70
+ this = definition.params[0]
71
+ this.name = "self"
72
+ gep = entry.class_gep(this, index).as(this.type)
73
+ entry.ret(entry.load(gep).as(element.type))
74
+ end
75
+
76
+ def class_write_accessor_definition(definition, element, index)
77
+ entry = definition.add("entry").build
78
+ this, value = definition.params
79
+ this.name, value.name = %w(self value)
80
+ gep = entry.class_gep(this, index).as(this.type)
81
+ entry.store(value, gep)
82
+ entry.ret(value)
83
+ end
84
+
85
+ def class_allocate_definition(definition)
86
+ entry = definition.add("entry").build
87
+ entry.ret(entry.malloc(entry.deref(@name).as(@name)).as(@name))
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Generation
8
+ # Context for building function bodies.
9
+ class Context
10
+ attr_reader :index
11
+ attr_reader :function
12
+
13
+ def initialize(definition, index, function)
14
+ @locals = []
15
+ @definition = definition
16
+ @index = index
17
+ @function = function
18
+ end
19
+
20
+ def block
21
+ @block ||= @definition.add("entry")
22
+ end
23
+
24
+ def new(name = "")
25
+ @definition.add(name)
26
+ end
27
+
28
+ def build(*p)
29
+ return block.build(*p) unless block_given?
30
+ result = nil
31
+ block.build(*p) { |*a| result = yield(*a) }
32
+ result
33
+ end
34
+
35
+ def swap(other)
36
+ old, @block = @block, other
37
+ old
38
+ end
39
+
40
+ def find(name)
41
+ index.fetch(name)
42
+ end
43
+
44
+ def key?(name)
45
+ current.key?(name)
46
+ end
47
+
48
+ def [](name)
49
+ current[name]
50
+ end
51
+
52
+ def []=(name, value)
53
+ top[name] = value
54
+ end
55
+
56
+ def current
57
+ @locals.inject({}, :merge)
58
+ end
59
+
60
+ def push
61
+ @locals << {}
62
+ end
63
+
64
+ def pop
65
+ @locals.pop
66
+ end
67
+
68
+ def top
69
+ @locals.last
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "carbon/compiler/visitor/generation/expressions/assignment"
5
+ require "carbon/compiler/visitor/generation/expressions/calls"
6
+
7
+ module Carbon
8
+ module Compiler
9
+ module Visitor
10
+ class Generation
11
+ module Expressions
12
+ include Generation::Expressions::Assignment
13
+ include Generation::Expressions::Calls
14
+
15
+ Generation.on Node::Expression::Literal => :visit_expression_literal
16
+ def visit_expression_literal(node, context)
17
+ Tacky::Typed.new(node.value, node.type)
18
+ end
19
+
20
+ # TODO: implement short circuitry
21
+ Generation.on Node::Expression::Operation::And =>
22
+ :visit_expression_operation_and
23
+ def visit_expression_operation_and(node, context)
24
+ context.build do |b|
25
+ left = accept(node.left, context)
26
+ assert_type_boolean(left.type, location: node.left.location)
27
+ lchk = b.icmp(:ne, left, 0).as(Carbon::Boolean)
28
+ right = accept(node.right, context)
29
+ assert_type_boolean(right.type, location: node.right.location)
30
+ rchk = b.icmp(:ne, right, 0).as(Carbon::Boolean)
31
+ b.and(lchk, rchk).as(Carbon::Boolean)
32
+ end
33
+ end
34
+
35
+ Generation.on Node::Expression::Operation::Or =>
36
+ :visit_expression_operation_or
37
+ def visit_expression_operation_or(node, context)
38
+ context.build do |b|
39
+ left = accept(node.left, context)
40
+ assert_type_boolean(left.type, location: node.left.location)
41
+ lchk = b.icmp(:ne, left, 0).as(Carbon::Boolean)
42
+ right = accept(node.right, context)
43
+ assert_type_boolean(left.right, location: node.right.location)
44
+ rchk = b.icmp(:ne, right, 0).as(Carbon::Boolean)
45
+ b.or(lchk, rchk).as(Carbon::Boolean)
46
+ end
47
+ end
48
+
49
+ Generation.on Node::Expression::Operation::Neq =>
50
+ :visit_expression_operation_neq
51
+ def visit_expression_operation_neq(node, context)
52
+ context.build do |b|
53
+ left = accept(node.left, context)
54
+ right = accept(node.right, context)
55
+ name = left.type.call(:==, [left.type, right.type])
56
+ result = b.call(name, left, right).as(Carbon::Boolean)
57
+ context.type(b.xor(result, 1), Carbon::Boolean)
58
+ end
59
+ end
60
+
61
+ Generation.on Node::Expression::Operation::Normal =>
62
+ :visit_expression_operation_normal
63
+ def visit_expression_operation_normal(node, context)
64
+ context.build do |b|
65
+ left = accept(node.left, context)
66
+ right = accept(node.right, context)
67
+ name = left.type.call(node.op.value, [left.type, right.type])
68
+ type = context.find(name).return
69
+ b.call(name, left, right).as(type)
70
+ end
71
+ end
72
+
73
+ Generation.on Node::Name => :visit_name
74
+ def visit_name(node, context)
75
+ value = context.current.fetch(node.value)
76
+ context.build.load(value).as(value.type)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Generation
8
+ module Expressions
9
+ module Assignment
10
+ Generation.on Node::Expression::Assignment =>
11
+ :visit_expression_assignment
12
+ def visit_expression_assignment(node, context)
13
+ case node.left
14
+ when Node::Expression::Call::Access
15
+ assign_access(node, context)
16
+ when Node::Expression::Call::Attribute
17
+ assign_attribute(node, context)
18
+ when Node::Name
19
+ assign_name(node, context)
20
+ else fail # not possible
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def assign_access(node, context)
27
+ access = node.left
28
+ base = accept(access.expression, context)
29
+ params = [*access.parameters, node.right]
30
+ .map { |p| accept(p, context) }
31
+ ptypes = params.map(&:type)
32
+ name = base.type.call("[]=", [base.type, *ptypes],
33
+ access.generics)
34
+ func, gens = context.find(name)
35
+ context.build.call(name, base, *params).as(func.return.sub(gens))
36
+ end
37
+
38
+ def assign_attribute(node, context)
39
+ attribute = node.left
40
+ base = accept(attribute.expression, context)
41
+ bitem = context.index.fetch(base.type).first
42
+
43
+ if bitem.is_a?(Carbon::Concrete::Item::Struct) &&
44
+ attribute.expression.is_a?(Node::Name)
45
+ assign_attribute_struct(attribute, base, node, context)
46
+ else
47
+ assign_attribute_other(attribute, base, node, context)
48
+ end
49
+ end
50
+
51
+ def assign_attribute_struct(attribute, base, node, context)
52
+ params = [accept(node.right, context)]
53
+ ptypes = params.map(&:type)
54
+ name = base.type.call("#{attribute.name.value}=",
55
+ [base.type.to_pointer, *ptypes], attribute.generics)
56
+ func, gens = context.find(name) do
57
+ return assign_attribute_other(attribute, base, node, context)
58
+ end
59
+
60
+ address = context.current.fetch(attribute.expression.value)
61
+ context.build do |b|
62
+ b.call(name, address, *params).as(func.return.sub(gens))
63
+ end
64
+ end
65
+
66
+ def assign_attribute_other(attribute, base, node, context)
67
+ params = [accept(node.right, context)]
68
+ ptypes = params.map(&:type)
69
+ name = base.type.call("#{attribute.name.value}=",
70
+ [base.type, *ptypes], attribute.generics)
71
+ func, gens = context.find(name)
72
+ context.build.call(name, base, *params).as(func.return.sub(gens))
73
+ end
74
+
75
+ def assign_name(node, context)
76
+ if context.current.key?(node.left.value)
77
+ assign_local(node, context)
78
+ else
79
+ assign_function(node, context)
80
+ end
81
+ end
82
+
83
+ def assign_function(node, context)
84
+ value = accept(node.right, context)
85
+ name = @name.call(node.left.value, [@name, value.type])
86
+ thisp = context.current.fetch("self")
87
+ this = context.build.load(thisp).as(@name)
88
+ func, gens = context.find(name)
89
+ context.build.call(name, this, value).as(func.return.sub(gens))
90
+ end
91
+
92
+ def assign_local(node, context)
93
+ local = context.current.fetch(node.left.value)
94
+ value = accept(node.right, context)
95
+ assert_type_equal(value.type, local.type,
96
+ location: node.right.location)
97
+ context.build.store(value, local)
98
+ context.build.load(local).as(local.type)
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,89 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Generation
8
+ module Expressions
9
+ module Calls
10
+ Generation.on Node::Expression::Call::Access =>
11
+ :visit_expression_call_access
12
+ def visit_expression_call_access(node, context)
13
+ base = accept(node.expression, context)
14
+ params = node.parameters.map { |p| accept(p, context) }
15
+ ptypes = params.map(&:type)
16
+ name = base.type.call(:[], [base.type, *ptypes],
17
+ node.generics || [])
18
+ func, gens = context.find(name)
19
+ context.build.call(name, base, *params)
20
+ .as(func.return.sub(gens))
21
+ end
22
+
23
+ Generation.on Node::Expression::Call::Attribute =>
24
+ :visit_expression_call_attribute
25
+ def visit_expression_call_attribute(node, context)
26
+ base = accept(node.expression, context)
27
+ name = base.type.call(node.name.value, [base.type],
28
+ node.generics || [])
29
+ func, gens = context.find(name)
30
+ context.build.call(name, base).as(func.return.sub(gens))
31
+ end
32
+
33
+ Generation.on Node::Expression::Call::Enum =>
34
+ :visit_expression_call_enum
35
+ def visit_expression_call_enum(node, context)
36
+ base = node.module
37
+ params = node.parameters.map { |p| accept(p, context) }
38
+ generics = node.generics.map { |p| accept(p, context) }
39
+ ptypes = params.map(&:type)
40
+ name = base.call(node.name.value, ptypes, node.generics || [])
41
+ func, gens = context.find(name)
42
+ context.build.call(name, *params).as(func.return.sub(gens))
43
+ end
44
+
45
+ Generation.on Node::Expression::Call::Module =>
46
+ :visit_expression_call_module
47
+ def visit_expression_call_module(node, context)
48
+ base = node.module
49
+ params = node.parameters.map { |p| accept(p, context) }
50
+ ptypes = params.map(&:type)
51
+ name = base.call(node.name.value, ptypes, node.generics || [])
52
+ func, gens = context.find(name)
53
+ context.build.call(name, *params).as(func.return.sub(gens))
54
+ end
55
+
56
+ Generation.on Node::Expression::Call::Self =>
57
+ :visit_expression_call_self
58
+ def visit_expression_call_self(node, context)
59
+ base = @name
60
+ params = node.parameters.map { |p| accept(p, context) }
61
+ ptypes = params.map(&:type)
62
+ name = base.call(node.name.value, [base, *ptypes],
63
+ node.generics || [])
64
+ func, gens = context.find(name)
65
+ thisp = context.current.fetch("self")
66
+ this = context.build.load(thisp).as(base)
67
+ context.build.call(name, this, *params)
68
+ .as(func.return.sub(gens))
69
+ end
70
+
71
+ Generation.on Node::Expression::Call::Unified =>
72
+ :visit_expression_call_unified
73
+ def visit_expression_call_unified(node, context)
74
+ base = accept(node.expression, context)
75
+ params = node.parameters.map { |p| accept(p, context) }
76
+ generics = node.generics.map { |p| accept(p, context) }
77
+ ptypes = params.map(&:type)
78
+ name = base.type.call(node.name.value, [base.type, *ptypes],
79
+ node.generics || [])
80
+ func, gens = context.find(name)
81
+ context.build.call(name, base, *params)
82
+ .as(func.return.sub(gens))
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end