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,68 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Generation
8
+ # Building functions and function bodies.
9
+ module Function
10
+ Generation.on Node::Definition::Function => :visit_function
11
+ def visit_function(node)
12
+ params = node.parameters.map { |p| function_parameter_type(p) }
13
+ full = @name.call(node.name, params, node.generics)
14
+
15
+ @index.define(function: full) do |function|
16
+ function[:return] = node.type
17
+ function_definition(function, node)
18
+ end
19
+ end
20
+
21
+ Generation.on Node::Definition::Function::Body =>
22
+ :visit_function_body
23
+ def visit_function_body(node, context)
24
+ context.push
25
+ node.children.each { |c| accept(c, context) }
26
+ context.pop
27
+ end
28
+
29
+ private
30
+
31
+ def function_definition(function, node)
32
+ return unless node.body
33
+ function_definition_intern(function, node)
34
+ end
35
+
36
+ def function_definition_intern(function, node)
37
+ function[:definition] = proc do |index|
38
+ definition = Tacky::Function.new(function[:parameters])
39
+ context = Context.new(definition, index, node).tap(&:push)
40
+ function_definition_intern_parameters(definition, node,
41
+ context)
42
+ accept(node.body, context)
43
+ definition
44
+ end
45
+ end
46
+
47
+ def function_definition_intern_parameters(defn, node, context)
48
+ defn.params.each_with_index do |param, i|
49
+ fparam = node.parameters[i]
50
+ next if fparam.name.value == "_"
51
+ param.name = "#{fparam.name.value}.p"
52
+ context.build do |b|
53
+ value = b.alloca(fparam.type).as(fparam.type)
54
+ context[fparam] = value
55
+ b.set(param, context[fparam])
56
+ end
57
+ end
58
+ end
59
+
60
+ def function_parameter_type(param)
61
+ return @name if param.name.value.to_s == "self"
62
+ param.type
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,131 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Generation
8
+ # Statement generation.
9
+ module Statements
10
+ Generation.on Node::Statement::Return => :visit_statement_return
11
+ def visit_statement_return(node, context)
12
+ if node.value
13
+ value = accept(node.value, context)
14
+ assert_type_equal(value.type, context.function.type,
15
+ location: node.location)
16
+ context.build { |b| b.ret(value) }
17
+ else
18
+ assert_type_equal(Carbon::Void, context.function.type,
19
+ location: node.location)
20
+ context.build(&:ret_void)
21
+ end
22
+ end
23
+
24
+ Generation.on Node::Statement::Let => :visit_statement_let
25
+ def visit_statement_let(node, context)
26
+ name = node.name.value
27
+ value = accept(node.value, context) if node.value
28
+ assert_type_equal(value.type, node.type,
29
+ location: node.value.location) if node.value
30
+ assert_nolocal(name, context)
31
+
32
+ context.build do |b|
33
+ context[name] = b.alloca(node.type).as(node.type)
34
+ value = value || b.null(node.type).as(node.type)
35
+ b.store(value, context[name])
36
+ end
37
+ end
38
+
39
+ Generation.on Node::Statement::While => :visit_statement_while
40
+ def visit_statement_while(node, context)
41
+ loop, merge = context.new("while-loop"), context.new("while-merge")
42
+
43
+ cond = accept(node.condition, context)
44
+ assert_type_boolean(cond.type, location: node.condition.location)
45
+ check = context.build.icmp(:ne, cond, 0)
46
+
47
+ context.build.cond(check, loop, merge)
48
+ context.swap(loop)
49
+ accept(node.body, context)
50
+ cond = accept(node.condition, context)
51
+ check = context.build.icmp(:ne, cond, 0)
52
+ context.build.cond(check, loop, merge)
53
+ context.swap(merge)
54
+ end
55
+
56
+ Generation.on Node::Statement::For => :visit_statement_for
57
+ def visit_statement_for(node, context)
58
+ loop, merge = context.new("for-loop"), context.new("for-merge")
59
+
60
+ accept(node.initial, context)
61
+ cond = accept(node.condition, context)
62
+ assert_type_boolean(cond.type, location: node.condition.location)
63
+ check = context.build.icmp(:ne, cond, 0)
64
+
65
+ context.build.cond(check, loop, merge)
66
+ context.swap(loop)
67
+ accept(node.body, context)
68
+ accept(node.increment, context)
69
+ cond = accept(node.condition, context)
70
+ check = context.build.icmp(:ne, cond, 0)
71
+ context.build.cond(check, loop, merge)
72
+ context.swap(merge)
73
+ end
74
+
75
+ Generation.on Node::Statement::If => :visit_statement_if
76
+ def visit_statement_if(node, context)
77
+ cond = accept(node.condition, context)
78
+ assert_type_boolean(cond.type, location: node.condition.location)
79
+ check = context.build.icmp(:ne, cond, 0)
80
+
81
+ iftrue, iffalse, ifmerge = context.new("if-true"),
82
+ context.new("if-false"), context.new("if-merge")
83
+
84
+ context.build.cond(check, iftrue, iffalse)
85
+ context.swap(iftrue)
86
+ accept(node.body, context)
87
+ context.build.br(ifmerge)
88
+ context.swap(iffalse)
89
+ statement_if_false_merge(node, context, merge)
90
+ context.swap(ifmerge)
91
+ end
92
+
93
+ Generation.on Node::Statement::ElsIf => :visit_statement_elsif
94
+ def visit_statement_elsif(node, context, merge)
95
+ cond = accept(node.condition)
96
+ assert_type_boolean(cond.type, location: node.condition.location)
97
+ check = context.build.icmp(:ne, cond, 0)
98
+
99
+ ifetrue = context.new("if-else-true")
100
+ ifefalse = context.new("if-else-false")
101
+
102
+ context.build.cond(check, ifetrue, ifefalse)
103
+ context.swap(ifetrue)
104
+ accept(node.body, context)
105
+ context.build.br(merge)
106
+ context.swap(ifefalse)
107
+ statement_if_false_merge(node, context, merge)
108
+ context.swap(merge)
109
+ end
110
+
111
+ Generation.on Node::Statement::Else => :visit_statement_else
112
+ def visit_statement_else(node, context, merge)
113
+ accept(node.body, context)
114
+ context.build.br(merge)
115
+ context.swap(merge)
116
+ end
117
+
118
+ private
119
+
120
+ def statement_if_false_merge(node, context, merge)
121
+ if node.follow
122
+ accept(node.follow, context, merge)
123
+ else
124
+ context.build.br(merge)
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,115 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Generation
8
+ module Struct
9
+ Generation.on Node::Definition::Struct => :visit_struct
10
+ def visit_struct(node)
11
+ @index.define(struct: @name) do |struct|
12
+ struct[:elements] = node.each
13
+ end
14
+
15
+ struct_accessors(node)
16
+ struct_allocate(node)
17
+ end
18
+
19
+ private
20
+
21
+ def struct_allocate(node)
22
+ fname = @name.call(:allocate, node.map(&:type))
23
+ @index.define(function: fname) do |function|
24
+ function[:return] = @name
25
+ struct_allocate_params_definition(node, function[:definition])
26
+ end
27
+
28
+ fname = @name.call(:allocate, [])
29
+ @index.define(function: fname) do |function|
30
+ function[:return] = @name
31
+ struct_allocate_null_definition(node, function[:definition])
32
+ end
33
+ end
34
+
35
+ def struct_accessors(node)
36
+ node.each_with_index do |element, index|
37
+ struct_read_accessor(element, index, node)
38
+ struct_write_accessor(element, index, node)
39
+ end
40
+ end
41
+
42
+ def struct_read_accessor(element, index, node)
43
+ fname = @name.call(element.name.value, [@name])
44
+ @index.define(function: fname) do |function|
45
+ function[:return] = element.type
46
+ struct_read_accessor_definition(function[:definition], element,
47
+ index)
48
+ end
49
+
50
+ fname = @name.call("@#{element.name.value}", [@name])
51
+ @index.define(function: fname) do |function|
52
+ function[:return] = element.type
53
+ struct_read_accessor_definition(function[:definition], element,
54
+ index)
55
+ end
56
+ end
57
+
58
+ def struct_write_accessor(element, index, node)
59
+ pname = @name.to_pointer
60
+ fname = @name.call("#{element.name.value}=", [pname, element.type])
61
+ @index.define(function: fname) do |function|
62
+ function[:return] = element.type
63
+ struct_write_accessor_definition(function[:definition], element,
64
+ index)
65
+ end
66
+
67
+ fname = @name.call("@#{element.name.value}=", [pname, element.type])
68
+ @index.define(function: fname) do |function|
69
+ function[:return] = element.type
70
+ struct_write_accessor_definition(function[:definition], element,
71
+ index)
72
+ end
73
+ end
74
+
75
+ def struct_read_accessor_definition(definition, element, index)
76
+ entry = definition.add("entry").build
77
+ this = definition.params[0]
78
+ this.name = "self"
79
+
80
+ entry.ret(entry.extract_value(this, index).as(element.type))
81
+ end
82
+
83
+ def struct_write_accessor_definition(definition, element, index)
84
+ entry = definition.add("entry").build
85
+ this, value = definition.params
86
+ this.name, value.name = %w(self value)
87
+
88
+ gep = entry.struct_gep(this, index).as(this.type)
89
+ entry.store(value, gep)
90
+ entry.ret(value)
91
+ end
92
+
93
+ def struct_allocate_params_definition(node, definition)
94
+ entry = definition.add("entry").build
95
+ node.each_with_index do |e, i|
96
+ definition.params[i].name = e.name.value
97
+ end
98
+
99
+ blank = entry.null(@name).as(@name)
100
+ definition.params.each_with_index do |param, i|
101
+ entry.insert_value(blank, param, i)
102
+ end
103
+
104
+ entry.ret(blank)
105
+ end
106
+
107
+ def struct_allocate_null_definition(node, definition)
108
+ entry = definition.add("entry").build
109
+ entry.ret(entry.null(@name).as(@name))
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Preparation
8
+ include Base
9
+
10
+ require "carbon/compiler/visitor/preparation/expressions"
11
+ require "carbon/compiler/visitor/preparation/function"
12
+ require "carbon/compiler/visitor/preparation/statements"
13
+ require "carbon/compiler/visitor/preparation/struct"
14
+
15
+ include Preparation::Expressions
16
+ include Preparation::Function
17
+ include Preparation::Statements
18
+ include Preparation::Struct
19
+
20
+ def initialize(file, index)
21
+ @index = index
22
+ @file = file
23
+ @name = @file.module
24
+ @directives = []
25
+ @_funcs = {}
26
+ @context = :normal
27
+ end
28
+
29
+ def call(node)
30
+ accept(node)
31
+ end
32
+
33
+ Preparation.on Concrete::Type => :visit_type
34
+ def visit_type(node)
35
+ node.sub(@file.aliases)
36
+ end
37
+
38
+ Preparation.on Node::Root => :visit_root
39
+ def visit_root(node)
40
+ node.map! { |c| accept(c) }
41
+ end
42
+
43
+ Preparation.on Node::Definition::Module => :visit_module
44
+ def visit_module(node)
45
+ error_mismatched_name(node) if node.name != @name
46
+ error_multiple_modules(node) if @_name
47
+ @_name = node
48
+ @file.module = @name = node.name
49
+ node
50
+ end
51
+
52
+ Preparation.on Node::Definition::Directive => :visit_directive
53
+ def visit_directive(node)
54
+ directive = Compiler::Directive.new(node, @file, @index)
55
+ @directives << node if directive.attach?
56
+ directive.call
57
+ node
58
+ end
59
+
60
+ private
61
+
62
+ def directives_pop
63
+ directives = @directives.clone
64
+ @directives.clear
65
+ directives
66
+ end
67
+
68
+ def error_mismatched_name(node)
69
+ @file.emit("Module/Definition/MismatchedName", node.location,
70
+ [@name, node.name])
71
+ end
72
+
73
+ def error_multiple_modules(node)
74
+ @file.emit("Module/Definition/MultipleNames", node.location)
75
+ @file.emit("Trace/Location", @_name.location, "previous name here")
76
+ end
77
+
78
+ def error_multiple_data(node)
79
+ @file.emit("Module/Definition/MultipleData", node.location)
80
+ @file.emit("Trace/Location", @_data.location,
81
+ "previous data definition here")
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Preparation
8
+ module Expressions
9
+ Preparation.on Node::Expression::Assignment => :visit_ignore
10
+ Preparation.on Node::Expression::Call::Access => :visit_ignore
11
+ Preparation.on Node::Expression::Call::Attribute => :visit_ignore
12
+ Preparation.on Node::Expression::Call::Enum => :visit_ignore
13
+ Preparation.on Node::Expression::Call::Module => :visit_ignore
14
+ Preparation.on Node::Expression::Call::Self => :visit_ignore
15
+ Preparation.on Node::Expression::Call::Unified => :visit_ignore
16
+ Preparation.on Node::Expression::Literal => :visit_ignore
17
+ Preparation.on Node::Expression::Operation::And => :visit_ignore
18
+ Preparation.on Node::Expression::Operation::Neq => :visit_ignore
19
+ Preparation.on Node::Expression::Operation::Normal => :visit_ignore
20
+ Preparation.on Node::Expression::Operation::Or => :visit_ignore
21
+ Preparation.on Node::Expression::Unit => :visit_ignore
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Visitor
7
+ class Preparation
8
+ module Function
9
+ Preparation.on Node::Definition::Function => :visit_function
10
+ def visit_function(node)
11
+ params = node.parameters.map { |c| accept(c) }
12
+ generics = node.generics.map { |c| accept(c) }
13
+ ptypes = params.map { |c| c.name.value == "self" ? @name : c.type }
14
+ name = @name.call(node.name, ptypes, generics)
15
+ error_function_duplicate(node, name) if @_funcs.key?(name)
16
+ @_funcs[name] = node
17
+ fname = node._name.merge(generics: generics)
18
+ body = accept(node.body)
19
+ node.merge(parameters: params, _name: fname, body: body)
20
+ end
21
+
22
+ Preparation.on Node::Definition::Function::Parameter =>
23
+ :visit_function_parameter
24
+ def visit_function_parameter(node)
25
+ return node if node.name.value == "self"
26
+ type = accept(node.type)
27
+ node.merge(type: type)
28
+ end
29
+
30
+ Preparation.on Concrete::Type::Generic => :visit_function_generic
31
+ def visit_function_generic(node)
32
+ name = accept(node.name)
33
+ implements = node.implements.map { |i| accept(i) }
34
+
35
+ Concrete::Type::Generic.new(name, implements)
36
+ end
37
+
38
+ Preparation.on Node::Definition::Function::Body =>
39
+ :visit_function_body
40
+ def visit_function_body(node)
41
+ node.map! { |c| accept(c) }
42
+ end
43
+
44
+ private
45
+
46
+ def error_function_duplicate(node, name)
47
+ @file.emit("Function/Duplicate", node.location)
48
+ @file.emit("Trace/Location", @_funcs[name].location,
49
+ "previous function location")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end