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,27 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ # The root node. This is the topmost level node, and includes
8
+ # all declarations, definitions, and directives.
9
+ class Name < Base
10
+ # The value of the name. This is a string representation of the
11
+ # name.
12
+ #
13
+ # @return [::String]
14
+ def value
15
+ @children[0].value
16
+ end
17
+
18
+ # Fancy inspection.
19
+ #
20
+ # @return [::String]
21
+ def inspect
22
+ "#(Name #{value})"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ # The root node. This is the topmost level node, and includes
8
+ # all declarations, definitions, and directives.
9
+ class Root < Base
10
+ # The "name" of the root.
11
+ #
12
+ # @return [Carbon::Concrete::Type]
13
+ def name
14
+ @children.select(&:identity?).last[0]
15
+ end
16
+
17
+ def inspect
18
+ "#[Module #{name.inspect}]"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "carbon/compiler/node/statement/catch"
5
+ require "carbon/compiler/node/statement/else"
6
+ require "carbon/compiler/node/statement/elsif"
7
+ require "carbon/compiler/node/statement/finally"
8
+ require "carbon/compiler/node/statement/for"
9
+ require "carbon/compiler/node/statement/if"
10
+ require "carbon/compiler/node/statement/let"
11
+ require "carbon/compiler/node/statement/match"
12
+ require "carbon/compiler/node/statement/return"
13
+ require "carbon/compiler/node/statement/try"
14
+ require "carbon/compiler/node/statement/while"
15
+
16
+ module Carbon
17
+ module Compiler
18
+ module Node
19
+ # A statement.
20
+ module Statement
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # A "catch" statement. This is used in try/catch/finally for
9
+ # exception handling.
10
+ # This has four children: the name of the variable to localize,
11
+ # the "klass" (type) of the variable, the body of the catch statement,
12
+ # and the following catch/finally statement. This takes the form of
13
+ # `catch <Name>:<Type> <Body> <Follow>`.
14
+ class Catch < Base
15
+ attributes name: 0, type: 1, body: 2, follow: 3
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ class Condition
9
+ attributes conditions: 0
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # An else statement. This is used in the if/elsif/else construct
9
+ # to handle control flow. This has one child: the body of the else
10
+ # statement. This has the form of `else <Body>`.
11
+ class Else < Base
12
+ attribute body: 0
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # An elsif statement. This is used in the if/elsif/else construct
9
+ # for control flow. This has three children: the condition for
10
+ # execution, the body for execution, and the following elsif/else
11
+ # statement. This has the form `elsif(<Condition>) <Body> <Follow>`.
12
+ class ElsIf < Base
13
+ attributes condition: 0, body: 1, follow: 2
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # A Finally statement. This is used in try/catch/finally constructs
9
+ # for exception handling. This has one child: the body to execute.
10
+ # This takes the form of `finally <Body>`.
11
+ class Finally < Base
12
+ attributes body: 0
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # A for loop. This is used to construct a loop with the given
9
+ # conditions. This has four children: the initial statement, the
10
+ # condition, the increment statement, and the body. This takes the
11
+ # form of `for(<Initial>; <Condition>; <Increment>) <Body>`.
12
+ class For < Base
13
+ attributes initial: 0, condition: 1, increment: 2, body: 3
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # An If statement. This is used in the if/elsif/else construct for
9
+ # control flow. This has three children: the children, the body,
10
+ # and the following elsif/else statement. This takes the form
11
+ # `if(<Condition>) <Body> <Follow>`.
12
+ class If < Base
13
+ attributes condition: 0, body: 1, follow: 2
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # A let statement. This introduces a local variable with a given
9
+ # "klass" (type). This has three children: the name of the local
10
+ # variable, the "klass" (type) of the local variable, and the given
11
+ # value of the new variable.
12
+ class Let < Base
13
+ attributes name: 0, type: 1, value: 2
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # TODO.
9
+ class Match < Base
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # A return statement. This is used for control flow to return from the
9
+ # current function. This has one child: the value to return. If no
10
+ # value is given, it returns a void type.
11
+ class Return < Base
12
+ attributes value: 0
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # A "try" statement. This is used in try/catch/finally for
9
+ # exception handling.
10
+ # This has two children: the body to attempt to execute, and the
11
+ # following catch/finally block. This takes the form of
12
+ # `try <Body> <Follow>`.
13
+ class Try < Base
14
+ attributes body: 0, follow: 1
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ module Node
7
+ module Statement
8
+ # A while loop. This creates a loop that executes while a given
9
+ # condition is true.
10
+ # This has two children: the condition to check for truthiness, and
11
+ # the body to execute. This takes the form of
12
+ # `while(<Condition>) <Body>`.
13
+ class While < Base
14
+ attributes condition: 0, body: 1
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "carbon/compiler/parser/firsts"
5
+ require "carbon/compiler/parser/helpers"
6
+ require "carbon/compiler/parser/common"
7
+ require "carbon/compiler/parser/root"
8
+ require "carbon/compiler/parser/statements"
9
+ require "carbon/compiler/parser/expressions"
10
+
11
+ module Carbon
12
+ module Compiler
13
+ # The parser. This takes a series of tokens, generated by the {Scanner},
14
+ # and derives structure from these tokens. This makes the fundamental
15
+ # bases of creating a concrete representation of what is in the file.
16
+ class Parser
17
+ include Parser::Helpers
18
+ include Parser::Common
19
+ include Parser::Root
20
+ include Parser::Statements
21
+ include Parser::Expressions
22
+
23
+ # The scanner that acts as the source of the tokens.
24
+ #
25
+ # @return [Scanner]
26
+ attr_reader :scanner
27
+
28
+ # Initialize the parser. It takes a scanner, and the project that
29
+ # the parser is a part of.
30
+ #
31
+ # @param scanner [Scanner]
32
+ # @param project [Project]
33
+ def initialize(scanner)
34
+ @scanner = scanner
35
+ @file = @scanner.file
36
+ @enum = @scanner.each
37
+ end
38
+
39
+ # Pretty inspect.
40
+ #
41
+ # @return [String]
42
+ def inspect
43
+ "#<#{self.class} #{@scanner.file.name}>"
44
+ end
45
+
46
+ # Parses the input. This is cached to prevent multiple runs.
47
+ #
48
+ # @return [Parser::Node]
49
+ def parse
50
+ @_root ||= parse_root
51
+ end
52
+ alias_method :root, :parse
53
+
54
+ # Destroys the cache for {#parse}, allowing the parsing to occur again.
55
+ #
56
+ # @return [void]
57
+ def clear!
58
+ @enum.reset
59
+ @_root = nil
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ class Parser
7
+ # Parses common items, such as module names and types.
8
+ module Common
9
+ protected
10
+
11
+ Parser.first(:name, [:IDENTIFIER, :module, :struct, :enum, :trait,
12
+ :def, :self, :_])
13
+ def parse_name
14
+ error(first(:name)) unless first(:name).include?(peek.type)
15
+ Node::Name.new([shift])
16
+ end
17
+
18
+ # TODO: pointer
19
+ Parser.first(:type, [:MNAME, :"("])
20
+ def parse_type
21
+ type =
22
+ case peek.type
23
+ when :MNAME then parse_module_name
24
+ when :"(" then parse_unit_type
25
+ else error first(:type)
26
+ end
27
+ end
28
+
29
+ def parse_unit_type
30
+ expect :"("
31
+ children = []
32
+ until peek? :")"
33
+ children << parse_type
34
+ break unless peek? :","
35
+ expect :","
36
+ end
37
+ expect :")"
38
+
39
+ Node::Type::Unit.new(children)
40
+ end
41
+
42
+ def parse_module_name
43
+ base = parse_module_name_part
44
+ children = [base]
45
+ while peek? :"::"
46
+ expect :"::"
47
+ children << parse_module_name_part
48
+ end
49
+
50
+ location = children.map(&:location).inject(:|)
51
+ Concrete::Type.new(Concrete::Type::Name.new(children, nil),
52
+ location: location)
53
+ end
54
+
55
+ def parse_module_name_part
56
+ root = expect :MNAME
57
+ generics = peek?(:<) ? parse_module_generics : []
58
+ location = [root].concat(generics).map(&:location).inject(:|)
59
+ Concrete::Type::Part.new(root.value, generics, location: location)
60
+ end
61
+
62
+ def parse_module_generics
63
+ children = []
64
+ expect :<
65
+ until peek? :>
66
+ name = parse_module_name
67
+ children << Concrete::Type::Generic.new(name, [],
68
+ location: name.location)
69
+ break unless peek? :","
70
+ expect :","
71
+ end
72
+ expect :>
73
+
74
+ children
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end