fix some stuff

This commit is contained in:
Rowan 2025-04-16 23:51:16 -05:00
parent 484502213e
commit 170e4b2ae6
4 changed files with 12 additions and 35 deletions

View file

@ -1,8 +1,8 @@
import { State } from './state.js' import { State } from './state.js'
import { anyOf } from './combinator.js' import { anyOf, map } from './combinator.js'
import { Alpha, Alphanumeric, Digits, LowerAlpha, UpperAlpha } from './const.js' import { Alpha, Alphanumeric, Digits, LowerAlpha, UpperAlpha } from './const.js'
import { fail, join, mapStr, next, succeed } from './fn.js' import { fail, join, mapStr, next, succeed } from './fn.js'
import { map, seq } from './seq.js' import { seq } from './seq.js'
import { curry } from '../vendor/izuna/src/curry.js' import { curry } from '../vendor/izuna/src/curry.js'
/** @import { ParserState } from './state.js' */ /** @import { ParserState } from './state.js' */
@ -12,12 +12,9 @@ export const char = curry(
* @param {string} ch * @param {string} ch
* @param {ParserState} state * @param {ParserState} state
*/ */
//(ch, state) => ( (ch, state) => (
// next(state) === ch ? succeed(ch, state) : fail(`could not parse ${ch} `, state) next(state) === ch ? succeed(ch, state) : fail(`could not parse ${ch} `, state)
//)) ))
(ch, state) => {
return next(state) === ch ? succeed(ch, state) : fail(`could not parse ${ch} `, state)
})
export const str = curry( export const str = curry(
/** /**

View file

@ -1,5 +1,5 @@
import { char } from './char.js' import { char } from './char.js'
import { fail, fork, mapStr } from './fn.js' import { diff, fail, fork, mapStr, succeed, Tuple } from './fn.js'
import { curry } from '../vendor/izuna/src/curry.js' import { curry } from '../vendor/izuna/src/curry.js'
/** @import { ParserState } from './state.js' */ /** @import { ParserState } from './state.js' */

View file

@ -19,12 +19,13 @@ export const maybe = curry(
}) })
export const not = curry((parser, state) => { export const not = curry((parser, state) => {
const result = parser(state) const [original, clone] = fork(state)
const result = parser(clone)
if (result.isOk()) { if (result.isOk()) {
return fail('"not" parser failed', state) return fail('"not" parser failed', original)
} else { } else {
return succeed([], state) return succeed([], original)
} }
}) })

View file

@ -51,34 +51,13 @@ export const seq = (...parsers) =>
return acc return acc
} }
export const map = curry(
/**
* @param {(...args: any[]) => any} fn
* @param {Parser} parser
* @param {ParserState} state
*/
(fn, parser, state) => {
return parser(state).chain(result => {
try {
/** @type {Result<ParserState, ParseError>} */
const parsed = fn(diff(state[0], result[0]))
const backtrack = Tuple(state[0], result[1])
return succeed(parsed, backtrack)
} catch (e) {
return fail('failed to map', state, e)
}
})
})
export const many = curry((parser, state) => { export const many = curry((parser, state) => {
let result = ok(state) let result = ok(state)
while (true) { while (true) {
const [a, b] = fork(state) const [original, clone] = result.chain(fork)
const res = parser(clone(result.unwrap())) const res = parser(clone)
if (res.isOk()) { if (res.isOk()) {
result = res result = res
} else { } else {