syntax: parse "not not x"

+Test

Change-Id: I888b3dbe4ee4a73702adb4182da2a35286ad10dc
diff --git a/syntax/parse.go b/syntax/parse.go
index b733b8b..2bcc6f2 100644
--- a/syntax/parse.go
+++ b/syntax/parse.go
@@ -538,7 +538,7 @@
 	// expr = NOT expr
 	if p.tok == NOT && prec == int(precedence[NOT]) {
 		pos := p.nextToken()
-		x := p.parseTestPrec(prec + 1)
+		x := p.parseTestPrec(prec)
 		return &UnaryExpr{
 			OpPos: pos,
 			Op:    NOT,
@@ -591,16 +591,16 @@
 // Unary MINUS, unary PLUS, and TILDE have higher precedence so are handled in parsePrimary.
 // See https://github.com/google/skylark/blob/master/doc/spec.md#binary-operators
 var preclevels = [...][]Token{
-	{OR},  // or
-	{AND}, // and
-	{NOT}, // not (unary)
+	{OR},                                   // or
+	{AND},                                  // and
+	{NOT},                                  // not (unary)
 	{EQL, NEQ, LT, GT, LE, GE, IN, NOT_IN}, // == != < > <= >= in not in
-	{PIPE},                             // |
-	{CIRCUMFLEX},                       // ^
-	{AMP},                              // &
-	{LTLT, GTGT},                       // << >>
-	{MINUS, PLUS},                      // -
-	{STAR, PERCENT, SLASH, SLASHSLASH}, // * % / //
+	{PIPE},                                 // |
+	{CIRCUMFLEX},                           // ^
+	{AMP},                                  // &
+	{LTLT, GTGT},                           // << >>
+	{MINUS, PLUS},                          // -
+	{STAR, PERCENT, SLASH, SLASHSLASH},     // * % / //
 }
 
 func init() {
@@ -759,7 +759,7 @@
 //          | '[' ...                    // list literal or comprehension
 //          | '{' ...                    // dict literal or comprehension
 //          | '(' ...                    // tuple or parenthesized expression
-//          | ('-'|'+') primary_with_suffix
+//          | ('-'|'+'|'~') primary_with_suffix
 func (p *parser) parsePrimary() Expr {
 	switch p.tok {
 	case IDENT:
@@ -805,8 +805,7 @@
 			Rparen: rparen,
 		}
 
-	case MINUS, PLUS, TILDE:
-		// unary minus/plus/tilde:
+	case MINUS, PLUS, TILDE: // unary
 		tok := p.tok
 		pos := p.nextToken()
 		x := p.parsePrimaryWithSuffix()
diff --git a/testdata/bool.sky b/testdata/bool.sky
index 19de9c2..4e6e622 100644
--- a/testdata/bool.sky
+++ b/testdata/bool.sky
@@ -5,17 +5,20 @@
 # truth
 assert.true(True)
 assert.true(not False)
+assert.true(not not True)
 
 # bool conversion
-assert.eq([bool(), bool(1), bool(0), bool("hello"), bool("")],
-          [False, True, False, True, False])
+assert.eq(
+    [bool(), bool(1), bool(0), bool("hello"), bool("")],
+    [False, True, False, True, False],
+)
 
 # comparison
 assert.true(None == None)
 assert.true(None != False)
 assert.true(None != True)
-assert.eq(1==1, True)
-assert.eq(1==2, False)
+assert.eq(1 == 1, True)
+assert.eq(1 == 2, False)
 assert.true(False == False)
 assert.true(True == True)
 
@@ -34,10 +37,11 @@
 
 # short-circuit evaluation of 'and' and 'or':
 # 'or' yields the first true operand, or the last if all are false.
-assert.eq(0 or "" or [] or 0, 0) 
-assert.eq(0 or "" or [] or 123 or 1/0, 123) 
-assert.fails(lambda: 0 or "" or [] or 0 or 1/0, "division by zero")
+assert.eq(0 or "" or [] or 0, 0)
+assert.eq(0 or "" or [] or 123 or 1 / 0, 123)
+assert.fails(lambda : 0 or "" or [] or 0 or 1 / 0, "division by zero")
+
 # 'and' yields the first false operand, or the last if all are true.
-assert.eq(1 and "a" and [1] and 123, 123) 
-assert.eq(1 and "a" and [1] and 0 and 1/0, 0) 
-assert.fails(lambda: 1 and "a" and [1] and 123 and 1/0, "division by zero")
+assert.eq(1 and "a" and [1] and 123, 123)
+assert.eq(1 and "a" and [1] and 0 and 1 / 0, 0)
+assert.fails(lambda : 1 and "a" and [1] and 123 and 1 / 0, "division by zero")