From ce459d4da717260b6a46f72ac5f0258500c1b627 Mon Sep 17 00:00:00 2001 From: Farzana Ahmed Siddique Date: Fri, 4 Aug 2023 13:23:46 -0700 Subject: [PATCH] Semantics & Lowering for simple assignment. (#3058) Co-authored-by: Farzana Ahmed Siddique --- .../testdata/operators/assignment.carbon | 37 ++++++++++++ .../semantics/semantics_handle_operator.cpp | 10 +++- .../testdata/operators/assignment.carbon | 55 +++++++++++++++++ .../fail_type_mismatch_assignment.carbon | 59 +++++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 toolchain/lowering/testdata/operators/assignment.carbon create mode 100644 toolchain/semantics/testdata/operators/assignment.carbon create mode 100644 toolchain/semantics/testdata/operators/fail_type_mismatch_assignment.carbon diff --git a/toolchain/lowering/testdata/operators/assignment.carbon b/toolchain/lowering/testdata/operators/assignment.carbon new file mode 100644 index 000000000000..4e36435083c8 --- /dev/null +++ b/toolchain/lowering/testdata/operators/assignment.carbon @@ -0,0 +1,37 @@ +// 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 +// +// AUTOUPDATE +// CHECK:STDOUT: ; ModuleID = 'assignment.carbon' +// CHECK:STDOUT: source_filename = "assignment.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: %TupleLiteralType = type { {}, {} } +// CHECK:STDOUT: %TupleLiteralType.0 = type { i32, i32 } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @Main() { +// CHECK:STDOUT: %var = alloca i32, align 4 +// CHECK:STDOUT: store i32 12, ptr %var, align 4 +// CHECK:STDOUT: store i32 -7, ptr %var, align 4 +// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8 +// CHECK:STDOUT: %1 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 0 +// CHECK:STDOUT: store {} zeroinitializer, ptr %1, align 1 +// CHECK:STDOUT: %2 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 1 +// CHECK:STDOUT: store {} zeroinitializer, ptr %2, align 1 +// CHECK:STDOUT: %var1 = alloca %TupleLiteralType.0, align 8 +// CHECK:STDOUT: %TupleLiteralValue2 = alloca %TupleLiteralType.0, align 8 +// CHECK:STDOUT: %3 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue2, i32 0, i32 0 +// CHECK:STDOUT: store i32 1, ptr %3, align 4 +// CHECK:STDOUT: %4 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue2, i32 0, i32 1 +// CHECK:STDOUT: store i32 2, ptr %4, align 4 +// CHECK:STDOUT: %5 = load %TupleLiteralType.0, ptr %TupleLiteralValue2, align 4 +// CHECK:STDOUT: store %TupleLiteralType.0 %5, ptr %var1, align 4 +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } + +fn Main() { + var a: i32 = 12; + a = 9; + var b: (i32, i32); + b = (1, 2); +} diff --git a/toolchain/semantics/semantics_handle_operator.cpp b/toolchain/semantics/semantics_handle_operator.cpp index 7ee5139037fd..0526db8a0418 100644 --- a/toolchain/semantics/semantics_handle_operator.cpp +++ b/toolchain/semantics/semantics_handle_operator.cpp @@ -51,7 +51,15 @@ auto SemanticsHandleInfixOperator(SemanticsContext& context, resume_block_id)); return true; } - + case TokenKind::Equal: { + // TODO: handle complex assignment expression such as `a += 1`. + // TODO: check if lhs node is assignable. + context.ImplicitAsRequired( + parse_node, rhs_id, context.semantics_ir().GetNode(lhs_id).type_id()); + context.AddNodeAndPush( + parse_node, SemanticsNode::Assign::Make(parse_node, lhs_id, rhs_id)); + return true; + } default: return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind)); } diff --git a/toolchain/semantics/testdata/operators/assignment.carbon b/toolchain/semantics/testdata/operators/assignment.carbon new file mode 100644 index 000000000000..49aa940fdc93 --- /dev/null +++ b/toolchain/semantics/testdata/operators/assignment.carbon @@ -0,0 +1,55 @@ +// 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 +// +// AUTOUPDATE +// CHECK:STDOUT: cross_reference_irs_size: 1 +// CHECK:STDOUT: functions: [ +// CHECK:STDOUT: {name: str0, param_refs: block0, body: {block2}}}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: integer_literals: [ +// CHECK:STDOUT: 12, +// CHECK:STDOUT: -7, +// CHECK:STDOUT: ] +// CHECK:STDOUT: real_literals: [ +// CHECK:STDOUT: ] +// CHECK:STDOUT: strings: [ +// CHECK:STDOUT: Main, +// CHECK:STDOUT: a, +// CHECK:STDOUT: ] +// CHECK:STDOUT: types: [ +// CHECK:STDOUT: nodeIntegerType, +// CHECK:STDOUT: ] +// CHECK:STDOUT: type_blocks: [ +// CHECK:STDOUT: ] +// CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, +// CHECK:STDOUT: {kind: VarStorage, type: type0}, +// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node+1, type: type0}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: node+3}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: node+5}, +// CHECK:STDOUT: {kind: Return}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: node_blocks: [ +// CHECK:STDOUT: [ +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+0, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, +// CHECK:STDOUT: ], +// CHECK:STDOUT: ] + +fn Main() { + var a: i32 = 12; + a = 9; +} diff --git a/toolchain/semantics/testdata/operators/fail_type_mismatch_assignment.carbon b/toolchain/semantics/testdata/operators/fail_type_mismatch_assignment.carbon new file mode 100644 index 000000000000..1ff5e87a8670 --- /dev/null +++ b/toolchain/semantics/testdata/operators/fail_type_mismatch_assignment.carbon @@ -0,0 +1,59 @@ +// 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 +// +// AUTOUPDATE +// CHECK:STDOUT: cross_reference_irs_size: 1 +// CHECK:STDOUT: functions: [ +// CHECK:STDOUT: {name: str0, param_refs: block0, body: {block2}}}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: integer_literals: [ +// CHECK:STDOUT: 3, +// CHECK:STDOUT: ] +// CHECK:STDOUT: real_literals: [ +// CHECK:STDOUT: {mantissa: 56, exponent: -1, is_decimal: 1}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: strings: [ +// CHECK:STDOUT: Main, +// CHECK:STDOUT: a, +// CHECK:STDOUT: ] +// CHECK:STDOUT: types: [ +// CHECK:STDOUT: nodeIntegerType, +// CHECK:STDOUT: nodeFloatingPointType, +// CHECK:STDOUT: ] +// CHECK:STDOUT: type_blocks: [ +// CHECK:STDOUT: ] +// CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, +// CHECK:STDOUT: {kind: VarStorage, type: type0}, +// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node+1, type: type0}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: node+3}, +// CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: node+5}, +// CHECK:STDOUT: {kind: Return}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: node_blocks: [ +// CHECK:STDOUT: [ +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+0, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, +// CHECK:STDOUT: ], +// CHECK:STDOUT: ] + +fn Main() { + var a: i32 = 3; + // CHECK:STDERR: fail_type_mismatch_assignment.carbon:[[@LINE+3]]:5: Cannot implicitly convert from `f64` to `i32`. + // CHECK:STDERR: a = 5.6; + // CHECK:STDERR: ^ + a = 5.6; +}