Skip to content

Commit dc35ae3

Browse files
committed
Minor changes
1 parent 4ac5772 commit dc35ae3

File tree

2 files changed

+113
-17
lines changed

2 files changed

+113
-17
lines changed

shared/src/main/scala/mlscript/JSBackend.scala

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ abstract class JSBackend(allowUnresolvedSymbols: Bool) {
308308
else Blk(stmts.map {
309309
case t: Term =>
310310
desugarQuote(t)(blkScope, isQuoted, freeVars)
311-
case s => desugarStatementForQuote(s)(blkScope, isQuoted, freeVars)
311+
case s => desugarStatementInUnquote(s)(blkScope, freeVars)
312312
})
313313
case Tup(eles) =>
314314
def toVar(b: Bool) = if (b) Var("true") else Var("false")
@@ -349,23 +349,28 @@ abstract class JSBackend(allowUnresolvedSymbols: Bool) {
349349
throw CodeGenError("this quote syntax is not supported yet.")
350350
}
351351

352-
private def desugarStatementForQuote(s: Statement)(implicit scope: Scope, isQuoted: Bool, freeVars: FreeVars): Statement = s match {
353-
case nd @ NuFunDef(isLetRec, nme, symbol, tparams, rhs) =>
354-
NuFunDef(isLetRec, nme, symbol, tparams, rhs match {
355-
case L(t) => L(desugarQuote(t))
356-
case R(t) => R(t)
357-
})(nd.declareLoc, nd.virtualLoc, nd.mutLoc, nd.signature, nd.outer, nd.genField)
358-
case nt @ NuTypeDef(kind, nme, tparams, params, ctor, sig, parents, superAnnot, thisAnnot, TypingUnit(body)) =>
359-
NuTypeDef(kind, nme, tparams, params, ctor.map(c => desugarStatementForQuote(c) match {
360-
case c: Constructor => c
352+
// * Statements inside **Unquote** can refer to quoted code fragments.
353+
// * Desugar them recursively.
354+
private def desugarStatementInUnquote(s: Statement)(implicit scope: Scope, freeVars: FreeVars): Statement = {
355+
implicit val isQuoted: Bool = false
356+
s match {
357+
case nd @ NuFunDef(isLetRec, nme, symbol, tparams, rhs) =>
358+
NuFunDef(isLetRec, nme, symbol, tparams, rhs match {
359+
case L(t) => L(desugarQuote(t))
360+
case R(t) => R(t)
361+
})(nd.declareLoc, nd.virtualLoc, nd.mutLoc, nd.signature, nd.outer, nd.genField)
362+
case nt @ NuTypeDef(kind, nme, tparams, params, ctor, sig, parents, superAnnot, thisAnnot, TypingUnit(body)) =>
363+
NuTypeDef(kind, nme, tparams, params, ctor.map(c => desugarStatementInUnquote(c) match {
364+
case c: Constructor => c
365+
case _ => die
366+
}), sig, parents.map(p => desugarQuote(p)), superAnnot, thisAnnot, TypingUnit(body.map(s => desugarStatementInUnquote(s))))(nt.declareLoc, nt.abstractLoc)
367+
case Constructor(ps, body) => Constructor(ps, desugarQuote(body) match {
368+
case b: Blk => b
361369
case _ => die
362-
}), sig, parents.map(p => desugarQuote(p)), superAnnot, thisAnnot, TypingUnit(body.map(s => desugarStatementForQuote(s))))(nt.declareLoc, nt.abstractLoc)
363-
case Constructor(ps, body) => Constructor(ps, desugarQuote(body) match {
364-
case b: Blk => b
365-
case _ => die
366-
})
367-
case t: Term => desugarQuote(t)
368-
case _: LetS | _: DataDefn | _: DatatypeDefn | _: TypeDef | _: Def => die // * Impossible. newDef is true
370+
})
371+
case t: Term => desugarQuote(t)
372+
case _: LetS | _: DataDefn | _: DatatypeDefn | _: TypeDef | _: Def => die // * Impossible. newDef is true
373+
}
369374
}
370375

371376
/**

shared/src/test/diff/qq/Codegen.mls

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,23 +365,67 @@ class Ref[A](init: A) { mut val value: A = init }
365365
//│ }
366366

367367
:ne
368+
:js
368369
x `=>
369370
let v = Ref(x)
370371
let _ = y `=>
371372
set v.value = y
372373
`0
373374
v.value
374375
//│ Code[forall 'a. 'a -> 'a, ??y & ~??x]
376+
//│ // Prelude
377+
//│ class TypingUnit30 {}
378+
//│ const typing_unit30 = new TypingUnit30;
379+
//│ // Query 1
380+
//│ res = ((x1) => Lam(Var(x1), (() => {
381+
//│ let v = Ref(Var(x1));
382+
//│ let _ = ((y1) => Lam(Var(y1), (() => {
383+
//│ void(v.value = Var(y1));
384+
//│ return IntLit(0);
385+
//│ })()))(freshName("y"));
386+
//│ return v.value;
387+
//│ })()))(freshName("x"));
388+
//│ // End of generated code
375389

376390
:ne
391+
:js
377392
x `=>
378393
class A(y: Code[Int, nothing]) {
379394
val z = x `+ y
380395
}
381396
A(`0).z
382397
//│ Code[Int -> Int, nothing]
398+
//│ // Prelude
399+
//│ class TypingUnit31 {}
400+
//│ const typing_unit31 = new TypingUnit31;
401+
//│ // Query 1
402+
//│ res = ((x1) => Lam(Var(x1), (() => {
403+
//│ const A = (() => {
404+
//│ class A {
405+
//│ #y;
406+
//│ #z;
407+
//│ get z() { return this.#z; }
408+
//│ constructor(y) {
409+
//│ this.#y = y;
410+
//│ this.#z = App(Var("+"), Var(x1), y);
411+
//│ const z = this.#z;
412+
//│ }
413+
//│ static
414+
//│ unapply(x) {
415+
//│ return [x.#y];
416+
//│ }
417+
//│ }
418+
//│ let ctor;
419+
//│ ctor = ((y) => new A(y));
420+
//│ ctor.class = A;
421+
//│ return ctor;
422+
//│ })();
423+
//│ return A(IntLit(0)).z;
424+
//│ })()))(freshName("x"));
425+
//│ // End of generated code
383426

384427
:ne
428+
:js
385429
x `=>
386430
class A() {
387431
constructor() {
@@ -390,12 +434,59 @@ x `=>
390434
}
391435
new A(), x
392436
//│ Code[forall 'a. 'a -> 'a, nothing]
437+
//│ // Prelude
438+
//│ class TypingUnit32 {}
439+
//│ const typing_unit32 = new TypingUnit32;
440+
//│ // Query 1
441+
//│ res = ((x1) => Lam(Var(x1), (() => {
442+
//│ const A = (() => {
443+
//│ class A {
444+
//│ constructor() {
445+
//│ log(Var(x1));
446+
//│ }
447+
//│ static
448+
//│ unapply(x) {
449+
//│ return [];
450+
//│ }
451+
//│ }
452+
//│ let ctor;
453+
//│ ctor = (() => new A());
454+
//│ ctor.class = A;
455+
//│ return ctor;
456+
//│ })();
457+
//│ return new A.class() , Var(x1);
458+
//│ })()))(freshName("x"));
459+
//│ // End of generated code
393460

394461
class Foo(x: Code[Int, anything])
395462
//│ class Foo(x: Code[Int, anything])
396463

397464
:ne
465+
:js
398466
x `=>
399467
class B() extends Foo(x)
400468
`x
401469
//│ Code[forall 'a. (Int & 'a) -> 'a, nothing]
470+
//│ // Prelude
471+
//│ class TypingUnit34 {}
472+
//│ const typing_unit34 = new TypingUnit34;
473+
//│ // Query 1
474+
//│ res = ((x1) => Lam(Var(x1), (() => {
475+
//│ const B = (() => {
476+
//│ class B extends Foo.class {
477+
//│ constructor() {
478+
//│ super(Var(x1));
479+
//│ }
480+
//│ static
481+
//│ unapply(x) {
482+
//│ return [];
483+
//│ }
484+
//│ }
485+
//│ let ctor;
486+
//│ ctor = (() => new B());
487+
//│ ctor.class = B;
488+
//│ return ctor;
489+
//│ })();
490+
//│ return Var(x1);
491+
//│ })()))(freshName("x"));
492+
//│ // End of generated code

0 commit comments

Comments
 (0)