Parser & desugarer support for "in"

This commit is contained in:
Stanisław Barzowski 2017-08-22 13:42:46 -04:00 committed by Dave Cunningham
parent a4456d8ecf
commit b1427d563b
4 changed files with 40 additions and 9 deletions

View File

@ -162,6 +162,7 @@ const (
BopGreaterEq
BopLess
BopLessEq
BopIn
BopManifestEqual
BopManifestUnequal
@ -189,6 +190,7 @@ var bopStrings = []string{
BopGreaterEq: ">=",
BopLess: "<",
BopLessEq: "<=",
BopIn: "in",
BopManifestEqual: "==",
BopManifestUnequal: "!=",
@ -216,6 +218,7 @@ var BopMap = map[string]BinaryOp{
">=": BopGreaterEq,
"<": BopLess,
"<=": BopLessEq,
"in": BopIn,
"==": BopManifestEqual,
"!=": BopManifestUnequal,
@ -496,6 +499,12 @@ type SuperIndex struct {
Id *Identifier
}
// Represents the e in super construct.
type InSuper struct {
NodeBase
Index Node
}
// ---------------------------------------------------------------------------
type UnaryOp int

View File

@ -509,6 +509,11 @@ func desugar(astPtr *ast.Node, objLevel int) (err error) {
node.Id = nil
}
case *ast.InSuper:
err := desugar(&node.Index, objLevel)
if err != nil {
return err
}
case *ast.Unary:
err = desugar(&node.Expr, objLevel)
if err != nil {

View File

@ -43,6 +43,7 @@ var bopPrecedence = map[ast.BinaryOp]precedence{
ast.BopGreaterEq: 8,
ast.BopLess: 8,
ast.BopLessEq: 8,
ast.BopIn: 8,
ast.BopManifestEqual: 9,
ast.BopManifestUnequal: 9,
ast.BopBitwiseAnd: 10,
@ -940,6 +941,11 @@ func (p *parser) parse(prec precedence) (ast.Node, error) {
// with higher precedence, then return lhs and let lower levels deal with
// the operator.
switch p.peek().kind {
case tokenIn:
bop = ast.BopIn
if bopPrecedence[bop] != prec {
return lhs, nil
}
case tokenOperator:
_ = "breakpoint"
if p.peek().data == ":" {
@ -1069,15 +1075,23 @@ func (p *parser) parse(prec precedence) (ast.Node, error) {
Right: obj,
}
default:
rhs, err := p.parse(prec - 1)
if err != nil {
return nil, err
}
lhs = &ast.Binary{
NodeBase: ast.NewNodeBaseLoc(locFromTokenAST(begin, rhs)),
Left: lhs,
Op: bop,
Right: rhs,
if op.kind == tokenIn && p.peek().kind == tokenSuper {
super := p.pop()
lhs = &ast.InSuper{
NodeBase: ast.NewNodeBaseLoc(locFromTokens(begin, super)),
Index: lhs,
}
} else {
rhs, err := p.parse(prec - 1)
if err != nil {
return nil, err
}
lhs = &ast.Binary{
NodeBase: ast.NewNodeBaseLoc(locFromTokenAST(begin, rhs)),
Left: lhs,
Op: bop,
Right: rhs,
}
}
}
}

View File

@ -107,6 +107,9 @@ var tests = []string{
`[][:1:1]`,
`[][1::1]`,
`[][1:1:1]`,
`a in b`,
`{ x: if "opt" in super then "x" else "y" }`,
}
func TestParser(t *testing.T) {