Skip to content

Change syntax of splices and quotes #5918

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

Merged
merged 26 commits into from
Feb 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ace1883
Use `$` for splices in syntax and parsing
odersky Feb 13, 2019
05e5309
Update bootstrap library to new syntax
odersky Feb 14, 2019
3257b9d
Update tests to new syntax
odersky Feb 14, 2019
6faa0df
Use nme.UNARY_~ directly
odersky Feb 14, 2019
a067989
Fix some tests
nicolasstucki Feb 18, 2019
eee09d4
Fix more tests
nicolasstucki Feb 18, 2019
e2086da
Fix ${ 'x } -> x and '{ $x } -> x transformation
nicolasstucki Feb 18, 2019
26ca221
Add regression tests
nicolasstucki Feb 18, 2019
d749bd9
Adapt more tests
nicolasstucki Feb 18, 2019
5bc50de
Change id syntax
odersky Feb 18, 2019
c6cc337
Drop Block(...) around quoted and spliced expressions where possible
odersky Feb 18, 2019
7a71580
Fix '{}
nicolasstucki Feb 18, 2019
6bcd70c
Readapt tests
nicolasstucki Feb 18, 2019
8b0ba22
Fix and adapt tests
nicolasstucki Feb 18, 2019
bc5e068
Rename $MaxSpecialized to MaxSpecialized
nicolasstucki Feb 19, 2019
cc279c8
Revert changes in tests/pos/t4579.scala
nicolasstucki Feb 19, 2019
7d39a1e
Update printer
nicolasstucki Feb 19, 2019
e23bf3c
Avoid accidental conversion from ${ x } to x.unary_~ and back
nicolasstucki Feb 19, 2019
94e3a03
Change use of `$` for splices in syntax and parsing
odersky Feb 19, 2019
bd17841
Update docs to new syntax
odersky Feb 19, 2019
b32a4a8
Fix quote parsing
odersky Feb 19, 2019
3846e49
Fix test
odersky Feb 19, 2019
ad3f519
Revert stdLib213 change after rebase
nicolasstucki Feb 20, 2019
b560392
Adapt i5954 tests
nicolasstucki Feb 21, 2019
2ad3310
Change `splice` member to `$splice`
nicolasstucki Feb 21, 2019
4b0c234
Adapt `splice` to `$splice` in test
nicolasstucki Feb 22, 2019
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 bench/tests/power-macro/PowerMacro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import scala.quoted.Expr

object PowerMacro {

inline def power(inline n: Long, x: Double) = ~powerCode(n, '(x))
inline def power(inline n: Long, x: Double) = ${powerCode(n, '{x})}

def powerCode(n: Long, x: Expr[Double]): Expr[Double] =
if (n == 0) '(1.0)
else if (n % 2 == 0) '{ val y = ~x * ~x; ~powerCode(n / 2, '(y)) }
else '{ ~x * ~powerCode(n - 1, x) }
if (n == 0) '{1.0}
else if (n % 2 == 0) '{ val y = $x * $x; ${powerCode(n / 2, '{y})} }
else '{ $x * ${powerCode(n - 1, x)} }

}
2 changes: 1 addition & 1 deletion community-build/community-projects/scalatest
Submodule scalatest updated 0 files
12 changes: 8 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1313,11 +1313,15 @@ object desugar {
val desugared = tree match {
case SymbolLit(str) =>
Literal(Constant(scala.Symbol(str)))
case Quote(expr) =>
if (expr.isType)
TypeApply(ref(defn.QuotedType_applyR), List(expr))
case Quote(t) =>
if (t.isType)
TypeApply(ref(defn.QuotedType_applyR), List(t))
else
Apply(ref(defn.QuotedExpr_applyR), expr)
Apply(ref(defn.QuotedExpr_applyR), t)
case Splice(expr) =>
Select(expr, nme.splice)
case TypSplice(expr) =>
Select(expr, tpnme.splice)
case InterpolatedString(id, segments) =>
val strs = segments map {
case ts: Thicket => ts.trees.head
Expand Down
41 changes: 28 additions & 13 deletions compiler/src/dotty/tools/dotc/ast/untpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {

abstract class OpTree(implicit @constructorOnly src: SourceFile) extends Tree {
def op: Ident
override def isTerm: Boolean = op.name.isTermName
override def isType: Boolean = op.name.isTypeName
override def isTerm: Boolean = op.isTerm
override def isType: Boolean = op.isType
}

/** A typed subtree of an untyped tree needs to be wrapped in a TypedSplice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nitpick 🙈, TypSplice.

Copy link
Contributor

@nicolasstucki nicolasstucki Feb 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is actually a TypeSplice which is a completely different concept 🙉. That one wraps a tree that is typed inside an untyped tree.

Expand Down Expand Up @@ -84,10 +84,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {

case class InfixOp(left: Tree, op: Ident, right: Tree)(implicit @constructorOnly src: SourceFile) extends OpTree
case class PostfixOp(od: Tree, op: Ident)(implicit @constructorOnly src: SourceFile) extends OpTree
case class PrefixOp(op: Ident, od: Tree)(implicit @constructorOnly src: SourceFile) extends OpTree {
override def isType: Boolean = op.isType
override def isTerm: Boolean = op.isTerm
}
case class PrefixOp(op: Ident, od: Tree)(implicit @constructorOnly src: SourceFile) extends OpTree
case class Parens(t: Tree)(implicit @constructorOnly src: SourceFile) extends ProxyTree {
def forwardTo: Tree = t
}
Expand All @@ -96,7 +93,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
override def isType: Boolean = !isTerm
}
case class Throw(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class Quote(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class Quote(t: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class Splice(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class TypSplice(expr: Tree)(implicit @constructorOnly src: SourceFile) extends TypTree
case class DoWhile(body: Tree, cond: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class ForYield(enums: List[Tree], expr: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
case class ForDo(enums: List[Tree], body: Tree)(implicit @constructorOnly src: SourceFile) extends TermTree
Expand Down Expand Up @@ -493,9 +492,17 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case tree: Throw if expr eq tree.expr => tree
case _ => finalize(tree, untpd.Throw(expr)(tree.source))
}
def Quote(tree: Tree)(expr: Tree)(implicit ctx: Context): TermTree = tree match {
case tree: Quote if expr eq tree.expr => tree
case _ => finalize(tree, untpd.Quote(expr)(tree.source))
def Quote(tree: Tree)(t: Tree)(implicit ctx: Context): Tree = tree match {
case tree: Quote if t eq tree.t => tree
case _ => finalize(tree, untpd.Quote(t)(tree.source))
}
def Splice(tree: Tree)(expr: Tree)(implicit ctx: Context): Tree = tree match {
case tree: Splice if expr eq tree.expr => tree
case _ => finalize(tree, untpd.Splice(expr)(tree.source))
}
def TypSplice(tree: Tree)(expr: Tree)(implicit ctx: Context): Tree = tree match {
case tree: TypSplice if expr eq tree.expr => tree
case _ => finalize(tree, untpd.TypSplice(expr)(tree.source))
}
def DoWhile(tree: Tree)(body: Tree, cond: Tree)(implicit ctx: Context): TermTree = tree match {
case tree: DoWhile if (body eq tree.body) && (cond eq tree.cond) => tree
Expand Down Expand Up @@ -557,8 +564,12 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
cpy.Tuple(tree)(transform(trees))
case Throw(expr) =>
cpy.Throw(tree)(transform(expr))
case Quote(expr) =>
cpy.Quote(tree)(transform(expr))
case Quote(t) =>
cpy.Quote(tree)(transform(t))
case Splice(expr) =>
cpy.Splice(tree)(transform(expr))
case TypSplice(expr) =>
cpy.TypSplice(tree)(transform(expr))
case DoWhile(body, cond) =>
cpy.DoWhile(tree)(transform(body), transform(cond))
case ForYield(enums, expr) =>
Expand Down Expand Up @@ -606,7 +617,11 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
this(x, trees)
case Throw(expr) =>
this(x, expr)
case Quote(expr) =>
case Quote(t) =>
this(x, t)
case Splice(expr) =>
this(x, expr)
case TypSplice(expr) =>
this(x, expr)
case DoWhile(body, cond) =>
this(this(x, body), cond)
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -707,16 +707,16 @@ class Definitions {
def QuotedExprModule(implicit ctx: Context): Symbol = QuotedExprClass.companionModule
lazy val QuotedExpr_applyR: TermRef = QuotedExprModule.requiredMethodRef(nme.apply)
def QuotedExpr_apply(implicit ctx: Context): Symbol = QuotedExpr_applyR.symbol
lazy val QuotedExpr_~ : TermSymbol = QuotedExprClass.requiredMethod(nme.UNARY_~)
lazy val QuotedExpr_splice : TermSymbol = QuotedExprClass.requiredMethod(nme.splice)

lazy val QuotedExprsModule: TermSymbol = ctx.requiredModule("scala.quoted.Exprs")
def QuotedExprsClass(implicit ctx: Context): ClassSymbol = QuotedExprsModule.asClass

lazy val QuotedTypeType: TypeRef = ctx.requiredClassRef("scala.quoted.Type")
def QuotedTypeClass(implicit ctx: Context): ClassSymbol = QuotedTypeType.symbol.asClass

lazy val QuotedType_spliceR: TypeRef = QuotedTypeClass.requiredType(tpnme.UNARY_~).typeRef
def QuotedType_~ : Symbol = QuotedType_spliceR.symbol
lazy val QuotedType_spliceR: TypeRef = QuotedTypeClass.requiredType(tpnme.splice).typeRef
def QuotedType_splice : Symbol = QuotedType_spliceR.symbol

lazy val QuotedTypeModuleType: TermRef = ctx.requiredModuleRef("scala.quoted.Type")
def QuotedTypeModule(implicit ctx: Context): Symbol = QuotedTypeModuleType.symbol
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/StdNames.scala
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ object StdNames {
val setSymbol: N = "setSymbol"
val setType: N = "setType"
val setTypeSignature: N = "setTypeSignature"
val splice: N = "splice"
val splice: N = "$splice"
val staticClass : N = "staticClass"
val staticModule : N = "staticModule"
val staticPackage : N = "staticPackage"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ object PickledQuotes {
def pickleQuote(tree: Tree)(implicit ctx: Context): scala.runtime.quoted.Unpickler.Pickled = {
if (ctx.reporter.hasErrors) Nil
else {
assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'(~x)` which should be optimized to `x`
assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'{$x}` which should be optimized to `x`
val pickled = pickle(tree)
TastyString.pickle(pickled)
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/parsing/CharArrayReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ abstract class CharArrayReader { self =>
/** A new reader that takes off at the current character position */
def lookaheadReader(): CharArrayLookaheadReader = new CharArrayLookaheadReader

def lookaheadChar(): Char = lookaheadReader().getc()

class CharArrayLookaheadReader extends CharArrayReader {
val buf: Array[Char] = self.buf
charOffset = self.charOffset
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/parsing/JavaScanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dotc
package parsing

import core.Contexts._
import core.Names.SimpleName
import Scanners._
import util.SourceFile
import JavaTokens._
Expand All @@ -13,8 +14,10 @@ object JavaScanners {

class JavaScanner(source: SourceFile, override val startFrom: Offset = 0)(implicit ctx: Context) extends ScannerCommon(source)(ctx) {

def toToken(idx: Int): Token =
def toToken(name: SimpleName): Token = {
val idx = name.start
if (idx >= 0 && idx <= lastKeywordStart) kwArray(idx) else IDENTIFIER
}

private class JavaTokenData0 extends TokenData

Expand Down
Loading