Skip to content

Commit 3c66451

Browse files
committed
Use implicit conversion to avoid repeating raw
1 parent 01cafb4 commit 3c66451

File tree

2 files changed

+147
-135
lines changed

2 files changed

+147
-135
lines changed

compiler/shared/main/scala/mlscript/compiler/codegen/CppAst.scala

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import mlscript.utils._
55
import mlscript.utils.shorthands._
66
import mlscript.compiler.utils._
77

8+
import scala.language.implicitConversions
9+
10+
given Conversion[String, Document] = raw
11+
812
enum Specifier:
913
case Extern
1014
case Static
@@ -50,16 +54,16 @@ enum Type:
5054

5155
def toDocument(extraTypename: Bool = false): Document =
5256
def aux(x: Type): Document = x match
53-
case Prim(name) => name |> raw
54-
case Ptr(inner) => aux(inner) <#> raw("*")
55-
case Ref(inner) => aux(inner) <#> raw("&")
56-
case Array(inner, size) => aux(inner) <#> raw("[") <#> size.fold(raw(""))(x => x.toString |> raw) <#> raw("]")
57-
case FuncPtr(ret, args) => aux(ret) <#> raw("(") <#> Type.toDocuments(args, sep = raw(", ")) <#> raw(")")
58-
case Struct(name) => raw(s"struct $name")
59-
case Enum(name) => raw(s"enum $name")
60-
case Template(name, args) => raw(s"$name") <#> raw("<") <#> Type.toDocuments(args, sep = raw(", ")) <#> raw(">")
61-
case Var(name) => name |> raw
62-
case Qualifier(inner, qual) => aux(inner) <:> raw(qual)
57+
case Prim(name) => name
58+
case Ptr(inner) => aux(inner) <#> "*"
59+
case Ref(inner) => aux(inner) <#> "&"
60+
case Array(inner, size) => aux(inner) <#> "[" <#> size.fold(raw(""))(x => x.toString) <#> "]"
61+
case FuncPtr(ret, args) => aux(ret) <#> "(" <#> Type.toDocuments(args, sep = ", ") <#> ")"
62+
case Struct(name) => s"struct $name"
63+
case Enum(name) => s"enum $name"
64+
case Template(name, args) => s"$name" <#> "<" <#> Type.toDocuments(args, sep = ", ") <#> ">"
65+
case Var(name) => name
66+
case Qualifier(inner, qual) => aux(inner) <:> qual
6367
aux(this)
6468

6569
override def toString: Str = toDocument().print
@@ -87,28 +91,29 @@ enum Stmt:
8791
case AutoBind(lhs, rhs) =>
8892
lhs match
8993
case Nil => rhs.toDocument
90-
case x :: Nil => raw("auto") <:> raw(x) <:> raw("=") <:> rhs.toDocument <#> raw(";")
91-
case _ => raw("auto") <:> raw(lhs.mkString("[", ",", "]")) <:> raw("=") <:> rhs.toDocument <#> raw(";")
92-
case Assign(lhs, rhs) => raw(lhs) <#> raw(" = ") <#> rhs.toDocument <#> raw(";")
93-
case Return(expr) => raw("return ") <#> expr.toDocument <#> raw(";")
94+
case x :: Nil => "auto" <:> x <:> "=" <:> rhs.toDocument <#> ";"
95+
case _ => "auto" <:> lhs.mkString("[", ",", "]") <:> "=" <:> rhs.toDocument <#> ";"
96+
case Assign(lhs, rhs) => lhs <#> " = " <#> rhs.toDocument <#> ";"
97+
case Return(expr) => "return " <#> expr.toDocument <#> ";"
9498
case If(cond, thenStmt, elseStmt) =>
95-
raw("if (") <#> cond.toDocument <#> raw(")") <#> thenStmt.toDocument <:> elseStmt.fold(raw(""))(x => raw("else") <:> x.toDocument)
99+
"if (" <#> cond.toDocument <#> ")" <#> thenStmt.toDocument <:> elseStmt.fold(raw(""))(x => "else" <:> x.toDocument)
96100
case While(cond, body) =>
97-
raw("while (") <#> cond.toDocument <#> raw(")") <#> body.toDocument
101+
"while (" <#> cond.toDocument <#> ")" <#> body.toDocument
98102
case For(init, cond, update, body) =>
99-
raw("for (") <#> init.toDocument <#> raw("; ") <#> cond.toDocument <#> raw("; ") <#> update.toDocument <#> raw(")") <#> body.toDocument
100-
case ExprStmt(expr) => expr.toDocument <#> raw(";")
101-
case Break => raw("break;")
102-
case Continue => raw("continue;")
103+
"for (" <#> init.toDocument <#> "; " <#> cond.toDocument <#> "; " <#> update.toDocument <#> ")" <#> body.toDocument
104+
case ExprStmt(expr) => expr.toDocument <#> ";"
105+
case Break => "break;"
106+
case Continue => "continue;"
103107
case Block(decl, stmts) =>
104-
stack(raw("{"),
108+
stack(
109+
"{",
105110
Stmt.toDocuments(decl, stmts) |> indent,
106-
raw("}"))
111+
"}")
107112
case Switch(expr, cases) =>
108-
raw("switch (") <#> expr.toDocument <#> raw(")") <#> raw("{") <#> stack_list(cases.map {
109-
case (cond, stmt) => raw("case ") <#> cond.toDocument <#> raw(":") <#> stmt.toDocument
110-
}) <#> raw("}")
111-
case Raw(stmt) => stmt |> raw
113+
"switch (" <#> expr.toDocument <#> ")" <#> "{" <#> stack_list(cases.map {
114+
case (cond, stmt) => "case " <#> cond.toDocument <#> ":" <#> stmt.toDocument
115+
}) <#> "}"
116+
case Raw(stmt) => stmt
112117
aux(this)
113118

