feat: add unary operators and variable assignment with precedence handling
Implement unary negation for numbers and logical not for booleans, introduce PREC_ASSIGNMENT and PREC_UNARY precedence levels, refactor parse functions to accept allowAssignment parameter, add assignment tests for global/local/chained/error cases, and update if-syntax to support statement branches and assignment in conditions.
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
var a = "before"
|
||||
io.write(a) // expect: before
|
||||
|
||||
a = "after"
|
||||
io.write(a) // expect: after
|
||||
|
||||
io.write(a = "arg") // expect: arg
|
||||
io.write(a) // expect: arg
|
||||
@@ -0,0 +1,10 @@
|
||||
fn {
|
||||
var a = "before"
|
||||
io.write(a) // expect: before
|
||||
|
||||
a = "after"
|
||||
io.write(a) // expect: after
|
||||
|
||||
io.write(a = "arg") // expect: arg
|
||||
io.write(a) // expect: arg
|
||||
}.call
|
||||
@@ -0,0 +1,11 @@
|
||||
// Chained assignment.
|
||||
var a = "a"
|
||||
var b = "b"
|
||||
a = b = "chain"
|
||||
io.write(a) // expect: chain
|
||||
io.write(a) // expect: chain
|
||||
|
||||
// Assignment on RHS of variable.
|
||||
var c = a = "var"
|
||||
io.write(a) // expect: var
|
||||
io.write(c) // expect: var
|
||||
@@ -0,0 +1,2 @@
|
||||
var a = "a"
|
||||
(a) = "value" // expect error
|
||||
@@ -0,0 +1,3 @@
|
||||
var a = "a"
|
||||
var b = "b"
|
||||
a + b = "value" // expect error
|
||||
@@ -0,0 +1,3 @@
|
||||
var a = "a"
|
||||
var b = "b"
|
||||
b is a = "value" // expect error
|
||||
@@ -0,0 +1,2 @@
|
||||
var a = "a"
|
||||
!a = "value" // expect error
|
||||
@@ -0,0 +1 @@
|
||||
unknown = "what" // expect error
|
||||
@@ -0,0 +1,3 @@
|
||||
io.write(!true) // expect: false
|
||||
io.write(!false) // expect: true
|
||||
io.write(!!true) // expect: true
|
||||
@@ -23,6 +23,9 @@ io.write(false == 2 <= 1) // expect: true
|
||||
// >= has higher precedence than ==.
|
||||
io.write(false == 1 >= 2) // expect: true
|
||||
|
||||
// Unary - has lower precedence than ..
|
||||
io.write(-"abc".count) // expect: -3
|
||||
|
||||
// TODO(bob): %, associativity.
|
||||
|
||||
// Using () for grouping.
|
||||
|
||||
+17
-3
@@ -6,11 +6,25 @@ if (false) io.write("bad")
|
||||
if (true) io.write("good") else io.write("bad") // expect: good
|
||||
if (false) io.write("bad") else io.write("good") // expect: good
|
||||
|
||||
// Allow statements for then branch.
|
||||
if (true) { io.write("block") } // expect: block
|
||||
if (true) if (true) io.write("double") // expect: double
|
||||
|
||||
// Allow statements for else branch.
|
||||
if (false) null else { io.write("block") } // expect: block
|
||||
if (false) null else if (true) io.write("double") // expect: double
|
||||
|
||||
// Return the 'then' expression if the condition is true.
|
||||
io.write(if (true) "good") // expect: good
|
||||
var a = if (true) "good"
|
||||
io.write(a) // expect: good
|
||||
|
||||
// Return null if the condition is false and there is no else.
|
||||
io.write(if (false) "bad") // expect: null
|
||||
var b = if (false) "bad"
|
||||
io.write(b) // expect: null
|
||||
|
||||
// Return the 'else' expression if the condition is false.
|
||||
io.write(if (false) "bad" else "good") // expect: good
|
||||
var c = if (false) "bad" else "good"
|
||||
io.write(c) // expect: good
|
||||
|
||||
// Assignment in if condition.
|
||||
if (a = true) io.write(a) // expect: true
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
// Infix.
|
||||
io.write(5 - 3) // expect: 2
|
||||
io.write(3.1 - 0.24) // expect: 2.86
|
||||
io.write(3 - 2 - 1) // expect: 0
|
||||
|
||||
// Unary negation.
|
||||
var a = 3
|
||||
io.write(-a) // expect: -3
|
||||
|
||||
// TODO(bob): Unsupported RHS types.
|
||||
|
||||
Reference in New Issue
Block a user