Skip to content

Commit

Permalink
Merge branch 'new-definition-typing' into js-parenthesis
Browse files Browse the repository at this point in the history
  • Loading branch information
HarrisL2 committed Oct 12, 2023
2 parents fe77ab0 + 38bf8fc commit 25bc4b9
Show file tree
Hide file tree
Showing 22 changed files with 787 additions and 337 deletions.
21 changes: 8 additions & 13 deletions shared/src/main/scala/mlscript/NewLexer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,19 +168,14 @@ class NewLexer(origin: Origin, raise: Diagnostic => Unit, dbg: Bool) {
// go(j, if (keywords.contains(n)) KEYWORD(n) else IDENT(n, isAlphaOp(n)))
lex(j, ind, next(j, if (keywords.contains(n)) KEYWORD(n) else IDENT(n, isAlphaOp(n))))
case _ if isOpChar(c) =>
// if (c === '-' && isDigit(bytes(i + 1))) {
// val (str, j) = takeWhile(i + 1)(isDigit)
// lex(j, ind, next(j, LITVAL(IntLit(-BigInt(str)))))
// } else {
val (n, j) = takeWhile(i)(isOpChar)
if (n === "." && j < length && isIdentFirstChar(bytes(j))) {
val (name, k) = takeWhile(j)(isIdentChar)
// go(k, SELECT(name))
lex(k, ind, next(k, SELECT(name)))
}
// else go(j, if (isSymKeyword.contains(n)) KEYWORD(n) else IDENT(n, true))
else lex(j, ind, next(j, if (isSymKeyword.contains(n)) KEYWORD(n) else IDENT(n, true)))
//}
val (n, j) = takeWhile(i)(isOpChar)
if (n === "." && j < length && isIdentFirstChar(bytes(j))) {
val (name, k) = takeWhile(j)(isIdentChar)
// go(k, SELECT(name))
lex(k, ind, next(k, SELECT(name)))
}
// else go(j, if (isSymKeyword.contains(n)) KEYWORD(n) else IDENT(n, true))
else lex(j, ind, next(j, if (isSymKeyword.contains(n)) KEYWORD(n) else IDENT(n, true)))
case _ if isDigit(c) =>
val (str, j) = takeWhile(i)(isDigit)
// go(j, LITVAL(IntLit(BigInt(str))))
Expand Down
9 changes: 5 additions & 4 deletions shared/src/main/scala/mlscript/NewParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -787,12 +787,13 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], newDefs: Bo
case ((KEYWORD(";;") /* | NEWLINE */ /* | BRACKETS(Curly, _) */, l0) :: _) =>
R(UnitLit(true).withLoc(S(l0)))
// R(errExpr) // TODO
case (IDENT("-", true), l0) :: _ /*if opPrec("-")._1 > prec*/ =>
case (IDENT("-", true), l0) :: _ /*if opPrec("-")._1 > prec*/ => // Unary minus
consume
val v = Var("-").withLoc(S(l0))
exprOrIf(opPrec("-")._2) match {
case L(rhs) => ???
case R(rhs) =>
expr(opPrec("-")._2) match {
case IntLit(i) => // Special case for negative literals
exprCont(IntLit(-i), prec, false)
case rhs: Term => // General case
exprCont(
if (newDefs) App(v, PlainTup(IntLit(BigInt(0)), rhs))
else App(App(v, PlainTup(IntLit(BigInt(0)))), PlainTup(rhs))
Expand Down
2 changes: 2 additions & 0 deletions shared/src/main/scala/mlscript/NuTypeDefs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class NuTypeDefs extends ConstraintSolver { self: Typer =>
def level: Level
def isImplemented: Bool
def isPublic: Bool
def isPrivate: Bool = !isPublic // * We currently don't support `protected`

def isValueParam: Bool = this match {
case p: NuParam => !p.isType
Expand Down Expand Up @@ -1267,6 +1268,7 @@ class NuTypeDefs extends ConstraintSolver { self: Typer =>
case (m: TypedNuTermDef, S(fun: TypedNuTermDef)) => fun match {
// * If the implementation and the declaration are in the same class,
// * it does not require to be virtual.
case _ if fun.isPrivate => () // * Private members are not actually inherited
case td: TypedNuFun if (!td.fd.isVirtual && !clsSigns.contains(fun)) =>
err(msg"${m.kind.str.capitalize} member `${m.name
}` is not virtual and cannot be overridden" -> m.toLoc ::
Expand Down
5 changes: 4 additions & 1 deletion shared/src/main/scala/mlscript/TyperDatatypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ abstract class TyperDatatypes extends TyperHelpers { Typer: Typer =>
Overload(alts.map(ft => FunctionType(f(pol.contravar, ft.lhs), f(pol, ft.rhs))(ft.prov)))(prov)
def approximatePos: FunctionType = {
val (lhss, rhss) = alts.map(ft => ft.lhs -> ft.rhs).unzip
FunctionType(lhss.reduce(_ & _), rhss.reduce(_ | _))(prov)
FunctionType(lhss.reduce(_ | _), rhss.reduce(_ | _))(prov)
// * Note: technically the following is another valid (but probably less useful)
// * approximation of the same function type:
// FunctionType(lhss.reduce(_ & _), rhss.reduce(_ & _))(prov)
}
lazy val level: Level = levelBelow(MaxLevel)(MutSet.empty)
def levelBelow(ub: Level)(implicit cache: MutSet[TV]): Level =
Expand Down
112 changes: 20 additions & 92 deletions shared/src/test/diff/basics/Intersections.fun
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,7 @@ foo(1) // returns int & bool, equivalent to nothing
succ / foo(1)
foo(true)
not / foo(true)
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.30: foo(1) // returns int & bool, equivalent to nothing
//│ ║ ^^^^^^
//│ ╟── integer literal of type `1` is not an instance of type `bool`
//│ ║ l.30: foo(1) // returns int & bool, equivalent to nothing
//│ ║ ^
//│ ╟── but it flows into argument with expected type `bool`
//│ ║ l.30: foo(1) // returns int & bool, equivalent to nothing
//│ ║ ^^^
//│ ╟── Note: constraint arises from reference:
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ╙── ^^^^
//│ res: bool | error | int
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.31: succ / foo(1)
//│ ║ ^^^^^^
//│ ╟── integer literal of type `1` is not an instance of type `bool`
//│ ║ l.31: succ / foo(1)
//│ ║ ^
//│ ╟── but it flows into argument with expected type `bool`
//│ ║ l.31: succ / foo(1)
//│ ║ ^^^
//│ ╟── Note: constraint arises from reference:
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ╙── ^^^^
//│ res: bool | int
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.31: succ / foo(1)
//│ ║ ^^^^^^^^^^^^^
Expand All @@ -66,31 +42,7 @@ not / foo(true)
//│ ║ l.31: succ / foo(1)
//│ ╙── ^^^^^^
//│ res: error | int
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.32: foo(true)
//│ ║ ^^^^^^^^^
//│ ╟── reference of type `true` is not an instance of type `int`
//│ ║ l.32: foo(true)
//│ ║ ^^^^
//│ ╟── but it flows into argument with expected type `int`
//│ ║ l.32: foo(true)
//│ ║ ^^^^^^
//│ ╟── Note: constraint arises from reference:
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ╙── ^^^
//│ res: bool | error | int
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.33: not / foo(true)
//│ ║ ^^^^^^^^^
//│ ╟── reference of type `true` is not an instance of type `int`
//│ ║ l.33: not / foo(true)
//│ ║ ^^^^
//│ ╟── but it flows into argument with expected type `int`
//│ ║ l.33: not / foo(true)
//│ ║ ^^^^^^
//│ ╟── Note: constraint arises from reference:
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ╙── ^^^
//│ res: bool | int
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.33: not / foo(true)
//│ ║ ^^^^^^^^^^^^^^^
Expand All @@ -106,76 +58,52 @@ not / foo(true)
not / foo(1)
foo(1) as Nothing
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.106: not / foo(1)
//│ ║ ^^^^^^
//│ ╟── integer literal of type `1` is not an instance of type `bool`
//│ ║ l.106: not / foo(1)
//│ ║ ^
//│ ╟── but it flows into argument with expected type `bool`
//│ ║ l.106: not / foo(1)
//│ ║ ^^^
//│ ╟── Note: constraint arises from reference:
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ╙── ^^^^
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.106: not / foo(1)
//│ ║ ^^^^^^^^^^^^
//│ ║ l.58: not / foo(1)
//│ ║ ^^^^^^^^^^^^
//│ ╟── reference of type `int` is not an instance of type `bool`
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ║ ^^^
//│ ╟── but it flows into application with expected type `bool`
//│ ║ l.106: not / foo(1)
//│ ╙── ^^^^^^
//│ ║ l.58: not / foo(1)
//│ ╙── ^^^^^^
//│ res: bool | error
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.107: foo(1) as Nothing
//│ ║ ^^^^^^
//│ ╟── integer literal of type `1` is not an instance of type `bool`
//│ ║ l.107: foo(1) as Nothing
//│ ║ ^
//│ ╟── but it flows into argument with expected type `bool`
//│ ║ l.107: foo(1) as Nothing
//│ ║ ^^^
//│ ╟── Note: constraint arises from reference:
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ╙── ^^^^
//│ ╔══[ERROR] Type mismatch in 'as' binding:
//│ ║ l.107: foo(1) as Nothing
//│ ║ ^^^^^^^^^^^^^^^^^
//│ ║ l.59: foo(1) as Nothing
//│ ║ ^^^^^^^^^^^^^^^^^
//│ ╟── reference of type `int` does not match type `nothing`
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ║ ^^^
//│ ╟── but it flows into application with expected type `nothing`
//│ ║ l.107: foo(1) as Nothing
//│ ║ ^^^^^^
//│ ║ l.59: foo(1) as Nothing
//│ ║ ^^^^^^
//│ ╟── Note: constraint arises from reference:
//│ ║ l.107: foo(1) as Nothing
//│ ╙── ^^^^^^^
//│ ║ l.59: foo(1) as Nothing
//│ ╙── ^^^^^^^
//│ res: nothing

:e
foo as Nothing
//│ ╔══[ERROR] Type mismatch in 'as' binding:
//│ ║ l.157: foo as Nothing
//│ ║ ^^^^^^^^^^^^^^
//│ ║ l.85: foo as Nothing
//│ ║ ^^^^^^^^^^^^^^
//│ ╟── type intersection of type `int -> int & bool -> bool` does not match type `nothing`
//│ ║ l.26: let foo = (Int => Int) & (Bool => Bool)
//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//│ ╟── but it flows into reference with expected type `nothing`
//│ ║ l.157: foo as Nothing
//│ ║ ^^^
//│ ║ l.85: foo as Nothing
//│ ║ ^^^
//│ ╟── Note: constraint arises from reference:
//│ ║ l.157: foo as Nothing
//│ ╙── ^^^^^^^
//│ ║ l.85: foo as Nothing
//│ ╙── ^^^^^^^
//│ res: nothing

:e
let oops = (&)
//│ ╔══[ERROR] Illegal use of reserved operator: &
//│ ║ l.173: let oops = (&)
//│ ║ l.101: let oops = (&)
//│ ╙── ^^^
//│ ╔══[ERROR] identifier not found: &
//│ ║ l.173: let oops = (&)
//│ ║ l.101: let oops = (&)
//│ ╙── ^^^
//│ oops: error

2 changes: 1 addition & 1 deletion shared/src/test/diff/ecoop23/SimpleRegionDSL_annot.mls
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ fun mk(n) = if n is
_ then Scale(Vector(0, 0), mk(n))
//│ fun mk: forall 'a. Object -> 'a
//│ where
//│ 'a :> Outside['a] | Scale['a] | Union['a] | Intersect['a] | Translate['a]
//│ 'a :> Outside['a] | Translate['a] | Scale['a] | Union['a] | Intersect['a]

:re
TestElim.eliminate(mk(100))
Expand Down
71 changes: 16 additions & 55 deletions shared/src/test/diff/fcp/Overloads.mls
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,22 @@ IISS : ZZII
//│ ╔══[ERROR] Type mismatch in type ascription:
//│ ║ l.30: IISS : ZZII
//│ ║ ^^^^
//│ ╟── type `0` is not an instance of type `string`
//│ ║ l.7: type ZZII = 0 -> 0 & int -> int
//│ ║ ^
//│ ╟── Note: constraint arises from type reference:
//│ ╟── type `int` does not match type `0`
//│ ║ l.12: def IISS: int -> int & string -> string
//│ ╙── ^^^^^^
//│ ║ ^^^
//│ ╟── Note: constraint arises from literal type:
//│ ║ l.7: type ZZII = 0 -> 0 & int -> int
//│ ╙── ^
//│ res: ZZII

:e
IISS : BBNN
//│ ╔══[ERROR] Type mismatch in type ascription:
//│ ║ l.43: IISS : BBNN
//│ ║ ^^^^
//│ ╟── type `bool` is not an instance of type `int`
//│ ╟── type `bool` does not match type `int | string`
//│ ║ l.6: type BBNN = bool -> bool & number -> number
//│ ║ ^^^^
//│ ╟── Note: constraint arises from type reference:
//│ ║ l.12: def IISS: int -> int & string -> string
//│ ╙── ^^^
//│ ╙── ^^^^
//│ res: BBNN


Expand All @@ -61,53 +58,20 @@ IISS : int -> int
IISS : (0 | 1) -> number
//│ res: (0 | 1) -> number

:e
IISS : 'a -> 'a
//│ ╔══[ERROR] Type mismatch in type ascription:
//│ ║ l.65: IISS : 'a -> 'a
//│ ║ ^^^^
//│ ╟── type `int` is not an instance of type `string`
//│ ║ l.12: def IISS: int -> int & string -> string
//│ ║ ^^^
//│ ╟── Note: constraint arises from type reference:
//│ ║ l.12: def IISS: int -> int & string -> string
//│ ║ ^^^^^^
//│ ╟── from type variable:
//│ ║ l.65: IISS : 'a -> 'a
//│ ╙── ^^
//│ res: nothing -> (error | int | string)
//│ res: ('a & (int | string)) -> (int | string | 'a)

:e
IISS 0
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.81: IISS 0
//│ ║ ^^^^^^
//│ ╟── integer literal of type `0` is not an instance of type `string`
//│ ║ l.81: IISS 0
//│ ║ ^
//│ ╟── Note: constraint arises from type reference:
//│ ║ l.12: def IISS: int -> int & string -> string
//│ ╙── ^^^^^^
//│ res: error | int | string
//│ res: int | string

(IISS : int -> int) 0
//│ res: int

:e
(if true then IISS else BBNN) 0
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.97: (if true then IISS else BBNN) 0
//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//│ ╟── integer literal of type `0` is not an instance of type `string`
//│ ║ l.97: (if true then IISS else BBNN) 0
//│ ║ ^
//│ ╟── Note: constraint arises from type reference:
//│ ║ l.12: def IISS: int -> int & string -> string
//│ ╙── ^^^^^^
//│ res: bool | error | number | string
//│ res: bool | number | string

fun x -> (if true then IISS else BBNN) x
//│ res: nothing -> (bool | number | string)
//│ res: int -> (bool | number | string)

if true then IISS else BBNN
//│ res: bool -> bool & number -> number | int -> int & string -> string
Expand All @@ -121,14 +85,11 @@ if true then IISS else BBNN
:e
(if true then IISS else BBNN) : (0 | 1 | true) -> number
//│ ╔══[ERROR] Type mismatch in type ascription:
//│ ║ l.122: (if true then IISS else BBNN) : (0 | 1 | true) -> number
//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//│ ╟── type `0` is not an instance of type `string`
//│ ║ l.122: (if true then IISS else BBNN) : (0 | 1 | true) -> number
//│ ║ ^
//│ ╟── Note: constraint arises from type reference:
//│ ║ l.12: def IISS: int -> int & string -> string
//│ ╙── ^^^^^^
//│ ║ l.86: (if true then IISS else BBNN) : (0 | 1 | true) -> number
//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//│ ╟── type `true` does not match type `int | string`
//│ ║ l.86: (if true then IISS else BBNN) : (0 | 1 | true) -> number
//│ ╙── ^^^^
//│ res: (0 | 1 | true) -> number


Expand Down
Loading

0 comments on commit 25bc4b9

Please sign in to comment.