carbon-compiler 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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