diff --git a/src/lang/parser/parser.ts b/src/lang/parser/parser.ts
index 57b9c35..8fa089d 100644
--- a/src/lang/parser/parser.ts
+++ b/src/lang/parser/parser.ts
@@ -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(cursor: Cursor, delimiter: CodePoint, terminator: CodePoint, p: Parser): A[] {
+function delimitedTerminalSequence(cursor: Cursor, delimiter: CodePoint, terminator: CodePoint | undefined, p: Parser): 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 {
}
}
+
+function functionParameters(cursor: Cursor): ProductPattern[] {
+ const parameters = delimitedTerminalSequence(cursor, DELIMITER_COMMA, undefined, productPattern);
+ return parameters;
+}
+
+export function parseFunctionParameters(source: SourceText): Result {
+ 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);
+ }
+}
+
diff --git a/src/lang/parser/source_text.ts b/src/lang/parser/source_text.ts
index 6a32584..d99eb10 100644
--- a/src/lang/parser/source_text.ts
+++ b/src/lang/parser/source_text.ts
@@ -110,7 +110,7 @@ export class SourceText {
}
}
-export function sourceText(s: string) {
+export function sourceText(s: string): SourceText {
return new SourceText(s);
}