File tree 3 files changed +64
-0
lines changed
3 files changed +64
-0
lines changed Original file line number Diff line number Diff line change
1
+ import { ContextTracker } from "@lezer/lr" ;
2
+ import { dedent , indent } from "./parser.terms.js" ;
3
+
4
+ class IndentLevel {
5
+ constructor ( parent , depth ) {
6
+ this . parent = parent ;
7
+ this . depth = depth ;
8
+ this . hash =
9
+ ( parent ? ( parent . hash + parent . hash ) << 8 : 0 ) + depth + ( depth << 4 ) ;
10
+ }
11
+ }
12
+
13
+ export const ctx = new ContextTracker ( {
14
+ start : { indent : new IndentLevel ( null , 0 ) } ,
15
+ shift ( context , term , stack , input ) {
16
+ if ( term === indent )
17
+ return {
18
+ ...context ,
19
+ indent : new IndentLevel ( context , stack . pos - input . pos ) ,
20
+ } ;
21
+ if ( term === dedent ) return { ...context , indent : context . parent } ;
22
+ return context ;
23
+ } ,
24
+ hash : ( context ) => context . hash ,
25
+ } ) ;
Original file line number Diff line number Diff line change
1
+ @context ctx from "./context"
2
+ @external tokens indentation from "./tokens.js" {
3
+ indent
4
+ dedent
5
+ blankLineStart
6
+ }
7
+
1
8
@top File {
2
9
(
3
10
preprocessor |
Original file line number Diff line number Diff line change
1
+ import { ExternalTokenizer } from "@lezer/lr" ;
2
+ import { blankLineStart , dedent , indent } from "./parser.terms" ;
3
+
4
+ const newline = "\n" . charCodeAt ( 0 ) ,
5
+ space = " " . charCodeAt ( 0 ) ,
6
+ tab = "\t" . charCodeAt ( 0 ) ,
7
+ hash = "#" . charCodeAt ( 0 ) ,
8
+ slash = "/" . charCodeAt ( 0 ) ,
9
+ star = "*" . charCodeAt ( 0 ) ;
10
+
11
+ export const indentation = new ExternalTokenizer ( ( input , stack ) => {
12
+ let prev = input . peek ( - 1 ) ;
13
+ if ( prev !== - 1 && prev !== newline ) return ;
14
+ let spaces = 0 ;
15
+ while ( input . next === space || input . next === tab ) {
16
+ input . advance ( ) ;
17
+ spaces ++ ;
18
+ }
19
+ if (
20
+ input . next === newline ||
21
+ input . next === hash ||
22
+ ( input . next === slash &&
23
+ ( input . peek ( 1 ) === slash || input . peek ( 1 ) === star ) )
24
+ ) {
25
+ if ( stack . canShift ( blankLineStart ) )
26
+ input . acceptToken ( blankLineStart , - spaces ) ;
27
+ } else if ( spaces > stack . context . indent . depth ) {
28
+ input . acceptToken ( indent ) ;
29
+ } else if ( spaces < stack . context . indent . depth ) {
30
+ input . acceptToken ( dedent , - spaces ) ;
31
+ }
32
+ } ) ;
You can’t perform that action at this time.
0 commit comments