Skip to content

Commit

Permalink
AST/HIR - Draft const blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
thepowersgang committed Dec 3, 2023
1 parent 8a99a6d commit 88ae396
Show file tree
Hide file tree
Showing 18 changed files with 147 additions and 18 deletions.
9 changes: 8 additions & 1 deletion src/ast/dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,15 @@ class RustPrinter:

virtual bool is_const() const override { return true; }
virtual void visit(AST::ExprNode_Block& n) override {
if( n.m_is_unsafe ) {
switch(n.m_block_type) {
case AST::ExprNode_Block::Type::Bare:
break;
case AST::ExprNode_Block::Type::Unsafe:
m_os << "unsafe ";
break;
case AST::ExprNode_Block::Type::Const:
m_os << "const ";
break;
}
m_os << "{";
inc_indent();
Expand Down
2 changes: 1 addition & 1 deletion src/ast/expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ NODE(ExprNode_Block, {
::std::vector<ExprNodeP> nodes;
for(const auto& n : m_nodes)
nodes.push_back( n->clone() );
return NEWNODE(ExprNode_Block, m_is_unsafe, m_yields_final_value, mv$(nodes), m_local_mod);
return NEWNODE(ExprNode_Block, m_block_type, m_yields_final_value, mv$(nodes), m_local_mod);
})

NODE(ExprNode_Try, {
Expand Down
13 changes: 9 additions & 4 deletions src/ast/expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,26 @@ class ExprNode
struct ExprNode_Block:
public ExprNode
{
bool m_is_unsafe;
enum class Type {
Bare,
Unsafe,
Const,
};
Type m_block_type;
bool m_yields_final_value;
Ident m_label;
::std::shared_ptr<AST::Module> m_local_mod;
::std::vector<ExprNodeP> m_nodes;

ExprNode_Block(::std::vector<ExprNodeP> nodes={}):
m_is_unsafe(false),
m_block_type(Type::Bare),
m_yields_final_value(true),
m_label(""),
m_local_mod(),
m_nodes( mv$(nodes) )
{}
ExprNode_Block(bool is_unsafe, bool yields_final_value, ::std::vector<ExprNodeP> nodes, ::std::shared_ptr<AST::Module> local_mod):
m_is_unsafe(is_unsafe),
ExprNode_Block(Type type, bool yields_final_value, ::std::vector<ExprNodeP> nodes, ::std::shared_ptr<AST::Module> local_mod):
m_block_type(type),
m_yields_final_value(yields_final_value),
m_label(""),
m_local_mod( move(local_mod) ),
Expand Down
2 changes: 1 addition & 1 deletion src/expand/derive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ class Deriver_Debug:
));
}
nodes.push_back(NEWNODE(CallMethod, NEWNODE(NamedValue, AST::Path("s")), AST::PathNode("finish",{}), {}));
node = NEWNODE(Block, false, /*yields_final_value*/true, mv$(nodes), {});
node = NEWNODE(Block, AST::ExprNode_Block::Type::Bare, /*yields_final_value*/true, mv$(nodes), {});
}
TU_ARMA(Tuple, e) {
node = NEWNODE(NamedValue, AST::Path("f"));
Expand Down
10 changes: 9 additions & 1 deletion src/expand/proc_macro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -931,8 +931,16 @@ namespace {

// === Expressions ====
void visit(::AST::ExprNode_Block& node) {
if( node.m_is_unsafe )
switch(node.m_block_type) {
case AST::ExprNode_Block::Type::Bare:
break;
case AST::ExprNode_Block::Type::Unsafe:
m_pmi.send_ident("unsafe");
break;
case AST::ExprNode_Block::Type::Const:
m_pmi.send_ident("const");
break;
}
m_pmi.send_symbol("{");
TODO(sp, "");
m_pmi.send_symbol("}");
Expand Down
5 changes: 5 additions & 0 deletions src/hir/dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,11 @@ namespace {
dec_indent();
m_os << indent() << "}";
}
void visit(::HIR::ExprNode_ConstBlock& node) override
{
m_os << "const ";
node.m_inner->visit(*this);
}

void visit(::HIR::ExprNode_Asm& node) override
{
Expand Down
4 changes: 4 additions & 0 deletions src/hir/expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ DEF_VISIT_H(ExprNode_Block, node) {
if( node.m_value_node )
visit_node_ptr(node.m_value_node);
}
DEF_VISIT_H(ExprNode_ConstBlock, node) {
TRACE_FUNCTION_F("_ConstBlock");
visit_node_ptr(node.m_inner);
}
DEF_VISIT_H(ExprNode_Asm, node) {
TRACE_FUNCTION_F("_Asm");
for(auto& v : node.m_outputs)
Expand Down
16 changes: 16 additions & 0 deletions src/hir/expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ struct ExprNode_Block:

NODE_METHODS();
};
struct ExprNode_ConstBlock:
public ExprNode
{
ExprNodeP m_inner;

ExprNode_ConstBlock(Span sp, ExprNodeP inner)
: ExprNode(mv$(sp))
, m_inner(mv$(inner))
{}

NODE_METHODS();
};
struct ExprNode_Asm:
public ExprNode
{
Expand Down Expand Up @@ -929,6 +941,8 @@ class ExprVisitor
#define NV(nt) virtual void visit(nt& n) = 0;

NV(ExprNode_Block)
NV(ExprNode_ConstBlock)
//NV(ExprNode_AsyncBlock)
NV(ExprNode_Asm)
NV(ExprNode_Asm2)
NV(ExprNode_Return)
Expand Down Expand Up @@ -982,6 +996,8 @@ class ExprVisitorDef:
virtual void visit_node_ptr(::std::unique_ptr<ExprNode>& node_ptr) override;

NV(ExprNode_Block)
NV(ExprNode_ConstBlock)
//NV(ExprNode_AsyncBlock)
NV(ExprNode_Asm)
NV(ExprNode_Asm2)
NV(ExprNode_Return)
Expand Down
22 changes: 22 additions & 0 deletions src/hir/from_ast_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ struct LowerHIR_ExprNode_Visitor:
rv->m_local_mod = ::HIR::SimplePath(g_crate_name, v.m_local_mod->path().nodes);
}

switch(v.m_block_type)
{
case AST::ExprNode_Block::Type::Bare:
break;
case AST::ExprNode_Block::Type::Unsafe:
rv->m_is_unsafe = true;
break;
case AST::ExprNode_Block::Type::Const:
break;
}

if( v.m_label != "" )
{
if(rv->m_value_node)
Expand All @@ -72,6 +83,17 @@ struct LowerHIR_ExprNode_Visitor:
{
m_rv.reset( static_cast< ::HIR::ExprNode*>(rv) );
}

switch(v.m_block_type)
{
case AST::ExprNode_Block::Type::Bare:
break;
case AST::ExprNode_Block::Type::Unsafe:
break;
case AST::ExprNode_Block::Type::Const:
m_rv.reset( new ::HIR::ExprNode_ConstBlock(v.span(), std::move(m_rv)) );
break;
}
}
virtual void visit(::AST::ExprNode_Try& v) override {
TODO(v.span(), "Handle _Try");
Expand Down
5 changes: 5 additions & 0 deletions src/hir_expand/annotate_value_usage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ namespace {
scope->yield_stack.pop_back();
}
}
void visit(::HIR::ExprNode_ConstBlock& node) override
{
auto _ = this->push_usage( ::HIR::ValueUsage::Move );
this->visit_node_ptr(node.m_inner);
}

void visit(::HIR::ExprNode_Asm& node) override
{
Expand Down
1 change: 1 addition & 0 deletions src/hir_expand/lifetime_infer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,7 @@ namespace {

#define NV(nt) void visit(HIR::nt& node) override { local(node); }
NV(ExprNode_Block)
NV(ExprNode_ConstBlock)
NV(ExprNode_Asm)
NV(ExprNode_Asm2)
NV(ExprNode_Return)
Expand Down
5 changes: 5 additions & 0 deletions src/hir_expand/static_borrow_constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,11 @@ namespace static_borrow_constants {
::HIR::ExprVisitorDef::visit(node);
m_is_constant = m_all_constant;
}
void visit(::HIR::ExprNode_ConstBlock& node) override {
::HIR::ExprVisitorDef::visit(node);
ASSERT_BUG(node.span(),m_all_constant, "const block wasn't constant");
m_is_constant = m_all_constant;
}
// - Root values
void visit(::HIR::ExprNode_Literal& node) override {
::HIR::ExprVisitorDef::visit(node);
Expand Down
6 changes: 6 additions & 0 deletions src/hir_typeck/expr_check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ namespace {
check_types_equal(node.span(), node.m_res_type, node.m_value_node->m_res_type);
}
}
void visit(::HIR::ExprNode_ConstBlock& node) override
{
TRACE_FUNCTION_F(&node << " const { ... }");
node.m_inner->visit(*this);
check_types_equal(node.span(), node.m_res_type, node.m_inner->m_res_type);
}
void visit(::HIR::ExprNode_Asm& node) override
{
TRACE_FUNCTION_F(&node << " llvm_asm! ...");
Expand Down
6 changes: 6 additions & 0 deletions src/hir_typeck/expr_cs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ namespace {
}
this->m_completed = true;
}
void visit(::HIR::ExprNode_ConstBlock& node) override {
no_revisit(node);
}
void visit(::HIR::ExprNode_Asm& node) override {
// TODO: Revisit for validation
no_revisit(node);
Expand Down Expand Up @@ -1662,6 +1665,9 @@ namespace {
void visit(::HIR::ExprNode_Block& node) override {
m_os << "_Block {" << context.m_ivars.fmt_type(node.m_nodes.back()->m_res_type) << "}";
}
void visit(::HIR::ExprNode_ConstBlock& node) override {
no_revisit(node);
}
void visit(::HIR::ExprNode_Asm& node) override {
no_revisit(node);
}
Expand Down
10 changes: 10 additions & 0 deletions src/hir_typeck/expr_cs__enum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,16 @@ namespace typecheck
}
this->pop_traits( node.m_traits );
}
void visit(::HIR::ExprNode_ConstBlock& node) override
{
TRACE_FUNCTION_F(&node << " const { ... }");
this->context.add_ivars( node.m_inner->m_res_type );

//this->push_inner_coerce( true );
node.m_inner->visit( *this );
//this->pop_inner_coerce();
this->context.equate_types(node.span(), node.m_res_type, node.m_inner->m_res_type);
}
void visit(::HIR::ExprNode_Asm& node) override
{
TRACE_FUNCTION_F(&node << " asm! ...");
Expand Down
4 changes: 4 additions & 0 deletions src/mir/from_hir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,10 @@ namespace {
}
}
}
void visit(::HIR::ExprNode_ConstBlock& node) override
{
BUG(node.span(), "Const block shouldn't have reached MIR generation");
}
void visit(::HIR::ExprNode_Asm& node) override
{
TRACE_FUNCTION_F("_Asm");
Expand Down
3 changes: 2 additions & 1 deletion src/parse/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ extern AST::Expr Parse_Expr(TokenStream& lex);
extern AST::Expr Parse_ExprBlock(TokenStream& lex);
extern AST::ExprNodeP Parse_Expr0(TokenStream& lex);
extern AST::ExprNodeP Parse_ExprVal(TokenStream& lex);
extern AST::ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe=false, Ident label=Ident(""));
//extern AST::ExprNodeP Parse_ExprBlockNode(TokenStream& lex, AST::ExprNode_Block::Type ty=AST::ExprNode_Block::Type::Bare, Ident label=Ident(""));
extern AST::ExprNodeP Parse_ExprBlockNode(TokenStream& lex);
extern AST::ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence);
extern AST::ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST::Module>& local_mod, bool& add_silence_if_end);
extern AST::ExprNodeP Parse_Stmt(TokenStream& lex);
Expand Down
42 changes: 33 additions & 9 deletions src/parse/expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ using AST::ExprNodeP;
static inline ExprNodeP mk_exprnodep(const TokenStream& lex, AST::ExprNode* en){en->set_span(lex.point_span()); return ExprNodeP(en); }
#define NEWNODE(type, ...) mk_exprnodep(lex, new type(__VA_ARGS__))

//ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe=false, Ident label=RcString()); // common.hpp
ExprNodeP Parse_ExprBlockNode(TokenStream& lex, AST::ExprNode_Block::Type ty, Ident label=Ident(""));
//ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST::Module>& local_mod, bool& add_silence_if_end);
//ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence);
ExprNodeP Parse_ExprBlockLine_Stmt(TokenStream& lex, bool& has_semicolon);
Expand All @@ -47,8 +47,11 @@ AST::Expr Parse_ExprBlock(TokenStream& lex)
{
return ::AST::Expr( Parse_ExprBlockNode(lex) );
}

ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe/*=false*/, Ident label/*=RcString()*/)
AST::ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
{
return Parse_ExprBlockNode(lex, AST::ExprNode_Block::Type::Bare, RcString());
}
ExprNodeP Parse_ExprBlockNode(TokenStream& lex, AST::ExprNode_Block::Type ty/*=Bare*/, Ident label/*=RcString()*/)
{
TRACE_FUNCTION;
Token tok;
Expand Down Expand Up @@ -97,7 +100,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe/*=false*/, Ident
DEBUG("Restore module from " << lex.parse_state().module->path() << " to " << orig_module->path() );
lex.parse_state().module = orig_module;
}
auto* rv_blk = new ::AST::ExprNode_Block(is_unsafe, last_value_yielded, mv$(nodes), mv$(local_mod) );
auto* rv_blk = new ::AST::ExprNode_Block(ty, last_value_yielded, mv$(nodes), mv$(local_mod) );
rv_blk->m_label = label;
auto rv = ExprNodeP(rv_blk);
rv->set_attrs( mv$(attrs) );
Expand Down Expand Up @@ -151,7 +154,6 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST:
case TOK_RWORD_TYPE:
case TOK_RWORD_USE:
case TOK_RWORD_EXTERN:
case TOK_RWORD_CONST:
case TOK_RWORD_STATIC:
case TOK_RWORD_STRUCT:
case TOK_RWORD_MACRO:
Expand All @@ -168,6 +170,20 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST:
}
Parse_Mod_Item(lex, *local_mod, mv$(item_attrs));
return ExprNodeP();
// 'const' - Check if the next token isn't a `{`, if so it's an item. Otherwise, fall through
case TOK_RWORD_CONST:
if( LOOK_AHEAD(lex) != TOK_BRACE_OPEN )
{
PUTBACK(tok, lex);
if( !local_mod ) {
local_mod = lex.parse_state().get_current_mod().add_anon();
DEBUG("Set module from " << lex.parse_state().module->path() << " to " << local_mod->path() );
lex.parse_state().module = local_mod.get();
}
Parse_Mod_Item(lex, *local_mod, mv$(item_attrs));
return ExprNodeP();
}
break;
// 'unsafe' - Check if the next token isn't a `{`, if so it's an item. Otherwise, fall through
case TOK_RWORD_UNSAFE:
if( LOOK_AHEAD(lex) != TOK_BRACE_OPEN )
Expand Down Expand Up @@ -226,10 +242,13 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence)
// NOTE: 1.39's libsyntax uses labelled block
case TOK_BRACE_OPEN:
PUTBACK(tok, lex);
ret = Parse_ExprBlockNode(lex, /*is_unsafe*/false, lifetime);
ret = Parse_ExprBlockNode(lex, /*is_unsafe*/AST::ExprNode_Block::Type::Bare, lifetime);
return ret;
case TOK_RWORD_UNSAFE:
ret = Parse_ExprBlockNode(lex, /*is_unsafe*/true, lifetime);
ret = Parse_ExprBlockNode(lex, /*is_unsafe*/AST::ExprNode_Block::Type::Unsafe, lifetime);
return ret;
case TOK_RWORD_CONST:
ret = Parse_ExprBlockNode(lex, /*is_unsafe*/AST::ExprNode_Block::Type::Const, lifetime);
return ret;
// TODO: Can these have labels?
//case TOK_RWORD_IF:
Expand Down Expand Up @@ -299,7 +318,10 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence)
ret = Parse_Expr_Match(lex);
if(0)
case TOK_RWORD_UNSAFE:
ret = Parse_ExprBlockNode(lex, true);
ret = Parse_ExprBlockNode(lex, AST::ExprNode_Block::Type::Unsafe);
if(0)
case TOK_RWORD_CONST:
ret = Parse_ExprBlockNode(lex, AST::ExprNode_Block::Type::Const);
if(0)
case TOK_BRACE_OPEN:
{ PUTBACK(tok, lex); ret = Parse_ExprBlockNode(lex); }
Expand Down Expand Up @@ -1282,7 +1304,9 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
case TOK_RWORD_IF:
return Parse_IfStmt(lex);
case TOK_RWORD_UNSAFE:
return Parse_ExprBlockNode(lex, true);
return Parse_ExprBlockNode(lex, AST::ExprNode_Block::Type::Unsafe);
case TOK_RWORD_CONST:
return Parse_ExprBlockNode(lex, AST::ExprNode_Block::Type::Const);

// Paths
// `self` can be a value, or start a path
Expand Down

0 comments on commit 88ae396

Please sign in to comment.