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

View File

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

View File

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