From 1e77e4894c4355272de8d0bfe391a29d44608604 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 13 Mar 2015 12:34:13 +0800 Subject: Const items in expressions, attributes in impl blocks --- src/ast/expr.cpp | 14 ++++++++++++++ src/ast/expr.hpp | 19 +++++++++++++++++++ src/dump_as_rust.cpp | 13 +++++++++++++ src/include/debug.hpp | 6 ++++++ src/parse/common.hpp | 12 ++++++++---- src/parse/expr.cpp | 13 +++++++++++-- src/parse/root.cpp | 10 ++++++++++ src/serialise.cpp | 1 + 8 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 0ed99e3f..9740a4d9 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -53,6 +53,7 @@ SERIALISE_TYPE(Expr::, "Expr", { _(ExprNode_Block) else _(ExprNode_Macro) else _(ExprNode_Return) + else _(ExprNode_Const) else _(ExprNode_LetBinding) else _(ExprNode_Assign) else _(ExprNode_CallPath) @@ -112,8 +113,17 @@ NODE(ExprNode_Return, { os << "return " << *m_value; }) +NODE(ExprNode_Const, { + s.item(m_name); + s.item(m_type); + s.item(m_value); +},{ + os << "const " << m_name << ": " << m_type << " = " << *m_value; +}) + NODE(ExprNode_LetBinding, { s.item(m_pat); + s.item(m_type); s.item(m_value); },{ os << "let " << m_pat << ": " << m_type << " = " << *m_value; @@ -398,6 +408,10 @@ NV(ExprNode_Return, { visit(node.m_value); }) +NV(ExprNode_Const, +{ + visit(node.m_value); +}) NV(ExprNode_LetBinding, { // TODO: Handle recurse into Let pattern diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index ca655fe0..4c6d6b7c 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -90,6 +90,23 @@ struct ExprNode_Return: NODE_METHODS(); }; +struct ExprNode_Const: + public ExprNode +{ + ::std::string m_name; + TypeRef m_type; + unique_ptr m_value; + + ExprNode_Const() {} + ExprNode_Const(::std::string name, TypeRef type, unique_ptr&& value): + m_name( move(name) ), + m_type( move(type) ), + m_value( move(value) ) + { + } + + NODE_METHODS(); +}; struct ExprNode_LetBinding: public ExprNode { @@ -454,6 +471,7 @@ public: NT(ExprNode_Block); NT(ExprNode_Macro); NT(ExprNode_Return); + NT(ExprNode_Const); NT(ExprNode_LetBinding); NT(ExprNode_Assign); NT(ExprNode_CallPath); @@ -491,6 +509,7 @@ public: NT(ExprNode_Block); NT(ExprNode_Macro); NT(ExprNode_Return); + NT(ExprNode_Const); NT(ExprNode_LetBinding); NT(ExprNode_Assign); NT(ExprNode_CallPath); diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index d28ab084..fe432268 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -63,6 +63,13 @@ public: m_os << "return "; AST::NodeVisitor::visit(n.m_value); } + virtual void visit(AST::ExprNode_Const& n) override { + m_expr_root = false; + m_os << "const " << n.m_name << ": "; + print_type(n.m_type); + m_os << " = "; + AST::NodeVisitor::visit(n.m_value); + } virtual void visit(AST::ExprNode_LetBinding& n) override { m_expr_root = false; m_os << "let "; @@ -370,6 +377,7 @@ private: void print_params(const AST::TypeParams& params); void print_bounds(const AST::TypeParams& params); void print_pattern(const AST::Pattern& p); + void print_type(const TypeRef& t); void inc_indent(); RepeatLitStr indent(); @@ -574,6 +582,11 @@ void RustPrinter::print_pattern(const AST::Pattern& p) } } +void RustPrinter::print_type(const TypeRef& t) +{ + m_os << t; +} + void RustPrinter::handle_struct(const AST::Struct& s) { print_params(s.params()); diff --git a/src/include/debug.hpp b/src/include/debug.hpp index 8376be07..11301d27 100644 --- a/src/include/debug.hpp +++ b/src/include/debug.hpp @@ -5,9 +5,15 @@ extern int g_debug_indent_level; +#ifndef DISABLE_DEBUG #define INDENT() do { g_debug_indent_level += 1; } while(0) #define UNINDENT() do { g_debug_indent_level -= 1; } while(0) #define DEBUG(ss) do{ if(debug_enabled()) { debug_output(g_debug_indent_level, __FUNCTION__) << ss << ::std::endl; } } while(0) +#else +#define INDENT() do { } while(0) +#define UNINDENT() do {} while(0) +#define DEBUG(ss) do{ } while(0) +#endif extern bool debug_enabled(); extern ::std::ostream& debug_output(int indent, const char* function); diff --git a/src/parse/common.hpp b/src/parse/common.hpp index 38ef3c96..ff72920c 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -4,12 +4,16 @@ #define GET_TOK(tok, lex) ((tok = lex.getToken()).type()) #define GET_CHECK_TOK(tok, lex, exp) do {\ - if((tok = lex.getToken()).type() != exp) \ - throw ParseError::Unexpected(lex, tok, Token(exp));\ + if((tok = lex.getToken()).type() != exp) { \ + DEBUG("GET_CHECK_TOK " << __FILE__ << ":" << __LINE__); \ + throw ParseError::Unexpected(lex, tok, Token(exp));\ + }\ } while(0) #define CHECK_TOK(tok, exp) do {\ - if(tok.type() != exp) \ - throw ParseError::Unexpected(lex, tok, Token(exp));\ + if(tok.type() != exp) { \ + DEBUG("CHECK_TOK " << __FILE__ << ":" << __LINE__); \ + throw ParseError::Unexpected(lex, tok, Token(exp));\ + } \ } while(0) enum eParsePathGenericMode diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 1a9b494c..0bebbc64 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -229,8 +229,18 @@ ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon) lex.putback(tok); opt_semicolon = true; return Parse_ExprBlockNode(lex); + case TOK_RWORD_CONST: { + opt_semicolon = false; + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + GET_CHECK_TOK(tok, lex, TOK_COLON); + TypeRef type = Parse_Type(lex); + GET_CHECK_TOK(tok, lex, TOK_EQUAL); + auto val = Parse_Expr1(lex); + return NEWNODE( AST::ExprNode_Const, ::std::move(name), ::std::move(type), ::std::move(val) ); + } case TOK_RWORD_LET: { - //ret.append(); + opt_semicolon = false; AST::Pattern pat = Parse_Pattern(lex); TypeRef type; if( GET_TOK(tok, lex) == TOK_COLON ) { @@ -241,7 +251,6 @@ ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon) CHECK_TOK(tok, TOK_EQUAL); } ExprNodeP val = Parse_ExprBlocks(lex); - opt_semicolon = false; return NEWNODE( AST::ExprNode_LetBinding, ::std::move(pat), ::std::move(type), ::std::move(val) ); } case TOK_RWORD_RETURN: diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 8f5bc737..b6b7af15 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -658,6 +658,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems meta_items) /// Parse a meta-item declaration (either #![ or #[) AST::MetaItem Parse_MetaItem(TokenStream& lex) { + TRACE_FUNCTION; Token tok; GET_CHECK_TOK(tok, lex, TOK_IDENT); ::std::string name = tok.str(); @@ -681,6 +682,7 @@ AST::MetaItem Parse_MetaItem(TokenStream& lex) AST::Impl Parse_Impl(TokenStream& lex) { + TRACE_FUNCTION; Token tok; AST::TypeParams params; @@ -719,8 +721,16 @@ AST::Impl Parse_Impl(TokenStream& lex) AST::Impl impl( ::std::move(params), ::std::move(impl_type), ::std::move(trait_type) ); // A sequence of method implementations + AST::MetaItems item_attrs; while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE ) { + while( tok.type() == TOK_ATTR_OPEN ) + { + item_attrs.push_back( Parse_MetaItem(lex) ); + GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE); + GET_TOK(tok, lex); + } + bool is_public = false; if(tok.type() == TOK_RWORD_PUB) { is_public = true; diff --git a/src/serialise.cpp b/src/serialise.cpp index e7d94948..55555c7c 100644 --- a/src/serialise.cpp +++ b/src/serialise.cpp @@ -1,5 +1,6 @@ /* */ +#define DISABLE_DEBUG #include #include #include "common.hpp" -- cgit v1.2.3