@surrealdb/lezer 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/.turbo/turbo-run-tests.log +500 -42
  3. package/dist/index.cjs +67 -65
  4. package/dist/index.js +67 -65
  5. package/package.json +1 -1
  6. package/src/parser.js +17 -17
  7. package/src/parser.terms.js +231 -229
  8. package/src/surrealql.grammar +41 -37
  9. package/src/tokens.js +2 -0
  10. package/test/misc/comments.txt +44 -0
  11. package/test/misc/functions.txt +63 -0
  12. package/test/misc/identifiers.txt +22 -0
  13. package/test/misc/javascript.txt +34 -0
  14. package/test/misc/operators.txt +213 -0
  15. package/test/misc/parameters.txt +23 -0
  16. package/test/misc/subqueries.txt +23 -0
  17. package/test/statements/alter.txt +47 -0
  18. package/test/statements/break-continue.txt +15 -0
  19. package/test/statements/create.txt +103 -0
  20. package/test/statements/define.txt +281 -0
  21. package/test/statements/delete.txt +63 -0
  22. package/test/statements/for.txt +19 -0
  23. package/test/statements/if-else.txt +47 -0
  24. package/test/statements/info.txt +63 -0
  25. package/test/statements/insert.txt +63 -0
  26. package/test/statements/let.txt +39 -0
  27. package/test/statements/live.txt +47 -0
  28. package/test/statements/option.txt +23 -0
  29. package/test/statements/rebuild.txt +15 -0
  30. package/test/statements/relate.txt +63 -0
  31. package/test/statements/remove.txt +95 -0
  32. package/test/statements/return.txt +39 -0
  33. package/test/statements/select.txt +231 -0
  34. package/test/statements/show.txt +31 -0
  35. package/test/statements/sleep.txt +23 -0
  36. package/test/statements/throw.txt +23 -0
  37. package/test/statements/transactions.txt +47 -0
  38. package/test/statements/update.txt +87 -0
  39. package/test/statements/upsert.txt +55 -0
  40. package/test/statements/use.txt +39 -0
  41. package/test/test-surrealql.js +81 -9
  42. package/test/values/arrays.txt +47 -0
  43. package/test/values/casting.txt +95 -0
  44. package/test/values/closures.txt +39 -0
  45. package/test/values/durations.txt +41 -0
  46. package/test/values/format-strings.txt +39 -0
  47. package/test/values/geometries.txt +23 -0
  48. package/test/values/idioms.txt +228 -0
  49. package/test/values/literals.txt +46 -0
  50. package/test/values/numbers.txt +75 -0
  51. package/test/values/objects.txt +64 -0
  52. package/test/values/ranges.txt +31 -0
  53. package/test/values/record-ids.txt +71 -0
  54. package/test/values/regex.txt +31 -0
  55. package/test/values/sets.txt +31 -0
  56. package/test/values/strings.txt +69 -0
  57. package/test/statement.txt +0 -132
  58. package/test/value.txt +0 -259
@@ -0,0 +1,39 @@
1
+ # Use namespace short
2
+
3
+ USE NS test
4
+
5
+ ==>
6
+
7
+ SurrealQL(UseStatement(Keyword,Keyword,Ident))
8
+
9
+ # Use namespace long
10
+
11
+ USE NAMESPACE test
12
+
13
+ ==>
14
+
15
+ SurrealQL(UseStatement(Keyword,Keyword,Ident))
16
+
17
+ # Use database short
18
+
19
+ USE DB test
20
+
21
+ ==>
22
+
23
+ SurrealQL(UseStatement(Keyword,Keyword,Ident))
24
+
25
+ # Use database long
26
+
27
+ USE DATABASE test
28
+
29
+ ==>
30
+
31
+ SurrealQL(UseStatement(Keyword,Keyword,Ident))
32
+
33
+ # Use namespace and database
34
+
35
+ USE NS test DB test
36
+
37
+ ==>
38
+
39
+ SurrealQL(UseStatement(Keyword,Keyword,Ident,Keyword,Ident))
@@ -4,21 +4,93 @@ import { fileTests } from "@lezer/generator/dist/test";
4
4
  import * as fs from "fs";
5
5
  import * as path from "path";
6
6
  import { fileURLToPath } from "url";
7
- let caseDir = path.dirname(fileURLToPath(import.meta.url));
8
7
 
9
- let filter = process.argv[2];
8
+ const testDir = path.dirname(fileURLToPath(import.meta.url));
9
+ const subdirs = ["statements", "values", "misc"];
10
10
 
11
- for (let file of fs.readdirSync(caseDir)) {
12
- if (!/\.txt$/.test(file)) continue;
13
- console.log("File " + file + ":");
14
- for (let { name, run } of fileTests(fs.readFileSync(path.join(caseDir, file), "utf8"), file)) {
15
- if (!filter || name.indexOf(filter) > -1) {
11
+ const args = process.argv.slice(2);
12
+ const llmMode = args.includes("--llm");
13
+ const filter = args.find((a) => a !== "--llm");
14
+
15
+ const green = (s) => (llmMode ? s : `\x1b[32m${s}\x1b[0m`);
16
+ const red = (s) => (llmMode ? s : `\x1b[31m${s}\x1b[0m`);
17
+ const bold = (s) => (llmMode ? s : `\x1b[1m${s}\x1b[0m`);
18
+ const dim = (s) => (llmMode ? s : `\x1b[2m${s}\x1b[0m`);
19
+
20
+ let totalPass = 0;
21
+ let totalFail = 0;
22
+ const failures = [];
23
+
24
+ for (const subdir of subdirs) {
25
+ const dirPath = path.join(testDir, subdir);
26
+ if (!fs.existsSync(dirPath)) continue;
27
+
28
+ if (!llmMode) console.log(`\n${bold(`=== ${subdir.toUpperCase()} ===`)}`);
29
+
30
+ for (const file of fs.readdirSync(dirPath).sort()) {
31
+ if (!/\.txt$/.test(file)) continue;
32
+
33
+ const filePath = path.join(dirPath, file);
34
+ const label = `${subdir}/${file}`;
35
+ const tests = fileTests(fs.readFileSync(filePath, "utf8"), file);
36
+
37
+ let filePass = 0;
38
+ let fileFail = 0;
39
+ const fileFailures = [];
40
+
41
+ if (!llmMode) console.log(`\n ${bold(label)}`);
42
+
43
+ for (const { name, run } of tests) {
44
+ if (filter && name.indexOf(filter) === -1) continue;
16
45
  try {
17
46
  run(parser);
18
- console.log(" ✔ " + name);
47
+ filePass++;
48
+ totalPass++;
49
+ if (!llmMode) console.log(` ${green("✔")} ${name}`);
19
50
  } catch (e) {
20
- console.log(" ✘ " + name + "\n " + String(e.message || e).replace(/\n/g, "\n "))
51
+ fileFail++;
52
+ totalFail++;
53
+ const msg = String(e.message || e);
54
+ fileFailures.push({ name, msg });
55
+ if (!llmMode) {
56
+ console.log(` ${red("✘")} ${name}\n ${red(msg.replace(/\n/g, "\n "))}`);
57
+ }
58
+ }
59
+ }
60
+
61
+ if (llmMode && fileFail > 0) {
62
+ console.log(`FAIL ${label} (${filePass} passed, ${fileFail} failed)`);
63
+ for (const f of fileFailures) {
64
+ console.log(` FAIL: ${f.name}`);
65
+ console.log(` ${f.msg.replace(/\n/g, "\n ")}`);
21
66
  }
22
67
  }
68
+
69
+ if (fileFail > 0) {
70
+ failures.push({ label, fileFailures });
71
+ }
72
+
73
+ if (!llmMode) {
74
+ console.log(dim(` ${filePass + fileFail} tests: ${filePass} passed${fileFail > 0 ? `, ${fileFail} failed` : ""}`));
75
+ }
23
76
  }
24
77
  }
78
+
79
+ console.log("");
80
+ if (llmMode) {
81
+ console.log("--- SUMMARY ---");
82
+ console.log(`Total: ${totalPass + totalFail} | Passed: ${totalPass} | Failed: ${totalFail}`);
83
+ if (failures.length > 0) {
84
+ console.log("\nFailed tests:");
85
+ for (const { label, fileFailures } of failures) {
86
+ for (const f of fileFailures) {
87
+ console.log(` [${label}] ${f.name}`);
88
+ }
89
+ }
90
+ }
91
+ } else {
92
+ const summary = `${bold("Total")}: ${totalPass + totalFail} | ${green(`Passed: ${totalPass}`)} | ${totalFail > 0 ? red(`Failed: ${totalFail}`) : dim("Failed: 0")}`;
93
+ console.log(summary);
94
+ }
95
+
96
+ if (totalFail > 0) process.exit(1);
@@ -0,0 +1,47 @@
1
+ # Empty array
2
+
3
+ []
4
+
5
+ ==>
6
+
7
+ SurrealQL(Array("[","]"))
8
+
9
+ # Single element
10
+
11
+ [1]
12
+
13
+ ==>
14
+
15
+ SurrealQL(Array("[",Int,"]"))
16
+
17
+ # Multiple elements
18
+
19
+ [1, 2, 3]
20
+
21
+ ==>
22
+
23
+ SurrealQL(Array("[",Int,Int,Int,"]"))
24
+
25
+ # Trailing comma
26
+
27
+ [1, 2, 3,]
28
+
29
+ ==>
30
+
31
+ SurrealQL(Array("[",Int,Int,Int,"]"))
32
+
33
+ # Nested arrays
34
+
35
+ [[1, 2], [3, 4]]
36
+
37
+ ==>
38
+
39
+ SurrealQL(Array("[",Array("[",Int,Int,"]"),Array("[",Int,Int,"]"),"]"))
40
+
41
+ # Mixed types
42
+
43
+ [1, "hello", true, null]
44
+
45
+ ==>
46
+
47
+ SurrealQL(Array("[",Int,String,Bool,None,"]"))
@@ -0,0 +1,95 @@
1
+ # Simple type cast
2
+
3
+ <string> test
4
+
5
+ ==>
6
+
7
+ SurrealQL(TypeCast("<",TypeName,">",Ident))
8
+
9
+ # Union type cast
10
+
11
+ <string|number> test
12
+
13
+ ==>
14
+
15
+ SurrealQL(TypeCast("<",UnionType(TypeName,Pipe,TypeName),">",Ident))
16
+
17
+ # Literal string type cast
18
+
19
+ <"test"> test
20
+
21
+ ==>
22
+
23
+ SurrealQL(TypeCast("<",LiteralType(String),">",Ident))
24
+
25
+ # Literal union type cast
26
+
27
+ <"test"|number> test
28
+
29
+ ==>
30
+
31
+ SurrealQL(TypeCast("<",UnionType(LiteralType(String),Pipe,TypeName),">",Ident))
32
+
33
+ # Literal string union
34
+
35
+ <"a"|"b"> test
36
+
37
+ ==>
38
+
39
+ SurrealQL(TypeCast("<",UnionType(LiteralType(String),Pipe,LiteralType(String)),">",Ident))
40
+
41
+ # Array literal type cast
42
+
43
+ <["test"]> test
44
+
45
+ ==>
46
+
47
+ SurrealQL(TypeCast("<",LiteralType(ArrayType("[",LiteralType(String),"]")),">",Ident))
48
+
49
+ # Array union literal type cast
50
+
51
+ <["test"|number]> test
52
+
53
+ ==>
54
+
55
+ SurrealQL(TypeCast("<",LiteralType(ArrayType("[",UnionType(LiteralType(String),Pipe,TypeName),"]")),">",Ident))
56
+
57
+ # Object type cast
58
+
59
+ <{ "a": string }> test
60
+
61
+ ==>
62
+
63
+ SurrealQL(TypeCast("<",LiteralType(ObjectType(BraceOpen,ObjectTypeContent(ObjectTypeProperty(ObjectKey(String),Colon,TypeName)),BraceClose)),">",Ident))
64
+
65
+ # Object union type cast
66
+
67
+ <{ "a": "test"|number }> test
68
+
69
+ ==>
70
+
71
+ SurrealQL(TypeCast("<",LiteralType(ObjectType(BraceOpen,ObjectTypeContent(ObjectTypeProperty(ObjectKey(String),Colon,UnionType(LiteralType(String),Pipe,TypeName))),BraceClose)),">",Ident))
72
+
73
+ # Complex nested type cast
74
+
75
+ <{ "a": "test"|[number] }|number> test
76
+
77
+ ==>
78
+
79
+ SurrealQL(TypeCast("<",UnionType(LiteralType(ObjectType(BraceOpen,ObjectTypeContent(ObjectTypeProperty(ObjectKey(String),Colon,UnionType(LiteralType(String),Pipe,LiteralType(ArrayType("[",TypeName,"]"))))),BraceClose)),Pipe,TypeName),">",Ident))
80
+
81
+ # Parameterized type cast
82
+
83
+ <record<hello>> test
84
+
85
+ ==>
86
+
87
+ SurrealQL(TypeCast("<",ParameterizedType(TypeName,"<",TypeName,">"),">",Ident))
88
+
89
+ # Complex union object type cast
90
+
91
+ <{ "a": string } | { "b": [record<hello>] | "test" }> test
92
+
93
+ ==>
94
+
95
+ SurrealQL(TypeCast("<",UnionType(LiteralType(ObjectType(BraceOpen,ObjectTypeContent(ObjectTypeProperty(ObjectKey(String),Colon,TypeName)),BraceClose)),Pipe,LiteralType(ObjectType(BraceOpen,ObjectTypeContent(ObjectTypeProperty(ObjectKey(String),Colon,UnionType(LiteralType(ArrayType("[",ParameterizedType(TypeName,"<",TypeName,">"),"]")),Pipe,LiteralType(String)))),BraceClose))),">",Ident))
@@ -0,0 +1,39 @@
1
+ # Empty closure
2
+
3
+ || { 1 }
4
+
5
+ ==>
6
+
7
+ SurrealQL(Closure(Pipe,Pipe,Block(BraceOpen,Int,BraceClose)))
8
+
9
+ # Closure with param
10
+
11
+ |$a| { $a }
12
+
13
+ ==>
14
+
15
+ SurrealQL(Closure(Pipe,ParamDefinition(VariableName),Pipe,Block(BraceOpen,VariableName,BraceClose)))
16
+
17
+ # Closure with typed param
18
+
19
+ |$a: number| { $a + 1 }
20
+
21
+ ==>
22
+
23
+ SurrealQL(Closure(Pipe,ParamDefinition(VariableName,Colon,Type(TypeName)),Pipe,Block(BraceOpen,BinaryExpression(VariableName,Operator,Int),BraceClose)))
24
+
25
+ # Closure with multiple params
26
+
27
+ |$a, $b| { $a + $b }
28
+
29
+ ==>
30
+
31
+ SurrealQL(Closure(Pipe,ParamDefinition(VariableName),ParamDefinition(VariableName),Pipe,Block(BraceOpen,BinaryExpression(VariableName,Operator,VariableName),BraceClose)))
32
+
33
+ # Closure with return type
34
+
35
+ |$a: number| -> number { $a + 1 }
36
+
37
+ ==>
38
+
39
+ SurrealQL(Closure(Pipe,ParamDefinition(VariableName,Colon,Type(TypeName)),Pipe,LookupRight,TypeName,Block(BraceOpen,BinaryExpression(VariableName,Operator,Int),BraceClose)))
@@ -0,0 +1,41 @@
1
+ # Single duration parts
2
+
3
+ 1ns;
4
+ 1us;
5
+ 1ms;
6
+ 1s;
7
+ 1m;
8
+ 1h;
9
+ 1d;
10
+ 1w;
11
+ 1y
12
+
13
+ ==>
14
+
15
+ SurrealQL(
16
+ Duration(DurationPart),
17
+ Duration(DurationPart),
18
+ Duration(DurationPart),
19
+ Duration(DurationPart),
20
+ Duration(DurationPart),
21
+ Duration(DurationPart),
22
+ Duration(DurationPart),
23
+ Duration(DurationPart),
24
+ Duration(DurationPart)
25
+ )
26
+
27
+ # Multi-part duration
28
+
29
+ 1s 1m 1 h
30
+
31
+ ==>
32
+
33
+ SurrealQL(Duration(DurationPart,DurationPart,DurationPart))
34
+
35
+ # Complex duration
36
+
37
+ 1d2h30m
38
+
39
+ ==>
40
+
41
+ SurrealQL(Duration(DurationPart,DurationPart,DurationPart))
@@ -0,0 +1,39 @@
1
+ # Basic format string
2
+
3
+ $"hello {name}"
4
+
5
+ ==>
6
+
7
+ SurrealQL(FormatString(Interpolation(BraceOpen,Ident,BraceClose)))
8
+
9
+ # Format string with expression
10
+
11
+ $"result is {1 + 2 + 3}"
12
+
13
+ ==>
14
+
15
+ SurrealQL(FormatString(Interpolation(BraceOpen,BinaryExpression(BinaryExpression(Int,Operator,Int),Operator,Int),BraceClose)))
16
+
17
+ # Escaped quote in format string
18
+
19
+ $"some \" quote {1 + 2 + 3} and \{ some } brackets"
20
+
21
+ ==>
22
+
23
+ SurrealQL(FormatString(Interpolation(BraceOpen,BinaryExpression(BinaryExpression(Int,Operator,Int),Operator,Int),BraceClose)))
24
+
25
+ # Nested format strings
26
+
27
+ $'nested {$"string {22}"}'
28
+
29
+ ==>
30
+
31
+ SurrealQL(FormatString(Interpolation(BraceOpen,FormatString(Interpolation(BraceOpen,Int,BraceClose)),BraceClose)))
32
+
33
+ # Single quoted format string
34
+
35
+ $'hello {name}'
36
+
37
+ ==>
38
+
39
+ SurrealQL(FormatString(Interpolation(BraceOpen,Ident,BraceClose)))
@@ -0,0 +1,23 @@
1
+ # Point with decimals
2
+
3
+ (10dec, 20dec)
4
+
5
+ ==>
6
+
7
+ SurrealQL(Point(Decimal,Decimal))
8
+
9
+ # Point with integers
10
+
11
+ (10, 20)
12
+
13
+ ==>
14
+
15
+ SurrealQL(Point(Int,Int))
16
+
17
+ # Point with floats
18
+
19
+ (1.5, 2.5)
20
+
21
+ ==>
22
+
23
+ SurrealQL(Point(Float,Float))
@@ -0,0 +1,228 @@
1
+ # Dot notation path
2
+
3
+ $variable.ident.ident
4
+
5
+ ==>
6
+
7
+ SurrealQL(Path(VariableName,Subscript(Ident),Subscript(Ident)))
8
+
9
+ # Wildcard on record ID
10
+
11
+ record:id.*
12
+
13
+ ==>
14
+
15
+ SurrealQL(Path(RecordId(RecordTbIdent,Colon,RecordIdIdent),Subscript(Any)))
16
+
17
+ # Lookup arrow right with any
18
+
19
+ ident->?
20
+
21
+ ==>
22
+
23
+ SurrealQL(Path(Ident,Lookup(LookupRight,Any)))
24
+
25
+ # Lookup arrow right
26
+
27
+ ident->ident
28
+
29
+ ==>
30
+
31
+ SurrealQL(Path(Ident,Lookup(LookupRight,Ident)))
32
+
33
+ # Multiple lookups
34
+
35
+ ident->ident<-ident<->ident
36
+
37
+ ==>
38
+
39
+ SurrealQL(Path(Ident,Lookup(LookupRight,Ident),Lookup(LookupLeft,Ident),Lookup(LookupBoth,Ident)))
40
+
41
+ # Record ID lookup
42
+
43
+ record:id->ident
44
+
45
+ ==>
46
+
47
+ SurrealQL(Path(RecordId(RecordTbIdent,Colon,RecordIdIdent),Lookup(LookupRight,Ident)))
48
+
49
+ # SELECT with lookup path
50
+
51
+ SELECT ->ident FROM ident
52
+
53
+ ==>
54
+
55
+ SurrealQL(SelectStatement(Keyword,Fields(Predicate(Path(Lookup(LookupRight,Ident)))),Keyword,Ident))
56
+
57
+ # Method call on number
58
+
59
+ 123.to_string()
60
+
61
+ ==>
62
+
63
+ SurrealQL(Path(Int,Subscript(IdiomFunction(FunctionName,ArgumentList))))
64
+
65
+ # Filter with variable key
66
+
67
+ {}[$variable]
68
+
69
+ ==>
70
+
71
+ SurrealQL(Path(Object(BraceOpen,BraceClose),Filter("[",VariableName,"]")))
72
+
73
+ # Filter with ident key
74
+
75
+ {}[ident]
76
+
77
+ ==>
78
+
79
+ SurrealQL(Path(Object(BraceOpen,BraceClose),Filter("[",Ident,"]")))
80
+
81
+ # Filter with string key
82
+
83
+ {}["string"]
84
+
85
+ ==>
86
+
87
+ SurrealQL(Path(Object(BraceOpen,BraceClose),Filter("[",String,"]")))
88
+
89
+ # Record ID filter
90
+
91
+ record:id[ident]
92
+
93
+ ==>
94
+
95
+ SurrealQL(Path(RecordId(RecordTbIdent,Colon,RecordIdIdent),Filter("[",Ident,"]")))
96
+
97
+ # Array index access
98
+
99
+ [][0]
100
+
101
+ ==>
102
+
103
+ SurrealQL(Path(Array("[","]"),Filter("[",Int,"]")))
104
+
105
+ # Array variable access
106
+
107
+ [][$variable]
108
+
109
+ ==>
110
+
111
+ SurrealQL(Path(Array("[","]"),Filter("[",VariableName,"]")))
112
+
113
+ # Array WHERE filter
114
+
115
+ [][WHERE ident = 123]
116
+
117
+ ==>
118
+
119
+ SurrealQL(Path(Array("[","]"),Filter("[",WhereClause(Keyword,BinaryExpression(Ident,Operator,Int)),"]")))
120
+
121
+ # Array question mark filter
122
+
123
+ [][? ident = 123]
124
+
125
+ ==>
126
+
127
+ SurrealQL(Path(Array("[","]"),Filter("[",WhereClause(BinaryExpression(Ident,Operator,Int)),"]")))
128
+
129
+ # Recurse unbounded
130
+
131
+ person:tobie.{..}->knows->person
132
+
133
+ ==>
134
+
135
+ SurrealQL(Path(
136
+ RecordId(RecordTbIdent,Colon,RecordIdIdent),
137
+ Subscript(Recurse(BraceOpen,RecurseRange(RangeOp),RecurseOptions,BraceClose)),
138
+ Lookup(LookupRight,Ident), Lookup(LookupRight,Ident)
139
+ ))
140
+
141
+ # Recurse with path expression
142
+
143
+ person:tobie.{..}(->knows->person).name
144
+
145
+ ==>
146
+
147
+ SurrealQL(Path(
148
+ RecordId(RecordTbIdent,Colon,RecordIdIdent),
149
+ Subscript(
150
+ Recurse(
151
+ BraceOpen, RecurseRange(RangeOp), RecurseOptions, BraceClose,
152
+ Lookup(LookupRight,Ident), Lookup(LookupRight,Ident)
153
+ )
154
+ ),
155
+ Subscript(Ident)
156
+ ))
157
+
158
+ # Recurse with destructure
159
+
160
+ person:tobie.{..}.{ id, name, knows: ->knows->person.@ }
161
+
162
+ ==>
163
+
164
+ SurrealQL(Path(
165
+ RecordId(RecordTbIdent,Colon,RecordIdIdent),
166
+ Subscript(Recurse(BraceOpen,RecurseRange(RangeOp),RecurseOptions,BraceClose)),
167
+ Subscript(Destructure(BraceOpen,Ident,Ident,Ident,Colon,Lookup(LookupRight,Ident),Lookup(LookupRight,Ident),Subscript(At),BraceClose))
168
+ ))
169
+
170
+ # Recurse with fixed depth
171
+
172
+ a:b.{1}
173
+
174
+ ==>
175
+
176
+ SurrealQL(Path(
177
+ RecordId(RecordTbIdent,Colon,RecordIdIdent),
178
+ Subscript(Recurse(BraceOpen,RecurseRange(Int),RecurseOptions,BraceClose))
179
+ ))
180
+
181
+ # Recurse with min range
182
+
183
+ a:b.{1..}
184
+
185
+ ==>
186
+
187
+ SurrealQL(Path(
188
+ RecordId(RecordTbIdent,Colon,RecordIdIdent),
189
+ Subscript(Recurse(BraceOpen,RecurseRange(Int,RangeOp),RecurseOptions,BraceClose))
190
+ ))
191
+
192
+ # Recurse with full range
193
+
194
+ a:b.{1..2}
195
+
196
+ ==>
197
+
198
+ SurrealQL(Path(
199
+ RecordId(RecordTbIdent,Colon,RecordIdIdent),
200
+ Subscript(Recurse(BraceOpen,RecurseRange(Int,RangeOp,Int),RecurseOptions,BraceClose))
201
+ ))
202
+
203
+ # Recurse with max range
204
+
205
+ a:b.{..2}
206
+
207
+ ==>
208
+
209
+ SurrealQL(Path(
210
+ RecordId(RecordTbIdent,Colon,RecordIdIdent),
211
+ Subscript(Recurse(BraceOpen,RecurseRange(RangeOp,Int),RecurseOptions,BraceClose))
212
+ ))
213
+
214
+ # At reference with subscript
215
+
216
+ @.name
217
+
218
+ ==>
219
+
220
+ SurrealQL(Path(At,Subscript(Ident)))
221
+
222
+ # At reference with ident
223
+
224
+ @name
225
+
226
+ ==>
227
+
228
+ SurrealQL(Path(At,Ident))
@@ -0,0 +1,46 @@
1
+ # Boolean true
2
+
3
+ true;
4
+ true
5
+
6
+ ==>
7
+
8
+ SurrealQL(Bool,Bool)
9
+
10
+ # Boolean false
11
+
12
+ false;
13
+ false
14
+
15
+ ==>
16
+
17
+ SurrealQL(Bool,Bool)
18
+
19
+ # Null
20
+
21
+ null;
22
+ null
23
+
24
+ ==>
25
+
26
+ SurrealQL(None,None)
27
+
28
+ # None
29
+
30
+ none;
31
+ none
32
+
33
+ ==>
34
+
35
+ SurrealQL(None,None)
36
+
37
+ # Mixed literals
38
+
39
+ true;
40
+ false;
41
+ null;
42
+ none
43
+
44
+ ==>
45
+
46
+ SurrealQL(Bool,Bool,None,None)