114119
object Expr:
@@ -135,18 +140,18 @@ enum Expr:
135140

136141
def toDocument: Document =
137142
def aux(x: Expr): Document = x match
138-
case Var(name) => name |> raw
139-
case IntLit(value) => value.toString |> raw
140-
case DoubleLit(value) => value.toString |> raw
141-
case StrLit(value) => s"\"$value\"" |> raw // need more reliable escape utils
142-
case CharLit(value) => value.toInt.toString |> raw
143-
case Call(func, args) => aux(func) <#> raw("(") <#> Expr.toDocuments(args, sep = raw(", ")) <#> raw(")")
144-
case Member(expr, member) => aux(expr) <#> raw("->") <#> raw(member)
145-
case Index(expr, index) => aux(expr) <#> raw("[") <#> aux(index) <#> raw("]")
146-
case Unary(op, expr) => raw("(") <#> raw(op) <#> aux(expr) <#> raw(")")
147-
case Binary(op, lhs, rhs) => raw("(") <#> aux(lhs) <#> raw(op) <#> aux(rhs) <#> raw(")")
148-
case Initializer(exprs) => raw("{") <#> Expr.toDocuments(exprs, sep = raw(", ")) <#> raw("}")
149-
case Constructor(name, init) => raw(name) <#> init.toDocument
143+
case Var(name) => name
144+
case IntLit(value) => value.toString
145+
case DoubleLit(value) => value.toString
146+
case StrLit(value) => s"\"$value\"" // need more reliable escape utils
147+
case CharLit(value) => value.toInt.toString
148+
case Call(func, args) => aux(func) <#> "(" <#> Expr.toDocuments(args, sep = ", ") <#> ")"
149+
case Member(expr, member) => aux(expr) <#> "->" <#> member
150+
case Index(expr, index) => aux(expr) <#> "[" <#> aux(index) <#> "]"
151+
case Unary(op, expr) => "(" <#> op <#> aux(expr) <#> ")"
152+
case Binary(op, lhs, rhs) => "(" <#> aux(lhs) <#> op <#> aux(rhs) <#> ")"
153+
case Initializer(exprs) => "{" <#> Expr.toDocuments(exprs, sep = ", ") <#> "}"
154+
case Constructor(name, init) => name <#> init.toDocument
150155
aux(this)
151156

152157
case class CompilationUnit(includes: Ls[Str], decls: Ls[Decl], defs: Ls[Def]):
@@ -161,10 +166,10 @@ enum Decl:
161166

162167
def toDocument: Document =
163168
def aux(x: Decl): Document = x match
164-
case StructDecl(name) => raw(s"struct $name;")
165-
case EnumDecl(name) => raw(s"enum $name;")
166-
case FuncDecl(ret, name, args) => ret.toDocument() <#> raw(s" $name(") <#> Type.toDocuments(args, sep = raw(", ")) <#> raw(");")
167-
case VarDecl(name, typ) => typ.toDocument() <#> raw(s" $name;")
169+
case StructDecl(name) => s"struct $name;"
170+
case EnumDecl(name) => s"enum $name;"
171+
case FuncDecl(ret, name, args) => ret.toDocument() <#> s" $name(" <#> Type.toDocuments(args, sep = ", ") <#> ");"
172+
case VarDecl(name, typ) => typ.toDocument() <#> s" $name;"
168173
aux(this)
169174

