@samitouri / QOS-React-2 / commits / c59ac387ae

[rust] Assignment expressions

Joe Savona committed Jul 6, 2023 at 09:24 UTC c59ac387aed46c90199f1bc9e057c1a09b4a0a6d
4 files changed +68 -26
compiler/forget/crates/build-hir/src/build.rs
+33 -16
@@ -1,7 +1,7 @@
1 use bumpalo::collections::{CollectIn, String};
2 use estree::{
3 - ExpressionLike, FunctionDeclaration, Literal, LiteralValue, Pattern, Statement,
4 - VariableDeclarationKind,
3 + AssignmentTarget, ExpressionLike, FunctionDeclaration, Literal, LiteralValue, Pattern,
4 + Statement, VariableDeclarationKind,
5 };
6 use hir::{
7 ArrayElement, BlockKind, Environment, Function, GotoKind, Identifier, InstructionKind,
@@ -114,7 +114,13 @@ fn lower_statement<'a>(
114 for declaration in stmt.declarations {
115 if let Some(init) = declaration.init {
116 let value = lower_expression_to_temporary(env, builder, init);
117 - lower_assignment(env, builder, kind, declaration.id, value);
117 + lower_assignment(
118 + env,
119 + builder,
120 + kind,
121 + AssignmentTarget::Pattern(declaration.id.into()),
122 + value,
123 + );
124 } else {
125 if let Pattern::Identifier(id) = declaration.id {
126 // TODO: handle unbound variables
@@ -195,6 +201,14 @@ fn lower_expression<'a>(
201 .collect_in(env.allocator);
202 InstructionValue::Array(hir::Array { elements })
203 }
204 + ExpressionLike::AssignmentExpression(expr) => match expr.operator {
205 + estree::AssignmentOperator::Equals => {
206 + let right = lower_expression_to_temporary(env, builder, expr.right);
207 + lower_assignment(env, builder, InstructionKind::Reassign, expr.left, right)
208 + }
209 + _ => todo!("lower assignment expr {:#?}", expr),
210 + },
211 +
212 // Cases that cannot appear in expression position but which are included in ExpressionLike
213 // to make serialization easier
214 ExpressionLike::SpreadElement(_) => {
@@ -208,22 +222,25 @@ fn lower_assignment<'a>(
222 env: &'a Environment<'a>,
223 builder: &mut Builder<'a>,
224 kind: InstructionKind,
211 - lvalue: Pattern,
225 + lvalue: AssignmentTarget,
226 value: Place<'a>,
227 ) -> InstructionValue<'a> {
228 match lvalue {
215 - Pattern::Identifier(lvalue) => {
216 - let place = lower_identifier_for_assignment(env, builder, kind, *lvalue).unwrap();
217 - let temporary = lower_value_to_temporary(
218 - env,
219 - builder,
220 - InstructionValue::StoreLocal(hir::StoreLocal {
221 - lvalue: LValue { place, kind },
222 - value,
223 - }),
224 - );
225 - InstructionValue::LoadLocal(LoadLocal { place: temporary })
226 - }
229 + AssignmentTarget::Pattern(lvalue) => match *lvalue {
230 + Pattern::Identifier(lvalue) => {
231 + let place = lower_identifier_for_assignment(env, builder, kind, *lvalue).unwrap();
232 + let temporary = lower_value_to_temporary(
233 + env,
234 + builder,
235 + InstructionValue::StoreLocal(hir::StoreLocal {
236 + lvalue: LValue { place, kind },
237 + value,
238 + }),
239 + );
240 + InstructionValue::LoadLocal(LoadLocal { place: temporary })
241 + }
242 + _ => todo!("lower assignment pattern for {:#?}", lvalue),
243 + },
244 _ => todo!("lower assignment for {:#?}", lvalue),
245 }
246 }
compiler/forget/crates/estree-swc/src/lib.rs
+26 -5
@@ -6,8 +6,8 @@ use swc_core::common::errors::Handler;
6 use swc_core::common::source_map::Pos;
7 use swc_core::common::{FileName, FilePathMapping, Mark, SourceMap, Span, SyntaxContext, GLOBALS};
8 use swc_core::ecma::ast::{
9 - AssignOp, BinaryOp, BlockStmt, Decl, EsVersion, Expr, Ident, Lit, ModuleItem, Pat, PatOrExpr,
10 - Program, Stmt, UnaryOp, VarDecl, VarDeclKind, VarDeclOrExpr,
9 + AssignOp, BinaryOp, BlockStmt, Decl, EsVersion, Expr, Ident, Lit, MemberExpr, ModuleItem, Pat,
10 + PatOrExpr, Program, Stmt, UnaryOp, VarDecl, VarDeclKind, VarDeclOrExpr,
11 };
12 use swc_core::ecma::parser::Syntax;
13 use swc_core::ecma::transforms::base::resolver;
@@ -360,7 +360,7 @@ fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
360 Expr::Assign(expr) => {
361 estree::ExpressionLike::AssignmentExpression(Box::new(estree::AssignmentExpression {
362 operator: convert_assignment_operator(expr.op),
363 - left: convert_assignment_target(&expr.left),
363 + left: convert_assignment_target(cx, &expr.left),
364 right: convert_expression(cx, &expr.right),
365 loc: None,
366 range: convert_span(&expr.span),
@@ -370,8 +370,28 @@ fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
370 }
371 }
372
373 -fn convert_assignment_target(_target: &PatOrExpr) -> estree::AssignmentTarget {
374 - todo!("translate assignment target")
373 +fn convert_assignment_target(cx: &Context, target: &PatOrExpr) -> estree::AssignmentTarget {
374 + match target {
375 + PatOrExpr::Pat(target) => {
376 + estree::AssignmentTarget::Pattern(Box::new(convert_pattern(cx, target)))
377 + }
378 + PatOrExpr::Expr(target) => {
379 + if let Expr::Member(target) = target.as_ref() {
380 + estree::AssignmentTarget::MemberExpression(Box::new(convert_member_expression(
381 + cx, target,
382 + )))
383 + } else {
384 + panic!(
385 + "Invalid input, expected either a pattern or member expression, got {:#?}",
386 + target
387 + )
388 + }
389 + }
390 + }
391 +}
392 +
393 +fn convert_member_expression(cx: &Context, expr: &MemberExpr) -> estree::MemberExpression {
394 + todo!("convert member expression")
395 }
396
397 fn convert_unary_operator(op: UnaryOp) -> estree::UnaryOperator {
@@ -388,6 +408,7 @@ fn convert_unary_operator(op: UnaryOp) -> estree::UnaryOperator {
408
409 fn convert_assignment_operator(op: AssignOp) -> estree::AssignmentOperator {
410 match op {
411 + AssignOp::Assign => estree::AssignmentOperator::Equals,
412 AssignOp::AddAssign => estree::AssignmentOperator::PlusEquals,
413 _ => todo!("translate assignment operator"),
414 }
compiler/forget/crates/fixtures/tests/fixtures/identifiers.js
+1
@@ -8,6 +8,7 @@ function id(x) {
8 Math;
9 id;
10 let y = true;
11 + y = false;
12 y;
13 let z;
14 z;
compiler/forget/crates/fixtures/tests/snapshots/fixtures_test__fixtures@identifiers.js.snap
+8 -5
@@ -14,6 +14,7 @@ function id(x) {
14 Math;
15 id;
16 let y = true;
17 + y = false;
18 y;
19 let z;
20 z;
@@ -28,9 +29,11 @@ bb0
29 [1] unknown $2 = LoadGlobal id
30 [2] unknown $3 = true
31 [3] unknown $5 = StoreLocal Let unknown y$4 = unknown $3
31 - [4] unknown $6 = LoadLocal unknown y$4
32 - [5] unknown $8 = DeclareLocal Let unknown z$7
33 - [6] unknown $9 = LoadLocal unknown z$7
34 - [7] unknown $11 = LoadLocal unknown x$10
35 - [8] Return unknown $11
32 + [4] unknown $6 = false
33 + [5] unknown $7 = StoreLocal Reassign unknown y$4 = unknown $6
34 + [6] unknown $8 = LoadLocal unknown y$4
35 + [7] unknown $10 = DeclareLocal Let unknown z$9
36 + [8] unknown $11 = LoadLocal unknown z$9
37 + [9] unknown $13 = LoadLocal unknown x$12
38 + [10] Return unknown $13
39