summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/expr.cpp43
-rw-r--r--src/ast/expr.hpp25
-rw-r--r--src/dump_as_rust.cpp22
-rw-r--r--src/parse/expr.cpp12
-rw-r--r--src/parse/root.cpp24
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;
}