diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/expr.cpp | 43 | ||||
-rw-r--r-- | src/ast/expr.hpp | 25 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 22 | ||||
-rw-r--r-- | src/parse/expr.cpp | 12 | ||||
-rw-r--r-- | src/parse/root.cpp | 24 |
5 files changed, 119 insertions, 7 deletions
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 7d6983f6..8c239092 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -69,6 +69,7 @@ SERIALISE_TYPE(Expr::, "Expr", { else _(ExprNode_Cast) else _(ExprNode_CallPath) else _(ExprNode_BinOp) + else _(ExprNode_UniOp) else throw ::std::runtime_error("Unknown node type " + tag); #undef _ @@ -278,6 +279,44 @@ NODE(ExprNode_BinOp, { os << " " << *m_right << ")"; }) +void operator%(::Serialiser& s, const ExprNode_UniOp::Type t) { + switch(t) + { + #define _(v) case ExprNode_UniOp::v: s << #v; return; + _(NEGATE) + _(INVERT) + _(BOX) + _(REF) + #undef _ + } +} +void operator%(::Deserialiser& s, enum ExprNode_UniOp::Type& t) { + ::std::string n; + s.item(n); + if(1) ; + #define _(v) else if(n == #v) t = ExprNode_UniOp::v; + _(NEGATE) + _(INVERT) + _(BOX) + _(REF) + else + throw ::std::runtime_error( FMT("No uniop type for '" << n << "'") ); + #undef _ +} +NODE(ExprNode_UniOp, { + s % m_type; + s.item(m_value); +},{ + switch(m_type) + { + case NEGATE: os << "(-"; break; + case INVERT: os << "(!"; break; + case BOX: os << "(box "; break; + case REF: os << "(&"; break; + } + os << *m_value << ")"; +}) + #define NV(type, actions)\ void NodeVisitorDef::visit(type& node) { DEBUG("DEF - "#type); actions } @@ -386,6 +425,10 @@ NV(ExprNode_BinOp, visit(node.m_left); visit(node.m_right); }) +NV(ExprNode_UniOp, +{ + visit(node.m_value); +}) #undef NV diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index 843abb3b..9ae6540e 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -348,6 +348,29 @@ struct ExprNode_BinOp: NODE_METHODS(); }; +struct ExprNode_UniOp: + public ExprNode +{ + enum Type { + REF, + BOX, + INVERT, + NEGATE, + }; + + enum Type m_type; + ::std::unique_ptr<ExprNode> m_value; + + ExprNode_UniOp() {} + ExprNode_UniOp(Type type, ::std::unique_ptr<ExprNode> value): + m_type(type), + m_value( ::std::move(value) ) + { + } + + NODE_METHODS(); +}; + class NodeVisitor { public: @@ -380,6 +403,7 @@ public: NT(ExprNode_Deref); NT(ExprNode_Cast); NT(ExprNode_BinOp); + NT(ExprNode_UniOp); #undef NT }; class NodeVisitorDef: @@ -413,6 +437,7 @@ public: NT(ExprNode_Deref); NT(ExprNode_Cast); NT(ExprNode_BinOp); + NT(ExprNode_UniOp); #undef NT }; diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index cfe9b5d6..1a7737ba 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -274,11 +274,18 @@ public: { case AST::ExprNode_BinOp::CMPEQU: m_os << "=="; break; case AST::ExprNode_BinOp::CMPNEQU:m_os << "!="; break; + case AST::ExprNode_BinOp::CMPLT: m_os << "<"; break; + case AST::ExprNode_BinOp::CMPLTE: m_os << "<="; break; + case AST::ExprNode_BinOp::CMPGT: m_os << ">"; break; + case AST::ExprNode_BinOp::CMPGTE: m_os << ">="; break; case AST::ExprNode_BinOp::BITAND: m_os << "&"; break; case AST::ExprNode_BinOp::BITOR: m_os << "|"; break; case AST::ExprNode_BinOp::BITXOR: m_os << "^"; break; case AST::ExprNode_BinOp::SHL: m_os << "<<"; break; case AST::ExprNode_BinOp::SHR: m_os << ">>"; break; + case AST::ExprNode_BinOp::MULTIPLY: m_os << "*"; break; + case AST::ExprNode_BinOp::DIVIDE: m_os << "/"; break; + case AST::ExprNode_BinOp::MODULO: m_os << "%"; break; } m_os << " "; if( IS(*n.m_right, AST::ExprNode_BinOp) ) @@ -286,6 +293,21 @@ public: else AST::NodeVisitor::visit(n.m_right); } + virtual void visit(AST::ExprNode_UniOp& n) override { + m_expr_root = false; + switch(n.m_type) + { + case AST::ExprNode_UniOp::NEGATE: m_os << "-"; break; + case AST::ExprNode_UniOp::INVERT: m_os << "!"; break; + case AST::ExprNode_UniOp::BOX: m_os << "box "; break; + case AST::ExprNode_UniOp::REF: m_os << "&"; break; + //case AST::ExprNode_UniOp::REFMUT: m_os << "&mut "; break; + } + + if( IS(*n.m_value, AST::ExprNode_BinOp) ) + m_os << " "; + AST::NodeVisitor::visit(n.m_value); + } private: diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 34630115..c7cceee0 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -492,18 +492,18 @@ ExprNodeP Parse_ExprFC(TokenStream& lex); ExprNodeP Parse_Expr12(TokenStream& lex)
{
Token tok;
- switch((tok = lex.getToken()).type())
+ switch(GET_TOK(tok, lex))
{
case TOK_DASH:
- throw ParseError::Todo("expr - negate");
+ return NEWNODE( AST::ExprNode_UniOp, AST::ExprNode_UniOp::NEGATE, Parse_Expr12(lex) );
case TOK_EXCLAM:
- throw ParseError::Todo("expr - logical negate");
+ return NEWNODE( AST::ExprNode_UniOp, AST::ExprNode_UniOp::INVERT, Parse_Expr12(lex) );
case TOK_STAR:
- throw ParseError::Todo("expr - dereference");
+ return NEWNODE( AST::ExprNode_Deref, Parse_Expr12(lex) );
case TOK_RWORD_BOX:
- throw ParseError::Todo("expr - box");
+ return NEWNODE( AST::ExprNode_UniOp, AST::ExprNode_UniOp::BOX, Parse_Expr12(lex) );
case TOK_AMP:
- throw ParseError::Todo("expr - borrow");
+ return NEWNODE( AST::ExprNode_UniOp, AST::ExprNode_UniOp::REF, Parse_Expr12(lex) );
default:
lex.putback(tok);
return Parse_ExprFC(lex);
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index ec2589f6..7484609b 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -822,7 +822,29 @@ MacroRule Parse_MacroRules_Var(Preproc& lex) TTStream slex(rep);
while(GET_TOK(tok, slex) != TOK_EOF)
- rule.m_contents.push_back( MacroRuleEnt(tok) );
+ {
+ if( tok.type() == TOK_DOLLAR )
+ {
+ GET_TOK(tok, slex);
+
+ if( tok.type() == TOK_PAREN_OPEN )
+ {
+ throw ParseError::Todo("Repetitions in macro_rules content");
+ }
+ else if( tok.type() == TOK_IDENT )
+ {
+ rule.m_contents.push_back( MacroRuleEnt(tok.str()) );
+ }
+ else
+ {
+ throw ParseError::Unexpected(lex, tok);
+ }
+ }
+ else
+ {
+ rule.m_contents.push_back( MacroRuleEnt(tok) );
+ }
+ }
return rule;
}
|