mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 07:24:42 +01:00
Migrate declaration parsing to value semantics (#614)
* Use Expression by value in FunctionDefinition * Migrate choice declarations to value semantics * Migrate Declaration parsing to value semantics
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
#include "executable_semantics/ast/declaration.h"
|
||||
|
||||
namespace Carbon {
|
||||
using AST = std::list<Carbon::Declaration>*;
|
||||
using AST = std::list<Carbon::Declaration>;
|
||||
}
|
||||
|
||||
#endif // EXECUTABLE_SEMANTICS_AST_ABSTRACT_SYNTAX_TREE_H_
|
||||
|
||||
@@ -20,9 +20,9 @@ void StructDeclaration::Print() const {
|
||||
|
||||
void ChoiceDeclaration::Print() const {
|
||||
std::cout << "choice " << name << " {" << std::endl;
|
||||
for (auto& alternative : alternatives) {
|
||||
std::cout << "alt " << alternative.first << " ";
|
||||
PrintExp(alternative.second);
|
||||
for (const auto& [name, signature] : alternatives) {
|
||||
std::cout << "alt " << name << " ";
|
||||
PrintExp(&signature);
|
||||
std::cout << ";" << std::endl;
|
||||
}
|
||||
std::cout << "}" << std::endl;
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#include "executable_semantics/ast/struct_definition.h"
|
||||
#include "executable_semantics/interpreter/dictionary.h"
|
||||
|
||||
namespace yy {
|
||||
class parser;
|
||||
}
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
struct Value;
|
||||
@@ -56,7 +60,7 @@ class Declaration {
|
||||
// Add an entry in the compile time global symbol tables for this declaration.
|
||||
auto TopLevel(TypeCheckContext& e) const -> void { return box->TopLevel(e); }
|
||||
|
||||
private: // types
|
||||
private:
|
||||
// A base class that erases the type of a `Boxed<Content>`, where `Content`
|
||||
// satisfies the Declaration concept.
|
||||
struct Box {
|
||||
@@ -95,15 +99,21 @@ class Declaration {
|
||||
}
|
||||
};
|
||||
|
||||
private: // data members
|
||||
// Constructs an instance in a "partially formed" state, which can only be
|
||||
// assigned to or destroyed.
|
||||
Declaration() = default;
|
||||
|
||||
// Give Bison access to the default constructor.
|
||||
friend class yy::parser;
|
||||
|
||||
// Note: the pointee is const as long as we have no mutating methods. When
|
||||
std::shared_ptr<const Box> box;
|
||||
};
|
||||
|
||||
struct FunctionDeclaration {
|
||||
const FunctionDefinition* definition;
|
||||
explicit FunctionDeclaration(const FunctionDefinition* definition)
|
||||
: definition(definition) {}
|
||||
FunctionDefinition definition;
|
||||
explicit FunctionDeclaration(FunctionDefinition definition)
|
||||
: definition(std::move(definition)) {}
|
||||
|
||||
auto Print() const -> void;
|
||||
auto Name() const -> std::string;
|
||||
@@ -127,12 +137,11 @@ struct StructDeclaration {
|
||||
struct ChoiceDeclaration {
|
||||
int line_num;
|
||||
std::string name;
|
||||
std::list<std::pair<std::string, const Expression*>> alternatives;
|
||||
std::list<std::pair<std::string, Expression>> alternatives;
|
||||
|
||||
ChoiceDeclaration(
|
||||
int line_num, std::string name,
|
||||
std::list<std::pair<std::string, const Expression*>> alternatives)
|
||||
: line_num(line_num), name(name), alternatives(alternatives) {}
|
||||
ChoiceDeclaration(int line_num, std::string name,
|
||||
std::list<std::pair<std::string, Expression>> alternatives)
|
||||
: line_num(line_num), name(name), alternatives(std::move(alternatives)) {}
|
||||
|
||||
void Print() const;
|
||||
auto Name() const -> std::string;
|
||||
|
||||
@@ -8,32 +8,32 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto MakeFunDef(int line_num, std::string name, const Expression* ret_type,
|
||||
const Expression* param_pattern, const Statement* body)
|
||||
-> struct FunctionDefinition* {
|
||||
auto* f = new struct FunctionDefinition();
|
||||
f->line_num = line_num;
|
||||
f->name = std::move(name);
|
||||
f->return_type = ret_type;
|
||||
f->param_pattern = param_pattern;
|
||||
f->body = body;
|
||||
auto MakeFunDef(int line_num, std::string name, Expression ret_type,
|
||||
Expression param_pattern, const Statement* body)
|
||||
-> FunctionDefinition {
|
||||
FunctionDefinition f;
|
||||
f.line_num = line_num;
|
||||
f.name = std::move(name);
|
||||
f.return_type = std::move(ret_type);
|
||||
f.param_pattern = std::move(param_pattern);
|
||||
f.body = body;
|
||||
return f;
|
||||
}
|
||||
|
||||
void PrintFunDefDepth(const FunctionDefinition* f, int depth) {
|
||||
std::cout << "fn " << f->name << " ";
|
||||
PrintExp(f->param_pattern);
|
||||
void PrintFunDefDepth(const FunctionDefinition& f, int depth) {
|
||||
std::cout << "fn " << f.name << " ";
|
||||
PrintExp(&f.param_pattern);
|
||||
std::cout << " -> ";
|
||||
PrintExp(f->return_type);
|
||||
if (f->body) {
|
||||
PrintExp(&f.return_type);
|
||||
if (f.body) {
|
||||
std::cout << " {" << std::endl;
|
||||
PrintStatement(f->body, depth);
|
||||
PrintStatement(f.body, depth);
|
||||
std::cout << std::endl << "}" << std::endl;
|
||||
} else {
|
||||
std::cout << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void PrintFunDef(const FunctionDefinition* f) { PrintFunDefDepth(f, -1); }
|
||||
void PrintFunDef(const FunctionDefinition& f) { PrintFunDefDepth(f, -1); }
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
@@ -13,16 +13,15 @@ namespace Carbon {
|
||||
struct FunctionDefinition {
|
||||
int line_num;
|
||||
std::string name;
|
||||
const Expression* param_pattern;
|
||||
const Expression* return_type;
|
||||
Expression param_pattern;
|
||||
Expression return_type;
|
||||
const Statement* body;
|
||||
};
|
||||
|
||||
auto MakeFunDef(int line_num, std::string name, const Expression* ret_type,
|
||||
const Expression* param, const Statement* body)
|
||||
-> FunctionDefinition*;
|
||||
void PrintFunDef(const FunctionDefinition*);
|
||||
void PrintFunDefDepth(const FunctionDefinition*, int);
|
||||
auto MakeFunDef(int line_num, std::string name, Expression ret_type,
|
||||
Expression param, const Statement* body) -> FunctionDefinition;
|
||||
void PrintFunDef(const FunctionDefinition&);
|
||||
void PrintFunDefDepth(const FunctionDefinition&, int);
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
|
||||
@@ -314,9 +314,9 @@ void InitGlobals(std::list<Declaration>* fs) {
|
||||
|
||||
auto ChoiceDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
auto alts = new VarValues();
|
||||
for (auto kv : alternatives) {
|
||||
auto t = InterpExp(Env(), kv.second);
|
||||
alts->push_back(make_pair(kv.first, t));
|
||||
for (const auto& [name, signature] : alternatives) {
|
||||
auto t = InterpExp(Env(), &signature);
|
||||
alts->push_back(make_pair(name, t));
|
||||
}
|
||||
auto ct = Value::MakeChoiceTypeVal(name, alts);
|
||||
auto a = state->heap.AllocateValue(ct);
|
||||
@@ -342,10 +342,10 @@ auto StructDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
}
|
||||
|
||||
auto FunctionDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
auto pt = InterpExp(globals, definition->param_pattern);
|
||||
auto f = Value::MakeFunVal(definition->name, pt, definition->body);
|
||||
auto pt = InterpExp(globals, &definition.param_pattern);
|
||||
auto f = Value::MakeFunVal(definition.name, pt, definition.body);
|
||||
Address a = state->heap.AllocateValue(f);
|
||||
globals.Set(definition->name, a);
|
||||
globals.Set(definition.name, a);
|
||||
}
|
||||
|
||||
// Adds an entry in `globals` mapping the variable's name to the
|
||||
|
||||
@@ -664,9 +664,9 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
|
||||
|
||||
auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
|
||||
-> struct FunctionDefinition* {
|
||||
auto param_res = TypeCheckExp(f->param_pattern, types, values, nullptr,
|
||||
auto param_res = TypeCheckExp(&f->param_pattern, types, values, nullptr,
|
||||
TCContext::PatternContext);
|
||||
auto return_type = InterpExp(values, f->return_type);
|
||||
auto return_type = InterpExp(values, &f->return_type);
|
||||
if (f->name == "main") {
|
||||
ExpectType(f->line_num, "return type of `main`", Value::MakeIntTypeVal(),
|
||||
return_type);
|
||||
@@ -675,18 +675,19 @@ auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
|
||||
auto res = TypeCheckStmt(f->body, param_res.types, values, return_type);
|
||||
bool void_return = TypeEqual(return_type, Value::MakeUnitTypeVal());
|
||||
auto body = CheckOrEnsureReturn(res.stmt, void_return, f->line_num);
|
||||
return MakeFunDef(f->line_num, f->name, ReifyType(return_type, f->line_num),
|
||||
f->param_pattern, body);
|
||||
return new FunctionDefinition(MakeFunDef(f->line_num, f->name,
|
||||
*ReifyType(return_type, f->line_num),
|
||||
f->param_pattern, body));
|
||||
}
|
||||
|
||||
auto TypeOfFunDef(TypeEnv types, Env values, const FunctionDefinition* fun_def)
|
||||
-> const Value* {
|
||||
auto param_res = TypeCheckExp(fun_def->param_pattern, types, values, nullptr,
|
||||
auto param_res = TypeCheckExp(&fun_def->param_pattern, types, values, nullptr,
|
||||
TCContext::PatternContext);
|
||||
auto ret = InterpExp(values, fun_def->return_type);
|
||||
auto ret = InterpExp(values, &fun_def->return_type);
|
||||
if (ret->tag == ValKind::AutoTV) {
|
||||
auto f = TypeCheckFunDef(fun_def, types, values);
|
||||
ret = InterpExp(values, f->return_type);
|
||||
ret = InterpExp(values, &f->return_type);
|
||||
}
|
||||
return Value::MakeFunTypeVal(param_res.type, ret);
|
||||
}
|
||||
@@ -705,7 +706,7 @@ auto TypeOfStructDef(const StructDefinition* sd, TypeEnv /*types*/, Env ct_top)
|
||||
}
|
||||
|
||||
auto FunctionDeclaration::Name() const -> std::string {
|
||||
return definition->name;
|
||||
return definition.name;
|
||||
}
|
||||
|
||||
auto StructDeclaration::Name() const -> std::string { return *definition.name; }
|
||||
@@ -729,7 +730,7 @@ auto StructDeclaration::TypeChecked(TypeEnv types, Env values) const
|
||||
|
||||
auto FunctionDeclaration::TypeChecked(TypeEnv types, Env values) const
|
||||
-> Declaration {
|
||||
return FunctionDeclaration(TypeCheckFunDef(definition, types, values));
|
||||
return FunctionDeclaration(*TypeCheckFunDef(&definition, types, values));
|
||||
}
|
||||
|
||||
auto ChoiceDeclaration::TypeChecked(TypeEnv types, Env values) const
|
||||
@@ -770,7 +771,7 @@ auto TopLevel(std::list<Declaration>* fs) -> TypeCheckContext {
|
||||
}
|
||||
|
||||
auto FunctionDeclaration::TopLevel(TypeCheckContext& tops) const -> void {
|
||||
auto t = TypeOfFunDef(tops.types, tops.values, definition);
|
||||
auto t = TypeOfFunDef(tops.types, tops.values, &definition);
|
||||
tops.types.Set(Name(), t);
|
||||
InitGlobals(tops.values);
|
||||
}
|
||||
@@ -790,9 +791,9 @@ auto StructDeclaration::TopLevel(TypeCheckContext& tops) const -> void {
|
||||
|
||||
auto ChoiceDeclaration::TopLevel(TypeCheckContext& tops) const -> void {
|
||||
auto alts = new VarValues();
|
||||
for (auto a : alternatives) {
|
||||
auto t = InterpExp(tops.values, a.second);
|
||||
alts->push_back(std::make_pair(a.first, t));
|
||||
for (const auto& [name, signature] : alternatives) {
|
||||
auto t = InterpExp(tops.values, &signature);
|
||||
alts->push_back(std::make_pair(name, t));
|
||||
}
|
||||
auto ct = Value::MakeChoiceTypeVal(name, alts);
|
||||
Address a = state->heap.AllocateValue(ct);
|
||||
|
||||
@@ -32,5 +32,5 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
// Typecheck and run the parsed program.
|
||||
Carbon::ExecProgram(std::get<Carbon::AST>(ast_or_error));
|
||||
Carbon::ExecProgram(&std::get<Carbon::AST>(ast_or_error));
|
||||
}
|
||||
|
||||
@@ -92,10 +92,10 @@ void yy::parser::error(
|
||||
%token <int> integer_literal
|
||||
%token <char*> identifier
|
||||
%type <char*> designator
|
||||
%type <Carbon::Declaration*> declaration
|
||||
%type <Carbon::FunctionDefinition*> function_declaration
|
||||
%type <Carbon::FunctionDefinition*> function_definition
|
||||
%type <std::list<Carbon::Declaration>*> declaration_list
|
||||
%type <Carbon::Declaration> declaration
|
||||
%type <Carbon::FunctionDefinition> function_declaration
|
||||
%type <Carbon::FunctionDefinition> function_definition
|
||||
%type <std::list<Carbon::Declaration>> declaration_list
|
||||
%type <const Carbon::Statement*> statement
|
||||
%type <const Carbon::Statement*> optional_else
|
||||
%type <const Carbon::Statement*> statement_list
|
||||
@@ -110,8 +110,8 @@ void yy::parser::error(
|
||||
%type <Carbon::FieldInitializer> field_initializer
|
||||
%type <Carbon::ParenContents> paren_contents
|
||||
%type <std::vector<Carbon::FieldInitializer>> paren_contents_without_trailing_comma
|
||||
%type <std::pair<std::string, const Carbon::Expression*>*> alternative
|
||||
%type <std::list<std::pair<std::string, const Carbon::Expression*>>*> alternative_list
|
||||
%type <std::pair<std::string, Carbon::Expression>> alternative
|
||||
%type <std::list<std::pair<std::string, Carbon::Expression>>> alternative_list
|
||||
%type <std::pair<const Carbon::Expression*, const Carbon::Statement*>*> clause
|
||||
%type <std::list<std::pair<const Carbon::Expression*, const Carbon::Statement*>>*> clause_list
|
||||
%token END_OF_FILE 0
|
||||
@@ -356,16 +356,16 @@ return_type:
|
||||
;
|
||||
function_definition:
|
||||
FN identifier tuple return_type "{" statement_list "}"
|
||||
{ $$ = MakeFunDef(yylineno, $2, $4, $3, $6); }
|
||||
{ $$ = MakeFunDef(yylineno, $2, *$4, *$3, $6); }
|
||||
| FN identifier tuple DBLARROW expression ";"
|
||||
{
|
||||
$$ = Carbon::MakeFunDef(yylineno, $2, Carbon::Expression::MakeAutoType(yylineno), $3,
|
||||
$$ = Carbon::MakeFunDef(yylineno, $2, *Carbon::Expression::MakeAutoType(yylineno), *$3,
|
||||
Carbon::Statement::MakeReturn(yylineno, *$5));
|
||||
}
|
||||
;
|
||||
function_declaration:
|
||||
FN identifier tuple return_type ";"
|
||||
{ $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
|
||||
{ $$ = MakeFunDef(yylineno, $2, *$4, *$3, 0); }
|
||||
;
|
||||
variable_declaration: identifier ":" expression
|
||||
{ $$ = MakeField(yylineno, $1, $3); }
|
||||
@@ -381,52 +381,52 @@ member_list:
|
||||
;
|
||||
alternative:
|
||||
identifier tuple
|
||||
{ $$ = new std::pair<std::string, const Carbon::Expression*>($1, $2); }
|
||||
{ $$ = std::pair<std::string, Carbon::Expression>($1, *$2); }
|
||||
| identifier
|
||||
{
|
||||
$$ = new std::pair<std::string, const Carbon::Expression*>(
|
||||
$1, Carbon::Expression::MakeTuple(yylineno, {}));
|
||||
$$ = std::pair<std::string, Carbon::Expression>(
|
||||
$1, *Carbon::Expression::MakeTuple(yylineno, {}));
|
||||
}
|
||||
;
|
||||
alternative_list:
|
||||
// Empty
|
||||
{ $$ = new std::list<std::pair<std::string, const Carbon::Expression*>>(); }
|
||||
{ $$ = std::list<std::pair<std::string, Carbon::Expression>>(); }
|
||||
| alternative
|
||||
{
|
||||
$$ = new std::list<std::pair<std::string, const Carbon::Expression*>>();
|
||||
$$->push_front(*$1);
|
||||
$$ = std::list<std::pair<std::string, Carbon::Expression>>();
|
||||
$$.push_front($1);
|
||||
}
|
||||
| alternative "," alternative_list
|
||||
{ $$ = $3; $$->push_front(*$1); }
|
||||
{ $$ = std::move($3); $$.push_front($1); }
|
||||
;
|
||||
declaration:
|
||||
function_definition
|
||||
{ $$ = new Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
|
||||
{ $$ = Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
|
||||
| function_declaration
|
||||
{ $$ = new Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
|
||||
{ $$ = Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
|
||||
| STRUCT identifier "{" member_list "}"
|
||||
{
|
||||
$$ = new Carbon::Declaration(
|
||||
$$ = Carbon::Declaration(
|
||||
Carbon::StructDeclaration{yylineno, $2, $4});
|
||||
}
|
||||
| CHOICE identifier "{" alternative_list "}"
|
||||
{
|
||||
$$ = new Carbon::Declaration(
|
||||
Carbon::ChoiceDeclaration{yylineno, $2, std::list(*$4)});
|
||||
$$ = Carbon::Declaration(
|
||||
Carbon::ChoiceDeclaration{yylineno, $2, $4});
|
||||
}
|
||||
| VAR variable_declaration "=" expression ";"
|
||||
{
|
||||
$$ = new Carbon::Declaration(
|
||||
$$ = Carbon::Declaration(
|
||||
Carbon::VariableDeclaration(yylineno, *$2->u.field.name, $2->u.field.type, $4));
|
||||
}
|
||||
;
|
||||
declaration_list:
|
||||
// Empty
|
||||
{ $$ = new std::list<Carbon::Declaration>(); }
|
||||
{ $$ = std::list<Carbon::Declaration>(); }
|
||||
| declaration declaration_list
|
||||
{
|
||||
$$ = $2;
|
||||
$$->push_front(*$1);
|
||||
$$.push_front($1);
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
Reference in New Issue
Block a user