Skip to content

Commit f91cb12

Browse files
committed
extract expression parsing from parsers to functions
1 parent 0fc8c72 commit f91cb12

File tree

1 file changed

+97
-68
lines changed

1 file changed

+97
-68
lines changed

src/ast.ts

Lines changed: 97 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -152,74 +152,12 @@ export namespace syxparser {
152152

153153
if (tt === TokenType.SingleQuote) return ExpressionParser.parseSingleQuotedString(this, put);
154154
else if (tt === TokenType.DoubleQuote) return ExpressionParser.parseDoubleQuotedString(this, put);
155-
else if (tt === TokenType.OpenDiamond) {
156-
157-
const newToken = at(1);
158-
if (newToken.type !== TokenType.Identifier) throw new CompilerError(newToken.range, `Expected identifier after '<', found '${newToken.value}'.`, filePath);
159-
if (!newToken.value.match(primitiveTypes)) throw new CompilerError(newToken.range, `Expected primitive type identifier after '<', found '${newToken.value}'`, filePath);
160-
if (at(2).type !== TokenType.CloseDiamond) throw new CompilerError(at(2).range, `Expected '>' after primitive type identifier, found '${at(2).value}'`, filePath);
161-
const t = tokens.shift();
162-
tokens.shift();
163-
164-
return node({ type: NodeType.PrimitiveType, value: newToken.value, range: combineTwo(t, tokens.shift()) }, put);
165-
} else if (tt === TokenType.WhitespaceIdentifier) {
166-
const { range } = tokens.shift();
167-
return node({ type: NodeType.WhitespaceIdentifier, value: '+s', range }, put);
168-
} else if (tt === TokenType.OpenBrace) {
169-
const { range } = tokens.shift();
170-
171-
const expr: BraceExpression = { type: NodeType.Brace, body: [], value: '{', range: defaultRange };
172-
173-
while (at().type !== TokenType.CloseBrace) {
174-
const stmt = parseStatement(false);
175-
expr.body.push(stmt);
176-
}
177-
expr.range = combineTwo(range, tokens.shift());
178-
return node(expr, put);
179-
180-
} else if (tt === TokenType.OpenParen) {
181-
const { range } = tokens.shift();
182-
183-
const expr: ParenExpression = { type: NodeType.Paren, body: [], value: '(', range: defaultRange };
184-
185-
while (at().type !== TokenType.CloseParen) {
186-
const stmt = parseStatement(false);
187-
expr.body.push(stmt);
188-
}
189-
expr.range = combineTwo(range, tokens.shift());
190-
return node(expr, put);
191-
192-
193-
} else if (tt === TokenType.OpenSquare) {
194-
const { range } = tokens.shift();
195-
196-
const expr: SquareExpression = { type: NodeType.Square, body: [], value: '[', range: defaultRange };
197-
198-
while (at().type !== TokenType.CloseSquare) {
199-
const stmt = parseStatement(false);
200-
expr.body.push(stmt);
201-
}
202-
expr.range = combineTwo(range, tokens.shift());
203-
return node(expr, put);
204-
205-
206-
} else if (tt === TokenType.Identifier && at(1).type === TokenType.VarSeperator) {
207-
208-
if (at(2).type !== TokenType.IntNumber) throw new CompilerError(at(2).range, `Expected index after ${at().value} variable, found ${at(2).value}.`, filePath);
209-
210-
const id = tokens.shift(); // id
211-
tokens.shift(); // sep
212-
const index = tokens.shift(); // index
213-
const expr: VariableExpression = { index: parseInt(index.value), type: NodeType.Variable, value: id.value, range: combineTwo(id, index) };
214-
215-
return node(expr, put);
216-
} else if (keywords.includes(tt)) {
217-
if (!statements) throw new CompilerError(at().range, 'Statement not allowed here.', filePath);
218-
return parseStatement();
219-
} else if (tt === TokenType.Identifier && expectIdentifier) {
220-
const { value, range } = tokens.shift();
221-
return node({ type: NodeType.String, value, range }, put);
222-
}
155+
else if (tt === TokenType.OpenDiamond) return ExpressionParser.parsePrimitiveType(this, primitiveTypes, put);
156+
else if (tt === TokenType.WhitespaceIdentifier) return ExpressionParser.parseWhitespaceIdentifier(this, put);
157+
else if (tt === TokenType.OpenBrace) return ExpressionParser.parseBraceExpression(this, put, defaultRange);
158+
else if (tt === TokenType.OpenSquare) return ExpressionParser.parseSquareExpression(this, put, defaultRange);
159+
else if (tt === TokenType.OpenParen) return ExpressionParser.parseParenExpression(this, put, defaultRange);
160+
else if (tt === TokenType.Identifier && at(1).type === TokenType.VarSeperator) return ExpressionParser.parsePrimitiveVariable(this, put);
223161
else throw new CompilerError(at().range, `Unexpected expression: '${at().value}'`, filePath);
224162

225163

@@ -593,4 +531,95 @@ namespace ExpressionParser {
593531
return node({ type: NodeType.String, value: s, range: combineTwo(range, tokens.shift()) }, put);
594532
}
595533

534+
/**
535+
* Parses a primitive type expression. Parameters are related to the environment of {@link syxparser.parseExpression} or {@link sysparser.parseExpression}.
536+
* @returns Parsed node.
537+
*/
538+
export function parsePrimitiveType({ at, tokens, filePath, combineTwo, node }: parser, primitiveTypes: RegExp, put: boolean): Node {
539+
const newToken = at(1);
540+
if (newToken.type !== TokenType.Identifier) throw new CompilerError(newToken.range, `Expected identifier after '<', found '${newToken.value}'.`, filePath);
541+
if (!primitiveTypes.test(newToken.value)) throw new CompilerError(newToken.range, `Expected primitive type identifier after '<', found '${newToken.value}'`, filePath);
542+
if (at(2).type !== TokenType.CloseDiamond) throw new CompilerError(at(2).range, `Expected '>' after primitive type identifier, found '${at(2).value}'`, filePath);
543+
const t = tokens.shift();
544+
tokens.shift();
545+
return node({ type: NodeType.PrimitiveType, value: newToken.value, range: combineTwo(t, tokens.shift()) }, put);
546+
}
547+
548+
/**
549+
* Parses a whitespace identifier expression. Parameters are related to the environment of {@link syxparser.parseExpression} or {@link sysparser.parseExpression}.
550+
* @returns Parsed node.
551+
*/
552+
export function parseWhitespaceIdentifier({ node, tokens }: parser, put: boolean): Node {
553+
const { range } = tokens.shift();
554+
return node({ type: NodeType.WhitespaceIdentifier, value: '+s', range }, put);
555+
}
556+
557+
/**
558+
* Parses a brace expression. Parameters are related to the environment of {@link syxparser.parseExpression} or {@link sysparser.parseExpression}.
559+
* @returns Parsed node.
560+
*/
561+
export function parseBraceExpression({ tokens, parseStatement, combineTwo, node, at }: parser, put: boolean, dr: Range) {
562+
const { range } = tokens.shift();
563+
564+
const expr: BraceExpression = { type: NodeType.Brace, body: [], value: '{', range: dr };
565+
566+
while (at().type !== TokenType.CloseBrace) {
567+
const stmt = parseStatement(false);
568+
expr.body.push(stmt);
569+
}
570+
expr.range = combineTwo(range, tokens.shift());
571+
return node(expr, put);
572+
}
573+
574+
/**
575+
* Parses a square expression. Parameters are related to the environment of {@link syxparser.parseExpression} or {@link sysparser.parseExpression}.
576+
* @returns Parsed node.
577+
*/
578+
export function parseSquareExpression({ tokens, parseStatement, combineTwo, node, at }: parser, put: boolean, dr: Range) {
579+
const { range } = tokens.shift();
580+
581+
const expr: SquareExpression = { type: NodeType.Square, body: [], value: '[', range: dr };
582+
583+
while (at().type !== TokenType.CloseSquare) {
584+
const stmt = parseStatement(false);
585+
expr.body.push(stmt);
586+
}
587+
expr.range = combineTwo(range, tokens.shift());
588+
return node(expr, put);
589+
}
590+
591+
592+
/**
593+
* Parses a paren expression. Parameters are related to the environment of {@link syxparser.parseExpression} or {@link sysparser.parseExpression}.
594+
* @returns Parsed node.
595+
*/
596+
export function parseParenExpression({ tokens, parseStatement, combineTwo, node, at }: parser, put: boolean, dr: Range) {
597+
const { range } = tokens.shift();
598+
599+
const expr: ParenExpression = { type: NodeType.Paren, body: [], value: '(', range: dr };
600+
601+
while (at().type !== TokenType.CloseParen) {
602+
const stmt = parseStatement(false);
603+
expr.body.push(stmt);
604+
}
605+
expr.range = combineTwo(range, tokens.shift());
606+
return node(expr, put);
607+
}
608+
609+
/**
610+
* Parses a primitive variable expression. Parameters are related to the environment of {@link syxparser.parseExpression} or {@link sysparser.parseExpression}.
611+
* @returns Parsed node.
612+
*/
613+
export function parsePrimitiveVariable({ at, tokens, node, filePath, combineTwo }: parser, put: boolean) {
614+
615+
if (at(2).type !== TokenType.IntNumber) throw new CompilerError(at(2).range, `Expected index after ${at().value} variable, found ${at(2).value}.`, filePath);
616+
617+
const id = tokens.shift(); // id
618+
tokens.shift(); // sep
619+
const index = tokens.shift(); // index
620+
const expr: VariableExpression = { index: parseInt(index.value), type: NodeType.Variable, value: id.value, range: combineTwo(id, index) };
621+
622+
return node(expr, put);
623+
}
624+
596625
}

0 commit comments

Comments
 (0)