170175
enum Def:
@@ -178,21 +183,21 @@ enum Def:
178183
def aux(x: Def): Document = x match
179184
case StructDef(name, fields, inherit, defs) =>
180185
stack(
181-
raw(s"struct $name") <#> (if inherit.nonEmpty then raw(": public") <:> raw(inherit.get.mkString(", ")) else raw("") ) <:> raw("{"),
186+
s"struct $name" <#> (if inherit.nonEmpty then ": public" <:> inherit.get.mkString(", ") else "" ) <:> "{",
182187
stack_list(fields.map {
183-
case (name, typ) => typ.toDocument() <#> raw(" ") <#> raw(name) <#> raw(";")
188+
case (name, typ) => typ.toDocument() <#> " " <#> name <#> ";"
184189
}) |> indent,
185190
stack_list(defs.map(_.toDocument)) |> indent,
186-
raw("};")
191+
"};"
187192
)
188193
case EnumDef(name, fields) =>
189-
raw(s"enum $name") <:> raw("{") <#> stack_list(fields.map {
190-
case (name, value) => value.fold(raw(s"$name"))(x => raw(s"$name = $x"))
191-
}) <#> raw("};")
194+
s"enum $name" <:> "{" <#> stack_list(fields.map {
195+
case (name, value) => value.fold(s"$name")(x => s"$name = $x")
196+
}) <#> "};"
192197
case FuncDef(specret, name, args, body, or, virt) =>
193-
(if virt then raw("virtual ") else raw(""))
194-
<#> specret.toDocument() <#> raw(s" $name(") <#> Type.toDocuments(args, sep = raw(", ")) <#> raw(")") <#> (if or then raw(" override") else raw("")) <#> body.toDocument
198+
(if virt then "virtual " else "")
199+
<#> specret.toDocument() <#> s" $name(" <#> Type.toDocuments(args, sep = ", ") <#> ")" <#> (if or then " override" else "") <#> body.toDocument
195200
case VarDef(typ, name, init) =>
196-
typ.toDocument() <#> raw(s" $name") <#> init.fold(raw(""))(x => raw(" = ") <#> x.toDocument) <#> raw(";")
197-
case RawDef(x) => x |> raw
201+
typ.toDocument() <#> s" $name" <#> init.fold(raw(""))(x => " = " <#> x.toDocument) <#> raw(";")
202+
case RawDef(x) => x
198203
aux(this)

compiler/shared/main/scala/mlscript/compiler/ir/IR.scala

Lines changed: 90 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import collection.mutable.{Map as MutMap, Set as MutSet, HashMap, ListBuffer}
1111
import annotation.unused
1212
import util.Sorting
1313
import scala.collection.immutable.SortedSet
14+
import scala.language.implicitConversions
1415

1516
final case class IRError(message: String) extends Exception(message)
1617

@@ -126,19 +127,21 @@ enum Expr:
126127
def show: String =
127128
toDocument.print
128129

129-
def toDocument: Document = this match
130-
case Ref(s) => s.toString |> raw
131-
case Literal(IntLit(lit)) => s"$lit" |> raw
132-
case Literal(DecLit(lit)) => s"$lit" |> raw
133-
case Literal(StrLit(lit)) => s"$lit" |> raw
134-
case Literal(CharLit(lit)) => s"$lit" |> raw
135-
case Literal(UnitLit(lit)) => s"$lit" |> raw
130+
def toDocument: Document =
131+
given Conversion[String, Document] = raw
132+
this match
133+
case Ref(s) => s.toString
134+
case Literal(IntLit(lit)) => s"$lit"
135+
case Literal(DecLit(lit)) => s"$lit"
136+
case Literal(StrLit(lit)) => s"$lit"
137+
case Literal(CharLit(lit)) => s"$lit"
138+
case Literal(UnitLit(lit)) => s"$lit"
136139
case CtorApp(cls, args) =>
137-
raw(cls.name) <#> raw("(") <#> raw(args |> showArguments) <#> raw(")")
140+
cls.name <#> "(" <#> (args |> showArguments) <#> ")"
138141
case Select(s, cls, fld) =>
139-
raw(cls.name) <#> raw(".") <#> raw(fld) <#> raw("(") <#> raw(s.toString) <#> raw(")")
142+
cls.name <#> "." <#> fld <#> "(" <#> s.toString <#> ")"
140143
case BasicOp(name: Str, args) =>
141-
raw(name) <#> raw("(") <#> raw(args |> showArguments) <#> raw(")")
144+
name <#> "(" <#> (args |> showArguments) <#> ")"
142145

