mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 09:21:04 +01:00
Store named constant values in the AST (#1011)
This enables us to stop using `Env` in the typechecker. As a byproduct, this commit also restructures the interpreter to handle run-time global initialization as part of ordinary execution, using the Action stack.
This commit is contained in:
@@ -108,11 +108,22 @@ class GenericBinding : public AstNode {
|
||||
auto has_static_type() const -> bool { return static_type_.has_value(); }
|
||||
|
||||
auto value_category() const -> ValueCategory { return ValueCategory::Let; }
|
||||
auto constant_value() const -> std::optional<Nonnull<const Value*>> {
|
||||
return constant_value_;
|
||||
}
|
||||
|
||||
// Sets the value returned by constant_value(). Can only be called once,
|
||||
// during typechecking.
|
||||
void set_constant_value(Nonnull<const Value*> value) {
|
||||
CHECK(!constant_value_.has_value());
|
||||
constant_value_ = value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
Nonnull<Expression*> type_;
|
||||
std::optional<Nonnull<const Value*>> static_type_;
|
||||
std::optional<Nonnull<const Value*>> constant_value_;
|
||||
};
|
||||
|
||||
// The syntactic representation of a function declaration's return type.
|
||||
@@ -232,6 +243,16 @@ class FunctionDeclaration : public Declaration {
|
||||
auto body() -> std::optional<Nonnull<Block*>> { return body_; }
|
||||
|
||||
auto value_category() const -> ValueCategory { return ValueCategory::Let; }
|
||||
auto constant_value() const -> std::optional<Nonnull<const Value*>> {
|
||||
return constant_value_;
|
||||
}
|
||||
|
||||
// Sets the value returned by constant_value(). Can only be called once,
|
||||
// during typechecking.
|
||||
void set_constant_value(Nonnull<const Value*> value) {
|
||||
CHECK(!constant_value_.has_value());
|
||||
constant_value_ = value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
@@ -239,6 +260,7 @@ class FunctionDeclaration : public Declaration {
|
||||
Nonnull<TuplePattern*> param_pattern_;
|
||||
ReturnTerm return_term_;
|
||||
std::optional<Nonnull<Block*>> body_;
|
||||
std::optional<Nonnull<const Value*>> constant_value_;
|
||||
};
|
||||
|
||||
class ClassDeclaration : public Declaration {
|
||||
@@ -259,10 +281,21 @@ class ClassDeclaration : public Declaration {
|
||||
auto members() const -> llvm::ArrayRef<Nonnull<Member*>> { return members_; }
|
||||
|
||||
auto value_category() const -> ValueCategory { return ValueCategory::Let; }
|
||||
auto constant_value() const -> std::optional<Nonnull<const Value*>> {
|
||||
return constant_value_;
|
||||
}
|
||||
|
||||
// Sets the value returned by constant_value(). Can only be called once,
|
||||
// during typechecking.
|
||||
void set_constant_value(Nonnull<const Value*> value) {
|
||||
CHECK(!constant_value_.has_value());
|
||||
constant_value_ = value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::vector<Nonnull<Member*>> members_;
|
||||
std::optional<Nonnull<const Value*>> constant_value_;
|
||||
};
|
||||
|
||||
class AlternativeSignature : public AstNode {
|
||||
@@ -312,10 +345,21 @@ class ChoiceDeclaration : public Declaration {
|
||||
}
|
||||
|
||||
auto value_category() const -> ValueCategory { return ValueCategory::Let; }
|
||||
auto constant_value() const -> std::optional<Nonnull<const Value*>> {
|
||||
return constant_value_;
|
||||
}
|
||||
|
||||
// Sets the value returned by constant_value(). Can only be called once,
|
||||
// during typechecking.
|
||||
void set_constant_value(Nonnull<const Value*> value) {
|
||||
CHECK(!constant_value_.has_value());
|
||||
constant_value_ = value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::vector<Nonnull<AlternativeSignature*>> alternatives_;
|
||||
std::optional<Nonnull<const Value*>> constant_value_;
|
||||
};
|
||||
|
||||
// Global variable definition implements the Declaration concept.
|
||||
|
||||
@@ -61,6 +61,7 @@ class Pattern : public AstNode {
|
||||
auto has_static_type() const -> bool { return static_type_.has_value(); }
|
||||
|
||||
// The value of this pattern. Cannot be called before typechecking.
|
||||
// TODO rename to avoid confusion with BindingPattern::constant_value
|
||||
auto value() const -> const Value& { return **value_; }
|
||||
|
||||
// Sets the value of this pattern. Can only be called once, during
|
||||
@@ -122,6 +123,10 @@ class BindingPattern : public Pattern {
|
||||
|
||||
auto value_category() const -> ValueCategory { return ValueCategory::Var; }
|
||||
|
||||
auto constant_value() const -> std::optional<Nonnull<const Value*>> {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
Nonnull<Pattern*> type_;
|
||||
|
||||
@@ -344,6 +344,9 @@ class Continuation : public Statement {
|
||||
auto has_static_type() const -> bool { return static_type_.has_value(); }
|
||||
|
||||
auto value_category() const -> ValueCategory { return ValueCategory::Var; }
|
||||
auto constant_value() const -> std::optional<Nonnull<const Value*>> {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
|
||||
@@ -37,6 +37,10 @@ static constexpr std::string_view AnonymousName = "_";
|
||||
// Returns the name of an IdentifierExpression that names *this. If *this
|
||||
// is anonymous, returns AnonymousName.
|
||||
auto name() const -> std::string_view;
|
||||
|
||||
// If *this names a compile-time constant whose value is known, returns that
|
||||
// value. Otherwise returns std::nullopt.
|
||||
auto constant_value() const -> std::optional<Nonnull<const Value*>>;
|
||||
*/
|
||||
// NodeType must be derived from AstNode.
|
||||
//
|
||||
@@ -70,7 +74,11 @@ class NamedEntityView {
|
||||
}),
|
||||
value_category_([](const AstNode& base) -> ValueCategory {
|
||||
return llvm::cast<NodeType>(base).value_category();
|
||||
}) {
|
||||
}),
|
||||
constant_value_(
|
||||
[](const AstNode& base) -> std::optional<Nonnull<const Value*>> {
|
||||
return llvm::cast<NodeType>(base).constant_value();
|
||||
}) {
|
||||
CHECK(node->name() != AnonymousName)
|
||||
<< "Entity with no name used as NamedEntity: " << *node;
|
||||
}
|
||||
@@ -94,6 +102,11 @@ class NamedEntityView {
|
||||
return value_category_(*base_);
|
||||
}
|
||||
|
||||
// Returns node->constant_value()
|
||||
auto constant_value() const -> std::optional<Nonnull<const Value*>> {
|
||||
return constant_value_(*base_);
|
||||
}
|
||||
|
||||
friend auto operator==(const NamedEntityView& lhs, const NamedEntityView& rhs)
|
||||
-> bool {
|
||||
return lhs.base_ == rhs.base_;
|
||||
@@ -114,6 +127,8 @@ class NamedEntityView {
|
||||
std::function<std::string_view(const AstNode&)> name_;
|
||||
std::function<const Value&(const AstNode&)> static_type_;
|
||||
std::function<ValueCategory(const AstNode&)> value_category_;
|
||||
std::function<std::optional<Nonnull<const Value*>>(const AstNode&)>
|
||||
constant_value_;
|
||||
};
|
||||
|
||||
// Maps the names visible in a given scope to the entities they name.
|
||||
|
||||
Reference in New Issue
Block a user