diff --git a/src/main.ts b/src/main.ts index c321126..111bc29 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,5 @@ export { parseDocument } from './parser'; -export type { FoundSyntax, ParseDocumentResult, ParseError } from './parser'; +export type { ParseDocumentResult } from './parser'; +export type { FoundSyntax, ParseError } from './parse_errors'; export { ConcreteSyntax, Expr } from './syntax'; export type { ConcreteSyntax as ConcreteSyntaxNode, Expr as ExprNode } from './syntax'; diff --git a/src/new_syntax.ts b/src/new_syntax.ts new file mode 100644 index 0000000..77a2851 --- /dev/null +++ b/src/new_syntax.ts @@ -0,0 +1,60 @@ +import type { CodePointSpan } from 'source-region'; +import type { ParseError } from './parse_errors'; + +export type ConcreteSyntaxResult = +| { tag: "valid", value: ValidConcreteSyntax } +| { tag: "invalid", value: PartialConcreteSyntax } + +// The main constraints are +// - `ValidConcreteSyntax` should be a subtype of `PartialConcreteSyntax` +// - if `PartialConcreteSyntax` doesn't contain any sort of error nodes, we should be able to coerce it to `ValidConcreteSyntax` without rebuilding the whole tree +export type ValidConcreteSyntax = Program<{ span: CodePointSpan }, never> +export type PartialConcreteSyntax = Program<{ span: CodePointSpan }, ConcreteError > + +export type ConcreteError = ConcreteErrorNode[] // Can't be empty array. +export type ConcreteErrorNode = { + span: CodePointSpan, + error: ParseError, + panickedOver?: CodePointSpan, +} + +export type DelimiterToken = + | { tag: "open-paren"; span: CodePointSpan } + | { tag: "close-paren"; span: CodePointSpan } + | { tag: "open-bracket"; span: CodePointSpan } + | { tag: "close-bracket"; span: CodePointSpan }; + +export type Program = { + expressions: Expr[], + error?: Error, +} & Info + +export type Expr = +| Literal +| List +| { tag: "error-expression", error: Error } & Info // This is for errors that don't really correspond to any sort of node. Unknown errors. + +export type List = + { tag: "list", open: DelimiterToken, items: ListItem[], close?: DelimiterToken, error?: Error } & Info + +export type ListItem = +| Expr +| { tag: "error-list-separator", error: Error } & Info + +export type Literal = +// === number === +| { tag: "number", value: number } & Info +| { tag: "error-number", error: Error } & Info +// === identifier === +| { tag: "identifier", value: Identifier } & Info +| { tag: "error-identifier", error: Error } & Info + +export type Identifier = string + + + +export namespace ConcreteError { + export function single(node: ConcreteErrorNode): ConcreteError { + return [node]; + } +} diff --git a/src/parse_errors.ts b/src/parse_errors.ts new file mode 100644 index 0000000..5599ffb --- /dev/null +++ b/src/parse_errors.ts @@ -0,0 +1,33 @@ +import type { CodePoint, CodePointSpan } from 'source-region'; + +export type ParseError = +| { + tag: "expected-expression"; + span: CodePointSpan; + found: FoundSyntax; + } +| { + tag: "expected-close-paren"; + span: CodePointSpan; + openParen: CodePointSpan; + found: FoundSyntax; + } +| { + tag: "unexpected-close-paren"; + span: CodePointSpan; + } +| { + tag: "unexpected-code-point"; + span: CodePointSpan; + found: FoundSyntax; + } +| { + tag: "invalid-number"; + span: CodePointSpan; + text: string; + reason: "unsafe-integer"; + }; + +export type FoundSyntax = +| { tag: "code-point"; value: CodePoint; span: CodePointSpan } +| { tag: "eof"; span: CodePointSpan }; diff --git a/src/parser.ts b/src/parser.ts index b967d30..da158f9 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -12,6 +12,7 @@ import type { CodePointSpan, SourceRegion, } from 'source-region'; +import type { FoundSyntax, ParseError } from './parse_errors'; import { consumeWhile, consumeWhile1, skipWhile } from './recognizers'; import { ConcreteSyntax } from './syntax'; @@ -42,38 +43,6 @@ export type ParseDocumentResult = { errors: ParseError[]; }; -export type ParseError = -| { - tag: "expected-expression"; - span: CodePointSpan; - found: FoundSyntax; - } -| { - tag: "expected-close-paren"; - span: CodePointSpan; - openParen: CodePointSpan; - found: FoundSyntax; - } -| { - tag: "unexpected-close-paren"; - span: CodePointSpan; - } -| { - tag: "unexpected-code-point"; - span: CodePointSpan; - found: FoundSyntax; - } -| { - tag: "invalid-number"; - span: CodePointSpan; - text: string; - reason: "unsafe-integer"; - }; - -export type FoundSyntax = -| { tag: "code-point"; value: CodePoint; span: CodePointSpan } -| { tag: "eof"; span: CodePointSpan }; - export function parseDocument(region: SourceRegion): ParseDocumentResult { return new Parser(region).parseDocument(); } diff --git a/src/ui/App.tsx b/src/ui/App.tsx index 7255ea8..5c8103e 100644 --- a/src/ui/App.tsx +++ b/src/ui/App.tsx @@ -2,7 +2,7 @@ import { createMemo, createSignal, Show } from 'solid-js'; import { sourceText } from 'source-region'; import type { CodePointSpan, SourceRegion, SourceText } from 'source-region'; import { parseDocument } from '../parser'; -import type { ParseError } from '../parser'; +import type { ParseError } from '../parse_errors'; import type { ConcreteSyntax } from '../syntax'; import { spanLabel } from './format'; import { PaneHeader, PaneSplitter } from './Pane'; diff --git a/src/ui/SyntaxPane.tsx b/src/ui/SyntaxPane.tsx index faf6353..2e7e325 100644 --- a/src/ui/SyntaxPane.tsx +++ b/src/ui/SyntaxPane.tsx @@ -1,7 +1,7 @@ import { For, Show } from 'solid-js'; import type { JSX } from 'solid-js'; import type { CodePointSpan } from 'source-region'; -import type { ParseError } from '../parser'; +import type { ParseError } from '../parse_errors'; import type { ConcreteSyntax } from '../syntax'; import { Expr } from '../syntax'; import { errorDetail, errorLabel, errorTitle } from './format'; diff --git a/src/ui/format.ts b/src/ui/format.ts index 56be364..63d8cf2 100644 --- a/src/ui/format.ts +++ b/src/ui/format.ts @@ -1,5 +1,5 @@ import type { CodePointSpan } from 'source-region'; -import type { FoundSyntax, ParseError } from '../parser'; +import type { FoundSyntax, ParseError } from '../parse_errors'; export function errorTitle(error: ParseError): string { switch (error.tag) {