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,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