Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 1 addition & 26 deletions fjs/asn.1/module.f.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @module
*
* @import { Unpacked, Vec } from '../types/bit_vec/types.ts'
* @import { _ParsedTag, _Round8 } from './private.ts'
* @import { ObjectIdentifier, Raw, Record, Sequence, SupportedRecord, _Tag } from './types.ts'
*/

Expand Down Expand Up @@ -32,29 +33,10 @@ const pop8 = pop(8n)

// tag

/**
* @typedef {|
* 0b000_00000n |
* 0b001_00000n |
* 0b010_00000n |
* 0b011_00000n |
* 0b100_00000n |
* 0b101_00000n |
* 0b110_00000n |
* 0b111_00000n
* } _ClassPc
*/

const classPcMask = 0b111_00000n

const tagNumberMask = 0b000_11111n

/**
* Note: the tag number (the second parameter) can be arbitrarily large,
* so we can't just use a single byte to represent it.
* @typedef {readonly[_ClassPc, bigint]} _ParsedTag
*/

/** @type {([classPc, number]: _ParsedTag) => Vec} */
const parsedTagEncode = ([classPc, number]) => {
const [firstByteNumber, rest] = number < tagNumberMask
Expand Down Expand Up @@ -140,13 +122,6 @@ export const constructedSet = 0x31n // constructed | set

//

/**
* @typedef {{
* readonly byteLen: bigint
* readonly v: Vec
* }} _Round8
*/

/** @type {(_: Unpacked) => _Round8} */
const round8 = ({ length, uint }) => {
const byteLen = divUp8(length)
Expand Down
22 changes: 22 additions & 0 deletions fjs/asn.1/private.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Vec } from "../types/bit_vec/types.ts"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep implementation-only types out of private.ts files

This adds authored TypeScript under a new filename even though types.ts is the repository's sole permitted authored TypeScript form. The same violation occurs in fjs/bnf/data/private.ts and fjs/bnf/descent/private.ts; these implementation-only aliases should remain JSDoc typedefs in their .f.mjs owners rather than introducing a second TypeScript source convention.

AGENTS.md reference: fjs/AGENTS.md:L192-L193

Useful? React with 👍 / 👎.


export type _ClassPc = |
0b000_00000n |
0b001_00000n |
0b010_00000n |
0b011_00000n |
0b100_00000n |
0b101_00000n |
0b110_00000n |
0b111_00000n

/**
* Note: the tag number (the second parameter) can be arbitrarily large,
* so we can't just use a single byte to represent it.
*/
export type _ParsedTag = readonly[_ClassPc, bigint]

export type _Round8 = {
readonly byteLen: bigint
readonly v: Vec
}
8 changes: 1 addition & 7 deletions fjs/bnf/data/module.f.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* @module
*
* @import { DataRule, Rule as FRule, Sequence as FSequence } from '../types.ts'
* @import { StringMap } from '../../types/object/types.ts'
* @import { StringSet } from '../../types/string_set/types.ts'
* @import { _EmptyTagMap, _FRuleMap, _NewRule } from './private.ts'
* @import { EmptyTag, Repeat, Rule, RuleSet, Sequence, Variant } from './types.ts'
*/

Expand All @@ -37,8 +37,6 @@ import { contains, set } from '../../types/string_set/module.f.mjs'
*/
export const isRepeat = rule => typeof rule === 'string'

/** @typedef {StringMap<EmptyTag>} _EmptyTagMap */

/** @type {(map: _EmptyTagMap) => (rule: Rule) => EmptyTag} */
const emptyTagOf = map => rule => {
if (typeof rule === 'number') {
Expand Down Expand Up @@ -102,8 +100,6 @@ export const emptyTagMap = ruleSet => {

//

/** @typedef {StringMap<FRule>} _FRuleMap */

const { entries } = Object

/** @type {(map: _FRuleMap) => (fr: FRule) => string | undefined} */
Expand All @@ -127,8 +123,6 @@ const newName = (map, name) => {
return result
}

/** @typedef {(m: _FRuleMap) => readonly [_FRuleMap, RuleSet, Rule]} _NewRule */

/** @type {(list: FSequence) => _NewRule} */
const sequence = list => map => {
/** @type {Sequence} */
Expand Down
9 changes: 9 additions & 0 deletions fjs/bnf/data/private.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { StringMap } from "../../types/object/types.ts"
import type { EmptyTag, Rule, RuleSet } from "./types.ts"
import type { Rule as FRule } from '../types.ts'

export type _EmptyTagMap = StringMap<EmptyTag>

export type _FRuleMap = StringMap<FRule>

export type _NewRule = (m: _FRuleMap) => readonly [_FRuleMap, RuleSet, Rule]
24 changes: 2 additions & 22 deletions fjs/bnf/descent/module.f.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
*
* @module
*
* @import { _Failure, _Result } from './private.ts'
* @import { TerminalRange } from '../types.ts'
* @import { Rule as DataRule, RuleSet, Sequence } from '../data/types.ts'
* @import { Rule as FRule } from '../types.ts'
* @import { List } from '../../types/list/types.ts'
* @import { Ast, AstResult, AstSequence, AstTag, Cursor } from '../matcher/types.ts'
* @import { Ast, AstSequence, AstTag, Cursor } from '../matcher/types.ts'
* @import { CodePointMeta, DescentFailure, DescentMatch, DescentMatchResult, DescentMatchRule } from './types.ts'
*/

Expand All @@ -40,27 +41,6 @@ import { definedEntries } from '../../types/object/module.f.mjs'
import { emptyTagMap, isRepeat, toData } from '../data/module.f.mjs'
import { leafAt, mrFail, mrSuccess, physicalIdx, symbolAt } from '../matcher/module.f.mjs'

/**
* The furthest-failure record while matching, positioned by the complete
* {@link Cursor}. {@link DescentFailure} is its public, physically-positioned
* form.
*
* @typedef {{
* readonly pos: Cursor
* readonly expected: readonly TerminalRange[]
* }} _Failure
*/

/**
* The machine's own result: a {@link DescentMatchResult} positioned by the
* complete cursor, and with no failure record — that one is tracked per match
* rather than per frame. This backend always has a position, so it needs no
* `null` case.
*
* @template T
* @typedef {AstResult<CodePointMeta<T>, Cursor>} _Result
*/

/**
* A leaf here is a code point with its metadata, so its symbol is the first
* half. This is the only thing {@link symbolAt} needs to know about a leaf.
Expand Down
21 changes: 21 additions & 0 deletions fjs/bnf/descent/private.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { AstResult, Cursor } from "../matcher/types.ts"
import type { TerminalRange } from "../types.ts"
import type { CodePointMeta } from "./types.ts"

/**
* The furthest-failure record while matching, positioned by the complete
* {@link Cursor}. {@link DescentFailure} is its public, physically-positioned
* form.
*/
export type _Failure = {
readonly pos: Cursor
readonly expected: readonly TerminalRange[]
}

/**
* The machine's own result: a {@link DescentMatchResult} positioned by the
* complete cursor, and with no failure record — that one is tracked per match
* rather than per frame. This backend always has a position, so it needs no
* `null` case.
*/
export type _Result<T> = AstResult<CodePointMeta<T>, Cursor>
3 changes: 2 additions & 1 deletion fjs/djs/serializer/module.f.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
import { fold } from '../../types/list/module.f.mjs'
import { concat } from '../../types/string/module.f.mjs'
import { flat, flatMap, map, concat as listConcat } from '../../types/list/module.f.mjs'
const { entries } = Object
import { compose, fn } from '../../types/function/module.f.mjs'
import { serialize as bigintSerialize } from '../../types/bigint/module.f.mjs'
import { objectWrap, arrayWrap, colon, stringSerialize, numberSerialize, nullSerialize, boolSerialize } from '../../media/json/serializer/module.f.mjs'
import { assertNotNullish } from '../../asserts/module.f.mjs'

const { entries } = Object

export const undefinedSerialize = ['undefined']

/** @typedef {readonly [number, number]} _RefCounter */
Expand Down
16 changes: 0 additions & 16 deletions fjs/emergent_testing/module.f.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -330,22 +330,6 @@ export const fmtPath = path =>
export const fmtImport = (file, path) =>
`import(${JSON.stringify(file)}).proof${fmtPath(path)}()`

/**
* Renders a key chain for terminal output: `| ` per level of depth, followed
* by the last segment formatted as a bare integer, a bare identifier, or a
* JSON-quoted string. E.g. `['math', 'add']` → `| | add`,
* `['a', '0']` → `| | 0`, `['x', 'hello world']` → `| | "hello world"`.
*
* @type {(path: Path) => string}
*/
export const fmtTerm = path => {
const keys = path.flatMap(k => k !== null ? [k] : [])
const indent = '| '.repeat(keys.length)
if (keys.length === 0) { return `${indent}()` }
const last = keys[keys.length - 1]
return `${indent}${isInteger(last) || isIdentifier(last) ? last : JSON.stringify(last)}`
}

/**

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Record the fmtTerm removal as a breaking change

fmtTerm was a shipped named export in version 0.47.0, so consumers importing it directly from fjs/emergent_testing/module.f.mjs will fail during module linking after upgrading. Because this commit removes the export without adding a **BREAKING CHANGES:** changelog entry, the release process can incorrectly ship it as a patch; add the required breaking entry so the version boundary warns affected consumers.

AGENTS.md reference: AGENTS.md:L100-L107

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the design that still requires fmtTerm

Removing this formatter leaves fjs/fsc/todo/66c-emit-literals-via-owner-modules.md stale: lines 74–80 still list the terminal-output JSON.stringify site, and lines 109–137 instruct the eventual implementation to replace all three emergent_testing sites. Anyone following that concrete design will now search for a nonexistent third site, so revise the issue to describe the remaining two sites rather than silently diverging from it.

AGENTS.md reference: AGENTS.md:L47-L53

Useful? React with 👍 / 👎.

* Percent-encodes characters that GitHub workflow-command property values
* treat as separators (`%`, `:`, `,`) plus newlines.
Expand Down
10 changes: 1 addition & 9 deletions fjs/emergent_testing/proof.f.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { log } from '../effects/node/module.f.mjs'
import { defaultNodeProgramOptions, emptyState, virtual } from '../effects/node/virtual/module.f.mjs'
import { assert, assertEq, todo } from '../asserts/module.f.mjs'
import {
testAll, fmtPath, fmtTerm, fmtImport, ghEscape, isInteger, isIdentifier,
testAll, fmtPath, fmtImport, ghEscape, isInteger, isIdentifier,
registerModule, parseTestSet,
defaultTest, main, register, testResult,
} from './module.f.mjs'
Expand Down Expand Up @@ -595,14 +595,6 @@ export const helpers = {
assertEq(fmtPath(['x', 'hello world']), '.x["hello world"]')
assertEq(fmtPath(['outer', null, 'inner']), '.outer().inner')
},
fmtTerm: () => {
assertEq(fmtTerm([]), '()')
assertEq(fmtTerm(['math', 'add']), '| | add')
assertEq(fmtTerm(['a', '0']), '| | 0')
assertEq(fmtTerm(['x', 'hello world']), '| | "hello world"')
// null marks a function-call boundary; fmtTerm filters it out
assertEq(fmtTerm(['outer', null, 'inner']), '| | inner')
},
ghEscape: () => {
assertEq(ghEscape('a%b'), 'a%25b')
assertEq(ghEscape('a:b'), 'a%3Ab')
Expand Down
Loading