Make the AST mutable (#849)

The code is pretty intertwined: having the AST be truly mutable means (to me) changing parser.ypp to return non-const values, but then the way things are passed around between objects should be non-const (particularly an issue with lists), which then creates issues with construction of lists in the TypeChecker, which then TypeChecker needs to mostly be non-const.

Due to the difficulties in breaking this apart, whereas I'd previously considering refactoring accessor naming in the same PR, I've largely avoided doing so. The intent is then that this PR focuses mainly on const -> non-const AST behavior.

call_main moves out of interpreter.cpp so that interpreter.cpp can receive a fully const AST.
This commit is contained in:
Jon Meow
2021-09-27 10:57:31 -07:00
committed by GitHub
parent 721743bc58
commit 04ab30f231
15 changed files with 282 additions and 270 deletions
+37 -41
View File
@@ -98,43 +98,43 @@
%type <std::vector<LibraryName>> import_directives
%type <std::string> optional_library_path
%type <bool> api_or_impl
%type <Nonnull<const Declaration*>> declaration
%type <Nonnull<const FunctionDefinition*>> function_declaration
%type <Nonnull<const FunctionDefinition*>> function_definition
%type <std::vector<Nonnull<const Declaration*>>> declaration_list
%type <Nonnull<const Statement*>> statement
%type <Nonnull<const Statement*>> if_statement
%type <std::optional<Nonnull<const Statement*>>> optional_else
%type <std::pair<Nonnull<const Expression*>, bool>> return_expression
%type <Nonnull<const Statement*>> block
%type <std::optional<Nonnull<const Statement*>>> statement_list
%type <Nonnull<const Expression*>> expression
%type <Nonnull<Declaration*>> declaration
%type <Nonnull<FunctionDefinition*>> function_declaration
%type <Nonnull<FunctionDefinition*>> function_definition
%type <std::vector<Nonnull<Declaration*>>> declaration_list
%type <Nonnull<Statement*>> statement
%type <Nonnull<Statement*>> if_statement
%type <std::optional<Nonnull<Statement*>>> optional_else
%type <std::pair<Nonnull<Expression*>, bool>> return_expression
%type <Nonnull<Statement*>> block
%type <std::optional<Nonnull<Statement*>>> statement_list
%type <Nonnull<Expression*>> expression
%type <GenericBinding> generic_binding
%type <std::vector<GenericBinding>> deduced_params
%type <std::vector<GenericBinding>> deduced_param_list
%type <Nonnull<const Pattern*>> pattern
%type <Nonnull<const Pattern*>> non_expression_pattern
%type <std::pair<Nonnull<const Expression*>, bool>> return_type
%type <Nonnull<const Expression*>> paren_expression
%type <Nonnull<const Expression*>> tuple
%type <Nonnull<Pattern*>> pattern
%type <Nonnull<Pattern*>> non_expression_pattern
%type <std::pair<Nonnull<Expression*>, bool>> return_type
%type <Nonnull<Expression*>> paren_expression
%type <Nonnull<Expression*>> tuple
%type <std::optional<std::string>> binding_lhs
%type <Nonnull<const BindingPattern*>> variable_declaration
%type <Nonnull<BindingPattern*>> variable_declaration
%type <Nonnull<Member*>> member
%type <std::vector<Nonnull<Member*>>> member_list
%type <ParenContents<Expression>::Element> paren_expression_element
%type <ParenContents<Expression>> paren_expression_base
%type <ParenContents<Expression>> paren_expression_contents
%type <Nonnull<const Pattern*>> paren_pattern
%type <Nonnull<const TuplePattern*>> tuple_pattern
%type <Nonnull<const TuplePattern*>> maybe_empty_tuple_pattern
%type <Nonnull<Pattern*>> paren_pattern
%type <Nonnull<TuplePattern*>> tuple_pattern
%type <Nonnull<TuplePattern*>> maybe_empty_tuple_pattern
%type <ParenContents<Pattern>> paren_pattern_base
%type <ParenContents<Pattern>::Element> paren_pattern_element
%type <ParenContents<Pattern>> paren_pattern_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
%type <std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>> clause
%type <std::vector<std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>>> clause_list
%token
// Most tokens have their spelling defined in lexer.lpp.
@@ -303,61 +303,61 @@ expression:
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Eq,
std::vector<Nonnull<const Expression*>>({$1, $3}));
std::vector<Nonnull<Expression*>>({$1, $3}));
}
| expression PLUS expression
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Add,
std::vector<Nonnull<const Expression*>>({$1, $3}));
std::vector<Nonnull<Expression*>>({$1, $3}));
}
| expression MINUS expression
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Sub,
std::vector<Nonnull<const Expression*>>({$1, $3}));
std::vector<Nonnull<Expression*>>({$1, $3}));
}
| expression BINARY_STAR expression
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Mul,
std::vector<Nonnull<const Expression*>>({$1, $3}));
std::vector<Nonnull<Expression*>>({$1, $3}));
}
| expression AND expression
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::And,
std::vector<Nonnull<const Expression*>>({$1, $3}));
std::vector<Nonnull<Expression*>>({$1, $3}));
}
| expression OR expression
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Or,
std::vector<Nonnull<const Expression*>>({$1, $3}));
std::vector<Nonnull<Expression*>>({$1, $3}));
}
| NOT expression
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Not,
std::vector<Nonnull<const Expression*>>({$2}));
std::vector<Nonnull<Expression*>>({$2}));
}
| MINUS expression %prec UNARY_MINUS
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Neg,
std::vector<Nonnull<const Expression*>>({$2}));
std::vector<Nonnull<Expression*>>({$2}));
}
| PREFIX_STAR expression
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Deref,
std::vector<Nonnull<const Expression*>>({$2}));
std::vector<Nonnull<Expression*>>({$2}));
}
| UNARY_STAR expression %prec PREFIX_STAR
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Deref,
std::vector<Nonnull<const Expression*>>({$2}));
std::vector<Nonnull<Expression*>>({$2}));
}
| expression tuple
{ $$ = arena->New<CallExpression>(context.SourceLoc(), $1, $2); }
@@ -365,13 +365,13 @@ expression:
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Ptr,
std::vector<Nonnull<const Expression*>>({$1}));
std::vector<Nonnull<Expression*>>({$1}));
}
| expression UNARY_STAR
{
$$ = arena->New<PrimitiveOperatorExpression>(
context.SourceLoc(), Operator::Ptr,
std::vector<Nonnull<const Expression*>>({$1}));
std::vector<Nonnull<Expression*>>({$1}));
}
| FNTY tuple return_type
{
@@ -501,17 +501,13 @@ maybe_empty_tuple_pattern:
;
clause:
CASE pattern DOUBLE_ARROW statement
{
$$ =
std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>($2, $4);
}
{ $$ = std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>($2, $4); }
| DEFAULT DOUBLE_ARROW statement
{
auto vp = arena -> New<BindingPattern>(
context.SourceLoc(), std::nullopt,
arena->New<AutoPattern>(context.SourceLoc()));
$$ =
std::pair<Nonnull<const Pattern*>, Nonnull<const Statement*>>(vp, $3);
$$ = std::pair<Nonnull<Pattern*>, Nonnull<Statement*>>(vp, $3);
}
;
clause_list:
@@ -701,7 +697,7 @@ declaration_list:
| declaration_list declaration
{
$$ = $1;
$$.push_back(Nonnull<const Declaration*>($2));
$$.push_back(Nonnull<Declaration*>($2));
}
;
%%