Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ultimate conditional syntax #150

Merged
merged 108 commits into from
Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
0601333
Add variable symbols inserted by Typer
LPTK Oct 5, 2022
0dd6518
Wire the desugaring logic with the typer
chengluyu Oct 13, 2022
899dcf8
Make some tests work
chengluyu Oct 13, 2022
1d435fa
Refactor DiffTests so code generation is after type checking
chengluyu Oct 20, 2022
4c11d87
Add some currently failing tests
LPTK Oct 20, 2022
ed1efa5
Implement code generation for the `new` syntax
chengluyu Oct 20, 2022
868af30
Revert removing a DiffTests regression
chengluyu Oct 21, 2022
d06585f
Report error if field `els` is missing in `If`
chengluyu Oct 21, 2022
cbc8688
Pretty-print debug outputs
chengluyu Oct 22, 2022
5c2a8b2
Fix some test cases
chengluyu Oct 22, 2022
42e8b13
Show the wrong syntax tree by `:p`
chengluyu Oct 24, 2022
a3ced76
Migrate test cases from the old branch
chengluyu Oct 25, 2022
8292da5
Wrap some test cases in functions
chengluyu Oct 25, 2022
787e69d
Handle more UCS cases
chengluyu Oct 25, 2022
7fa00ff
Rectify a false positive
chengluyu Oct 26, 2022
841fd22
Handle wildcard cases and dedup let bindings
chengluyu Oct 26, 2022
39ee376
Fix cases in `DirectLines.mls`
chengluyu Oct 26, 2022
967a2d3
Review test cases in `Humiliation.mls`
chengluyu Oct 26, 2022
5e3fce0
Implement basic exhaustiveness check
chengluyu Oct 26, 2022
3fe4565
Suppor tuple pattern syntax and improve defualt case propagation
chengluyu Oct 26, 2022
a8b1052
Handle `IfOpsApp` at the pattern position
chengluyu Oct 26, 2022
c304723
Review test cases
chengluyu Oct 26, 2022
0e9a09e
Fix my stupid double negation phrasing
chengluyu Oct 26, 2022
e0d976f
Check the test case mentioned in Telegram chat
chengluyu Oct 26, 2022
dfa5cec
Add missing test file changes
chengluyu Oct 26, 2022
f0b2e18
Embed UCS related code to a layer in the cake pattern
chengluyu Oct 26, 2022
77aad6b
Get rid of `Typer#Ctx`
chengluyu Oct 26, 2022
e7a1fc6
Adjust methods due to the previous refactor
chengluyu Oct 27, 2022
b283378
Reduce boilerplate by implementing an ADT for `PartialTerm`
chengluyu Oct 27, 2022
ada0e7a
Organize branches in `desugarIf`
chengluyu Oct 27, 2022
f1e57d1
Localize scrutinee if it is not a `Var`
chengluyu Oct 27, 2022
54de014
Implement interleaved let bindings
chengluyu Oct 27, 2022
80a66ee
Merge branch 'ucs-translation' of github.com:hkust-taco/mlscript into…
chengluyu Nov 9, 2022
6ce327c
Gather parser failure examples
chengluyu Nov 9, 2022
f1db324
Prepare for improving error messages
chengluyu Nov 9, 2022
ca093d0
Improve error messages but it's still far from perfect
chengluyu Nov 9, 2022
10aa691
Inspect test files and mark problematic tests
chengluyu Nov 9, 2022
2a54460
Add an additional test suggested in the PR
chengluyu Nov 10, 2022
8029543
Fix the `mapPartition` test and add some related tests
chengluyu Nov 10, 2022
4486820
Implement a basic solution to type errors at desugared terms
chengluyu Nov 10, 2022
3108486
Split `UltimateConditions` into smaller files
chengluyu Nov 10, 2022
e145de8
Tracking locations everywhere!
chengluyu Nov 12, 2022
6af229d
Show `IfBody` in the `inspect` method
chengluyu Nov 13, 2022
a78475e
Move UCS tests to a new folder
chengluyu Nov 13, 2022
588f69e
Fix the exhaustiveness checker
chengluyu Nov 15, 2022
3418524
Fix that UCS expressions return nothing
chengluyu Nov 15, 2022
6f3b96a
Warn of pattern matching with only one case
chengluyu Nov 15, 2022
2cd2c0b
Support nested tuple patterns produced by the Ocaml parser
chengluyu Nov 16, 2022
123f1b1
Add some tests from previous meeting
LPTK Nov 16, 2022
5ddf361
Clean up tests
chengluyu Nov 22, 2022
3eaf7cd
Merge branch 'ucs-translation' of github.com:chengluyu/mlscript into …
chengluyu Nov 22, 2022
bb4bcdb
Add locations to duplicated else branch warnings
chengluyu Nov 22, 2022
50cb72f
Merge branch 'mlscript' into ucs-translation
chengluyu Nov 22, 2022
4cdd1dd
Commit changed files changed by the GitHub merge
chengluyu Nov 22, 2022
43dc8e1
Add more changed tests
chengluyu Nov 22, 2022
298edc3
Minor
LPTK Nov 22, 2022
1f6e41b
Update shared/src/main/scala/mlscript/ucs/Scrutinee.scala
chengluyu Nov 23, 2022
e762c18
Update shared/src/main/scala/mlscript/ucs/Scrutinee.scala
chengluyu Nov 23, 2022
20580e3
Update shared/src/main/scala/mlscript/ucs/Clause.scala
chengluyu Nov 23, 2022
308a09d
Handle `Lit` in `makeScrutinee`
chengluyu Nov 23, 2022
8005611
Remove useless re-throw
chengluyu Nov 23, 2022
fa948a7
Remove an useless import
chengluyu Nov 23, 2022
7243b52
Mark two test cases as FIXME
chengluyu Nov 23, 2022
2540828
Call `lastWords` in some unreachable cases
chengluyu Nov 23, 2022
c253fe6
Remove an unused commented code
chengluyu Nov 23, 2022
a48e88b
Remove an outdated to-do
chengluyu Nov 23, 2022
b360168
Make `Conjunction` a class
chengluyu Nov 23, 2022
e759658
Identify scrutinees not only by terms but also by locations
chengluyu Nov 23, 2022
41ae122
Move `Scrutinee.matchRootLoc` to the second parameter list
chengluyu Nov 23, 2022
f25d488
Move `Clause.locations` to the second parameter list
chengluyu Nov 23, 2022
b426842
Hide minor UCS desugaring debug messages
chengluyu Nov 23, 2022
b18dae8
Remove debug output from UCS test files
chengluyu Nov 23, 2022
8ee63e5
Remove dead code, add comments and die for unreachable cases
chengluyu Nov 23, 2022
f06a2b9
Revert two misuse of `lastWords`
chengluyu Nov 23, 2022
6fe7cca
I just knew how to use `// FIXME` in DiffTests
chengluyu Nov 23, 2022
feb4511
Use `IdentityHashMap` as a workaround
chengluyu Nov 23, 2022
c524283
Add `TODO` and use it at rare cases
chengluyu Nov 24, 2022
65c9883
Prefer `desugaredFrom` than `withLoc`
chengluyu Nov 24, 2022
bfd43d4
Update shared/src/main/scala/mlscript/ucs/Conjunction.scala
chengluyu Nov 24, 2022
86e3a86
Update shared/src/main/scala/mlscript/ucs/Conjunction.scala
chengluyu Nov 24, 2022
25b78f4
Update shared/src/main/scala/mlscript/ucs/PartialTerm.scala
chengluyu Nov 24, 2022
d64e92c
Update shared/src/main/scala/mlscript/ucs/DesugaringException.scala
chengluyu Nov 24, 2022
e86de28
Remove unused `MutExhaustivenessMap`
chengluyu Nov 24, 2022
e6ed1ac
Simplify `DesugaringException`
chengluyu Nov 24, 2022
d364bf1
Remove duplicated code in `PartialTerm`
chengluyu Nov 24, 2022
dedead3
Remove unnecessary `override` specifiers
chengluyu Nov 24, 2022
1926e2f
Remove unnecessary `override`
chengluyu Nov 24, 2022
db530b5
Remove unnecessary implicits
chengluyu Nov 24, 2022
e2b3fac
Update shared/src/main/scala/mlscript/helpers.scala
chengluyu Nov 24, 2022
075ac1d
Change the key of `FieldAliasMap` to `SimpleTerm`
chengluyu Nov 24, 2022
fd48cbb
Check if name exists in `freshName`
chengluyu Nov 24, 2022
2459338
Add a failed case about split scrutinees
chengluyu Nov 24, 2022
50c1d8b
Fix the bug shown by the previous commit
chengluyu Nov 24, 2022
7d6384d
Add a couple of new tests
LPTK Nov 25, 2022
91a7f8c
Fix parser precedences and generalize Term desugaring scheme
LPTK Nov 25, 2022
ec8e7cc
It seems that blank lines are created by a solved bug
chengluyu Nov 25, 2022
2a7713c
Check out mlscript/*.mls from the main branch
chengluyu Nov 25, 2022
cb9c234
Append more test files
chengluyu Nov 25, 2022
47a3769
Revert "Append more test files"
chengluyu Nov 25, 2022
f72054e
Revert "Check out mlscript/*.mls from the main branch"
chengluyu Nov 25, 2022
def757c
Revert "It seems that blank lines are created by a solved bug"
chengluyu Nov 25, 2022
35fee65
Checkout files at basics, codegen and gen from the fork origin
chengluyu Nov 26, 2022
02cede5
Checkout files at mlscript and typegen from the fork origin
chengluyu Nov 26, 2022
b4c195c
Remove blank lines from files at nu
chengluyu Nov 26, 2022
a06cb37
Prevent too much changes in PR #150
chengluyu Nov 26, 2022
984cfe2
Keep the original order between types, diagnosis and results
chengluyu Nov 26, 2022
407fcad
Clean up DiffTests
chengluyu Nov 26, 2022
301e4d0
Minor UCS PR polishing
LPTK Nov 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/shared/test/diff/Lifter.mls
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,16 @@ class A<T, U>(x: Int): {a1: Int} & B<T> & D(x){
}
}
//│ |#class| |B|‹|T|›| |{||}|↵|#class| |C| |{||}|↵|#class| |D|(|y|#:| |Int|)| |{||}|↵|#class| |A|‹|T|,| |U|›|(|x|#:| |Int|)|#:| |{|a1|#:| |Int|}| |&| |B|‹|T|›| |&| |D|(|x|)|{|→|#fun| |getA|(||)| |#=| |#new| |C|{|→|#fun| |foo|(|x|#:| |T|)| |#=| |x|←|↵|}|←|↵|}|
//│ Parsed: {class B‹T›() {}; class C() {}; class D(y: Int,) {}; class A‹T, U›(x: Int,): & ('{' {a1: Int} '}',) (& (B‹T›,) (D (x,),),) {fun getA = => new C() {fun foo = x: T, => x}}}
//│ Parsed: {class B‹T›() {}; class C() {}; class D(y: Int,) {}; class A‹T, U›(x: Int,): & (& ('{' {a1: Int} '}',) (B‹T›,),) (D (x,),) {fun getA = => new C() {fun foo = x: T, => x}}}
//│ Parsed:
//│ TypingUnit(NuTypeDef(class, B, (TypeName(T)), Tup(), (), TypingUnit()), NuTypeDef(class, C, (), Tup(), (), TypingUnit()), NuTypeDef(class, D, (), Tup(y: Var(Int)), (), TypingUnit()), NuTypeDef(class, A, (TypeName(T), TypeName(U)), Tup(x: Var(Int)), (App(App(Var(&), Tup(_: Bra(rcd = true, Rcd(Var(a1) = Var(Int))))), Tup(_: App(App(Var(&), Tup(_: TyApp(Var(B), List(TypeName(T))))), Tup(_: App(Var(D), Tup(_: Var(x)))))))), TypingUnit(NuFunDef(None, getA, [], Lam(Tup(), New(Some((TypeName(C),)), TypingUnit(List(fun foo = x: T, => x))))))))
//│ TypingUnit(NuTypeDef(class, B, (TypeName(T)), Tup(), (), TypingUnit()), NuTypeDef(class, C, (), Tup(), (), TypingUnit()), NuTypeDef(class, D, (), Tup(y: Var(Int)), (), TypingUnit()), NuTypeDef(class, A, (TypeName(T), TypeName(U)), Tup(x: Var(Int)), (App(App(Var(&), Tup(_: App(App(Var(&), Tup(_: Bra(rcd = true, Rcd(Var(a1) = Var(Int))))), Tup(_: TyApp(Var(B), List(TypeName(T))))))), Tup(_: App(Var(D), Tup(_: Var(x)))))), TypingUnit(NuFunDef(None, getA, [], Lam(Tup(), New(Some((TypeName(C),)), TypingUnit(List(fun foo = x: T, => x))))))))
//│ Lifted:
//│ TypingUnit {
//│ class B$1[T]() {}
//│ class C$2() {}
//│ class D$3(y: Int,) {}
//│ class A$4_C$1$5[T](par$A$4,): C$2 () {fun foo = x: T, => x}
//│ class A$4[T,U](x: Int,): & ('{' {a1: Int} '}',) (& (B$1 ()‹T›,) (D$3 ((this).x,),),) {fun getA = => {new A$4_C$1$5(this,) {}}}
//│ class A$4[T,U](x: Int,): & (& ('{' {a1: Int} '}',) (B$1 ()‹T›,),) (D$3 ((this).x,),) {fun getA = => {new A$4_C$1$5(this,) {}}}
//│ }
// │ TypingUnit(NuTypeDef(class, B, (TypeName(T)), Tup(), (), TypingUnit()), NuTypeDef(class, C, (), Tup(), (), TypingUnit()), NuTypeDef(class, A, (TypeName(T), TypeName(U)), Tup(x: Var(Int)), (App(App(Var(&), Tup(_: Bra(rcd = true, Rcd(Var(a1) = Var(Int)})))), Tup(_: TyApp(Var(B), List(TypeName(T)))))), TypingUnit(NuFunDef(None, getA, [], Lam(Tup(), New(Some((TypeName(C),)), TypingUnit(List(fun foo = x: T, => x))))))))

Expand Down Expand Up @@ -269,7 +269,7 @@ new B{
//│ |#class| |A| |{|→|#fun| |getA| |#=| |0|↵|#fun| |funcA| |#=| |10|←|↵|}|↵|#class| |B|#:| |A|{|→|#fun| |getA| |#=| |1|↵|#fun| |funcB| |#=| |11|←|↵|}|↵|#new| |A|↵|#new| |B|↵|#fun| |f|(|x|)| |#=| |#if| |x| |is| |A| |#then| |0| |#else| |1|↵|f|(|#new| |A|{|→|#fun| |getA| |#=| |2|←|↵|}|)|↵|#new| |B|{|→|#fun| |getA| |#=| |funcB|←|↵|}|
//│ Parsed: {class A() {fun getA = 0; fun funcA = 10}; class B(): A {fun getA = 1; fun funcB = 11}; new A() {}; new B() {}; fun f = x, => if (is (x,) (A,)) then 0 else 1; f (new A() {fun getA = 2},); new B() {fun getA = funcB}}
//│ Parsed:
//│ TypingUnit(NuTypeDef(class, A, (), Tup(), (), TypingUnit(NuFunDef(None, getA, [], IntLit(0)), NuFunDef(None, funcA, [], IntLit(10)))), NuTypeDef(class, B, (), Tup(), (Var(A)), TypingUnit(NuFunDef(None, getA, [], IntLit(1)), NuFunDef(None, funcB, [], IntLit(11)))), New(Some((TypeName(A),)), TypingUnit(List())), New(Some((TypeName(B),)), TypingUnit(List())), NuFunDef(None, f, [], Lam(Tup(_: Var(x)), If((is (x,) (A,)) then 0, Some(IntLit(1))))), App(Var(f), Tup(_: New(Some((TypeName(A),)), TypingUnit(List(fun getA = 2))))), New(Some((TypeName(B),)), TypingUnit(List(fun getA = funcB))))
//│ TypingUnit(NuTypeDef(class, A, (), Tup(), (), TypingUnit(NuFunDef(None, getA, [], IntLit(0)), NuFunDef(None, funcA, [], IntLit(10)))), NuTypeDef(class, B, (), Tup(), (Var(A)), TypingUnit(NuFunDef(None, getA, [], IntLit(1)), NuFunDef(None, funcB, [], IntLit(11)))), New(Some((TypeName(A),)), TypingUnit(List())), New(Some((TypeName(B),)), TypingUnit(List())), NuFunDef(None, f, [], Lam(Tup(_: Var(x)), If(IfThen(App(App(Var(is), Tup(_: Var(x))), Tup(_: Var(A))), IntLit(0), Some(IntLit(1))))), App(Var(f), Tup(_: New(Some((TypeName(A),)), TypingUnit(List(fun getA = 2))))), New(Some((TypeName(B),)), TypingUnit(List(fun getA = funcB))))
//│ Lifted:
//│ TypingUnit {
//│ class A$1() {fun getA = 0; fun funcA = 10}
Expand Down
4 changes: 2 additions & 2 deletions compiler/shared/test/diff/LifterBlks.mls
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ fun f(x,y,z) =
fun boo = (new A).bar1 + B().bar2 + z
}
//│ |#fun| |f|(|x|,|y|,|z|)| |#=| |→|#class| |C|{|→|#class| |A|{|→|#fun| |foo| |#=| |#new| |B|↵|#fun| |bar1| |#=| |x|←|↵|}|↵|#class| |B|{|→|#fun| |foo| |#=| |#new| |A|↵|#fun| |bar2| |#=| |y|←|↵|}|↵|#fun| |boo| |#=| |(|#new| |A|)|.bar1| |+| |B|(||)|.bar2| |+| |z|←|↵|}|←|
//│ Parsed: {fun f = x, y, z, => {class C() {class A() {fun foo = new B() {}; fun bar1 = x}; class B() {fun foo = new A() {}; fun bar2 = y}; fun boo = + (('(' new A() {}, ')').bar1,) (+ ((B ()).bar2,) (z,),)}}}
//│ Parsed: {fun f = x, y, z, => {class C() {class A() {fun foo = new B() {}; fun bar1 = x}; class B() {fun foo = new A() {}; fun bar2 = y}; fun boo = + (+ (('(' new A() {}, ')').bar1,) ((B ()).bar2,),) (z,)}}}
//│ Parsed:
//│ TypingUnit(NuFunDef(None, f, [], Lam(Tup(_: Var(x), _: Var(y), _: Var(z)), Blk(...))))
//│ Lifted:
Expand All @@ -146,7 +146,7 @@ fun f(x,y,z) =
//│ fun bar2 = ((this).par$C$1).y
//│ }
//│ class C$1(x, y, z,) {
//│ fun boo = + (('(' new C$1_A$2(this,) {}, ')').bar1,) (+ ((C$1_B$3 (this,)).bar2,) ((this).z,),)
//│ fun boo = + (+ (('(' new C$1_A$2(this,) {}, ')').bar1,) ((C$1_B$3 (this,)).bar2,),) ((this).z,)
//│ }
//│ fun f = x, y, z, => {}
//│ }
Expand Down
8 changes: 4 additions & 4 deletions js/src/main/scala/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ object Main {
subsume(ty_sch, sign)(ctx, raise, TypeProvenance(d.toLoc, "def definition"))
// Note: keeping the less precise declared type signature here (no ctx update)
case N =>
ctx += nme.name -> ty_sch
ctx += nme.name -> VarSymbol(ty_sch, nme)
}
res ++= formatBinding(d.nme.name, ty_sch)
results append S(d.nme.name) -> htmlize(getType(ty_sch).show)
Expand All @@ -327,22 +327,22 @@ object Main {
}
val ty_sch = PolymorphicType(0, typeType(rhs)(ctx.nextLevel, raise,
vars = tps.map(tp => tp.name -> freshVar(noProv/*FIXME*/)(1)).toMap))
ctx += nme.name -> ty_sch
ctx += nme.name -> VarSymbol(ty_sch, nme)
declared += nme -> ty_sch
results append S(d.nme.name) -> htmlize(getType(ty_sch).show)
case s: DesugaredStatement =>
typer.typeStatement(s, allowPure = true) match {
case R(binds) =>
binds.foreach { case (nme, pty) =>
ctx += nme -> pty
ctx += nme -> VarSymbol(pty, Var(nme))
res ++= formatBinding(nme, pty)
results append S(nme) -> htmlize(getType(pty).show)
}
case L(pty) =>
val exp = getType(pty)
if (exp =/= TypeName("unit")) {
val nme = "res"
ctx += nme -> pty
ctx += nme -> VarSymbol(pty, Var(nme))
res ++= formatBinding(nme, pty)
results append N -> htmlize(getType(pty).show)
}
Expand Down
36 changes: 25 additions & 11 deletions shared/src/main/scala/mlscript/JSBackend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class JSBackend(allowUnresolvedSymbols: Boolean) {
* Translate MLscript terms into JavaScript expressions.
*/
protected def translateTerm(term: Term)(implicit scope: Scope): JSExpr = term match {
case _ if term.desugaredTerm.isDefined => translateTerm(term.desugaredTerm.get)
case Var(name) => translateVar(name, false)
case Lam(params, body) =>
val lamScope = scope.derive("Lam")
Expand Down Expand Up @@ -178,15 +179,17 @@ class JSBackend(allowUnresolvedSymbols: Boolean) {
)
case Blk(stmts) =>
val blkScope = scope.derive("Blk")
val flattened = stmts.iterator.flatMap(_.desugared._2).toList
JSImmEvalFn(
N,
Nil,
R(blkScope.tempVars `with` (stmts flatMap (_.desugared._2) map {
case t: Term => JSExprStmt(translateTerm(t))
R(blkScope.tempVars `with` (flattened.iterator.zipWithIndex.map {
case (t: Term, index) if index + 1 == flattened.length => translateTerm(t)(blkScope).`return`
case (t: Term, index) => JSExprStmt(translateTerm(t)(blkScope))
// TODO: find out if we need to support this.
case _: Def | _: TypeDef | _: NuFunDef /* | _: NuTypeDef */ =>
throw CodeGenError("unexpected definitions in blocks")
})),
case (_: Def | _: TypeDef | _: NuFunDef /* | _: NuTypeDef */, _) =>
throw CodeGenError("unsupported definitions in blocks")
}.toList)),
Nil
)
// Pattern match with only one branch -> comma expression
Expand Down Expand Up @@ -235,7 +238,15 @@ class JSBackend(allowUnresolvedSymbols: Boolean) {
case _ =>
throw CodeGenError(s"illegal assignemnt left-hand side: ${inspect(lhs)}")
}
case _: Bind | _: Test | If(_, _) | New(_, _) | TyApp(_, _) | _: Splc =>
case iff: If =>
throw CodeGenError(s"if expression has not been desugared")
case New(N, TypingUnit(Nil)) => JSRecord(Nil)
case New(S(TypeName(className) -> Tup(args)), TypingUnit(Nil)) =>
val callee = translateVar(className, true)
callee(args.map { case (_, Fld(_, _, arg)) => translateTerm(arg) }: _*)
case New(_, TypingUnit(_)) =>
throw CodeGenError("custom class body is not supported yet")
case _: Bind | _: Test | If(_, _) | TyApp(_, _) | _: Splc =>
throw CodeGenError(s"cannot generate code for term ${inspect(term)}")
}

Expand Down Expand Up @@ -629,22 +640,23 @@ class JSTestBackend extends JSBackend(allowUnresolvedSymbols = false) {
// Generate statements.
val queries = otherStmts.map {
case Def(recursive, Var(name), L(body), isByname) =>
val bodyIsLam = body match { case _: Lam => true case _ => false }
(if (recursive) {
val isByvalueRecIn = if (isByname) None else Some(true)
val sym = scope.declareValue(name, isByvalueRecIn, body.isInstanceOf[Lam])
val sym = scope.declareValue(name, isByvalueRecIn, bodyIsLam)
try {
val translated = translateTerm(body)
scope.unregisterSymbol(sym)
val isByvalueRecOut = if (isByname) None else Some(false)
R((translated, scope.declareValue(name, isByvalueRecOut, body.isInstanceOf[Lam])))
R((translated, scope.declareValue(name, isByvalueRecOut, bodyIsLam)))
} catch {
case e: UnimplementedError =>
scope.stubize(sym, e.symbol)
L(e.getMessage())
case e: Throwable =>
scope.unregisterSymbol(sym)
val isByvalueRecOut = if (isByname) None else Some(false)
scope.declareValue(name, isByvalueRecOut, body.isInstanceOf[Lam])
scope.declareValue(name, isByvalueRecOut, bodyIsLam)
throw e
}
} else {
Expand All @@ -655,7 +667,7 @@ class JSTestBackend extends JSBackend(allowUnresolvedSymbols = false) {
case e: Throwable => throw e
}) map {
val isByvalueRec = if (isByname) None else Some(false)
expr => (expr, scope.declareValue(name, isByvalueRec, body.isInstanceOf[Lam]))
expr => (expr, scope.declareValue(name, isByvalueRec, bodyIsLam))
}
}) match {
case R((originalExpr, sym)) =>
Expand Down Expand Up @@ -736,7 +748,9 @@ object JSTestBackend {
/**
* Represents the result of code generation.
*/
abstract class Result
abstract class Result {
def showFirstResult(prefixLength: Int): Unit = ()
}

/**
* Emitted code.
Expand Down
15 changes: 9 additions & 6 deletions shared/src/main/scala/mlscript/NewParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D
"",
"",
"",
"",
// ^ for keywords
",",
";",
Expand All @@ -116,10 +117,11 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D

def opCharPrec(opChar: Char): Int = prec(opChar)
def opPrec(opStr: Str): (Int, Int) = opStr match {
case "is" => (4, 4)
case "and" => (3, 3)
case "or" => (2, 2)
case _ if opStr.exists(_.isLetter) =>
(4, 4)
(5, 5)
case _ =>
val r = opStr.last
(prec(opStr.head), prec(r) - (if (r === '@' || r === '/' || r === ',') 1 else 0))
Expand Down Expand Up @@ -652,25 +654,26 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D
}
case _ => ???
})
exprCont(res, 0, allowNewlines)
exprCont(res, prec, allowNewlines)

case (br @ BRACKETS(Square, toks), loc) :: _ =>
consume
val idx = rec(toks, S(br.innerLoc), "subscript").concludeWith(_.expr(0))
val res = Subs(acc, idx.withLoc(S(loc)))
exprCont(res, 0, allowNewlines)
exprCont(res, prec, allowNewlines)

case (br @ BRACKETS(Round, toks), loc) :: _ =>
consume
val as = rec(toks, S(br.innerLoc), br.describe).concludeWith(_.argsMaybeIndented())
val res = App(acc, Tup(as).withLoc(S(loc)))
exprCont(res, 0, allowNewlines)
exprCont(res, prec, allowNewlines)

case (KEYWORD("of"), _) :: _ =>
consume
val as = argsMaybeIndented()
// val as = argsOrIf(Nil) // TODO
val res = App(acc, Tup(as))
exprCont(res, 0, allowNewlines)
exprCont(res, prec, allowNewlines)

case c @ (h :: _) if (h._1 match {
case KEYWORD(";" | "of") | BRACKETS(Round | Square, _)
Expand All @@ -686,7 +689,7 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D
val res = App(acc, Tup(as))
raise(WarningReport(msg"Paren-less applications should use the 'of' keyword"
-> res.toLoc :: Nil))
exprCont(res, 0, allowNewlines)
exprCont(res, prec, allowNewlines)

case _ => R(acc)
}
Expand Down
6 changes: 3 additions & 3 deletions shared/src/main/scala/mlscript/TypeDefs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class TypeDefs extends NuTypeDefs { self: Typer =>
val (bodyTy, tvars) =
typeType2(td.body, simplify = false)(ctx.copy(lvl = 0), raise, tparamsargs.map(_.name -> _).toMap, newDefsInfo)
val td1 = TypeDef(td.kind, td.nme, tparamsargs.toList, tvars, bodyTy,
td.mthDecls, td.mthDefs, baseClassesOf(td), td.toLoc, Nil)
td.mthDecls, td.mthDefs, baseClassesOf(td), td.toLoc, td.positionals.map(_.name))
allDefs += n -> td1
S(td1)
}
Expand Down Expand Up @@ -337,7 +337,7 @@ class TypeDefs extends NuTypeDefs { self: Typer =>
singleTup(tv), tv & nomTag & RecordType.mk(tparamTags)(noProv)
)(originProv(td.nme.toLoc, "trait constructor", td.nme.name)))
}
ctx += n.name -> ctor
ctx += n.name -> VarSymbol(ctor, Var(n.name))
}
true
}
Expand Down Expand Up @@ -491,7 +491,7 @@ class TypeDefs extends NuTypeDefs { self: Typer =>
def go(md: MethodDef[_ <: Term \/ Type]): (Str, MethodType) = {
val thisTag = TraitTag(Var("this"))(noProv)
val thisTy = thisTag & tr
thisCtx += "this" -> thisTy
thisCtx += "this" -> VarSymbol(thisTy, Var("this"))
val MethodDef(rec, prt, nme, tparams, rhs) = md
val prov: TypeProvenance = tp(md.toLoc,
(if (!top) "inherited " else "")
Expand Down
Loading