Change Alternative to a class (#853)

Revives BisonWrap because this seems a reasonable use of it (avoiding the need to have an std::optional or pointer for Alternative, both of which I thought could be unclear about the intent).
This commit is contained in:
Jon Meow
2021-09-27 09:05:22 -07:00
committed by GitHub
parent 6ab2bff69c
commit 721743bc58
7 changed files with 84 additions and 22 deletions
+7
View File
@@ -6,6 +6,12 @@ load("@mypy_integration//:mypy.bzl", "mypy_test")
package(default_visibility = ["//executable_semantics:__pkg__"])
cc_library(
name = "bison_wrap",
hdrs = ["bison_wrap.h"],
deps = ["//common:check"],
)
cc_library(
name = "syntax",
srcs = [
@@ -27,6 +33,7 @@ cc_library(
"-Wno-writable-strings",
],
deps = [
":bison_wrap",
"//common:check",
"//common:ostream",
"//common:string_helpers",
+44
View File
@@ -0,0 +1,44 @@
// 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
#ifndef EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_
#define EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_
#include <optional>
#include "common/check.h"
namespace Carbon {
// Bison requires that types be default initializable for use with its variant
// semantics. This wraps arbitrary types to support a default constructor, while
// still requiring they be properly initialized.
template <typename T>
class BisonWrap {
public:
// Assigning a value initializes the wrapper.
auto operator=(T&& rhs) -> BisonWrap& {
val = std::move(rhs);
return *this;
}
// Support transparent conversion to the wrapped type.
operator T() { return Release(); }
// Deliberately releases the contained value. Errors if not initialized.
// Called directly in parser.ypp when releasing pairs.
auto Release() -> T {
CHECK(val.has_value());
T ret = std::move(*val);
val.reset();
return ret;
}
private:
std::optional<T> val;
};
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_
+8 -7
View File
@@ -73,6 +73,7 @@
#include "executable_semantics/ast/pattern.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/common/nonnull.h"
#include "executable_semantics/syntax/bison_wrap.h"
namespace Carbon {
class ParseAndLexContext;
@@ -129,9 +130,9 @@
%type <ParenContents<Pattern>> paren_pattern_base
%type <ParenContents<Pattern>::Element> paren_pattern_element
%type <ParenContents<Pattern>> paren_pattern_contents
%type <std::pair<std::string, Nonnull<const Expression*>>> alternative
%type <std::vector<std::pair<std::string, Nonnull<const Expression*>>>> alternative_list
%type <std::vector<std::pair<std::string, Nonnull<const Expression*>>>> alternative_list_contents
%type <BisonWrap<ChoiceDeclaration::Alternative>> alternative
%type <std::vector<ChoiceDeclaration::Alternative>> alternative_list
%type <std::vector<ChoiceDeclaration::Alternative>> alternative_list_contents
%type <std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>> clause
%type <std::vector<std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>>> clause_list
@@ -658,10 +659,10 @@ member_list:
;
alternative:
identifier tuple
{ $$ = std::pair<std::string, Nonnull<const Expression*>>($1, $2); }
{ $$ = ChoiceDeclaration::Alternative($1, $2); }
| identifier
{
$$ = std::pair<std::string, Nonnull<const Expression*>>(
$$ = ChoiceDeclaration::Alternative(
$1, arena->New<TupleLiteral>(context.SourceLoc()));
}
;
@@ -675,11 +676,11 @@ alternative_list:
;
alternative_list_contents:
alternative
{ $$ = {$1}; }
{ $$ = {std::move($1)}; }
| alternative_list_contents COMMA alternative
{
$$ = $1;
$$.push_back($3);
$$.push_back(std::move($3));
}
;
declaration: