mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-18 13:49:59 +01:00
Reorganize trailing comma code a bit.
- Split out syntax error tests. - Avoid redundant handling of empty literals.
This commit is contained in:
@ -230,8 +230,10 @@ class Test:
|
|||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
|
|
||||||
def fail(self, message, *args, **kwargs):
|
def fail(self, message, *args):
|
||||||
self.failures.append(message.format(*args, **kwargs))
|
if args:
|
||||||
|
message = message.format(*args)
|
||||||
|
self.failures.append(message)
|
||||||
|
|
||||||
|
|
||||||
def color_text(text, color):
|
def color_text(text, color):
|
||||||
|
|||||||
@ -1809,27 +1809,26 @@ static void list(Compiler* compiler, bool allowAssignment)
|
|||||||
// Instantiate a new list.
|
// Instantiate a new list.
|
||||||
callMethod(compiler, 0, "new()", 5);
|
callMethod(compiler, 0, "new()", 5);
|
||||||
|
|
||||||
|
ignoreNewlines(compiler);
|
||||||
|
|
||||||
// Compile the list elements. Each one compiles to a ".add()" call.
|
// Compile the list elements. Each one compiles to a ".add()" call.
|
||||||
if (peek(compiler) != TOKEN_RIGHT_BRACKET)
|
do
|
||||||
{
|
{
|
||||||
do
|
ignoreNewlines(compiler);
|
||||||
{
|
|
||||||
ignoreNewlines(compiler);
|
|
||||||
|
|
||||||
// List with trailing comma.
|
// Stop if we hit the end of the list.
|
||||||
if (peek(compiler) == TOKEN_RIGHT_BRACKET) break;
|
if (peek(compiler) == TOKEN_RIGHT_BRACKET) break;
|
||||||
|
|
||||||
// Push a copy of the list since the add() call will consume it.
|
// Push a copy of the list since the add() call will consume it.
|
||||||
emit(compiler, CODE_DUP);
|
emit(compiler, CODE_DUP);
|
||||||
|
|
||||||
// The element.
|
// The element.
|
||||||
expression(compiler);
|
expression(compiler);
|
||||||
callMethod(compiler, 1, "add(_)", 6);
|
callMethod(compiler, 1, "add(_)", 6);
|
||||||
|
|
||||||
// Discard the result of the add() call.
|
// Discard the result of the add() call.
|
||||||
emit(compiler, CODE_POP);
|
emit(compiler, CODE_POP);
|
||||||
} while (match(compiler, TOKEN_COMMA));
|
} while (match(compiler, TOKEN_COMMA));
|
||||||
}
|
|
||||||
|
|
||||||
// Allow newlines before the closing ']'.
|
// Allow newlines before the closing ']'.
|
||||||
ignoreNewlines(compiler);
|
ignoreNewlines(compiler);
|
||||||
@ -1850,31 +1849,28 @@ static void map(Compiler* compiler, bool allowAssignment)
|
|||||||
|
|
||||||
// Compile the map elements. Each one is compiled to just invoke the
|
// Compile the map elements. Each one is compiled to just invoke the
|
||||||
// subscript setter on the map.
|
// subscript setter on the map.
|
||||||
if (peek(compiler) != TOKEN_RIGHT_BRACE)
|
do
|
||||||
{
|
{
|
||||||
do
|
ignoreNewlines(compiler);
|
||||||
{
|
|
||||||
ignoreNewlines(compiler);
|
|
||||||
|
|
||||||
// Map with trailing comma.
|
// Stop if we hit the end of the map.
|
||||||
if (peek(compiler) == TOKEN_RIGHT_BRACE) break;
|
if (peek(compiler) == TOKEN_RIGHT_BRACE) break;
|
||||||
|
|
||||||
// Push a copy of the map since the subscript call will consume it.
|
// Push a copy of the map since the subscript call will consume it.
|
||||||
emit(compiler, CODE_DUP);
|
emit(compiler, CODE_DUP);
|
||||||
|
|
||||||
// The key.
|
// The key.
|
||||||
parsePrecedence(compiler, false, PREC_PRIMARY);
|
parsePrecedence(compiler, false, PREC_PRIMARY);
|
||||||
consume(compiler, TOKEN_COLON, "Expect ':' after map key.");
|
consume(compiler, TOKEN_COLON, "Expect ':' after map key.");
|
||||||
|
ignoreNewlines(compiler);
|
||||||
|
|
||||||
// The value.
|
// The value.
|
||||||
expression(compiler);
|
expression(compiler);
|
||||||
|
callMethod(compiler, 2, "[_]=(_)", 7);
|
||||||
|
|
||||||
callMethod(compiler, 2, "[_]=(_)", 7);
|
// Discard the result of the setter call.
|
||||||
|
emit(compiler, CODE_POP);
|
||||||
// Discard the result of the setter call.
|
} while (match(compiler, TOKEN_COMMA));
|
||||||
emit(compiler, CODE_POP);
|
|
||||||
} while (match(compiler, TOKEN_COMMA));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow newlines before the closing '}'.
|
// Allow newlines before the closing '}'.
|
||||||
ignoreNewlines(compiler);
|
ignoreNewlines(compiler);
|
||||||
|
|||||||
1
test/language/list/duplicate_comma.wren
Normal file
1
test/language/list/duplicate_comma.wren
Normal file
@ -0,0 +1 @@
|
|||||||
|
[1,,2] // expect error
|
||||||
1
test/language/list/duplicate_trailing_comma.wren
Normal file
1
test/language/list/duplicate_trailing_comma.wren
Normal file
@ -0,0 +1 @@
|
|||||||
|
[1,,] // expect error
|
||||||
1
test/language/list/empty_list_with_comma.wren
Normal file
1
test/language/list/empty_list_with_comma.wren
Normal file
@ -0,0 +1 @@
|
|||||||
|
[,] // expect error
|
||||||
@ -8,3 +8,17 @@ var list = [
|
|||||||
|
|
||||||
IO.print(list[0]) // expect: a
|
IO.print(list[0]) // expect: a
|
||||||
IO.print(list[1]) // expect: b
|
IO.print(list[1]) // expect: b
|
||||||
|
|
||||||
|
// Newline after trailing comma.
|
||||||
|
list = ["c",
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
IO.print(list[0]) // expect: c
|
||||||
|
|
||||||
|
// Newline in empty list.
|
||||||
|
list = [
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
IO.print(list.count) // expect: 0
|
||||||
|
|||||||
@ -1,12 +1,4 @@
|
|||||||
var list = [
|
var list = ["a", "b",]
|
||||||
"a",
|
|
||||||
"b",
|
|
||||||
]
|
|
||||||
|
|
||||||
IO.print(list[0]) // expect: a
|
IO.print(list[0]) // expect: a
|
||||||
IO.print(list[1]) // expect: b
|
IO.print(list[1]) // expect: b
|
||||||
|
|
||||||
// Invalid syntax
|
|
||||||
IO.print(new Fiber { Meta.eval("[,]") }.try()) // expect: Could not compile source code.
|
|
||||||
IO.print(new Fiber { Meta.eval("[1,,]") }.try()) // expect: Could not compile source code.
|
|
||||||
IO.print(new Fiber { Meta.eval("[1,,2]") }.try()) // expect: Could not compile source code.
|
|
||||||
|
|||||||
1
test/language/map/duplicate_comma.wren
Normal file
1
test/language/map/duplicate_comma.wren
Normal file
@ -0,0 +1 @@
|
|||||||
|
{1:1,,2:2} // expect error
|
||||||
1
test/language/map/duplicate_trailing_comma.wren
Normal file
1
test/language/map/duplicate_trailing_comma.wren
Normal file
@ -0,0 +1 @@
|
|||||||
|
{1:1,,} // expect error
|
||||||
1
test/language/map/empty_map_with_comma.wren
Normal file
1
test/language/map/empty_map_with_comma.wren
Normal file
@ -0,0 +1 @@
|
|||||||
|
{,} // expect error
|
||||||
27
test/language/map/newlines.wren
Normal file
27
test/language/map/newlines.wren
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Allow after '{', ':', and ',', and before ']'.
|
||||||
|
var map = {
|
||||||
|
|
||||||
|
"a":
|
||||||
|
|
||||||
|
"a value",
|
||||||
|
|
||||||
|
"b": "b value"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IO.print(map["a"]) // expect: a value
|
||||||
|
IO.print(map["b"]) // expect: b value
|
||||||
|
|
||||||
|
// Newline after trailing comma.
|
||||||
|
map = {"c": "c value",
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IO.print(map["c"]) // expect: c value
|
||||||
|
|
||||||
|
// Newline in empty map.
|
||||||
|
map = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IO.print(map.count) // expect: 0
|
||||||
@ -5,9 +5,3 @@ var map = {
|
|||||||
|
|
||||||
IO.print(map["a"]) // expect: 1
|
IO.print(map["a"]) // expect: 1
|
||||||
IO.print(map["b"]) // expect: 2
|
IO.print(map["b"]) // expect: 2
|
||||||
|
|
||||||
// Invalid syntax
|
|
||||||
// Parentheses are necessary to have these interpret as maps and not as blocks.
|
|
||||||
IO.print(new Fiber { Meta.eval("({,})") }.try()) // expect: Could not compile source code.
|
|
||||||
IO.print(new Fiber { Meta.eval("({1:1,,})") }.try()) // expect: Could not compile source code.
|
|
||||||
IO.print(new Fiber { Meta.eval("({1:1,,2:2})") }.try()) // expect: Could not compile source code.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user