143146
def mapName(f: Name => Name): Expr = this match
144147
case Ref(name) => Ref(f(name))
@@ -221,67 +224,69 @@ enum Node:
221224
val names_copy = names.map(_.copy)
222225
LetCall(names_copy, defn, args.map(_.mapNameOfTrivialExpr(_.trySubst(ctx))), body.copy(ctx ++ names_copy.map(x => x.str -> x)))
223226

224-
private def toDocument: Document = this match
225-
case Result(res) => raw(res |> showArguments) <:> raw(s"-- $tag")
227+
private def toDocument: Document =
228+
given Conversion[String, Document] = raw
229+
this match
230+
case Result(res) => (res |> showArguments) <:> s"-- $tag"
226231
case Jump(jp, args) =>
227-
raw("jump")
228-
<:> raw(jp.name)
229-
<#> raw("(")
230-
<#> raw(args |> showArguments)
231-
<#> raw(")")
232-
<:> raw(s"-- $tag")
232+
"jump"
233+
<:> jp.name
234+
<#> "("
235+
<#> (args |> showArguments)
236+
<#> ")"
237+
<:> s"-- $tag"
233238
case Case(x, Ls((tpat, tru), (fpat, fls)), N) if tpat.isTrue && fpat.isFalse =>
234-
val first = raw("if") <:> raw(x.toString) <:> raw(s"-- $tag")
235-
val tru2 = indent(stack(raw("true") <:> raw ("=>"), tru.toDocument |> indent))
236-
val fls2 = indent(stack(raw("false") <:> raw ("=>"), fls.toDocument |> indent))
239+
val first = "if" <:> x.toString <:> s"-- $tag"
240+
val tru2 = indent(stack("true" <:> "=>", tru.toDocument |> indent))
241+
val fls2 = indent(stack("false" <:> "=>", fls.toDocument |> indent))
237242
Document.Stacked(Ls(first, tru2, fls2))
238243
case Case(x, cases, default) =>
239-
val first = raw("case") <:> raw(x.toString) <:> raw("of") <:> raw(s"-- $tag")
244+
val first = "case" <:> x.toString <:> "of" <:> s"-- $tag"
240245
val other = cases flatMap {
241246
case (pat, node) =>
242-
Ls(raw(pat.toString) <:> raw("=>"), node.toDocument |> indent)
247+
Ls(pat.toString <:> "=>", node.toDocument |> indent)
243248
}
244249
default match
245250
case N => stack(first, (Document.Stacked(other) |> indent))
246251
case S(dc) =>
247-
val default = Ls(raw("_") <:> raw("=>"), dc.toDocument |> indent)
252+
val default = Ls("_" <:> "=>", dc.toDocument |> indent)
248253
stack(first, (Document.Stacked(other ++ default) |> indent))
249254
case LetExpr(x, expr, body) =>
250255
stack(
251-
raw("let")
252-
<:> raw(x.toString)
253-
<:> raw("=")
256+
"let"
257+
<:> x.toString
258+
<:> "="
254259
<:> expr.toDocument
255-
<:> raw("in")
256-
<:> raw(s"-- $tag"),
260+
<:> "in"
261+
<:> s"-- $tag",
257262
body.toDocument)
258263
case LetMethodCall(xs, cls, method, args, body) =>
259264
stack(
260-
raw("let")
261-
<:> raw(xs.map(_.toString).mkString(","))
262-
<:> raw("=")
263-
<:> raw(cls.name)
264-
<#> raw(".")
265-
<#> raw(method.toString)
266-
<#> raw("(")
267-
<#> raw(args.map{ x => x.toString }.mkString(","))
268-
<#> raw(")")
269-
<:> raw("in")
270-
<:> raw(s"-- $tag"),
265+
"let"
266+
<:> xs.map(_.toString).mkString(",")
267+
<:> "="
268+
<:> cls.name
269+
<#> "."
270+
<#> method.toString
271+
<#> "("
272+
<#> args.map{ x => x.toString }.mkString(",")
273+
<#> ")"
274+
<:> "in"
275+
<:> s"-- $tag",
271276
body.toDocument)
272277
case LetCall(xs, defn, args, body) =>
273278
stack(
274-
raw("let*")
275-
<:> raw("(")
276-
<#> raw(xs.map(_.toString).mkString(","))
277-
<#> raw(")")
278-
<:> raw("=")
279-
<:> raw(defn.name)
280-
<#> raw("(")
281-
<#> raw(args.map{ x => x.toString }.mkString(","))
282-
<#> raw(")")
283-
<:> raw("in")
284-
<:> raw(s"-- $tag"),
279+
"let*"
280+
<:> "("
281+
<#> xs.map(_.toString).mkString(",")
282+
<#> ")"
283+
<:> "="
284+
<:> defn.name
285+
<#> "("
286+
<#> args.map{ x => x.toString }.mkString(",")
287+
<#> ")"
288+
<:> "in"
289+
<:> s"-- $tag",
285290
body.toDocument)
286291

