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