@@ -7,13 +7,16 @@ import t from "@babel/types"
77import type { LaxPartial } from "@samual/lib"
88import { assert } from "@samual/lib/assert"
99import { spliceString } from "@samual/lib/spliceString"
10+ import { tokenizer as tokenise , tokTypes as TokenTypes } from "acorn"
1011import { resolve as resolveModule } from "import-meta-resolve"
1112
1213// eslint-disable-next-line @typescript-eslint/consistent-type-imports
1314const { default : traverse } = babelTraverse as any as typeof import ( "@babel/traverse" )
1415// eslint-disable-next-line @typescript-eslint/consistent-type-imports
1516const { default : generate } = babelGenerator as any as typeof import ( "@babel/generator" )
1617
18+ const SUBSCRIPT_PREFIXES = [ `s` , `fs` , `4s` , `hs` , `3s` , `ms` , `2s` , `ls` , `1s` , `ns` , `0s` ]
19+
1720export type PreprocessOptions = LaxPartial < { /** 11 a-z 0-9 characters */ uniqueId : string } >
1821
1922/** @param code source code for preprocessing
@@ -22,6 +25,25 @@ export async function preprocess(code: string, { uniqueId = `00000000000` }: Pre
2225: Promise < { code : string } > {
2326 assert ( / ^ \w { 11 } $ / . test ( uniqueId ) , HERE )
2427
28+ const tokensIterable = tokenise ( code , { ecmaVersion : `latest` } )
29+
30+ for ( const token of tokensIterable ) {
31+ assert ( `value` in token , HERE )
32+
33+ if ( token . type != TokenTypes . privateId )
34+ continue
35+
36+ assert ( typeof token . value == `string` , HERE )
37+
38+ if ( ! SUBSCRIPT_PREFIXES . includes ( token . value ) )
39+ continue
40+
41+ const nextToken = tokensIterable . getToken ( )
42+
43+ if ( nextToken . type != TokenTypes . _in && nextToken . type != TokenTypes . dot )
44+ throw SyntaxError ( `Subscripts must be in the form of #fs.foo.bar` )
45+ }
46+
2547 const sourceCode = code
2648 let lengthBefore
2749
0 commit comments