mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
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:
co-authored by
m new
Richard Smith
parent
8ba4916ab4
commit
9f89c63503
@@ -54,6 +54,7 @@ message OperatorExpression {
|
||||
Ptr = 11;
|
||||
Combine = 12;
|
||||
As = 13;
|
||||
Mod = 14;
|
||||
}
|
||||
optional Operator op = 1;
|
||||
repeated Expression arguments = 2;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -81,6 +81,8 @@ auto ToString(Operator op) -> std::string_view {
|
||||
return "or";
|
||||
case Operator::Eq:
|
||||
return "==";
|
||||
case Operator::Mod:
|
||||
return "%";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ enum class Operator {
|
||||
Deref,
|
||||
Eq,
|
||||
Mul,
|
||||
Mod,
|
||||
Neg,
|
||||
Not,
|
||||
Or,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user