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,39 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "carbon/compiler/parser/expressions/precedence"
5
+ require "carbon/compiler/parser/expressions/primary"
6
+
7
+ module Carbon
8
+ module Compiler
9
+ class Parser
10
+ # Parses expressions.
11
+ module Expressions
12
+ include Precedence
13
+ include Primary
14
+
15
+ protected
16
+
17
+ PRECEDENCE = {
18
+ "=": 1,
19
+ "||": 2,
20
+ "&&": 3,
21
+ "|": 4,
22
+ "^": 5,
23
+ "&": 6,
24
+ "===": 7, "==": 7, "!=": 7,
25
+ "<": 8, ">": 8, "<=": 8, ">=": 8,
26
+ "<<": 9, ">>": 9,
27
+ "+": 10, "-": 10,
28
+ "*": 11, "/": 11, "%": 11,
29
+ ".": 12, "[": 12
30
+ }.freeze
31
+ RIGHT = [:"=", :"."].freeze
32
+
33
+ def parse_expression
34
+ parse_precedence(parse_expression_primary, 0)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,134 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ class Parser
7
+ module Expressions
8
+ # Parses precedence rules for expressions.
9
+ module Precedence
10
+ protected
11
+
12
+ def parse_precedence(expr, prec)
13
+ left = expr
14
+ while PRECEDENCE[peek.type] && PRECEDENCE[peek.type] >= prec
15
+ op = expect peek.type
16
+ left =
17
+ case op.type
18
+ when :< then parse_precedence_less(left)
19
+ when :"." then parse_precedence_period(left)
20
+ when :"[" then parse_precedence_access(left)
21
+ else
22
+ parse_precedence_op([left, op, parse_expression_primary])
23
+ end
24
+ end
25
+
26
+ left
27
+ end
28
+
29
+ def parse_precedence_less(left)
30
+ default = proc {
31
+ parse_precedence_op([left, :<, parse_expression_primary]) }
32
+ return default.call unless first(:type).include?(peek.type) &&
33
+ left.respond_to?(:generics)
34
+ position = @enum.dup
35
+ name = parse_type
36
+ case peek.type
37
+ when :>, :",", :":" then parse_precendence_generic(left, name)
38
+ else
39
+ @enum = position
40
+ parse_precedence_op([left, :<, parse_expression_primary])
41
+ end
42
+ end
43
+
44
+ def parse_precedence_generic(left, name)
45
+ children = [name]
46
+ until peek? :>
47
+ children << Concrete::Type::Generic.new(parse_module_name, [])
48
+ break unless peek? :","
49
+ expect :","
50
+ end
51
+ expect :>
52
+
53
+ if peek?(:"(") # if this is a call, our left should be an attribute
54
+ children = []
55
+ until peek? :")"
56
+ children << parse_expression
57
+ break unless peek? :","
58
+ expect :","
59
+ end
60
+ expect :")"
61
+
62
+ arguments = Node::Expression::Call::Parameters.new(children)
63
+ Node::Expression::Call::Unified.new([left.expression, left.name,
64
+ arguments, generics])
65
+ else
66
+ left.merge(generics: children)
67
+ end
68
+ end
69
+
70
+ def parse_precedence_period(left)
71
+ name = parse_name
72
+ generics = peek?(:<) ? parse_module_generics : []
73
+
74
+ if peek?(:"(")
75
+ parse_precedence_period_call(left, name, generics)
76
+ else
77
+ Node::Expression::Call::Attribute.new([left, name, generics])
78
+ end
79
+ end
80
+
81
+ def parse_precedence_access(left, generics = [])
82
+ children = []
83
+ until peek? :"]"
84
+ children << parse_expression
85
+ break unless peek? :","
86
+ expect :","
87
+ end
88
+ expect :"]"
89
+
90
+ arguments = Node::Expression::Call::Parameters.new(children)
91
+ Node::Expression::Call::Access.new([left, arguments, generics])
92
+ end
93
+
94
+ def parse_precedence_period_call(left, name, generics)
95
+ l = expect :"("
96
+ children = []
97
+ until peek? :")"
98
+ children << parse_expression
99
+ break unless peek? :","
100
+ expect :","
101
+ end
102
+ r = expect :")"
103
+
104
+ arguments = Node::Expression::Call::Parameters.new(children)
105
+ Node::Expression::Call::Unified.new([left, name, arguments,
106
+ generics], components: [left, name, l, r])
107
+ end
108
+
109
+ def parse_precedence_op(data)
110
+ left, op, right = *data
111
+ oprec = PRECEDENCE.fetch(op.type)
112
+ while PRECEDENCE[peek.type] && (PRECEDENCE[peek.type] > oprec ||
113
+ (RIGHT.include?(peek.type) && PRECEDENCE[peek.type] == oprec))
114
+ right = parse_precedence(right, PRECEDENCE[peek.type])
115
+ end
116
+
117
+ case op.type
118
+ when :"="
119
+ Node::Expression::Assignment.new([left, op, right])
120
+ when :"&&"
121
+ Node::Expression::Operation::And.new([left, op, right])
122
+ when :"||"
123
+ Node::Expression::Operation::Or.new([left, op, right])
124
+ when :"!="
125
+ Node::Expression::Operation::Neq.new([left, op, right])
126
+ else
127
+ Node::Expression::Operation::Normal.new([left, op, right])
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,120 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ class Parser
7
+ module Expressions
8
+ # Parses primary expressions, e.g. literals, module calls, etc.
9
+ module Primary
10
+ protected
11
+
12
+ FUNCTION_NAMES = Set[:|, :&, :"^", :===, :==, :<, :>, :<=, :>=,
13
+ :<=>, :<<, :>>, :+, :-, :*, :/, :%, :[], :[]=]
14
+ Parser.first(:module, [:MNAME])
15
+ Parser.first(:literal, [:NUMBER, :FLOAT, :STRING])
16
+ Parser.first(:unit, [:"("])
17
+ Parser.first(:expression, Parser.first(:module) |
18
+ Parser.first(:literal) | Parser.first(:unit) |
19
+ Parser.first(:name))
20
+ Parser.first(:call, Parser.first(:name))
21
+ def parse_expression_primary
22
+ if first(:module).include?(peek.type)
23
+ parse_expression_module
24
+ elsif first(:literal).include?(peek.type)
25
+ parse_expression_literal
26
+ elsif first(:unit).include?(peek.type)
27
+ parse_expression_unit
28
+ elsif first(:name).include?(peek.type)
29
+ parse_expression_name
30
+ else
31
+ error(first(:expression))
32
+ end
33
+ end
34
+
35
+ def parse_expression_module
36
+ mname = parse_module_name
37
+ case peek.type
38
+ when :"."
39
+ parse_expression_call(mname)
40
+ else
41
+ error([:"."])
42
+ end
43
+ end
44
+
45
+ def parse_expression_name
46
+ name = parse_name
47
+ return name unless peek? :"("
48
+ l = expect :"("
49
+ children = []
50
+ until peek? :")"
51
+ children << parse_expression
52
+ break unless peek? :","
53
+ expect :","
54
+ end
55
+ r = expect :")"
56
+
57
+ arguments = Node::Expression::Call::Parameters.new(children,
58
+ components: [l, r])
59
+ Node::Expression::Call::Self.new([name, arguments])
60
+ end
61
+
62
+ def parse_expression_call_name
63
+ if first(:name).include?(peek.type)
64
+ parse_name
65
+ elsif peek?(:MNAME)
66
+ expect :MNAME
67
+ else
68
+ error(first(:name) | [:MNAME])
69
+ end
70
+ end
71
+
72
+ def parse_expression_call(mname)
73
+ expect :"."
74
+ name = parse_expression_call_name
75
+ generics = peek?(:<) ? parse_module_generics : []
76
+
77
+ l = expect :"("
78
+ children = []
79
+ until peek? :")"
80
+ children << parse_expression
81
+ break unless peek? :","
82
+ expect :","
83
+ end
84
+ r = expect :")"
85
+
86
+ arguments = Node::Expression::Call::Parameters.new(children,
87
+ components: [l, r])
88
+ Node::Expression::Call::Module.new([mname, name, arguments,
89
+ generics])
90
+ end
91
+
92
+ def parse_expression_unit
93
+ expect :"("
94
+ children = []
95
+ until peek? :")"
96
+ children << parse_expression
97
+ break unless peek? :","
98
+ expect :","
99
+ end
100
+ expect :")"
101
+ Node::Expression::Unit.new(children)
102
+ end
103
+
104
+ def parse_expression_literal
105
+ case peek.type
106
+ when :NUMBER
107
+ Node::Expression::Literal.new([expect(:NUMBER)])
108
+ when :FLOAT
109
+ Node::Expression::Literal.new([expect(:FLOAT)])
110
+ when :STRING
111
+ Node::Expression::Literal.new([expect(:STRING)])
112
+ else
113
+ error first(:literal)
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require "set"
4
+
5
+ module Carbon
6
+ module Compiler
7
+ class Parser
8
+ # Manages first sets for the parser. This is only for internal
9
+ # reference to make parsing easier.
10
+ module Firsts
11
+ # The class methods that should be placed on the parser.
12
+ module ClassMethods
13
+ # The first sets. The key is the name of a node, and the value
14
+ # is a set of all tokens that can be at the start of that node.
15
+ #
16
+ # @return [{Symbol => Set<Symbol>}]
17
+ def firsts
18
+ @firsts ||= Hash.new { |h, k| h[k] = Set.new }
19
+ end
20
+
21
+ # @overload first(name)
22
+ # Retrieves the first set for the given node name. If none exists,
23
+ # a `KeyError` is raised.
24
+ #
25
+ # @api private
26
+ # @param name [::Symbol] The name of the node to look up the first
27
+ # set for.
28
+ # @return [Set<::Symbol>] The first set
29
+ # @raise [KeyError] If the node has no defined first set.
30
+ # @overload first(name, tokens)
31
+ # Merges the given tokens into the first set of the name of the
32
+ # node given.
33
+ #
34
+ # @api private
35
+ # @param name [::Symbol] The name of the node that the first set is
36
+ # for.
37
+ # @param tokens [<::Symbol>] The tokens that act as the first set
38
+ # for the node.
39
+ # @return [void]
40
+ def first(name, tokens = nil)
41
+ if tokens
42
+ firsts[name].merge(tokens)
43
+ else
44
+ firsts.fetch(name)
45
+ end
46
+ end
47
+ end
48
+
49
+ # The instance methods that should be placed in the parser.
50
+ module InstanceMethods
51
+ # Retrieves the first set for the given node name.
52
+ #
53
+ # @param name [Symbol]
54
+ # @return [Set<Symbol>]
55
+ def first(name)
56
+ self.class.firsts.fetch(name)
57
+ end
58
+ end
59
+
60
+ # Includes the {ClassMethods} and {InstanceMethods} into the
61
+ # parser or whatever base includes it.
62
+ #
63
+ # @param base [Parser]
64
+ # @api private
65
+ def self.included(base)
66
+ base.extend ClassMethods
67
+ base.send :include, InstanceMethods
68
+ end
69
+ end
70
+
71
+ include Firsts
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Carbon
5
+ module Compiler
6
+ class Parser
7
+ # helpers that manage the state of the parser. This can be things like
8
+ # peeking, shifting, and erroring.
9
+ module Helpers
10
+ # Peeks to the next token. If peeking would cause a `StopIteration`
11
+ # error, it instead returns the last value that was peeked.
12
+ #
13
+ # @return [Scanner::Token]
14
+ def peek
15
+ value = @enum.peek
16
+ @_last = value
17
+ rescue StopIteration
18
+ @_last
19
+ end
20
+
21
+ # Checks to see if any of the given types includes the next token.
22
+ #
23
+ # @param types [Symbol] The possible types.
24
+ # @return [Boolean]
25
+ def peek?(*types)
26
+ types.include?(peek.type)
27
+ end
28
+
29
+ # Shifts to the next token, and returns the old token.
30
+ #
31
+ # @return [Scanner::Token]
32
+ def shift
33
+ @enum.next
34
+ end
35
+
36
+ # Sets up an expectation for a given token. If the next token is
37
+ # an expected token, it shifts, returning the token; otherwise,
38
+ # it {#error}s with the token information.
39
+ #
40
+ # @param tokens [Symbol] The expected tokens.
41
+ # @return [Scanner::Token]
42
+ def expect(*tokens)
43
+ return shift if peek?(*tokens)
44
+ error(tokens)
45
+ end
46
+
47
+ # Errors, noting the expected tokens, the given token, the location
48
+ # of given tokens. It does this by emitting a diagnostic. The
49
+ # diagnostic is only allowed to be a {Metanostic::Mode::PANIC}
50
+ # diagnostic, so this is garenteed to error.
51
+ #
52
+ # @param tokens [<Symbol>] The expected tokens.
53
+ # @return [void]
54
+ def error(tokens)
55
+ @file.emit("Syntax/Token/Unexpected", peek.location,
56
+ [peek.type.inspect, tokens.map(&:inspect).join(", ")])
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ # rubocop:disable Metrics/CyclomaticComplexity
4
+
5
+ require "carbon/compiler/parser/root/class"
6
+ require "carbon/compiler/parser/root/directive"
7
+ require "carbon/compiler/parser/root/enum"
8
+ require "carbon/compiler/parser/root/function"
9
+ require "carbon/compiler/parser/root/struct"
10
+ require "carbon/compiler/parser/root/trait"
11
+
12
+ module Carbon
13
+ module Compiler
14
+ class Parser
15
+ # Parses root definitions, like functions and enums.
16
+ module Root
17
+ include Class
18
+ include Directive
19
+ include Enum
20
+ include Function
21
+ include Struct
22
+ include Trait
23
+
24
+ protected
25
+
26
+ Parser.first(:root, [:":", :module, :struct, :class, :trait, :enum,
27
+ :def])
28
+ def parse_root
29
+ children = []
30
+ until peek? :EOF
31
+ children <<
32
+ case peek.type
33
+ when :":" then parse_directive
34
+ when :module then parse_module
35
+ when :struct then parse_struct
36
+ when :class then parse_class
37
+ when :trait then parse_trait
38
+ when :enum then parse_enum
39
+ when :def then parse_function
40
+ else error first(:root)
41
+ end
42
+ end
43
+
44
+ Node::Root.new(children)
45
+ end
46
+
47
+ def parse_module
48
+ expect :module
49
+ name = parse_module_name
50
+ expect :"."
51
+
52
+ Node::Definition::Module.new([name])
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end