// TypeScript syntax subset
// Focus: declarations, function syntax, blocks, if/else, arrays, unions
Identifier ::= /[a-zA-Z_][a-zA-Z0-9_]*/
TypeName ::= 'string' | 'number' | 'boolean' | 'void'
BaseType ::= TypeName | '(' Type ')'
ArrayType ::= BaseType '[' ']'
UnionTail ::= '|' TypePart
TypePart ::= ArrayType | BaseType
Type ::= TypePart UnionTail?
String ::= /"[^"]*"/
Number ::= /[0-9]+(\.[0-9]+)?/
Boolean ::= 'true' | 'false'
Variable(var) ::= Identifier[x]
ArrayRest ::= ',' Expression
ArrayLiteral(array) ::= '[' ']' | '[' Expression ']'
Primary ::= Variable
| String
| Number
| Boolean
| ArrayLiteral
| '(' Expression ')'
CallArgRest ::= ',' Expression
CallArgs(args) ::= Expression CallArgRest?
Call(call) ::= Primary[func] '(' ')' | Primary[func] '(' CallArgs[args] ')'
Expression ::= Call
| Primary
Parameter(param) ::= Identifier[name] ':' Type[τ]
ParamRest ::= ',' Parameter
ParameterList(params) ::= Parameter ParamRest? | ε
ExprOpt ::= Expression?
ReturnStmt(ret) ::= 'return' ExprOpt[value] ';'
ExprStmt(stmt) ::= Expression ';'
VarDecl(decl) ::= 'let' Identifier[name] ':' Type[τ] '=' Expression[value] ';'
ConstDecl(const_decl) ::= 'const' Identifier[name] ':' Type[τ] '=' Expression[value] ';'
Block(block) ::= '{' Statement '}'
IfStmt(if_else) ::= 'if' '(' Expression[cond] ')' Block[then_block] 'else' Block[else_block]
FunctionDecl(function) ::= 'function' Identifier[name] '(' ParameterList[params] ')' ':' Type[ret] Block[body]
Statement ::= FunctionDecl | VarDecl | ConstDecl | ReturnStmt | IfStmt | ExprStmt
Program(program) ::= Statement
start ::= Program