mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-30 22:02:41 +01:00
This is a first pass at what semantic type checking might look like. Types propagate along nodes, we use an InvalidType object when there's an error, and once there's an InvalidType we stop doing so much type checking. This adds some RealLiteral handling in order to get type mismatches. I'm cautious about creating some real value for SemanticsIR (since the tokenized buffer version is a bit constrained), so I'm not doing that yet. But I will probably need to in order to maintain SemanticsIR having hermetic copies of its data, without a parse tree dependency.
103 lines
3.7 KiB
C++
103 lines
3.7 KiB
C++
// 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 CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_PARSE_TREE_HANDLER_H_
|
|
#define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_PARSE_TREE_HANDLER_H_
|
|
|
|
#include "toolchain/parser/parse_tree.h"
|
|
#include "toolchain/semantics/semantics_ir.h"
|
|
#include "toolchain/semantics/semantics_node.h"
|
|
|
|
namespace Carbon {
|
|
|
|
// Handles processing of a ParseTree for semantics.
|
|
class SemanticsParseTreeHandler {
|
|
public:
|
|
// Stores references for work.
|
|
explicit SemanticsParseTreeHandler(const TokenizedBuffer& tokens,
|
|
TokenDiagnosticEmitter& emitter,
|
|
const ParseTree& parse_tree,
|
|
SemanticsIR& semantics,
|
|
llvm::raw_ostream* vlog_stream)
|
|
: tokens_(&tokens),
|
|
emitter_(&emitter),
|
|
parse_tree_(&parse_tree),
|
|
semantics_(&semantics),
|
|
vlog_stream_(vlog_stream) {}
|
|
|
|
// Outputs the ParseTree information into SemanticsIR.
|
|
auto Build() -> void;
|
|
|
|
private:
|
|
// Prints the node_stack_ on stack dumps.
|
|
class PrettyStackTraceNodeStack;
|
|
// Prints the node_block_stack_ on stack dumps.
|
|
class PrettyStackTraceNodeBlockStack;
|
|
|
|
struct TraversalStackEntry {
|
|
ParseTree::Node parse_node;
|
|
llvm::Optional<SemanticsNodeId> result_id;
|
|
};
|
|
|
|
// Adds an identifier for a DeclaredName node, returning its reference.
|
|
auto AddIdentifier(ParseTree::Node decl_node) -> SemanticsIdentifierId;
|
|
|
|
// Adds a node to the current block, returning the produced ID.
|
|
auto AddNode(SemanticsNode node) -> SemanticsNodeId;
|
|
|
|
// Pushes a parse tree onto the stack. Used when there is no IR generated by
|
|
// the node.
|
|
auto Push(ParseTree::Node parse_node) -> void;
|
|
|
|
// Pushes a parse tree onto the stack, storing the SemanticsNode as the
|
|
// result.
|
|
auto Push(ParseTree::Node parse_node, SemanticsNode node) -> void;
|
|
|
|
// Pops the top of the stack, verifying that it's the expected kind.
|
|
auto Pop(ParseNodeKind pop_parse_kind) -> void;
|
|
|
|
// Pops the top of the stack, returning the result_id. Must only be called for
|
|
// nodes that have results.
|
|
auto PopWithResult() -> SemanticsNodeId;
|
|
|
|
// Pops the top of the stack, verifying that it's the expected kind and
|
|
// returning the result_id. Must only be called for nodes that have results.
|
|
auto PopWithResult(ParseNodeKind pop_parse_kind) -> SemanticsNodeId;
|
|
|
|
// Parse node handlers.
|
|
auto HandleDeclaredName(ParseTree::Node parse_node) -> void;
|
|
auto HandleFunctionDefinition(ParseTree::Node parse_node) -> void;
|
|
auto HandleFunctionDefinitionStart(ParseTree::Node parse_node) -> void;
|
|
auto HandleInfixOperator(ParseTree::Node parse_node) -> void;
|
|
auto HandleLiteral(ParseTree::Node parse_node) -> void;
|
|
auto HandleParameterList(ParseTree::Node parse_node) -> void;
|
|
auto HandleReturnStatement(ParseTree::Node parse_node) -> void;
|
|
|
|
// Tokens for getting data on literals.
|
|
const TokenizedBuffer* tokens_;
|
|
|
|
// Handles diagnostics.
|
|
TokenDiagnosticEmitter* emitter_;
|
|
|
|
// The file's parse tree.
|
|
const ParseTree* parse_tree_;
|
|
|
|
// The SemanticsIR being added to.
|
|
SemanticsIR* semantics_;
|
|
|
|
// Whether to print verbose output.
|
|
llvm::raw_ostream* vlog_stream_;
|
|
|
|
// The stack during Build. Will contain file-level parse nodes on return.
|
|
llvm::SmallVector<TraversalStackEntry> node_stack_;
|
|
|
|
// The stack of node blocks during build. Only updated on ParseTree nodes that
|
|
// affect the stack.
|
|
llvm::SmallVector<SemanticsNodeBlockId> node_block_stack_;
|
|
};
|
|
|
|
} // namespace Carbon
|
|
|
|
#endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_PARSE_TREE_HANDLER_H_
|