AndreVanDelft / scala

The SubScript extension to the Scala programming language
http://www.subscript-lang.org/
12 stars 1 forks source link

The compiler can't digest negative integers in the script variables assignments #53

Closed anatoliykmetyuk closed 9 years ago

anatoliykmetyuk commented 9 years ago

Consider the following script:

  def script live = (
    val i: Int = -1
    {println(i)}
  )

On compilation, it will fail the compiler with the following exception (first few lines):

[ant:scalac] java.lang.NullPointerException
[ant:scalac]    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$90.apply(Typers.scala:4443)
[ant:scalac]    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$90.apply(Typers.scala:4443)
[ant:scalac]    at scala.collection.LinearSeqOptimized$class.forall(LinearSeqOptimized.scala:69)
[ant:scalac]    at scala.collection.immutable.List.forall(List.scala:83)
[ant:scalac]    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$onError$2(Typers.scala:4443)
[ant:scalac]    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$tryTypedApply$1$2.apply(Typers.scala:4467)
[ant:scalac]    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$tryTypedApply$1$2.apply(Typers.scala:4467)

If we rewrite it without specifying the type, like this:

  def script live = (
    val i = -1
    {println(i)}
  )

then before the exception we'll get the following error:

[ant:scalac] /Users/anatolii/Projects/SSPolygon/src/main/scala/Main.scala:20: error: not found: value -
[ant:scalac]     val i = -1
[ant:scalac]             ^

Positive integers work correctly.

A workaround to the problem is to enclose the negative integer into parentheses:

  def script live = (
    val i = (-1)
    {println(i)}
  )
anatoliykmetyuk commented 9 years ago

Also, roughly same thing happens when trying to evaluate a mathematical expression in a script variable definition:

val i = 2 * 2
AndreVanDelft commented 9 years ago

This is because in the current syntax specification the RHS of a local variable initializer is a simpleValueExpression:

simpleValueExpression   = "_"
                          + literal
                          + "new" (classTemplate + templateBody)
                          + ( "here"
                            + currentInstanceExpression
                            + identifier . "." currentInstanceExpression )
                            (.. "." identifier)

So operator symbols such as - and * are not allowed. But maybe we should change this, just like newlines may have to become a different kind of whitespace than spaces and tabs. A val/var declaration is always an operand of a sequence operator, and not the last operand there. Maybe such a declaration should be terminated by a semicolon or newline, so that the RHS may become any Scala value expression.

AndreVanDelft commented 9 years ago

A var/val initializer expression may require that an annotation directive be run first. Then this annotation should be placed just before the expression, rather than before the var/val keyword. E.g.,

val selectionResult = @gui: fileChooser.showSaveDialog(destinationFileLabel)

This way it will be easier to enforce that after the declaration a sequential operator follows.

AndreVanDelft commented 9 years ago

Solved