diff --git a/src/cst.ts b/src/cst.ts index cc7324a9a..4a43a7c2b 100644 --- a/src/cst.ts +++ b/src/cst.ts @@ -1,6 +1,8 @@ import { assert, JSONObject, JSONValue } from "./util"; import { isNodeWithScope, Scope } from "./scope" import type { InferContext, Kind, KindEnv, Scheme, Type, TypeEnv } from "./checker" +import { array, middleware } from "yargs"; +import { warn } from "console"; export type TextSpan = [number, number]; @@ -91,6 +93,7 @@ export const enum SyntaxKind { Comma, Colon, Equals, + Backslash, Integer, StringLiteral, LetKeyword, @@ -152,6 +155,7 @@ export const enum SyntaxKind { PrefixExpression, PostfixExpression, InfixExpression, + FunctionExpression, // Statements ReturnStatement, @@ -199,9 +203,14 @@ export type Syntax | ClassDeclaration | InstanceDeclaration | ClassConstraint + | ClassConstraintClause | Token | Param | Body + | MatchArm + | WrappedOperator + | Initializer + | IfStatementCase | StructDeclarationField | EnumDeclarationElement | TypeAssert @@ -228,6 +237,8 @@ abstract class SyntaxBase { public abstract getLastToken(): Token; + public abstract clone(): Syntax; + public getRange(): TextRange { return new TextRange( this.getFirstToken().getStartPosition(), @@ -382,7 +393,7 @@ abstract class TokenBase extends SyntaxBase { private endPos: TextPosition | null = null; public constructor( - private startPos: TextPosition, + public startPos: TextPosition | null = null, ) { super(); } @@ -403,6 +414,7 @@ abstract class TokenBase extends SyntaxBase { } public getStartPosition(): TextPosition { + assert(this.startPos !== null); return this.startPos; } @@ -442,19 +454,43 @@ abstract class VirtualTokenBase extends TokenBase { } export class EndOfFile extends VirtualTokenBase { + public readonly kind = SyntaxKind.EndOfFile; + + public clone(): EndOfFile { + return new EndOfFile(this.startPos); + } + } export class BlockEnd extends VirtualTokenBase { + public readonly kind = SyntaxKind.BlockEnd; + + public clone(): BlockEnd { + return new BlockEnd(this.startPos); + } + } export class BlockStart extends VirtualTokenBase { + public readonly kind = SyntaxKind.BlockStart; + + public clone(): BlockStart { + return new BlockStart(this.startPos); + } + } export class LineFoldEnd extends VirtualTokenBase { + public readonly kind = SyntaxKind.LineFoldEnd; + + public clone(): LineFoldEnd { + return new LineFoldEnd(this.startPos); + } + } export class Integer extends TokenBase { @@ -464,7 +500,7 @@ export class Integer extends TokenBase { public constructor( public value: bigint, public radix: number, - startPos: TextPosition, + startPos: TextPosition | null = null, ) { super(startPos); } @@ -473,6 +509,14 @@ export class Integer extends TokenBase { return this.value; } + public clone(): Integer { + return new Integer( + this.value, + this.radix, + this.startPos + ); + } + public get text(): string { switch (this.radix) { case 16: @@ -496,7 +540,7 @@ export class StringLiteral extends TokenBase { public constructor( public contents: string, - startPos: TextPosition, + startPos: TextPosition | null = null, ) { super(startPos); } @@ -505,6 +549,13 @@ export class StringLiteral extends TokenBase { return this.contents; } + public clone(): StringLiteral { + return new StringLiteral( + this.contents, + this.startPos + ); + } + public get text(): string { let out = '"'; for (const ch of this.contents) { @@ -529,11 +580,18 @@ export class IdentifierAlt extends TokenBase { public constructor( public text: string, - startPos: TextPosition, + startPos: TextPosition | null = null, ) { super(startPos); } + public clone(): IdentifierAlt { + return new IdentifierAlt( + this.text, + this.startPos + ); + } + } export class Identifier extends TokenBase { @@ -542,11 +600,18 @@ export class Identifier extends TokenBase { public constructor( public text: string, - startPos: TextPosition, + startPos: TextPosition | null = null, ) { super(startPos); } + public clone(): Identifier { + return new Identifier( + this.text, + this.startPos + ); + } + } export class CustomOperator extends TokenBase { @@ -555,11 +620,18 @@ export class CustomOperator extends TokenBase { public constructor( public text: string, - startPos: TextPosition, + startPos: TextPosition | null = null, ) { super(startPos); } + public clone(): CustomOperator { + return new CustomOperator( + this.text, + this.startPos, + ); + } + } export type ExprOperator @@ -577,11 +649,18 @@ export class Assignment extends TokenBase { public constructor( public text: string, - startPos: TextPosition, + startPos: TextPosition | null = null, ) { super(startPos); } + public clone(): Assignment { + return new Assignment( + this.text, + this.startPos + ); + } + } export class LParen extends TokenBase { @@ -592,6 +671,10 @@ export class LParen extends TokenBase { return '('; } + public clone(): LParen { + return new LParen(this.startPos); + } + } export class RParen extends TokenBase { @@ -602,6 +685,10 @@ export class RParen extends TokenBase { return ')'; } + public clone(): RParen { + return new RParen(this.startPos); + } + } export class LBrace extends TokenBase { @@ -612,6 +699,10 @@ export class LBrace extends TokenBase { return '{'; } + public clone(): LBrace { + return new LBrace(this.startPos); + } + } export class RBrace extends TokenBase { @@ -622,6 +713,10 @@ export class RBrace extends TokenBase { return '}'; } + public clone(): RBrace { + return new RBrace(this.startPos); + } + } export class LBracket extends TokenBase { @@ -632,6 +727,10 @@ export class LBracket extends TokenBase { return '['; } + public clone(): LBracket { + return new LBracket(this.startPos); + } + } export class RBracket extends TokenBase { @@ -642,6 +741,10 @@ export class RBracket extends TokenBase { return ']'; } + public clone(): RBracket { + return new RBracket(this.startPos); + } + } export class Dot extends TokenBase { @@ -652,6 +755,10 @@ export class Dot extends TokenBase { return '.'; } + public clone(): Dot { + return new Dot(this.startPos); + } + } export class Comma extends TokenBase { @@ -662,6 +769,10 @@ export class Comma extends TokenBase { return ','; } + public clone(): Comma { + return new Comma(this.startPos); + } + } export class DotDot extends TokenBase { @@ -672,6 +783,10 @@ export class DotDot extends TokenBase { return '..'; } + public clone(): DotDot { + return new DotDot(this.startPos); + } + } export class Colon extends TokenBase { @@ -682,6 +797,10 @@ export class Colon extends TokenBase { return ':'; } + public clone(): Colon { + return new Colon(this.startPos); + } + } export class Equals extends TokenBase { @@ -692,6 +811,24 @@ export class Equals extends TokenBase { return '='; } + public clone(): Equals { + return new Equals(this.startPos); + } + +} + +export class Backslash extends TokenBase { + + public readonly kind = SyntaxKind.Equals; + + public get text(): string { + return '\\'; + } + + public clone(): Backslash { + return new Backslash(this.startPos); + } + } export class IfKeyword extends TokenBase { @@ -702,6 +839,10 @@ export class IfKeyword extends TokenBase { return 'if'; } + public clone(): IfKeyword { + return new IfKeyword(this.startPos); + } + } export class ElseKeyword extends TokenBase { @@ -712,6 +853,10 @@ export class ElseKeyword extends TokenBase { return 'else'; } + public clone(): ElseKeyword { + return new ElseKeyword(this.startPos); + } + } export class ElifKeyword extends TokenBase { @@ -722,6 +867,10 @@ export class ElifKeyword extends TokenBase { return 'elif'; } + public clone(): ElifKeyword { + return new ElifKeyword(this.startPos); + } + } export class StructKeyword extends TokenBase { @@ -732,6 +881,10 @@ export class StructKeyword extends TokenBase { return 'struct'; } + public clone(): StructKeyword { + return new StructKeyword(this.startPos); + } + } export class EnumKeyword extends TokenBase { @@ -742,6 +895,10 @@ export class EnumKeyword extends TokenBase { return 'enum'; } + public clone(): EnumKeyword { + return new EnumKeyword(this.startPos); + } + } export class ReturnKeyword extends TokenBase { @@ -752,6 +909,10 @@ export class ReturnKeyword extends TokenBase { return 'return'; } + public clone(): ReturnKeyword { + return new ReturnKeyword(this.startPos); + } + } export class MatchKeyword extends TokenBase { @@ -762,6 +923,10 @@ export class MatchKeyword extends TokenBase { return 'match'; } + public clone(): MatchKeyword { + return new MatchKeyword(this.startPos); + } + } export class ForeignKeyword extends TokenBase { @@ -772,6 +937,10 @@ export class ForeignKeyword extends TokenBase { return 'foreign'; } + public clone(): ForeignKeyword { + return new ForeignKeyword(this.startPos); + } + } export class ModKeyword extends TokenBase { @@ -782,6 +951,10 @@ export class ModKeyword extends TokenBase { return 'mod'; } + public clone(): ModKeyword { + return new ModKeyword(this.startPos); + } + } export class MutKeyword extends TokenBase { @@ -792,6 +965,10 @@ export class MutKeyword extends TokenBase { return 'mut'; } + public clone(): MutKeyword { + return new MutKeyword(this.startPos); + } + } export class ImportKeyword extends TokenBase { @@ -802,6 +979,10 @@ export class ImportKeyword extends TokenBase { return 'import' } + public clone(): ImportKeyword { + return new ImportKeyword(this.startPos); + } + } export class ClassKeyword extends TokenBase { @@ -812,6 +993,10 @@ export class ClassKeyword extends TokenBase { return 'trait'; } + public clone(): ClassKeyword { + return new ClassKeyword(this.startPos); + } + } export class InstanceKeyword extends TokenBase { @@ -822,6 +1007,10 @@ export class InstanceKeyword extends TokenBase { return 'impl'; } + public clone(): InstanceKeyword { + return new InstanceKeyword(this.startPos); + } + } @@ -833,6 +1022,10 @@ export class TypeKeyword extends TokenBase { return 'type'; } + public clone(): TypeKeyword { + return new TypeKeyword(this.startPos); + } + } export class PubKeyword extends TokenBase { @@ -843,6 +1036,10 @@ export class PubKeyword extends TokenBase { return 'pub'; } + public clone(): PubKeyword { + return new PubKeyword(); + } + } export class LetKeyword extends TokenBase { @@ -853,6 +1050,10 @@ export class LetKeyword extends TokenBase { return 'let'; } + public clone(): LetKeyword { + return new LetKeyword(); + } + } export class RArrow extends TokenBase { @@ -863,6 +1064,10 @@ export class RArrow extends TokenBase { return '->'; } + public clone(): RArrow { + return new RArrow(this.startPos); + } + } export class RArrowAlt extends TokenBase { @@ -873,6 +1078,10 @@ export class RArrowAlt extends TokenBase { return '=>'; } + public clone(): RArrowAlt { + return new RArrowAlt(this.startPos); + } + } export class VBar extends TokenBase { @@ -883,6 +1092,10 @@ export class VBar extends TokenBase { return '|'; } + public clone(): VBar { + return new VBar(this.startPos); + } + } export type Token @@ -905,6 +1118,7 @@ export type Token | DotDot | Colon | Equals + | Backslash | LetKeyword | PubKeyword | MutKeyword @@ -941,6 +1155,13 @@ export class ArrowTypeExpression extends SyntaxBase { super(); } + public clone(): ArrowTypeExpression { + return new ArrowTypeExpression( + this.paramTypeExprs.map(te => te.clone()), + this.returnTypeExpr.clone(), + ); + } + public getFirstToken(): Token { if (this.paramTypeExprs.length > 0) { return this.paramTypeExprs[0].getFirstToken(); @@ -966,6 +1187,14 @@ export class TupleTypeExpression extends SyntaxBase { super(); } + public clone(): TupleTypeExpression { + return new TupleTypeExpression( + this.lparen.clone(), + this.elements.map(element => element.clone()), + this.rparen.clone(), + ); + } + public getFirstToken(): Token { return this.lparen; } @@ -987,6 +1216,13 @@ export class ReferenceTypeExpression extends SyntaxBase { super(); } + public clone(): ReferenceTypeExpression { + return new ReferenceTypeExpression( + this.modulePath.map(([name, dot]) => [name.clone(), dot.clone()]), + this.name.clone(), + ); + } + public getFirstToken(): Token { if (this.modulePath.length > 0) { return this.modulePath[0][0]; @@ -1011,6 +1247,13 @@ export class AppTypeExpression extends SyntaxBase { super(); } + public clone(): AppTypeExpression { + return new AppTypeExpression( + this.operator.clone(), + this.args.map(arg => arg.clone()), + ); + } + public getFirstToken(): Token { return this.operator.getFirstToken(); } @@ -1034,6 +1277,10 @@ export class VarTypeExpression extends SyntaxBase { super(); } + public clone(): VarTypeExpression { + return new VarTypeExpression( this.name.clone() ); + } + public getFirstToken(): Token { return this.name; } @@ -1056,6 +1303,14 @@ export class NestedTypeExpression extends SyntaxBase { super(); } + public clone(): NestedTypeExpression { + return new NestedTypeExpression( + this.lparen.clone(), + this.typeExpr.clone(), + this.rparen.clone(), + ); + } + public getFirstToken(): Token { return this.lparen; } @@ -1084,6 +1339,10 @@ export class BindPattern extends SyntaxBase { super(); } + public clone(): BindPattern { + return new BindPattern( this.name.clone() ); + } + public get isHole(): boolean { return this.name.text == '_'; } @@ -1110,6 +1369,14 @@ export class TuplePattern extends SyntaxBase { super(); } + public clone(): TuplePattern { + return new TuplePattern( + this.lparen.clone(), + this.elements.map(element => element.clone()), + this.rparen.clone(), + ); + } + public getFirstToken(): Token { return this.lparen; } @@ -1131,6 +1398,13 @@ export class NamedTuplePattern extends SyntaxBase { super(); } + public clone(): NamedTuplePattern { + return new NamedTuplePattern( + this.name.clone(), + this.elements.map(element => element.clone()), + ); + } + public getFirstToken(): Token { return this.name; } @@ -1156,6 +1430,14 @@ export class StructPatternField extends SyntaxBase { super(); } + public clone(): StructPatternField { + return new StructPatternField( + this.name.clone(), + this.equals.clone(), + this.pattern.clone(), + ); + } + public getFirstToken(): Token { return this.name; } @@ -1177,6 +1459,13 @@ export class VariadicStructPatternElement extends SyntaxBase { super(); } + public clone(): VariadicStructPatternElement { + return new VariadicStructPatternElement( + this.dotdot.clone(), + this.pattern !== null ? this.pattern.clone() : null, + ); + } + public getFirstToken(): Token { return this.dotdot; } @@ -1200,6 +1489,10 @@ export class PunnedStructPatternField extends SyntaxBase { super(); } + public clone(): PunnedStructPatternField { + return new PunnedStructPatternField( this.name.clone() ); + } + public getFirstToken(): Token { return this.name; } @@ -1228,6 +1521,15 @@ export class StructPattern extends SyntaxBase { super(); } + public clone(): StructPattern { + return new StructPattern( + this.name.clone(), + this.lbrace.clone(), + this.members.map(member => member.clone()), + this.rbrace.clone(), + ); + } + public getFirstToken(): Token { return this.name; } @@ -1250,6 +1552,14 @@ export class NestedPattern extends SyntaxBase { super(); } + public clone(): NestedPattern { + return new NestedPattern( + this.lparen.clone(), + this.pattern.clone(), + this.rparen.clone(), + ); + } + public getFirstToken(): Token { return this.lparen; } @@ -1272,6 +1582,14 @@ export class DisjunctivePattern extends SyntaxBase { super(); } + public clone(): DisjunctivePattern { + return new DisjunctivePattern( + this.left.clone(), + this.operator.clone(), + this.right.clone(), + ); + } + public getFirstToken(): Token { return this.left.getFirstToken(); } @@ -1293,6 +1611,10 @@ export class LiteralPattern extends SyntaxBase { super(); } + public clone(): LiteralPattern { + return new LiteralPattern( this.token.clone() ); + } + public getFirstToken(): Token { return this.token; } @@ -1324,6 +1646,14 @@ export class TupleExpression extends SyntaxBase { super(); } + public clone(): TupleExpression { + return new TupleExpression( + this.lparen.clone(), + this.elements.map(element => element.clone()), + this.rparen.clone() + ); + } + public getFirstToken(): Token { return this.lparen; } @@ -1346,6 +1676,14 @@ export class NestedExpression extends SyntaxBase { super(); } + public clone(): NestedExpression { + return new NestedExpression( + this.lparen.clone(), + this.expression.clone(), + this.rparen.clone(), + ); + } + public getFirstToken(): Token { return this.lparen; } @@ -1366,6 +1704,10 @@ export class ConstantExpression extends SyntaxBase { super(); } + public clone(): ConstantExpression { + return new ConstantExpression( this.token.clone() ); + } + public getFirstToken(): Token { return this.token; } @@ -1387,6 +1729,13 @@ export class CallExpression extends SyntaxBase { super(); } + public clone(): CallExpression { + return new CallExpression( + this.func.clone(), + this.args.map(arg => arg.clone()), + ); + } + public getFirstToken(): Token { return this.func.getFirstToken(); } @@ -1412,6 +1761,14 @@ export class StructExpressionField extends SyntaxBase { super(); } + public clone(): StructExpressionField { + return new StructExpressionField( + this.name.clone(), + this.equals.clone(), + this.expression.clone(), + ); + } + public getFirstToken(): Token { return this.name; } @@ -1432,6 +1789,10 @@ export class PunnedStructExpressionField extends SyntaxBase { super(); } + public clone(): PunnedStructExpressionField { + return new PunnedStructExpressionField( this.name.clone() ); + } + public getFirstToken(): Token { return this.name; } @@ -1458,6 +1819,14 @@ export class StructExpression extends SyntaxBase { super(); } + public clone(): StructExpression { + return new StructExpression( + this.lbrace.clone(), + this.members.map(member => member.clone()), + this.rbrace.clone(), + ); + } + public getFirstToken(): Token { return this.lbrace; } @@ -1480,6 +1849,14 @@ export class MatchArm extends SyntaxBase { super(); } + public clone(): MatchArm { + return new MatchArm( + this.pattern.clone(), + this.rarrowAlt.clone(), + this.expression.clone(), + ); + } + public getFirstToken(): Token { return this.pattern.getFirstToken(); } @@ -1490,6 +1867,37 @@ export class MatchArm extends SyntaxBase { } +export class FunctionExpression extends SyntaxBase { + + public readonly kind = SyntaxKind.FunctionExpression; + + public constructor( + public backslash: Backslash, + public params: Param[], + public body: Body, + ) { + super(); + } + + public clone(): FunctionExpression { + return new FunctionExpression( + this.backslash.clone(), + this.params.map(param => param.clone()), + this.body.clone(), + ); + } + + public getFirstToken(): Token { + return this.backslash; + } + + public getLastToken(): Token { + return this.body.getLastToken(); + } + + +} + export class MatchExpression extends SyntaxBase { public readonly kind = SyntaxKind.MatchExpression; @@ -1502,6 +1910,14 @@ export class MatchExpression extends SyntaxBase { super(); } + public clone(): MatchExpression { + return new MatchExpression( + this.matchKeyword.clone(), + this.expression !== null ? this.expression.clone() : null, + this.arms.map(arm => arm.clone()), + ); + } + public getFirstToken(): Token { return this.matchKeyword; } @@ -1529,6 +1945,13 @@ export class ReferenceExpression extends SyntaxBase { super(); } + public clone(): ReferenceExpression { + return new ReferenceExpression( + this.modulePath.map(([name, dot]) => [name.clone(), dot.clone()]), + this.name.clone(), + ); + } + public getFirstToken(): Token { if (this.modulePath.length > 0) { return this.modulePath[0][0]; @@ -1553,6 +1976,13 @@ export class MemberExpression extends SyntaxBase { super(); } + public clone(): MemberExpression { + return new MemberExpression( + this.expression.clone(), + this.path.map(([dot, name]) => [dot.clone(), name.clone()]), + ); + } + public getFirstToken(): Token { return this.expression.getFirstToken(); } @@ -1574,6 +2004,13 @@ export class PrefixExpression extends SyntaxBase { super(); } + public clone(): PrefixExpression { + return new PrefixExpression( + this.operator.clone(), + this.expression.clone(), + ); + } + public getFirstToken(): Token { return this.operator; } @@ -1595,6 +2032,13 @@ export class PostfixExpression extends SyntaxBase { super(); } + public clone(): PostfixExpression { + return new PostfixExpression( + this.expression.clone(), + this.operator.clone(), + ); + } + public getFirstToken(): Token { return this.expression.getFirstToken(); } @@ -1617,6 +2061,14 @@ export class InfixExpression extends SyntaxBase { super(); } + public clone(): InfixExpression { + return new InfixExpression( + this.left.clone(), + this.operator.clone(), + this.right.clone(), + ); + } + public getFirstToken(): Token { return this.left.getFirstToken(); } @@ -1639,6 +2091,7 @@ export type Expression | PrefixExpression | InfixExpression | PostfixExpression + | FunctionExpression export class IfStatementCase extends SyntaxBase { @@ -1653,6 +2106,15 @@ export class IfStatementCase extends SyntaxBase { super(); } + public clone(): IfStatementCase { + return new IfStatementCase( + this.keyword.clone(), + this.test !== null ? this.test.clone() : null, + this.blockStart.clone(), + this.elements.map(element => element.clone()), + ); + } + public getFirstToken(): Token { return this.keyword; } @@ -1676,6 +2138,12 @@ export class IfStatement extends SyntaxBase { super(); } + public clone(): IfStatement { + return new IfStatement( + this.cases.map(caze => caze.clone()), + ); + } + public getFirstToken(): Token { return this.cases[0].getFirstToken(); } @@ -1697,6 +2165,13 @@ export class ReturnStatement extends SyntaxBase { super(); } + public clone(): ReturnStatement { + return new ReturnStatement( + this.returnKeyword.clone(), + this.expression !== null ? this.expression.clone() : null, + ); + } + public getFirstToken(): Token { return this.returnKeyword; } @@ -1720,6 +2195,10 @@ export class ExpressionStatement extends SyntaxBase { super(); } + public clone(): ExpressionStatement { + return new ExpressionStatement( this.expression.clone() ); + } + public getFirstToken(): Token { return this.expression.getFirstToken(); } @@ -1745,6 +2224,12 @@ export class Param extends SyntaxBase { super(); } + public clone(): Param { + return new Param( + this.pattern.clone(), + ); + } + public getFirstToken(): Token { return this.pattern.getFirstToken(); } @@ -1769,6 +2254,14 @@ export class EnumDeclarationStructElement extends SyntaxBase { super(); } + public clone(): EnumDeclarationStructElement { + return new EnumDeclarationStructElement( + this.name.clone(), + this.blockStart.clone(), + this.fields.map(field => field.clone()), + ); + } + public getFirstToken(): Token { return this.name; } @@ -1793,6 +2286,13 @@ export class EnumDeclarationTupleElement extends SyntaxBase { super(); } + public clone(): EnumDeclarationElement { + return new EnumDeclarationTupleElement( + this.name.clone(), + this.elements.map(element => element.clone()), + ); + } + public getFirstToken(): Token { return this.name; } @@ -1826,6 +2326,16 @@ export class EnumDeclaration extends SyntaxBase { super(); } + public clone(): EnumDeclaration { + return new EnumDeclaration( + this.pubKeyword !== null ? this.pubKeyword.clone() : null, + this.enumKeyword.clone(), + this.name.clone(), + this.varExps.map(ve => ve.clone()), + this.members !== null ? this.members.map(member => member.clone()) : null, + ); + } + public getFirstToken(): Token { if (this.pubKeyword !== null) { return this.pubKeyword; @@ -1854,6 +2364,14 @@ export class StructDeclarationField extends SyntaxBase { super(); } + public clone(): StructDeclarationField { + return new StructDeclarationField( + this.name.clone(), + this.colon.clone(), + this.typeExpr.clone(), + ); + } + public getFirstToken(): Token { return this.name; } @@ -1880,6 +2398,16 @@ export class StructDeclaration extends SyntaxBase { super(); } + public clone(): StructDeclaration { + return new StructDeclaration( + this.pubKeyword !== null ? this.pubKeyword.clone() : null, + this.structKeyword.clone(), + this.name.clone(), + this.varExps.map(ve => ve.clone()), + this.fields !== null ? this.fields.map(field => field.clone()) : null, + ); + } + public getFirstToken(): Token { if (this.pubKeyword !== null) { return this.pubKeyword; @@ -1907,6 +2435,13 @@ export class TypeAssert extends SyntaxBase { super(); } + public clone(): TypeAssert { + return new TypeAssert( + this.colon.clone(), + this.typeExpression.clone(), + ); + } + public getFirstToken(): Token { return this.colon; } @@ -1926,12 +2461,19 @@ export class ExprBody extends SyntaxBase { public readonly kind = SyntaxKind.ExprBody; public constructor( - public equals: Equals, + public equals: Equals | RArrow, public expression: Expression, ) { super(); } + public clone(): ExprBody { + return new ExprBody( + this.equals.clone(), + this.expression.clone(), + ); + } + public getFirstToken(): Token { return this.equals; } @@ -1957,6 +2499,13 @@ export class BlockBody extends SyntaxBase { super(); } + public clone(): BlockBody { + return new BlockBody( + this.blockStart.clone(), + this.elements.map(element => element.clone()), + ); + } + public getFirstToken(): Token { return this.blockStart; } @@ -1982,6 +2531,14 @@ export class WrappedOperator extends SyntaxBase { super(); } + public clone(): WrappedOperator { + return new WrappedOperator( + this.lparen.clone(), + this.operator.clone(), + this.rparen.clone(), + ); + } + public getFirstToken(): Token { return this.lparen; } @@ -2009,6 +2566,17 @@ export class TypeDeclaration extends SyntaxBase { super(); } + public clone(): TypeDeclaration { + return new TypeDeclaration( + this.pubKeyword !== null ? this.pubKeyword.clone() : null, + this.typeKeyword.clone(), + this.name.clone(), + this.varExps.map(ve => ve.clone()), + this.equals.clone(), + this.typeExpression.clone(), + ); + } + public getFirstToken(): Token { if (this.pubKeyword !== null) { return this.pubKeyword; @@ -2045,6 +2613,19 @@ export class LetDeclaration extends SyntaxBase { super(); } + public clone(): LetDeclaration { + return new LetDeclaration( + this.pubKeyword !== null ? this.pubKeyword.clone() : null, + this.letKeyword.clone(), + this.foreignKeyword !== null ? this.foreignKeyword.clone() : null, + this.mutKeyword !== null ? this.mutKeyword.clone() : null, + this.pattern.clone(), + this.params.map(param => param.clone()), + this.typeAssert !== null ? this.typeAssert.clone() : null, + this.body !== null ? this.body.clone() : null, + ); + } + public getFirstToken(): Token { if (this.pubKeyword !== null) { return this.pubKeyword; @@ -2078,6 +2659,13 @@ export class ImportDeclaration extends SyntaxBase { super(); } + public clone(): ImportDeclaration { + return new ImportDeclaration( + this.importKeyword.clone(), + this.importSource.clone(), + ); + } + public getFirstToken(): Token { return this.importKeyword; } @@ -2106,6 +2694,13 @@ export class Initializer extends SyntaxBase { super(); } + public clone(): Initializer { + return new Initializer( + this.equals.clone(), + this.expression.clone() + ); + } + public getFirstToken(): Token { return this.equals; } @@ -2127,6 +2722,13 @@ export class ClassConstraint extends SyntaxBase { super(); } + public clone(): ClassConstraint { + return new ClassConstraint( + this.name.clone(), + this.types.map(ty => ty.clone()), + ); + } + public getFirstToken(): Token { return this.name; } @@ -2148,6 +2750,13 @@ export class ClassConstraintClause extends SyntaxBase { super(); } + public clone(): ClassConstraintClause { + return new ClassConstraintClause( + this.constraints.map(constraint => constraint.clone()), + this.rarrowAlt.clone(), + ); + } + public getFirstToken(): Token { if (this.constraints.length > 0) { return this.constraints[0].getFirstToken(); @@ -2209,6 +2818,16 @@ export class ClassDeclaration extends SyntaxBase { } + public clone(): ClassDeclaration { + return new ClassDeclaration( + this.pubKeyword !== null ? this.pubKeyword.clone() : null, + this.classKeyword.clone(), + this.constraints !== null ? this.constraints.clone() : null, + this.constraint.clone(), + this.elements.map(element => element.clone()), + ); + } + public getFirstToken(): Token { if (this.pubKeyword !== null) { return this.pubKeyword; @@ -2243,6 +2862,16 @@ export class InstanceDeclaration extends SyntaxBase { super(); } + public clone(): InstanceDeclaration { + return new InstanceDeclaration( + this.pubKeyword !== null ? this.pubKeyword.clone() : null, + this.classKeyword.clone(), + this.constraints !== null ? this.constraints.clone() : null, + this.constraint.clone(), + this.elements.map(element => element.clone()), + ); + } + public getFirstToken(): Token { if (this.pubKeyword !== null) { return this.pubKeyword; @@ -2275,6 +2904,16 @@ export class ModuleDeclaration extends SyntaxBase { super(); } + public clone(): ModuleDeclaration { + return new ModuleDeclaration( + this.pubKeyword !== null ? this.pubKeyword.clone() : null, + this.modKeyword.clone(), + this.name.clone(), + this.blockStart.clone(), + this.elements.map(element => element.clone()) + ); + } + public getFirstToken(): Token { if (this.pubKeyword !== null) { return this.pubKeyword; @@ -2314,6 +2953,14 @@ export class SourceFile extends SyntaxBase { super(); } + public clone(): SourceFile { + return new SourceFile( + this.file, + this.elements.map(element => element.clone()), + this.eof, + ); + } + public getFirstToken(): Token { if (this.elements.length > 0) { return this.elements[0].getFirstToken(); diff --git a/src/scanner.ts b/src/scanner.ts index 11ba4a373..227905f06 100644 --- a/src/scanner.ts +++ b/src/scanner.ts @@ -44,6 +44,7 @@ import { ModKeyword, ClassKeyword, InstanceKeyword, + Backslash, } from "./cst" import { Diagnostics, UnexpectedCharDiagnostic } from "./diagnostics" import { Stream, BufferedStream, assert } from "./util"; @@ -220,6 +221,7 @@ export class Scanner extends BufferedStream { return new EndOfFile(startPos); } + case '\\': return new Backslash(startPos); case '(': return new LParen(startPos); case ')': return new RParen(startPos); case '[': return new LBracket(startPos);