Skip to content

Commit 9b359cd

Browse files
committed
Add way to refer to Predef symbol in Elab. by declaring it in Prelude
TODO We have not yet properly implemented declarations: their implementations currently create new symbols.
1 parent 0cc3189 commit 9b359cd

File tree

5 files changed

+51
-8
lines changed

5 files changed

+51
-8
lines changed

hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,20 @@ object Elaborator:
6464
def getBuiltin(nme: Str): Opt[Ctx.Elem] =
6565
parent.filter(_.parent.nonEmpty).fold(env.get(nme))(_.getBuiltin(nme))
6666
object Builtins:
67-
private def assumeBuiltinCls(nme: Str): ClassSymbol =
67+
private def assumeBuiltin(nme: Str): Symbol =
6868
getBuiltin(nme)
69-
.getOrElse(throw new NoSuchElementException(s"builtin $nme ${env.keySet} $parent"))
69+
.getOrElse(throw new NoSuchElementException(s"builtin $nme not in ${parent.map(_.env.keySet)}"))
7070
.symbol.getOrElse(throw new NoSuchElementException(s"builtin symbol $nme"))
71-
.asCls.getOrElse(throw new NoSuchElementException(s"builtin class symbol $nme"))
71+
private def assumeBuiltinCls(nme: Str): ClassSymbol =
72+
assumeBuiltin(nme).asCls.getOrElse(throw new NoSuchElementException(
73+
s"builtin class symbol $nme"))
74+
private def assumeBuiltinMod(nme: Str): ModuleSymbol =
75+
assumeBuiltin(nme).asMod.getOrElse(throw new NoSuchElementException(
76+
s"builtin module symbol $nme"))
7277
val Int = assumeBuiltinCls("Int")
7378
val Num = assumeBuiltinCls("Num")
7479
val Str = assumeBuiltinCls("Str")
80+
val Predef = assumeBuiltinMod("Predef")
7581

7682
object Ctx:
7783
abstract class Elem:

hkmc2/shared/src/test/mlscript-compile/Predef.mjs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
const Predef$class = class Predef {
22
constructor() {
3-
3+
this.Test = class Test {
4+
constructor() {
5+
this.y = 1;
6+
}
7+
toString() { return "Test"; }
8+
};
49
}
510
id(x) {
611
return x;
@@ -15,9 +20,14 @@ const Predef$class = class Predef {
1520
pipe(x2, f) {
1621
return f(x2);
1722
}
18-
call(receiver, f1) {
19-
return (arg) => {
20-
return f1.call(receiver, arg);
23+
apply(receiver, f1) {
24+
return (...args) => {
25+
return f1(receiver, ...args);
26+
};
27+
}
28+
call(receiver1, f2) {
29+
return (...args) => {
30+
return f2.call(receiver1, ...args);
2131
};
2232
}
2333
print(x3) {

hkmc2/shared/src/test/mlscript-compile/Predef.mls

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ fun not(x) = x is false
77

88
fun (|>) pipe(x, f) = f(x)
99

10-
fun (|>.) call(receiver, f)(arg) = f.call(receiver, arg)
10+
fun (.) apply(receiver, f)(...args) = f(receiver, ...args)
11+
12+
fun (|>.) call(receiver, f)(...args) = f.call(receiver, ...args)
1113

1214
fun print(x) =
1315
console.log(String(x))
@@ -29,3 +31,6 @@ fun checkArgs(functionName, expected, isUB, got) =
2931
// + " arguments but got " + got)
3032
else ()
3133

34+
class Test with
35+
val y = 1
36+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
:js
2+
3+
4+
Test === Predef.Test
5+
//│ = true
6+
7+
Predef.Test === globalThis.Predef.Test
8+
//│ = true
9+
10+
(new Predef.Test).y
11+
//│ = 1
12+
13+
:re
14+
(new Predef.Test).x
15+
//│ ═══[RUNTIME ERROR] Error: Access to required field 'x' yielded 'undefined'
16+
17+

hkmc2/shared/src/test/mlscript/decls/Prelude.mls

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ declare val process
2020
declare val fs
2121

2222

23+
declare module Predef with
24+
class Test with
25+
val x = 0
26+
27+
2328
// TODO: rm
2429

2530
declare fun log: (Any) -> ()

0 commit comments

Comments
 (0)