mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 07:24:42 +01:00
Parser for array type. (#3075)
Co-authored-by: Farzana Ahmed Siddique <fasiddique@google.com>
This commit is contained in:
co-authored by
Farzana Ahmed Siddique
parent
2f70c7d8bb
commit
a67aeb5724
@@ -50,6 +50,7 @@ CARBON_DIAGNOSTIC_KIND(WrongRealLiteralExponent)
|
||||
// ============================================================================
|
||||
|
||||
CARBON_DIAGNOSTIC_KIND(BinaryOperatorRequiresWhitespace)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedArraySemi)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedCloseSymbol)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedCodeBlock)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedExpression)
|
||||
|
||||
@@ -115,6 +115,18 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParameterListComma, 0)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ParameterList, ParameterListStart)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(DeducedParameterList, DeducedParameterListStart)
|
||||
|
||||
// An array type, such as `[i32; 3]` or `[i32;]`:
|
||||
// ArrayExpressionStart
|
||||
// _external_: type expression
|
||||
// ArrayExpressionSemi
|
||||
// _external_: expression
|
||||
// ArrayExpression
|
||||
//
|
||||
// The bound expression is optional.
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ArrayExpressionStart, 0)
|
||||
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ArrayExpressionSemi, 2)
|
||||
CARBON_PARSE_NODE_KIND_BRACKET(ArrayExpression, ArrayExpressionSemi)
|
||||
|
||||
// A pattern binding, such as `name: Type`:
|
||||
// Name
|
||||
// _external_: type expression
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "toolchain/lexer/token_kind.h"
|
||||
#include "toolchain/lexer/tokenized_buffer.h"
|
||||
#include "toolchain/parser/parse_node_kind.h"
|
||||
#include "toolchain/parser/parser_context.h"
|
||||
#include "toolchain/parser/parser_state.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto ParserHandleArrayExpression(ParserContext& context) -> void {
|
||||
auto state = context.PopState();
|
||||
state.state = ParserState::ArrayExpressionSemi;
|
||||
context.AddLeafNode(ParseNodeKind::ArrayExpressionStart,
|
||||
context.ConsumeChecked(TokenKind::OpenSquareBracket),
|
||||
state.has_error);
|
||||
context.PushState(state);
|
||||
context.PushState(ParserState::Expression);
|
||||
}
|
||||
|
||||
auto ParserHandleArrayExpressionSemi(ParserContext& context) -> void {
|
||||
auto state = context.PopState();
|
||||
auto semi = context.ConsumeIf(TokenKind::Semi);
|
||||
if (!semi) {
|
||||
context.AddNode(ParseNodeKind::ArrayExpressionSemi, *context.position(),
|
||||
state.subtree_start, true);
|
||||
CARBON_DIAGNOSTIC(ExpectedArraySemi, Error, "Expected `;` in array type.");
|
||||
context.emitter().Emit(*context.position(), ExpectedArraySemi);
|
||||
state.has_error = true;
|
||||
} else {
|
||||
context.AddNode(ParseNodeKind::ArrayExpressionSemi, *semi,
|
||||
state.subtree_start, state.has_error);
|
||||
}
|
||||
state.state = ParserState::ArrayExpressionFinish;
|
||||
context.PushState(state);
|
||||
if (!context.PositionIs(TokenKind::CloseSquareBracket)) {
|
||||
context.PushState(ParserState::Expression);
|
||||
}
|
||||
}
|
||||
|
||||
auto ParserHandleArrayExpressionFinish(ParserContext& context) -> void {
|
||||
auto state = context.PopState();
|
||||
context.ConsumeAndAddCloseSymbol(
|
||||
*(TokenizedBuffer::TokenIterator(state.token)), state,
|
||||
ParseNodeKind::ArrayExpression);
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
@@ -88,6 +88,11 @@ auto ParserHandleExpressionInPostfix(ParserContext& context) -> void {
|
||||
context.PushState(ParserState::ParenExpression);
|
||||
break;
|
||||
}
|
||||
case TokenKind::OpenSquareBracket: {
|
||||
context.PushState(state);
|
||||
context.PushState(ParserState::ArrayExpression);
|
||||
break;
|
||||
}
|
||||
case TokenKind::SelfValueIdentifier: {
|
||||
context.AddLeafNode(ParseNodeKind::SelfValueName, context.Consume());
|
||||
context.PushState(state);
|
||||
@@ -115,9 +120,7 @@ auto ParserHandleExpressionInPostfixLoop(ParserContext& context) -> void {
|
||||
// This is a cyclic state that repeats, so this state is typically pushed back
|
||||
// on.
|
||||
auto state = context.PopState();
|
||||
|
||||
state.token = *context.position();
|
||||
|
||||
switch (context.PositionKind()) {
|
||||
case TokenKind::Period: {
|
||||
context.PushState(state);
|
||||
|
||||
@@ -52,6 +52,28 @@ CARBON_PARSER_STATE(IndexExpression)
|
||||
// (state done)
|
||||
CARBON_PARSER_STATE(IndexExpressionFinish)
|
||||
|
||||
// Handles an array expression `[T; N]`.
|
||||
//
|
||||
// Always:
|
||||
// 1. Expression
|
||||
// 2. ArrayExpressionSemi
|
||||
CARBON_PARSER_STATE(ArrayExpression)
|
||||
|
||||
// Handles ';' in an array expression `[T; N]`.
|
||||
//
|
||||
// If `CloseSquareBracket`:
|
||||
// 1. ArrayExpressionFinish
|
||||
// Else:
|
||||
// 1. Expression
|
||||
// 2. ArrayExpressionFinish
|
||||
CARBON_PARSER_STATE(ArrayExpressionSemi)
|
||||
|
||||
// Handles finishing the array expression.
|
||||
//
|
||||
// Always:
|
||||
// (state done)
|
||||
CARBON_PARSER_STATE(ArrayExpressionFinish)
|
||||
|
||||
// Handles the `{` of a brace expression.
|
||||
//
|
||||
// If `CloseCurlyBrace`:
|
||||
@@ -260,6 +282,9 @@ CARBON_PARSER_STATE(Expression)
|
||||
// If `OpenParen`:
|
||||
// 1. ParenExpression
|
||||
// 2. ExpressionInPostfixLoop
|
||||
// If `OpenSquareBracket`:
|
||||
// 1. ArrayExpression
|
||||
// 2. ExpressionInPostfixLoop
|
||||
// Else:
|
||||
// (state done)
|
||||
CARBON_PARSER_STATE(ExpressionInPostfix)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TODO: It should emit only one error message.
|
||||
|
||||
// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+9]]:8: Closing symbol does not match most recent opening symbol.
|
||||
// CHECK:STDERR: var x: [i32;;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+6]]:13: Expected expression.
|
||||
// CHECK:STDERR: var x: [i32;;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+3]]:13: Unexpected tokens before `]`.
|
||||
// CHECK:STDERR: var x: [i32;;
|
||||
// CHECK:STDERR: ^
|
||||
var x: [i32;;
|
||||
|
||||
// CHECK:STDERR: fail_require_close_bracket.carbon:[[@LINE+14]]:19: `var` declarations must end with a `;`.
|
||||
// CHECK:STDERR: // CHECK:STDOUT: ]
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
|
||||
// CHECK:STDOUT: {kind: 'Name', text: 'x'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpressionStart', text: '['},
|
||||
// CHECK:STDOUT: {kind: 'Literal', text: 'i32'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpressionSemi', text: ';', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpression', text: ']', has_error: yes, subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', has_error: yes, subtree_size: 9},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -0,0 +1,22 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
|
||||
// CHECK:STDERR: fail_require_semi.carbon:[[@LINE+3]]:12: Expected `;` in array type.
|
||||
// CHECK:STDERR: var x: [i32];
|
||||
// CHECK:STDERR: ^
|
||||
var x: [i32];
|
||||
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
|
||||
// CHECK:STDOUT: {kind: 'Name', text: 'x'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpressionStart', text: '['},
|
||||
// CHECK:STDOUT: {kind: 'Literal', text: 'i32'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpressionSemi', text: ']', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpression', text: ']', has_error: yes, subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 8},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -0,0 +1,20 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
|
||||
var x: [i32; 10];
|
||||
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
|
||||
// CHECK:STDOUT: {kind: 'Name', text: 'x'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpressionStart', text: '['},
|
||||
// CHECK:STDOUT: {kind: 'Literal', text: 'i32'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpressionSemi', text: ';', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'Literal', text: '10'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpression', text: ']', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 9},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -0,0 +1,19 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
|
||||
var x: [i32;];
|
||||
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
|
||||
// CHECK:STDOUT: {kind: 'Name', text: 'x'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpressionStart', text: '['},
|
||||
// CHECK:STDOUT: {kind: 'Literal', text: 'i32'},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpressionSemi', text: ';', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ArrayExpression', text: ']', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 8},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -0,0 +1,24 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "toolchain/semantics/semantics_context.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto SemanticsHandleArrayExpressionStart(SemanticsContext& context,
|
||||
ParseTree::Node parse_node) -> bool {
|
||||
return context.TODO(parse_node, "HandleArrayExpressionStart");
|
||||
}
|
||||
|
||||
auto SemanticsHandleArrayExpressionSemi(SemanticsContext& context,
|
||||
ParseTree::Node parse_node) -> bool {
|
||||
return context.TODO(parse_node, "HandleArrayExpressionSemi");
|
||||
}
|
||||
|
||||
auto SemanticsHandleArrayExpression(SemanticsContext& context,
|
||||
ParseTree::Node parse_node) -> bool {
|
||||
return context.TODO(parse_node, "HandleArrayExpression");
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
Reference in New Issue
Block a user