Add operator modulo (#1681)

Co-authored-by: m new <michael.burzan@outlook.de>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
pmqtt
2022-07-28 12:51:35 -07:00
committed by GitHub
co-authored by m new Richard Smith
parent 8ba4916ab4
commit 9f89c63503
10 changed files with 98 additions and 1 deletions
+1
View File
@@ -54,6 +54,7 @@ message OperatorExpression {
Ptr = 11;
Combine = 12;
As = 13;
Mod = 14;
}
optional Operator op = 1;
repeated Expression arguments = 2;
+4
View File
@@ -117,6 +117,10 @@ static auto OperatorToCarbon(const Fuzzing::OperatorExpression& operator_expr,
BinaryOperatorToCarbon(arg0, " * ", arg1, out);
break;
case Fuzzing::OperatorExpression::Mod:
BinaryOperatorToCarbon(arg0, " % ", arg1, out);
break;
case Fuzzing::OperatorExpression::Ptr:
PostfixUnaryOperatorToCarbon(arg0, "*", out);
break;
+2
View File
@@ -81,6 +81,8 @@ auto ToString(Operator op) -> std::string_view {
return "or";
case Operator::Eq:
return "==";
case Operator::Mod:
return "%";
}
}
+1
View File
@@ -120,6 +120,7 @@ enum class Operator {
Deref,
Eq,
Mul,
Mod,
Neg,
Not,
Or,
+2
View File
@@ -55,6 +55,8 @@ static auto OperatorToProtoEnum(const Operator op)
return Fuzzing::OperatorExpression::Eq;
case Operator::Mul:
return Fuzzing::OperatorExpression::Mul;
case Operator::Mod:
return Fuzzing::OperatorExpression::Mod;
case Operator::Or:
return Fuzzing::OperatorExpression::Or;
case Operator::Sub:
+3 -1
View File
@@ -173,7 +173,6 @@ void Interpreter::PrintState(llvm::raw_ostream& out) {
out << "\nmemory: " << heap_;
out << "\n}\n";
}
auto Interpreter::EvalPrim(Operator op, Nonnull<const Value*> static_type,
const std::vector<Nonnull<const Value*>>& args,
SourceLocation source_loc)
@@ -190,6 +189,9 @@ auto Interpreter::EvalPrim(Operator op, Nonnull<const Value*> static_type,
case Operator::Mul:
return arena_->New<IntValue>(cast<IntValue>(*args[0]).value() *
cast<IntValue>(*args[1]).value());
case Operator::Mod:
return arena_->New<IntValue>(cast<IntValue>(*args[0]).value() %
cast<IntValue>(*args[1]).value());
case Operator::Not:
return arena_->New<BoolValue>(!cast<BoolValue>(*args[0]).value());
case Operator::And:
+11
View File
@@ -1995,6 +1995,17 @@ auto TypeChecker::TypeCheckExp(Nonnull<Expression*> e,
return handle_binary_arithmetic(Builtins::SubWith);
case Operator::Mul:
return handle_binary_arithmetic(Builtins::MulWith);
case Operator::Mod:
CARBON_RETURN_IF_ERROR(ExpectExactType(e->source_loc(), "modulo(1)",
arena_->New<IntType>(), ts[0],
impl_scope));
CARBON_RETURN_IF_ERROR(ExpectExactType(e->source_loc(), "modulo(2)",
arena_->New<IntType>(), ts[1],
impl_scope));
op.set_static_type(arena_->New<IntType>());
op.set_value_category(ValueCategory::Let);
return Success();
case Operator::And:
CARBON_RETURN_IF_ERROR(ExpectExactType(e->source_loc(), "&&(1)",
arena_->New<BoolType>(), ts[0],
+2
View File
@@ -73,6 +73,7 @@ LET "let"
LIBRARY "library"
MATCH "match"
MINUS "-"
MODULO "%"
NOT "not"
OR "or"
PACKAGE "package"
@@ -161,6 +162,7 @@ operand_start [(A-Za-z0-9_\"]
{LIBRARY} { return CARBON_SIMPLE_TOKEN(LIBRARY); }
{MATCH} { return CARBON_SIMPLE_TOKEN(MATCH); }
{MINUS} { return CARBON_SIMPLE_TOKEN(MINUS); }
{MODULO} { return CARBON_SIMPLE_TOKEN(MODULO); }
{NOT} { return CARBON_SIMPLE_TOKEN(NOT); }
{OR} { return CARBON_SIMPLE_TOKEN(OR); }
{PACKAGE} { return CARBON_SIMPLE_TOKEN(PACKAGE); }
+16
View File
@@ -130,6 +130,8 @@
%type <Nonnull<Expression*>> additive_operand
%type <Nonnull<Expression*>> additive_lhs
%type <Nonnull<Expression*>> additive_expression
%type <Nonnull<Expression*>> modulo_operand
%type <Nonnull<Expression*>> modulo_expression
%type <Nonnull<Expression*>> as_operand
%type <Nonnull<Expression*>> as_expression
%type <Nonnull<Expression*>> unimpl_expression
@@ -226,6 +228,7 @@
LIBRARY
MATCH
MINUS
MODULO
NOT
OR
PACKAGE
@@ -446,6 +449,18 @@ multiplicative_expression:
std::vector<Nonnull<Expression*>>({$1, $3}));
}
;
modulo_operand:
ref_deref_expression
| minus_expression
;
modulo_expression:
modulo_operand MODULO modulo_operand
{
$$ = arena->New<OperatorExpression>(
context.source_loc(), Operator::Mod,
std::vector<Nonnull<Expression*>>({$1, $3}));
}
;
additive_operand:
ref_deref_expression
| multiplicative_expression
@@ -492,6 +507,7 @@ unimpl_expression:
value_expression:
// ref_deref_expression excluded due to precedence diamond.
additive_expression
| modulo_expression
| as_expression
| combine_expression
| fn_type_expression
+56
View File
@@ -0,0 +1,56 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// RUN: %{explorer} %s 2>&1 | \
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
// AUTOUPDATE: %{explorer} %s
// CHECK: result: 0
package ExplorerTest api;
fn identFn( x: i32 ) -> i32{
return x;
}
fn Main() -> i32 {
var x : i32 = 7 % 2;
if( not (x == 1) ){
return 1;
}
x = (3*3) % 3;
if( not (x == 0)){
return 2;
}
x = (4+4+4+4) % (2+1);
if( not (x == 1) ){
return 3;
}
x = 15 % (identFn(2)+1);
if( not (x == 0)){
return 4;
}
x = -15 % 7;
if( not (x == -1)){
return 5;
}
x = 15 % -7;
if( not ( x == 1)){
return 6;
}
x = -15 % -identFn(7);
if( not (x == -1)){
return 7;
}
return 0;
}