Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
163 changes: 163 additions & 0 deletions hkmc2/shared/src/test/mlscript-compile/Block.mls
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import "./Predef.mls"
import "./Option.mls"
import "./Term.mls"
import "./StrOps.mls"

open StrOps
open Predef
open Option

module Block with...

type Opt[A] = Option[A]

// dependancies referenced in Block classes, referencing implementation in Term.mls

type Ident = Symbol

type Literal = null | undefined | Str | Int | Num | Bool
class Arg(val spread: Opt[Bool], val value: Path) // unused

type ParamList = Array[Symbol]

// Classes defined in Block.scala

class Path with
constructor
Select(val qual: Path, val name: Ident)
DynSelect(val qual: Path, val fld: Path, arrayIdx: Bool)
ValueRef(val l: Symbol)
ValueLit(val lit: Literal)

// Match pattern for staged code
class Case with
constructor
Lit(val lit: Literal)
Cls(val cls: Symbol, val path: Path)
Tup(val len: Int, val inf: Bool) // TODO: remove inf?
Field(val name: Ident)
Wildcard

class Result with
constructor
// unused?
TrivialResult(val path: Path) // only Path extends TrivialResult
Call(val _fun: Path, val args: Array[Arg])
Instantiate(val cls: Path, val args: Array[Arg]) // assume immutable
Tuple(val elems: Array[Arg]) // assume immutable

class Defn with
constructor
ValDefn(val sym: Symbol, val rhs: Path)
ClsLikeDefn(val sym: Symbol, val paramsOpt: Opt[ParamList], val companion: Opt[ClsLikeBody]) // unused
FunDefn(val sym: Symbol, val params: Array[ParamList], val body: Block)

class ClsLikeBody(val isym: Symbol, val methods: Array[FunDefn], val publicFields: Array[Symbol -> Symbol]) // unused

class Block with
constructor
Match(val scrut: Path, val arms: Array[Case -> Block], val dflt: Opt[Block], val rest: Block)
Return(val res: Result, val implct: Bool)
Assign(val lhs: Symbol, val rhs: Result, val rest: Block)
Define(val defn: Defn, val rest: Block)
End()

fun showBool(b: Bool) = if b then "true" else "false"

fun showLiteral(l: Literal) =
if l is
null => "null"
| undefined => "undefined"
| s: Str => "\"" + s + "\""
| i: Int => str(i)
| n: Num => str(n)
| b: Bool => showBool(b)

fun showSymbol(s: Symbol) = "Symbol(" + "\"" + s.name + "\"" + ")"

fun showIdent(i: Ident) = showSymbol(i)

// Path
fun showPath(p: Path): Str =
if p is
Select(qual, name) =>
"Select(" + showPath(qual) + ", " + showIdent(name) + ")"
| DynSelect(qual, fld, arrayIdx) =>
"DynSelect(" + showPath(qual) + ", " + showPath(fld) + ", " + showBool(arrayIdx) + ")"
| ValueRef(l) =>
// match Term/Quasiquotes style: Ref(Symbol("x"))
"Ref(" + showSymbol(l) + ")"
| ValueLit(lit) =>
// match Term/Quasiquotes style: Lit(42)
"Lit(" + showLiteral(lit) + ")"

// Arg (used in Result.Call/Tuple/etc.)
fun showArg(a: Arg) =
if a.spread is
Some(true) => "..." + showPath(a.value)
| _ => showPath(a.value)

fun showArgs(as: Array[Arg]) =
"[" + as.map(showArg).joinWith(", ") + "]"

// Case (match arm patterns)
fun showCase(c: Case): Str =
if c is
Lit(lit) => "Lit(" + showLiteral(lit) + ")"
| Cls(cls, path) => "Cls(" + showSymbol(cls) + ", " + showPath(path) + ")"
| Tup(len, inf) => "Tup(" + str(len) + ", " + showBool(inf) + ")"
| Field(name) => "Field(" + showIdent(name) + ")"
| Wildcard => "Wildcard"

