Create proper validation library. Rewrite new-function-draft component.
This commit is contained in:
parent
0941756bf9
commit
8e4dcb5de7
8 changed files with 366 additions and 55 deletions
|
|
@ -2,7 +2,7 @@ import { Cursor } from './cursor';
|
|||
import { ExprScanError, exprStart, ExprStartToken, IdentifierKind, identifierScanner, isNextTokenExprStart, isNextTokenProductPatternStart, patternStart, PatternStartToken, signalExprStart, SignalExprStartToken, skipWhitespaceAndComments } from './scanner';
|
||||
import { char, CodePoint, SourceText, Span } from './source_text';
|
||||
import { Result } from '../result';
|
||||
import { Expr, ExprBinding, FieldAssignment, FieldPattern, MatchBranch, Pattern, ProductPattern, SignalExpr } from '../expr';
|
||||
import { Expr, ExprBinding, FieldAssignment, FieldPattern, FunctionName, MatchBranch, Pattern, ProductPattern, SignalExpr } from '../expr';
|
||||
|
||||
// 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.
|
||||
|
|
@ -492,8 +492,7 @@ function finishProductPattern(cursor: Cursor, token: PatternStartToken): Product
|
|||
switch (token.kw) {
|
||||
case ":": {
|
||||
// :( a = p, b )
|
||||
// TODO: parse open-paren
|
||||
if (!tryConsume(cursor, char('{'))) {
|
||||
if (!tryConsume(cursor, char('('))) {
|
||||
throw {
|
||||
tag: "ExpectedRecordPatternOpen",
|
||||
span: cursor.makeSpan(cursor.currentLocation())
|
||||
|
|
@ -598,3 +597,25 @@ export function parseFunctionParameters(source: SourceText): Result<ProductPatte
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
export function parseFunctionName(source: SourceText): Result<FunctionName, ParseError> {
|
||||
const cursor = new Cursor(source);
|
||||
try {
|
||||
skipWhitespaceAndComments(cursor);
|
||||
// TODO: We should introduce new `function_name`
|
||||
const name = identifier(cursor, "function_call");
|
||||
|
||||
if (!cursor.eof()) {
|
||||
return Result.error({
|
||||
tag: "UnexpectedToken",
|
||||
expected: "EndOfFile",
|
||||
span: cursor.makeSpan(cursor.currentLocation())
|
||||
} as ParseError);
|
||||
}
|
||||
|
||||
return Result.ok(name.name);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ type PrimitiveSignalDefinition = {
|
|||
|
||||
export namespace Program {
|
||||
|
||||
type Error =
|
||||
export type Error =
|
||||
| { tag: "DuplicateFunctionName", name: FunctionName }
|
||||
| { tag: "FunctionNotFound", name: FunctionName }
|
||||
| { tag: "CannotEditPrimitiveFunction", name: FunctionName }
|
||||
|
|
@ -98,7 +98,7 @@ export namespace Program {
|
|||
| { tag: "CannotDeletePrimitiveSignal", name: SignalName }
|
||||
| { tag: "PrimitiveSignalAlreadyExists", name: SignalName }
|
||||
|
||||
type Result<T> =
|
||||
export type Result<T> =
|
||||
| { tag: "ok", value: T }
|
||||
| { tag: "error", error: Error }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue