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