carbon-compiler 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +17 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +39 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +9 -0
- data/Vagrantfile +84 -0
- data/carbon-compiler.gemspec +28 -0
- data/lib/carbon/compiler.rb +20 -0
- data/lib/carbon/compiler/directive.rb +48 -0
- data/lib/carbon/compiler/directive/import.rb +17 -0
- data/lib/carbon/compiler/errors.rb +7 -0
- data/lib/carbon/compiler/location.rb +136 -0
- data/lib/carbon/compiler/metanostic.rb +123 -0
- data/lib/carbon/compiler/metanostic/defaults.rb +41 -0
- data/lib/carbon/compiler/metanostic/defaults.yml +138 -0
- data/lib/carbon/compiler/metanostic/diagnostic.rb +112 -0
- data/lib/carbon/compiler/metanostic/list.rb +109 -0
- data/lib/carbon/compiler/metanostic/mode.rb +162 -0
- data/lib/carbon/compiler/metanostic/state.rb +174 -0
- data/lib/carbon/compiler/metanostic/template.erb +11 -0
- data/lib/carbon/compiler/node.rb +18 -0
- data/lib/carbon/compiler/node/base.rb +213 -0
- data/lib/carbon/compiler/node/definition.rb +19 -0
- data/lib/carbon/compiler/node/definition/class.rb +24 -0
- data/lib/carbon/compiler/node/definition/class/element.rb +18 -0
- data/lib/carbon/compiler/node/definition/directive.rb +22 -0
- data/lib/carbon/compiler/node/definition/directive/function.rb +18 -0
- data/lib/carbon/compiler/node/definition/enum.rb +20 -0
- data/lib/carbon/compiler/node/definition/enum/element.rb +17 -0
- data/lib/carbon/compiler/node/definition/function.rb +44 -0
- data/lib/carbon/compiler/node/definition/function/body.rb +17 -0
- data/lib/carbon/compiler/node/definition/function/name.rb +18 -0
- data/lib/carbon/compiler/node/definition/function/parameter.rb +18 -0
- data/lib/carbon/compiler/node/definition/function/parameters.rb +17 -0
- data/lib/carbon/compiler/node/definition/module.rb +23 -0
- data/lib/carbon/compiler/node/definition/struct.rb +24 -0
- data/lib/carbon/compiler/node/definition/struct/element.rb +18 -0
- data/lib/carbon/compiler/node/etype.rb +66 -0
- data/lib/carbon/compiler/node/etype/option.rb +25 -0
- data/lib/carbon/compiler/node/etype/star.rb +13 -0
- data/lib/carbon/compiler/node/expression.rb +18 -0
- data/lib/carbon/compiler/node/expression/assignment.rb +22 -0
- data/lib/carbon/compiler/node/expression/call.rb +22 -0
- data/lib/carbon/compiler/node/expression/call/access.rb +24 -0
- data/lib/carbon/compiler/node/expression/call/attribute.rb +23 -0
- data/lib/carbon/compiler/node/expression/call/enum.rb +25 -0
- data/lib/carbon/compiler/node/expression/call/module.rb +24 -0
- data/lib/carbon/compiler/node/expression/call/parameters.rb +17 -0
- data/lib/carbon/compiler/node/expression/call/self.rb +17 -0
- data/lib/carbon/compiler/node/expression/call/unified.rb +27 -0
- data/lib/carbon/compiler/node/expression/literal.rb +83 -0
- data/lib/carbon/compiler/node/expression/operation.rb +20 -0
- data/lib/carbon/compiler/node/expression/operation/and.rb +20 -0
- data/lib/carbon/compiler/node/expression/operation/neq.rb +21 -0
- data/lib/carbon/compiler/node/expression/operation/normal.rb +20 -0
- data/lib/carbon/compiler/node/expression/operation/or.rb +20 -0
- data/lib/carbon/compiler/node/expression/unit.rb +16 -0
- data/lib/carbon/compiler/node/name.rb +27 -0
- data/lib/carbon/compiler/node/root.rb +23 -0
- data/lib/carbon/compiler/node/statement.rb +24 -0
- data/lib/carbon/compiler/node/statement/catch.rb +20 -0
- data/lib/carbon/compiler/node/statement/condition.rb +14 -0
- data/lib/carbon/compiler/node/statement/else.rb +17 -0
- data/lib/carbon/compiler/node/statement/elsif.rb +18 -0
- data/lib/carbon/compiler/node/statement/finally.rb +17 -0
- data/lib/carbon/compiler/node/statement/for.rb +18 -0
- data/lib/carbon/compiler/node/statement/if.rb +18 -0
- data/lib/carbon/compiler/node/statement/let.rb +18 -0
- data/lib/carbon/compiler/node/statement/match.rb +14 -0
- data/lib/carbon/compiler/node/statement/return.rb +17 -0
- data/lib/carbon/compiler/node/statement/try.rb +19 -0
- data/lib/carbon/compiler/node/statement/while.rb +19 -0
- data/lib/carbon/compiler/parser.rb +63 -0
- data/lib/carbon/compiler/parser/common.rb +79 -0
- data/lib/carbon/compiler/parser/expressions.rb +39 -0
- data/lib/carbon/compiler/parser/expressions/precedence.rb +134 -0
- data/lib/carbon/compiler/parser/expressions/primary.rb +120 -0
- data/lib/carbon/compiler/parser/firsts.rb +74 -0
- data/lib/carbon/compiler/parser/helpers.rb +61 -0
- data/lib/carbon/compiler/parser/root.rb +57 -0
- data/lib/carbon/compiler/parser/root/class.rb +34 -0
- data/lib/carbon/compiler/parser/root/directive.rb +87 -0
- data/lib/carbon/compiler/parser/root/enum.rb +45 -0
- data/lib/carbon/compiler/parser/root/function.rb +90 -0
- data/lib/carbon/compiler/parser/root/struct.rb +34 -0
- data/lib/carbon/compiler/parser/root/trait.rb +44 -0
- data/lib/carbon/compiler/parser/statements.rb +86 -0
- data/lib/carbon/compiler/parser/statements/if.rb +50 -0
- data/lib/carbon/compiler/parser/statements/match.rb +39 -0
- data/lib/carbon/compiler/parser/statements/try.rb +49 -0
- data/lib/carbon/compiler/project.rb +37 -0
- data/lib/carbon/compiler/project/file.rb +64 -0
- data/lib/carbon/compiler/scanner.rb +82 -0
- data/lib/carbon/compiler/scanner/main.rb +76 -0
- data/lib/carbon/compiler/scanner/token.rb +58 -0
- data/lib/carbon/compiler/version.rb +8 -0
- data/lib/carbon/compiler/visitor.rb +13 -0
- data/lib/carbon/compiler/visitor/base.rb +52 -0
- data/lib/carbon/compiler/visitor/generation.rb +45 -0
- data/lib/carbon/compiler/visitor/generation/asserts.rb +30 -0
- data/lib/carbon/compiler/visitor/generation/class.rb +93 -0
- data/lib/carbon/compiler/visitor/generation/context.rb +75 -0
- data/lib/carbon/compiler/visitor/generation/expressions.rb +82 -0
- data/lib/carbon/compiler/visitor/generation/expressions/assignment.rb +105 -0
- data/lib/carbon/compiler/visitor/generation/expressions/calls.rb +89 -0
- data/lib/carbon/compiler/visitor/generation/function.rb +68 -0
- data/lib/carbon/compiler/visitor/generation/statements.rb +131 -0
- data/lib/carbon/compiler/visitor/generation/struct.rb +115 -0
- data/lib/carbon/compiler/visitor/preparation.rb +86 -0
- data/lib/carbon/compiler/visitor/preparation/expressions.rb +26 -0
- data/lib/carbon/compiler/visitor/preparation/function.rb +55 -0
- data/lib/carbon/compiler/visitor/preparation/statements.rb +73 -0
- data/lib/carbon/compiler/visitor/preparation/struct.rb +37 -0
- data/program.ca +16 -0
- data/test.rb +21 -0
- metadata +234 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Compiler
|
6
|
+
class Parser
|
7
|
+
module Root
|
8
|
+
# Parses a class.
|
9
|
+
module Class
|
10
|
+
protected
|
11
|
+
|
12
|
+
def parse_class
|
13
|
+
start = expect :class
|
14
|
+
expect :do
|
15
|
+
elements = []
|
16
|
+
elements << parse_class_element until peek?(:end)
|
17
|
+
stop = expect :end
|
18
|
+
|
19
|
+
Node::Definition::Class.new(elements, components: [start, stop])
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_class_element
|
23
|
+
name = parse_name
|
24
|
+
expect :":"
|
25
|
+
type = parse_type
|
26
|
+
expect :";"
|
27
|
+
|
28
|
+
Node::Definition::Class::Element.new([name, type])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Compiler
|
6
|
+
class Parser
|
7
|
+
module Root
|
8
|
+
# Parses a directive.
|
9
|
+
module Directive
|
10
|
+
protected
|
11
|
+
|
12
|
+
def parse_directive
|
13
|
+
expect :":"
|
14
|
+
name = parse_name
|
15
|
+
parameters = []
|
16
|
+
parameters << parse_directive_parameter until peek? :"."
|
17
|
+
expect :"."
|
18
|
+
|
19
|
+
Node::Definition::Directive.new([name, parameters])
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_directive_parameter
|
23
|
+
case peek.type
|
24
|
+
when :"(" then parse_directive_parameter_function
|
25
|
+
when :do then parse_function_body
|
26
|
+
when :FLOAT, :STRING, :NUMBER then parse_expression_literal
|
27
|
+
when :MNAME then parse_directive_module_name
|
28
|
+
else parse_name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_directive_parameter_function
|
33
|
+
expect :"("
|
34
|
+
parameters = []
|
35
|
+
until peek? :")"
|
36
|
+
parameters << parse_function_parameter
|
37
|
+
break unless peek? :","
|
38
|
+
expect :","
|
39
|
+
end
|
40
|
+
expect :")"
|
41
|
+
|
42
|
+
Node::Definition::Directive::Function.new(parameters)
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_directive_module_name
|
46
|
+
base = parse_directive_module_name_part
|
47
|
+
children = [base]
|
48
|
+
while peek? :"::"
|
49
|
+
expect :"::"
|
50
|
+
children << parse_directive_module_name_part
|
51
|
+
end
|
52
|
+
|
53
|
+
Node::EType.new(children)
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_directive_module_name_part
|
57
|
+
case peek.type
|
58
|
+
when :MNAME then parse_module_name_part
|
59
|
+
when :"{" then parse_directive_module_name_option
|
60
|
+
when :* then parse_directive_module_name_star
|
61
|
+
else error [:MNAME, :"{", :*]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def parse_directive_module_name_option
|
66
|
+
l = expect :"{"
|
67
|
+
children = []
|
68
|
+
until peek? :"}"
|
69
|
+
children << parse_directive_module_name
|
70
|
+
break unless peek? :","
|
71
|
+
expect :","
|
72
|
+
end
|
73
|
+
r = expect :"}"
|
74
|
+
|
75
|
+
Node::EType::Option.new(children, components: [l, r])
|
76
|
+
end
|
77
|
+
|
78
|
+
def parse_directive_module_name_star
|
79
|
+
star = expect :*
|
80
|
+
|
81
|
+
Node::EType::Star.new([], components: [star])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Compiler
|
6
|
+
class Parser
|
7
|
+
module Root
|
8
|
+
# Parses an enum.
|
9
|
+
module Enum
|
10
|
+
protected
|
11
|
+
|
12
|
+
def parse_enum
|
13
|
+
start = expect :enum
|
14
|
+
expect :do
|
15
|
+
elements = []
|
16
|
+
elements << parse_enum_element until peek?(:end)
|
17
|
+
stop = expect :end
|
18
|
+
|
19
|
+
Node::Definition::Enum.new(elements, components: [start, stop])
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_enum_element
|
23
|
+
name = expect :MNAME
|
24
|
+
value = parse_enum_element_value if peek?(:"(") || peek?(:"=")
|
25
|
+
expect :";"
|
26
|
+
|
27
|
+
Node::Definition::Enum::Element.new([name, value])
|
28
|
+
end
|
29
|
+
|
30
|
+
def parse_enum_element_value
|
31
|
+
case peek.type
|
32
|
+
when :"(" then parse_unit_type
|
33
|
+
when :"=" then parse_enum_element_value_expr
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_enum_element_value_expr
|
38
|
+
expect :"="
|
39
|
+
parse_expression
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Compiler
|
6
|
+
class Parser
|
7
|
+
module Root
|
8
|
+
# Parses a function.
|
9
|
+
module Function
|
10
|
+
protected
|
11
|
+
|
12
|
+
def parse_function
|
13
|
+
expect :def
|
14
|
+
|
15
|
+
name = parse_function_name
|
16
|
+
parameters = parse_function_parameters
|
17
|
+
type = parse_function_type
|
18
|
+
body = parse_function_body if peek?(:do)
|
19
|
+
|
20
|
+
Node::Definition::Function.new([name, parameters, type, body])
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_function_name
|
24
|
+
name = parse_name
|
25
|
+
generics = peek?(:"<") ? parse_module_generics : []
|
26
|
+
|
27
|
+
Node::Definition::Function::Name.new([name, generics])
|
28
|
+
end
|
29
|
+
|
30
|
+
def parse_function_parameters
|
31
|
+
l = expect :"("
|
32
|
+
parameters = []
|
33
|
+
until peek? :")"
|
34
|
+
parameters << parse_function_parameter
|
35
|
+
break unless peek? :","
|
36
|
+
expect :","
|
37
|
+
end
|
38
|
+
r = expect :")"
|
39
|
+
|
40
|
+
Node::Definition::Function::Parameters.new(parameters,
|
41
|
+
components: [l, r])
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_function_parameter
|
45
|
+
case peek.type
|
46
|
+
when :self then parse_function_argument_self
|
47
|
+
when :_ then parse_function_argument_ignore
|
48
|
+
else parse_function_argument_normal
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_function_argument_self
|
53
|
+
Node::Definition::Function::Argument.new([expect(:self)])
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_function_argument_ignore
|
57
|
+
under = expect :_
|
58
|
+
expect :":"
|
59
|
+
type = parse_type
|
60
|
+
|
61
|
+
Node::Definition::Function::Argument.new([under, type])
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_function_argument_normal
|
65
|
+
name = parse_name
|
66
|
+
expect :":"
|
67
|
+
type = parse_type
|
68
|
+
|
69
|
+
Node::Definition::Function::Argument.new([name, type])
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_function_type
|
73
|
+
expect :":"
|
74
|
+
parse_type
|
75
|
+
end
|
76
|
+
|
77
|
+
def parse_function_body
|
78
|
+
start = expect :do
|
79
|
+
statements = []
|
80
|
+
statements << parse_statement until peek? :end
|
81
|
+
stop = expect :end
|
82
|
+
|
83
|
+
Node::Definition::Function::Body.new(statements,
|
84
|
+
components: [start, stop])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Compiler
|
6
|
+
class Parser
|
7
|
+
module Root
|
8
|
+
# Parses a struct.
|
9
|
+
module Struct
|
10
|
+
protected
|
11
|
+
|
12
|
+
def parse_struct
|
13
|
+
start = expect :struct
|
14
|
+
expect :do
|
15
|
+
elements = []
|
16
|
+
elements << parse_struct_element until peek?(:end)
|
17
|
+
stop = expect :end
|
18
|
+
|
19
|
+
Node::Definition::Struct.new(elements, components: [start, stop])
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_struct_element
|
23
|
+
name = parse_name
|
24
|
+
expect :":"
|
25
|
+
type = parse_type
|
26
|
+
expect :";"
|
27
|
+
|
28
|
+
Node::Definition::Struct::Element.new([name, type])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Compiler
|
6
|
+
class Parser
|
7
|
+
module Root
|
8
|
+
# Parses a trait.
|
9
|
+
module Trait
|
10
|
+
protected
|
11
|
+
|
12
|
+
# TODO: fix
|
13
|
+
|
14
|
+
def parse_trait
|
15
|
+
expect :trait
|
16
|
+
expect :do
|
17
|
+
elements = []
|
18
|
+
elements << parse_trait_element until peek?(:end)
|
19
|
+
expect :end
|
20
|
+
|
21
|
+
Node.new(:trait, [Node.new(:trait_elements, elements)])
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_trait_element
|
25
|
+
name = parse_name
|
26
|
+
arguments = []
|
27
|
+
expect :"("
|
28
|
+
until peek? :")"
|
29
|
+
arguments << parse_type
|
30
|
+
break unless peek? :","
|
31
|
+
expect :","
|
32
|
+
end
|
33
|
+
expect :")"
|
34
|
+
expect :":"
|
35
|
+
ret = parse_type
|
36
|
+
expect :";"
|
37
|
+
|
38
|
+
Node.new(:trait_element, [name, arguments, ret])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
4
|
+
|
5
|
+
require "carbon/compiler/parser/statements/if"
|
6
|
+
require "carbon/compiler/parser/statements/match"
|
7
|
+
require "carbon/compiler/parser/statements/try"
|
8
|
+
|
9
|
+
module Carbon
|
10
|
+
module Compiler
|
11
|
+
class Parser
|
12
|
+
# Parses statements.
|
13
|
+
module Statements
|
14
|
+
include If
|
15
|
+
include Match
|
16
|
+
include Try
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def parse_statement
|
21
|
+
case peek.type
|
22
|
+
when :if then parse_statement_if
|
23
|
+
when :match then parse_statement_match
|
24
|
+
when :try then parse_statement_try
|
25
|
+
when :for then parse_statement_for
|
26
|
+
when :return then parse_statement_return
|
27
|
+
when :while then parse_statement_while
|
28
|
+
when :let then parse_statement_let
|
29
|
+
when :do then parse_function_body
|
30
|
+
else
|
31
|
+
expr = parse_expression
|
32
|
+
expect :";"
|
33
|
+
expr
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_statement_return
|
38
|
+
expect :return
|
39
|
+
expr = parse_expression unless peek? :";"
|
40
|
+
expect :";"
|
41
|
+
|
42
|
+
Node::Statement::Return.new([expr].compact)
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_statement_let
|
46
|
+
expect :let
|
47
|
+
name = parse_name
|
48
|
+
expect :":"
|
49
|
+
type = parse_type
|
50
|
+
value =
|
51
|
+
if peek? :"="
|
52
|
+
expect :"="
|
53
|
+
parse_expression
|
54
|
+
end
|
55
|
+
expect :";"
|
56
|
+
|
57
|
+
Node::Statement::Let.new([name, type, value])
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_statement_while
|
61
|
+
expect :while
|
62
|
+
expect :"("
|
63
|
+
condition = parse_expression
|
64
|
+
expect :")"
|
65
|
+
body = parse_statement
|
66
|
+
|
67
|
+
Node::Statement::While.new([condition, body])
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_statement_for
|
71
|
+
expect :for
|
72
|
+
expect :"("
|
73
|
+
initial = parse_expression
|
74
|
+
expect :";"
|
75
|
+
condition = parse_expression
|
76
|
+
expect :";"
|
77
|
+
increment = parse_expression
|
78
|
+
expect :")"
|
79
|
+
body = parse_statement
|
80
|
+
|
81
|
+
Node::Statement::For.new([initial, condition, increment, body])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Compiler
|
6
|
+
class Parser
|
7
|
+
module Statements
|
8
|
+
# Parses an if statement.
|
9
|
+
module If
|
10
|
+
protected
|
11
|
+
|
12
|
+
def parse_statement_if
|
13
|
+
expect :if
|
14
|
+
expect :"("
|
15
|
+
condition = parse_expression
|
16
|
+
expect :")"
|
17
|
+
body = parse_statement
|
18
|
+
follow = parse_statement_if_continued
|
19
|
+
|
20
|
+
Node::Statement::If.new([condition, body, follow])
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_statement_if_continued
|
24
|
+
case peek.type
|
25
|
+
when :elsif then parse_statement_if_elsif
|
26
|
+
when :else then parse_statement_if_else
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def parse_statement_if_elsif
|
31
|
+
expect :elsif
|
32
|
+
expect :"("
|
33
|
+
condition = parse_expression
|
34
|
+
expect :")"
|
35
|
+
body = parse_statement
|
36
|
+
follow = parse_statement_if_continued
|
37
|
+
|
38
|
+
Node::Statement::Elsif.new([condition, body, follow])
|
39
|
+
end
|
40
|
+
|
41
|
+
def parse_statement_if_else
|
42
|
+
expect :else
|
43
|
+
|
44
|
+
Node::Statement::Else.new([parse_statement])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|