Parser for function parameters
This commit is contained in:
parent
5dfa31f27f
commit
24c09c8fbe
2 changed files with 31 additions and 2 deletions
|
|
@ -3,6 +3,8 @@ import { ExprScanError, exprStart, ExprStartToken, IdentifierKind, identifierSca
|
|||
import { char, CodePoint, SourceText, Span } from './source_text';
|
||||
import { Result } from '../result';
|
||||
import { Expr, ExprBinding, FieldAssignment, FieldPattern, MatchBranch, Pattern, ProductPattern } from '../expr';
|
||||
import { UserFunctionDefinition } from '../program';
|
||||
import { Product } from 'electron';
|
||||
|
||||
// CONVENTION: Every parser is responsible to consume whitespace/comments at the end.
|
||||
// Every parser is not responsible for cleaning up whitespace/comments at the start - only the final `parse` that's exposed to the public.
|
||||
|
|
@ -83,7 +85,7 @@ function tryConsume(cursor: Cursor, expected: CodePoint): boolean {
|
|||
|
||||
// TODO: Perhaps when it comes to terminators, we should allow the user of this function to create better contextual errors?
|
||||
// Parses a delimited sequence of `p` that's terminated by a special character.
|
||||
function delimitedTerminalSequence<A>(cursor: Cursor, delimiter: CodePoint, terminator: CodePoint, p: Parser<A>): A[] {
|
||||
function delimitedTerminalSequence<A>(cursor: Cursor, delimiter: CodePoint, terminator: CodePoint | undefined, p: Parser<A>): A[] {
|
||||
// Let's say the terminator is `.` and delimiter is `,`. This is the grammar for valid sequences
|
||||
// list(p) :=
|
||||
// | p
|
||||
|
|
@ -473,3 +475,30 @@ export function parse(source: SourceText): Result<Expr, ParseError> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function functionParameters(cursor: Cursor): ProductPattern[] {
|
||||
const parameters = delimitedTerminalSequence(cursor, DELIMITER_COMMA, undefined, productPattern);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
export function parseFunctionParameters(source: SourceText): Result<ProductPattern[], ParseError> {
|
||||
const cursor = new Cursor(source);
|
||||
try {
|
||||
skipWhitespaceAndComments(cursor);
|
||||
const parameters = functionParameters(cursor);
|
||||
|
||||
if (!cursor.eof()) {
|
||||
return Result.error({
|
||||
tag: "UnexpectedToken",
|
||||
expected: "EndOfFile",
|
||||
span: cursor.makeSpan(cursor.currentLocation())
|
||||
} as ParseError);
|
||||
}
|
||||
|
||||
return Result.ok(parameters);
|
||||
} catch (e) {
|
||||
// TODO: This is a bit sketchy. We maybe forced to have "checked" Exceptions for `ParseError` by wrapping it in something that has a proper tag.
|
||||
return Result.error(e as ParseError);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export class SourceText {
|
|||
}
|
||||
}
|
||||
|
||||
export function sourceText(s: string) {
|
||||
export function sourceText(s: string): SourceText {
|
||||
return new SourceText(s);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue