Start cleaning up document and the example parser. I think this is the way to move forward, finally. Next up: DSL on top of functions.

This commit is contained in:
Joshua Bemenderfer
2023-01-30 18:54:13 -05:00
parent b02e742c89
commit 67e7811772
9 changed files with 221 additions and 302 deletions

View File

@@ -1,77 +0,0 @@
import { useDocument } from '@terrace/core'
import { createStringReader } from '@terrace/core/readers/js-string'
export async function parse(lines) {
const { tail, each, match, buildObject } = useDocument(createStringReader(lines))
const structure = {
name: null,
version: null,
license: null,
exports: null,
scripts: null,
devDependencies: null,
author: null
}
await each(async () => {
if (match('name')) structure.name = tail().trim()
if (match('version')) structure.version = tail().trim()
if (match('license')) structure.license = tail().trim()
// FIXME: Order of operations causes other parts to break if this doesn't run first?!
if (match('exports')) structure.exports = await buildObject([], async () => {
const section = { import: null, require: null }
await each(() => {
if (match('import')) section.import = tail().trim()
if (match('require')) section.require = tail().trim()
if (section.import && section.require) return true
})
return section
})
if (match('scripts')) structure.scripts = await buildObject()
if (match('devDependencies')) structure.devDependencies = await buildObject()
if (match('author')) structure.author = await buildObject(['name', 'email', '#text'])
return structure.name &&
structure.version &&
structure.license &&
structure.exports &&
structure.scripts &&
structure.devDependencies &&
structure.author
})
return structure
}
export async function toArrays(lines) {
const { next, level, line } = useDocument(createStringReader(lines))
const levelTracker = []
function createScope(level, line) {
levelTracker.length = level
const scope = levelTracker[level] = [line, []]
return scope
}
createScope(0, 'root')
// Simple parser that produces canonical array structure for blocks.
while (true) {
// If next() returns true we've ended the document.
if (await next()) break;
// Determine parent for this scope.
const parent = levelTracker[level()]
// If there's no parent, skip this line.
if (!parent) continue
// Create new scope
const scope = createScope(level() + 1, line())
// Add current scope to parent.
parent[1].push(scope)
}
return levelTracker[0]
}

View File

@@ -1,40 +1,7 @@
import { parse, toArrays } from './core.js'
import { useDocument } from '@terrace/core'
import { createStringReader } from '@terrace/core/readers/js-string'
const linesArrays = [
`title Example`,
`options`,
` parameter1 30`,
` parameter2 Enim eu id anim minim reprehenderit nostrud eu amet deserunt ea ut do cupidatat ea.`,
`options`,
` parameter1 0`,
` parameter2 Esse incididunt et est adipisicing eiusmod aliqua enim ea aliqua id enim.`,
` deep Enim fugiat do in est commodo culpa dolore.`,
`subsection`,
` position 1`,
` Ea dolore in aliquip fugiat anim adipisicing amet aute tempor et deserunt est duis sint.`,
`subsection 2`,
` position 2`,
` `,
` Aute deserunt incididunt ad in sint adipisicing est officia velit pariatur ipsum deserunt quis nulla.`,
` Ea dolore in aliquip fugiat anim adipisicing amet aute tempor et deserunt est duis sint.`,
`list`,
` - item 1`,
` - item 2`,
`collection`,
` section`,
` lorem ipsum 1`,
` section`,
` lorem ipsum 2`,
`collection2`,
` section`,
` position 3`,
` Laborum aute anim occaecat occaecat pariatur tempor proident magna sit magna non non.`,
` list`,
` 1`,
` 2`
]
const linesParse = [
const lines = [
`name @terrace/core`,
`version 0.0.1`,
`randomthing test`,
@@ -75,35 +42,53 @@ const linesParse = [
` way of dealing with this problem.`,
]
const schema = {
"name": {count: 1},
"version": {count: 1},
"license": {count: 1},
"exports": {count: 1, children: {
"?": {count: -1, children: {
"import": {count: 1},
"require": {count: 1}
}}
}},
"scripts": {count: 1, children: {
"?": { count: -1 }
}},
"devDependencies": {count: 1, children: {
"?": { count: -1 }
}},
"author": { count: 1, children: {
"name": { count: 1 },
"email": { count: 1 },
"? literal": { count: -1 }
}}
}
async function main() {
const resultArrays = await toArrays(linesArrays)
// console.dir(resultArrays, { depth: null })
const { toArrays } = useDocument(createStringReader(lines))
const resultArrays = await toArrays()
console.dir(resultArrays, { depth: null })
const resultParse = await parse(linesParse)
console.dir(resultParse, { depth: null })
const { tail, each, match, buildObject } = useDocument(createStringReader(lines))
const structure = {
name: null,
version: null,
license: null,
exports: null,
scripts: null,
devDependencies: null,
author: null
}
await each(async () => {
if (match('name')) structure.name = tail().trim()
if (match('version')) structure.version = tail().trim()
if (match('license')) structure.license = tail().trim()
// FIXME: Order of operations causes other parts to break if this doesn't run first?!
if (match('exports')) structure.exports = await buildObject([], async () => {
const section = { import: null, require: null }
await each(() => {
if (match('import')) section.import = tail().trim()
if (match('require')) section.require = tail().trim()
if (section.import && section.require) return true
})
return section
})
if (match('scripts')) structure.scripts = await buildObject()
if (match('devDependencies')) structure.devDependencies = await buildObject()
if (match('author')) structure.author = await buildObject(['name', 'email', '#text'])
return structure.name &&
structure.version &&
structure.license &&
structure.exports &&
structure.scripts &&
structure.devDependencies &&
structure.author
})
console.dir(structure, { depth: null })
}
main()