@@ -334,7 +334,7 @@ class Parser {
334
334
FailureOr<ast::Expr *> parseLogicalAndExpr ();
335
335
FailureOr<ast::Expr *> parseEqualityExpr ();
336
336
FailureOr<ast::Expr *> parseRelationExpr ();
337
- FailureOr<ast::Expr *> parseExp2Log2Expr ();
337
+ FailureOr<ast::Expr *> parseExp2Log2AbsExpr ();
338
338
FailureOr<ast::Expr *> parseAddSubExpr ();
339
339
FailureOr<ast::Expr *> parseMulDivModExpr ();
340
340
FailureOr<ast::Expr *> parseLogicalNotExpr ();
@@ -624,13 +624,15 @@ class Parser {
624
624
ast::UserRewriteDecl *subRewrite;
625
625
ast::UserRewriteDecl *log2Rewrite;
626
626
ast::UserRewriteDecl *exp2Rewrite;
627
+ ast::UserRewriteDecl *absRewrite;
627
628
ast::UserConstraintDecl *mulConstraint;
628
629
ast::UserConstraintDecl *divConstraint;
629
630
ast::UserConstraintDecl *modConstraint;
630
631
ast::UserConstraintDecl *addConstraint;
631
632
ast::UserConstraintDecl *subConstraint;
632
633
ast::UserConstraintDecl *log2Constraint;
633
634
ast::UserConstraintDecl *exp2Constraint;
635
+ ast::UserConstraintDecl *absConstraint;
634
636
} builtins{};
635
637
};
636
638
} // namespace
@@ -701,6 +703,8 @@ void Parser::declareBuiltins() {
701
703
" __builtin_log2Rewrite" , {" Attr" }, true );
702
704
builtins.exp2Rewrite = declareBuiltin<ast::UserRewriteDecl>(
703
705
" __builtin_exp2Rewrite" , {" Attr" }, true );
706
+ builtins.absRewrite = declareBuiltin<ast::UserRewriteDecl>(
707
+ " __builtin_absRewrite" , {" Attr" }, true );
704
708
builtins.mulConstraint = declareBuiltin<ast::UserConstraintDecl>(
705
709
" __builtin_mulConstraint" , {" lhs" , " rhs" }, true );
706
710
builtins.divConstraint = declareBuiltin<ast::UserConstraintDecl>(
@@ -715,6 +719,8 @@ void Parser::declareBuiltins() {
715
719
" __builtin_log2Constraint" , {" Attr" }, true );
716
720
builtins.exp2Constraint = declareBuiltin<ast::UserConstraintDecl>(
717
721
" __builtin_exp2Constraint" , {" Attr" }, true );
722
+ builtins.absConstraint = declareBuiltin<ast::UserConstraintDecl>(
723
+ " __builtin_absConstraint" , {" Attr" }, true );
718
724
}
719
725
720
726
FailureOr<ast::Module *> Parser::parseModule () {
@@ -2030,15 +2036,15 @@ FailureOr<ast::Expr *> Parser::parseAddSubExpr() {
2030
2036
}
2031
2037
2032
2038
FailureOr<ast::Expr *> Parser::parseMulDivModExpr () {
2033
- auto lhs = parseExp2Log2Expr ();
2039
+ auto lhs = parseExp2Log2AbsExpr ();
2034
2040
if (failed (lhs))
2035
2041
return failure ();
2036
2042
2037
2043
for (;;) {
2038
2044
switch (curToken.getKind ()) {
2039
2045
case Token::mul: {
2040
2046
consumeToken ();
2041
- auto rhs = parseExp2Log2Expr ();
2047
+ auto rhs = parseExp2Log2AbsExpr ();
2042
2048
if (failed (rhs))
2043
2049
return failure ();
2044
2050
SmallVector<ast::Expr *> args{*lhs, *rhs};
@@ -2058,7 +2064,7 @@ FailureOr<ast::Expr *> Parser::parseMulDivModExpr() {
2058
2064
}
2059
2065
case Token::div: {
2060
2066
consumeToken ();
2061
- auto rhs = parseExp2Log2Expr ();
2067
+ auto rhs = parseExp2Log2AbsExpr ();
2062
2068
if (failed (rhs))
2063
2069
return failure ();
2064
2070
SmallVector<ast::Expr *> args{*lhs, *rhs};
@@ -2078,7 +2084,7 @@ FailureOr<ast::Expr *> Parser::parseMulDivModExpr() {
2078
2084
}
2079
2085
case Token::mod: {
2080
2086
consumeToken ();
2081
- auto rhs = parseExp2Log2Expr ();
2087
+ auto rhs = parseExp2Log2AbsExpr ();
2082
2088
if (failed (rhs))
2083
2089
return failure ();
2084
2090
SmallVector<ast::Expr *> args{*lhs, *rhs};
@@ -2100,7 +2106,7 @@ FailureOr<ast::Expr *> Parser::parseMulDivModExpr() {
2100
2106
}
2101
2107
}
2102
2108
2103
- FailureOr<ast::Expr *> Parser::parseExp2Log2Expr () {
2109
+ FailureOr<ast::Expr *> Parser::parseExp2Log2AbsExpr () {
2104
2110
FailureOr<ast::Expr *> expr = nullptr ;
2105
2111
2106
2112
switch (curToken.getKind ()) {
@@ -2144,6 +2150,26 @@ FailureOr<ast::Expr *> Parser::parseExp2Log2Expr() {
2144
2150
: createBuiltinCall (curToken.getLoc (), builtins.exp2Constraint ,
2145
2151
{*expr});
2146
2152
}
2153
+ case Token::abs: {
2154
+ consumeToken ();
2155
+ consumeToken (Token::l_paren);
2156
+ expr = parseAddSubExpr ();
2157
+ if (failed (expr))
2158
+ return failure ();
2159
+
2160
+ // Check if it is in rewrite section but not in the let statement
2161
+ bool inRewriteSection = parserContext == ParserContext::Rewrite;
2162
+ if (inRewriteSection && nativeOperatorContext != NativeOperatorContext::Let)
2163
+ return emitError (" cannot evaluate abs operator in rewrite section. "
2164
+ " Assign to a variable with `let`" );
2165
+
2166
+ consumeToken (Token::r_paren);
2167
+ return inRewriteSection
2168
+ ? createBuiltinCall (curToken.getLoc (), builtins.absRewrite ,
2169
+ {*expr})
2170
+ : createBuiltinCall (curToken.getLoc (), builtins.absConstraint ,
2171
+ {*expr});
2172
+ }
2147
2173
default :
2148
2174
return parseLogicalNotExpr ();
2149
2175
}
0 commit comments