11import type * as CST from './cst-types.js' ;
22import type { ParseContext } from './message.js' ;
3- import { parseExpression } from './expression.js' ;
3+ import { parseExpression , parseReservedBody } from './expression.js' ;
44import { whitespaces } from './util.js' ;
55import { parseVariable } from './values.js' ;
6+ import { parseNameValue } from './names.js' ;
67
78export function parseDeclarations ( ctx : ParseContext ) : {
89 declarations : CST . Declaration [ ] ;
@@ -11,13 +12,22 @@ export function parseDeclarations(ctx: ParseContext): {
1112 const { source } = ctx ;
1213 let pos = whitespaces ( source , 0 ) ;
1314 const declarations : CST . Declaration [ ] = [ ] ;
14- while ( pos < source . length ) {
15- const decl = source . startsWith ( '.input' , pos )
16- ? parseInputDeclaration ( ctx , pos )
17- : source . startsWith ( '.local' , pos )
18- ? parseLocalDeclaration ( ctx , pos )
19- : null ;
20- if ( ! decl ) break ;
15+ loop: while ( source [ pos ] === '.' ) {
16+ const keyword = parseNameValue ( source , pos + 1 ) ;
17+ let decl ;
18+ switch ( keyword ) {
19+ case '' :
20+ case 'match' :
21+ break loop;
22+ case 'input' :
23+ decl = parseInputDeclaration ( ctx , pos ) ;
24+ break ;
25+ case 'local' :
26+ decl = parseLocalDeclaration ( ctx , pos ) ;
27+ break ;
28+ default :
29+ decl = parseReservedStatement ( ctx , pos , '.' + keyword ) ;
30+ }
2131 declarations . push ( decl ) ;
2232 pos = decl . end ;
2333 pos += whitespaces ( source , pos ) ;
@@ -29,7 +39,7 @@ export function parseDeclarations(ctx: ParseContext): {
2939function parseInputDeclaration (
3040 ctx : ParseContext ,
3141 start : number
32- ) : CST . Declaration {
42+ ) : CST . InputDeclaration {
3343 //
3444 let pos = start + 6 ; // '.input'
3545 const keyword : CST . Syntax < '.input' > = { start, end : pos , value : '.input' } ;
@@ -105,6 +115,36 @@ function parseLocalDeclaration(
105115 } ;
106116}
107117
118+ function parseReservedStatement (
119+ ctx : ParseContext ,
120+ start : number ,
121+ keyword : string
122+ ) : CST . ReservedStatement {
123+ let pos = start + keyword . length ;
124+ pos += whitespaces ( ctx . source , pos ) ;
125+
126+ const body = parseReservedBody ( ctx , pos ) ;
127+ let end = body . end ;
128+ pos = end + whitespaces ( ctx . source , end ) ;
129+
130+ const values : CST . Expression [ ] = [ ] ;
131+ while ( ctx . source [ pos ] === '{' ) {
132+ const value = parseExpression ( ctx , pos ) ;
133+ end = value . end ;
134+ pos = end + whitespaces ( ctx . source , end ) ;
135+ }
136+ if ( values . length === 0 ) ctx . onError ( 'missing-syntax' , end , '{' ) ;
137+
138+ return {
139+ type : 'reserved-statement' ,
140+ start,
141+ end,
142+ keyword : { start, end : keyword . length , value : keyword } ,
143+ body,
144+ values
145+ } ;
146+ }
147+
108148function parseDeclarationValue (
109149 ctx : ParseContext ,
110150 start : number
@@ -130,7 +170,7 @@ function checkDeclarations(ctx: ParseContext, declarations: CST.Declaration[]) {
130170 }
131171 } ;
132172
133- for ( const decl of declarations ) {
173+ loop: for ( const decl of declarations ) {
134174 let target : CST . VariableRef | undefined ;
135175 switch ( decl . type ) {
136176 case 'input' :
@@ -148,6 +188,8 @@ function checkDeclarations(ctx: ParseContext, declarations: CST.Declaration[]) {
148188 case 'local' :
149189 if ( decl . target . type === 'variable' ) target = decl . target ;
150190 break ;
191+ default :
192+ continue loop;
151193 }
152194 if ( target ) {
153195 if ( targets . has ( target . name ) ) {
0 commit comments