// Result
fun showResult(r: Result): Str =
if r is
TrivialResult(path) => showPath(path)
| Call(fun, args) => "Call(" + showPath(fun) + ", " + showArgs(args) + ")"
| Instantiate(cls, args) => "Instantiate(" + showPath(cls) + ", " + showArgs(args) + ")"
| Tuple(elems) => "Tuple(" + showArgs(elems) + ")"

// Defn
fun showParamList(ps: ParamList) =
"[" + ps.map(showSymbol).joinWith(", ") + "]"

fun showDefn(d: Defn): Str =
if d is
ValDefn(sym, rhs) =>
"ValDefn(" + showSymbol(sym) + ", " + showPath(rhs) + ")"
| FunDefn(sym, params, body) =>
"FunDefn(" + showSymbol(sym) + ", " +
"[" + params.map(showParamList).joinWith(", ") + "], " +
showBlock(body) + ")"
| ClsLikeDefn(sym, paramsOpt, companion) =>
// minimal, since this is unused in your staged Block for now
"ClsLikeDefn(" + showSymbol(sym) + ")"

// Block
fun showOptBlock(ob: Opt[Block]) =
if ob is Some(b) then showBlock(b) else "None"

fun showArm(pair: Case -> Block) =
if pair is cse -> body then showCase(cse) + " -> " + showBlock(body) else "<bad-arm>"

fun showBlock(b: Block): Str =
if b is
Match(scrut, arms, dflt, rest) =>
"Match(" +
showPath(scrut) + ", " +
"[" + arms.map(showArm).joinWith(", ") + "], " +
showOptBlock(dflt) + ", " +
showBlock(rest) + ")"
| Return(res, implct) =>
"Return(" + showResult(res) + ", " + showBool(implct) + ")"
| Assign(lhs, rhs, rest) =>
"Assign(" + showSymbol(lhs) + ", " + showResult(rhs) + ", " + showBlock(rest) + ")"
| Define(defn, rest) =>
"Define(" + showDefn(defn) + ", " + showBlock(rest) + ")"
| End() => "End"

// Public entry
fun printCode(p: Block): Str = console.log(showBlock(p))


fun compile(p: Block) = ???
5 changes: 2 additions & 3 deletions hkmc2DiffTests/src/test/scala/hkmc2/JSBackendDiffMaker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ abstract class JSBackendDiffMaker extends MLsDiffMaker:
h.execute(s"const $definitionMetadataNme = Symbol.for(\"mlscript.definitionMetadata\");")
h.execute(s"const $prettyPrintNme = Symbol.for(\"mlscript.prettyPrint\");")
if importQQ.isSet then importRuntimeModule(termNme, termFile)
if stageCode.isSet then
importRuntimeModule(blockNme, blockFile)
importRuntimeModule(shapeNme, shapeFile)
if stageCode.isSet then importRuntimeModule(blockNme, blockFile)
// importRuntimeModule(shapeNme, shapeFile)
h

private var hostCreated = false
Expand Down
4 changes: 3 additions & 1 deletion hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ abstract class MLsDiffMaker extends DiffMaker:
val runtimeFile: os.Path = predefFile/os.up/"Runtime.mjs" // * Contains MLscript runtime definitions
val termFile: os.Path = predefFile/os.up/"Term.mjs" // * Contains MLscript runtime term definitions
val blockFile: os.Path = predefFile/os.up/"Block.mjs" // * Contains MLscript runtime block definitions
val shapeFile: os.Path = predefFile/os.up/"Shape.mjs" // * Contains MLscript runtime shape definitions
// val shapeFile: os.Path = predefFile/os.up/"Shape.mjs" // * Contains MLscript runtime shape definitions

val wd = file / os.up

Expand Down Expand Up @@ -163,8 +163,10 @@ abstract class MLsDiffMaker extends DiffMaker:
given Config = mkConfig
processTrees(
PrefixApp(Keywrd(`import`), StrLit(blockFile.toString)) :: Nil)
/*
processTrees(
PrefixApp(Keywrd(`import`), StrLit(shapeFile.toString)) :: Nil)
*/
super.init()


Expand Down
Loading