mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Move a little logic into TypeChecker to narrow what's exposed. (#938)
This commit is contained in:
@@ -155,6 +155,7 @@ cc_library(
|
||||
":dictionary",
|
||||
":interpreter",
|
||||
"//common:ostream",
|
||||
"//executable_semantics/ast",
|
||||
"//executable_semantics/ast:declaration",
|
||||
"//executable_semantics/ast:expression",
|
||||
"//executable_semantics/ast:statement",
|
||||
|
||||
@@ -50,13 +50,7 @@ void ExecProgram(Nonnull<Arena*> arena, AST ast, bool trace) {
|
||||
// (particularly templates) may require more passes.
|
||||
ResolveNames(arena, ast);
|
||||
ResolveControlFlow(ast);
|
||||
TypeChecker type_checker(arena, trace);
|
||||
TypeChecker::TypeCheckContext p = type_checker.TopLevel(&ast.declarations);
|
||||
TypeEnv top = p.types;
|
||||
Env ct_top = p.values;
|
||||
for (const auto decl : ast.declarations) {
|
||||
type_checker.TypeCheck(decl, top, ct_top);
|
||||
}
|
||||
TypeChecker(arena, trace).TypeCheck(ast);
|
||||
if (trace) {
|
||||
llvm::outs() << "\n";
|
||||
llvm::outs() << "********** type checking complete **********\n";
|
||||
|
||||
@@ -75,7 +75,7 @@ TypeChecker::ReturnTypeContext::ReturnTypeContext(
|
||||
: std::optional(orig_return_type)),
|
||||
is_omitted_(is_omitted) {}
|
||||
|
||||
void PrintTypeEnv(TypeEnv types, llvm::raw_ostream& out) {
|
||||
void TypeChecker::PrintTypeEnv(TypeEnv types, llvm::raw_ostream& out) {
|
||||
llvm::ListSeparator sep;
|
||||
for (const auto& [name, type] : types) {
|
||||
out << sep << name << ": " << *type;
|
||||
@@ -238,15 +238,9 @@ static void ExpectType(SourceLocation source_loc, const std::string& context,
|
||||
}
|
||||
}
|
||||
|
||||
// Perform type argument deduction, matching the parameter type `param`
|
||||
// against the argument type `arg`. Whenever there is an VariableType
|
||||
// in the parameter type, it is deduced to be the corresponding type
|
||||
// inside the argument type.
|
||||
// The `deduced` parameter is an accumulator, that is, it holds the
|
||||
// results so-far.
|
||||
static auto ArgumentDeduction(SourceLocation source_loc, TypeEnv deduced,
|
||||
Nonnull<const Value*> param,
|
||||
Nonnull<const Value*> arg) -> TypeEnv {
|
||||
auto TypeChecker::ArgumentDeduction(SourceLocation source_loc, TypeEnv deduced,
|
||||
Nonnull<const Value*> param,
|
||||
Nonnull<const Value*> arg) -> TypeEnv {
|
||||
switch (param->kind()) {
|
||||
case Value::Kind::VariableType: {
|
||||
const auto& var_type = cast<VariableType>(*param);
|
||||
@@ -1140,8 +1134,18 @@ static auto GetName(const Declaration& d) -> const std::string& {
|
||||
}
|
||||
}
|
||||
|
||||
void TypeChecker::TypeCheck(Nonnull<Declaration*> d, const TypeEnv& types,
|
||||
const Env& values) {
|
||||
void TypeChecker::TypeCheck(AST& ast) {
|
||||
TypeCheckContext p = TopLevel(&ast.declarations);
|
||||
TypeEnv top = p.types;
|
||||
Env ct_top = p.values;
|
||||
for (const auto decl : ast.declarations) {
|
||||
TypeCheckDeclaration(decl, top, ct_top);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeChecker::TypeCheckDeclaration(Nonnull<Declaration*> d,
|
||||
const TypeEnv& types,
|
||||
const Env& values) {
|
||||
switch (d->kind()) {
|
||||
case Declaration::Kind::FunctionDeclaration:
|
||||
TypeCheckFunDef(&cast<FunctionDeclaration>(*d), types, values);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <set>
|
||||
|
||||
#include "common/ostream.h"
|
||||
#include "executable_semantics/ast/ast.h"
|
||||
#include "executable_semantics/ast/expression.h"
|
||||
#include "executable_semantics/ast/statement.h"
|
||||
#include "executable_semantics/common/nonnull.h"
|
||||
@@ -16,13 +17,16 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
using TypeEnv = Dictionary<std::string, Nonnull<const Value*>>;
|
||||
|
||||
class TypeChecker {
|
||||
public:
|
||||
explicit TypeChecker(Nonnull<Arena*> arena, bool trace)
|
||||
: arena_(arena), interpreter_(arena, trace), trace_(trace) {}
|
||||
|
||||
void TypeCheck(AST& ast);
|
||||
|
||||
private:
|
||||
using TypeEnv = Dictionary<std::string, Nonnull<const Value*>>;
|
||||
|
||||
struct TypeCheckContext {
|
||||
explicit TypeCheckContext(Nonnull<Arena*> arena)
|
||||
: types(arena), values(arena) {}
|
||||
@@ -33,12 +37,6 @@ class TypeChecker {
|
||||
Env values;
|
||||
};
|
||||
|
||||
void TypeCheck(Nonnull<Declaration*> d, const TypeEnv& types,
|
||||
const Env& values);
|
||||
|
||||
auto TopLevel(std::vector<Nonnull<Declaration*>>* fs) -> TypeCheckContext;
|
||||
|
||||
private:
|
||||
// Context about the return type, which may be updated during type checking.
|
||||
class ReturnTypeContext {
|
||||
public:
|
||||
@@ -76,6 +74,18 @@ class TypeChecker {
|
||||
TypeEnv types;
|
||||
};
|
||||
|
||||
static void PrintTypeEnv(TypeEnv types, llvm::raw_ostream& out);
|
||||
|
||||
// Perform type argument deduction, matching the parameter type `param`
|
||||
// against the argument type `arg`. Whenever there is an VariableType
|
||||
// in the parameter type, it is deduced to be the corresponding type
|
||||
// inside the argument type.
|
||||
// The `deduced` parameter is an accumulator, that is, it holds the
|
||||
// results so-far.
|
||||
static auto ArgumentDeduction(SourceLocation source_loc, TypeEnv deduced,
|
||||
Nonnull<const Value*> param,
|
||||
Nonnull<const Value*> arg) -> TypeEnv;
|
||||
|
||||
// TypeCheckExp performs semantic analysis on an expression. It returns a new
|
||||
// version of the expression, its type, and an updated environment which are
|
||||
// bundled into a TCResult object. The purpose of the updated environment is
|
||||
@@ -98,6 +108,9 @@ class TypeChecker {
|
||||
std::optional<Nonnull<const Value*>> expected)
|
||||
-> TCResult;
|
||||
|
||||
void TypeCheckDeclaration(Nonnull<Declaration*> d, const TypeEnv& types,
|
||||
const Env& values);
|
||||
|
||||
// TypeCheckStmt performs semantic analysis on a statement. It returns a new
|
||||
// version of the statement and a new type environment.
|
||||
//
|
||||
@@ -122,6 +135,7 @@ class TypeChecker {
|
||||
auto TypeOfClassDef(const ClassDefinition* sd, TypeEnv /*types*/, Env ct_top)
|
||||
-> Nonnull<const Value*>;
|
||||
|
||||
auto TopLevel(std::vector<Nonnull<Declaration*>>* fs) -> TypeCheckContext;
|
||||
void TopLevel(Nonnull<Declaration*> d, TypeCheckContext* tops);
|
||||
|
||||
// Verifies that opt_stmt holds a statement, and it is structurally impossible
|
||||
|
||||
Reference in New Issue
Block a user