287292
def locMarker: LocMarker =
@@ -484,44 +489,46 @@ enum LocMarker:
484489
case MLetCall(names: Ls[Str], defn: Str, args: Ls[LocMarker])
485490
var tag = DefnTag(-1)
486491

487-
def toDocument: Document = this match
488-
case MResult(res) => raw("...")
492+
def toDocument: Document =
493+
given Conversion[String, Document] = raw
494+
this match
495+
case MResult(res) => "..."
489496
case MJump(jp, args) =>
490-
raw("jump")
491-
<:> raw(jp)
492-
<:> raw("...")
497+
"jump"
498+
<:> jp
499+
<:> "..."
493500
case MCase(x, Ls(tpat, fpat), false) if tpat.isTrue && fpat.isFalse =>
494-
raw("if") <:> raw(x.toString) <:> raw("...")
501+
"if" <:> x.toString <:> "..."
495502
case MCase(x, cases, default) =>
496-
raw("case") <:> raw(x.toString) <:> raw("of") <:> raw("...")
503+
"case" <:> x.toString <:> "of" <:> "..."
497504
case MLetExpr(x, expr) =>
498-
raw("let")
499-
<:> raw(x.toString)
500-
<:> raw("=")
501-
<:> raw("...")
505+
"let"
506+
<:> x.toString
507+
<:> "="
508+
<:> "..."
502509
case MLetMethodCall(xs, cls, method, args) =>
503-
raw("let")
504-
<:> raw(xs.map(_.toString).mkString(","))
505-
<:> raw("=")
506-
<:> raw(cls.name)
507-
<:> raw(".")
508-
<:> raw(method)
509-
<:> raw("...")
510+
"let"
511+
<:> xs.map(_.toString).mkString(",")
512+
<:> "="
513+
<:> cls.name
514+
<:> "."
515+
<:> method
516+
<:> "..."
510517
case MLetCall(xs, defn, args) =>
511-
raw("let*")
512-
<:> raw("(")
513-
<#> raw(xs.map(_.toString).mkString(","))
514-
<#> raw(")")
515-
<:> raw("=")
516-
<:> raw(defn)
517-
<:> raw("...")
518-
case MRef(s) => s.toString |> raw
519-
case MLit(IntLit(lit)) => s"$lit" |> raw
520-
case MLit(DecLit(lit)) => s"$lit" |> raw
521-
case MLit(StrLit(lit)) => s"$lit" |> raw
522-
case MLit(CharLit(lit)) => s"$lit" |> raw
523-
case MLit(UnitLit(undefinedOrNull)) => (if undefinedOrNull then "undefined" else "null") |> raw
524-
case _ => raw("...")
518+
"let*"
519+
<:> "("
520+
<#> xs.map(_.toString).mkString(",")
521+
<#> ")"
522+
<:> "="
523+
<:> defn
524+
<:> "..."
525+
case MRef(s) => s.toString
526+
case MLit(IntLit(lit)) => s"$lit"
527+
case MLit(DecLit(lit)) => s"$lit"
528+
case MLit(StrLit(lit)) => s"$lit"
529+
case MLit(CharLit(lit)) => s"$lit"
530+
case MLit(UnitLit(undefinedOrNull)) => if undefinedOrNull then "undefined" else "null"
531+
case _ => "..."
525532

526533
def show = s"$tag-" + toDocument.print
527534

0 commit comments

Comments
 (0)