feat: Translate VRML 1 to VRML97 #6
@ -1,6 +1,7 @@
|
|||||||
moo from ../deps/moo.js
|
moo from ../deps/moo.js
|
||||||
|
import type {Lexer, Token} from ../deps/moo.d.ts
|
||||||
|
|
||||||
type Tree = {[key:string]: string | Tree}
|
type Tree = {[key:string]: (string | Tree)[]}
|
||||||
|
|
||||||
lexer := moo.compile
|
lexer := moo.compile
|
||||||
comment: /#.*?$/
|
comment: /#.*?$/
|
||||||
@ -20,27 +21,66 @@ lexer := moo.compile
|
|||||||
oparen: '('
|
oparen: '('
|
||||||
cparen: ')'
|
cparen: ')'
|
||||||
|
|
||||||
export function tree97(vrml1: string): Tree
|
export function tree97(vrml1: string)
|
||||||
tree: Tree := {}
|
parse lexer.reset vrml1
|
||||||
for tok, index of lexer.reset vrml1
|
|
||||||
if tok.type and tok.type !== 'whitespace' and tok.type !== 'comment'
|
// separatorIgnore :=
|
||||||
tree[`${index}`] = {tok.type, tok.value}
|
// 'TextureCoordinate Normal Coordinate Texture Material'.split(' ')
|
||||||
|
|
||||||
|
function filtered(stream: Lexer): Token | undefined
|
||||||
|
result .= stream.next()
|
||||||
|
while result and (result.type === 'whitespace' or result.type === 'comment')
|
||||||
|
result = stream.next()
|
||||||
|
result
|
||||||
|
|
||||||
|
function parse(stream: Lexer, tree: Tree = {}): Tree
|
||||||
|
deferred: Token[] := []
|
||||||
|
held .= filtered stream // for lookahead
|
||||||
|
|
||||||
|
while next := filtered stream
|
||||||
|
unless held break
|
||||||
|
switch data :=
|
||||||
|
{nt: next.type, nv: next.value, ht: held.type, hv: held.value}
|
||||||
|
{ht: 'word', nt: 'obrace'}
|
||||||
|
switch held.value
|
||||||
|
/(?:Transform)?Separator/
|
||||||
|
{children, ...context} := tree
|
||||||
|
subTree := parse(stream, context)
|
||||||
|
// separatorIgnore.map((prop) => subTree.delete prop) // unneeded?
|
||||||
|
if newKids := subTree.children
|
||||||
|
if 'children' not in tree then tree.children = []
|
||||||
|
tree.children.push(`
|
||||||
|
Transform { children [
|
||||||
|
${renderList newKids}
|
||||||
|
] }`)
|
||||||
|
/Group|Switch|WWWAnchor/
|
||||||
|
{children, ...context} := tree
|
||||||
|
subTree := parse(stream, context)
|
||||||
|
if newKids := subTree.children
|
||||||
|
if 'children' not in tree then tree.children = []
|
||||||
|
tree.children.push(`
|
||||||
|
Group { children [
|
||||||
|
${renderList newKids}
|
||||||
|
] }`)
|
||||||
|
held = filtered stream
|
||||||
|
{ht: 'word', hv: 'vertexOrdering', nt: 'word', nv: 'COUNTERCLOCKWISE'}
|
||||||
|
tree.vertexOrdering = ['ccw']
|
||||||
|
held = filtered stream
|
||||||
|
else
|
||||||
|
console.log 'How did I end up with held', held, 'and next', next
|
||||||
|
unless held and held.type === 'cbrace'
|
||||||
|
console.log 'Oddly ended up with held', held
|
||||||
tree
|
tree
|
||||||
|
|
||||||
function render(t: string | Tree): string
|
function render(t: string | Tree): string
|
||||||
if typeof t is 'string'
|
if typeof t is 'string'
|
||||||
return t
|
return t
|
||||||
result .= ''
|
return .= ''
|
||||||
for item of Object.values t
|
for prop in t
|
||||||
if typeof item is 'string' then result += item + ' '
|
return.value += ` ${prop}: ${renderList t[prop]}\n`
|
||||||
else
|
|
||||||
typ := item.type
|
function renderList(l: (string | Tree)[]): string
|
||||||
result += render(typ)
|
l.map(render).join(' ')
|
||||||
if typeof typ === 'string' and
|
|
||||||
['cbrace', 'cbracket', 'cparen'].includes(typ)
|
|
||||||
result += "\n"
|
|
||||||
else result += ' '
|
|
||||||
result
|
|
||||||
|
|
||||||
export function convert(vrml1: string): string
|
export function convert(vrml1: string): string
|
||||||
render tree97 vrml1
|
render tree97 vrml1
|
||||||
|
Loading…
Reference in New Issue
Block a user