Skip to content

Commit

Permalink
correctly parse enum values
Browse files Browse the repository at this point in the history
enum values can be expressions including
- unary operators
- binary operators
- string and number literals
- parenthesis
- identifiers

See:
https://github.com/microsoft/TypeScript/blob/master/doc/spec.md#92-enum-members
https://github.com/microsoft/TypeScript/blob/master/doc/spec.md#419-binary-operators

Note:
this implementation performs a flat parse that neither
handles expression-tree-building nor operator precedences.

Note:
This commit removes the minus from the NumericLit-token and
parses it explicitly in TSDefParser.numberLiteral
  • Loading branch information
SrTobi committed Jun 16, 2019
1 parent 1a9a723 commit 91adb75
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 5 deletions.
8 changes: 8 additions & 0 deletions samples/valueExpression.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare module valueExpression {
export enum Color {
A = 3 + 3,
B = "test" + "teste",
C = 1 << 3,
D = 10**2+1*8- - -3/3>>2<<3>>>+19%~~~3+ + +9
}
}
27 changes: 27 additions & 0 deletions samples/valueExpression.d.ts.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

import scala.scalajs.js
import js.annotation._
import js.|

package valueExpression {

package valueExpression {

@js.native
sealed trait Color extends js.Object {
}

@js.native
@JSGlobal("valueExpression.Color")
object Color extends js.Object {
var A: Color = js.native
var B: Color = js.native
var C: Color = js.native
var D: Color = js.native
@JSBracketAccess
def apply(value: Color): String = js.native
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class TSDefLexical extends Lexical with StdTokens with ImplicitConversions {
digits => digits.foldLeft(0L)(_ * 8 + _).toString
}
)
| opt('-') ~ stringOf1(digit) ~ opt(stringOf1('.', digit)) ^^ {
case sign ~ part1 ~ part2 => sign.getOrElse("") + part1 + (part2.getOrElse(""))
| stringOf1(digit) ~ opt(stringOf1('.', digit)) ^^ {
case part1 ~ part2 => part1 + part2.getOrElse("")
}
) ^^ NumericLit

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ class TSDefParser extends StdTokenParsers with ImplicitConversions {
"...", "=>"
)

// for value expressions
val binaryValueOperators = Set(
"+", "-", "*", "/", "**", "%",
"<<", ">>>", ">>", "&", "|", "^"
)
lexical.delimiters ++= binaryValueOperators

val unaryValueOperators = Set(
"+", "-", "~"
)
lexical.delimiters ++= unaryValueOperators

def parseDefinitions(input: Reader[Char]) =
phrase(ambientDeclarations)(new lexical.Scanner(input))

Expand Down Expand Up @@ -105,7 +117,20 @@ class TSDefParser extends StdTokenParsers with ImplicitConversions {
"enum" ~> typeName ~ ("{" ~> ambientEnumBody <~ "}") ^^ EnumDecl

lazy val ambientEnumBody: Parser[List[Ident]] =
repsep(identifier <~ opt("=" ~ (numericLit | stringLit) ), ",") <~ opt(",")
repsep(identifier <~ opt("=" ~! valueExpression), ",") <~ opt(",")

lazy val valueExpression: Parser[_] =
rep1sep(success() ~>! rep(unaryValueOperator) ~
(numericLit | stringLit | identifierName | parenthesizedValueExpression), binaryValueOperator)

lazy val parenthesizedValueExpression =
"(" ~! valueExpression ~ ")"

lazy val binaryValueOperator =
elem("binary operator", tok => binaryValueOperators.contains(tok.chars))

lazy val unaryValueOperator =
elem("unary operator", tok => unaryValueOperators.contains(tok.chars))

lazy val ambientClassDecl: Parser[DeclTree] =
(abstractModifier <~ "class") ~ typeName ~ tparams ~ classParent ~ classImplements ~ memberBlock <~ opt(";") ^^ {
Expand Down Expand Up @@ -342,8 +367,8 @@ class TSDefParser extends StdTokenParsers with ImplicitConversions {
stringLit ^^ StringLiteral

lazy val numberLiteral: Parser[NumberLiteral] =
numericLit ^^ { s =>
val d = s.toDouble
opt("-") ~ numericLit ^^ { case minus ~ s =>
val d = (minus.getOrElse("") + s).toDouble
if (!s.contains(".") && d.isValidInt) {
IntLiteral(d.toInt)
} else {
Expand Down

0 comments on commit 91adb75

Please sign in to comment.