@@ 79,7 79,7 @@ function parseObj (tokens) {
throw new Error(`Comma missing in pattern? ${JSON.stringify(tokens)}`)
return
}
- result[key] = parsePatternFragment(token)
+ result[key] = parsePatternFragment([token])
key = null
mode = null
} else {
@@ 119,49 119,54 @@ function parsePatternGroup(tokens) {
}
}
if (tokens.length === 1) {
- return parsePatternFragment(tokens[0])
+ return parsePatternFragment(tokens)
} else if (tokens.length === 0) {
throw new Error('Missing tokens in pattern')
} else {
return {
type: GROUP,
- data: parsePatternFragment(tokens[0]),
+ data: parsePatternFragment([tokens[0]]),
patterns: parseGroups(tokens.slice(1)).patterns
}
}
}
-function parsePatternFragment (group) {
- if (typeof group === 'object') {
- if (group.type === 'brackets') {
- const result = parseObj(group.tokens)
+function parsePatternFragment (tokens) {
+ if (tokens.length !== 1) {
+ console.log(tokens)
+ throw Error(`Only one token allowed for pattern fragments: ${JSON.stringify(tokens)}`)
+ }
+ token = tokens[0]
+ if (typeof token === 'object') {
+ if (token.type === 'brackets') {
+ const result = parseObj(token.tokens)
return {
type: OBJ,
value: result
}
- } else if (group.type === 'square') {
- const result = parseList(group.tokens)
+ } else if (token.type === 'square') {
+ const result = parseList(token.tokens)
return {
type: LIST,
value: result
}
- } else if (group.type === 'quote') {
+ } else if (token.type === 'quote') {
return {
type: LIT,
- value: group.tokens.join('')
+ value: token.tokens.join('')
}
- } else if (group.type === 'parens') {
- return parsePatternGroup(group.tokens)
+ } else if (token.type === 'parens') {
+ return parsePatternGroup(token.tokens)
}
} else {
- const number = parseFloat(group);
+ const number = parseFloat(token);
if (!isNaN(number)) {
return { type: LIT, value: number }
}
// This is a single token, which we assume is a reference
return {
type: REF,
- value: group
+ value: token
}
}
}
@@ 197,31 202,49 @@ function processPipeToken (r, tokens) {
}
function processPatternMatch(r, tokens) {
- if (tokens.length !== 1) {
- console.error(r)
- throw Error(`Only one token allowed for pattern results: ${JSON.stringify(tokens)}`)
- }
- token = tokens[0]
return {
...r,
mode: 'pending',
match: null,
+ opeartion: null,
pendingPatterns: r.pendingPatterns.concat([{
type: PATTERN,
match: r.match,
- result: parsePatternFragment(token)
+ condition: r.condition,
+ result: parsePatternFragment(tokens)
}]),
}
}
+function endPattern(r) {
+ let result;
+ if (r.match) {
+ result = processPatternMatch(r, r.pendingTokens)
+ } else {
+ result = processPipeToken(r, r.pendingTokens)
+ }
+ return {
+ ...result,
+ mode: null,
+ pendingTokens: [],
+ pendingPatterns: [],
+ patterns: result.patterns.concat([result.pendingPatterns])
+ }
+}
+
function parseGroups (tokenGroups) {
- const result = tokenGroups.reduce((r, token) => {
+ let result = tokenGroups.reduce((r, token) => {
if (!r.mode) {
if (token === 'def') {
return {
...r,
mode: 'define'
}
+ } else if (token === '|') {
+ return {
+ ...r,
+ mode: 'pending'
+ }
} else {
return {
...r,
@@ 238,29 261,34 @@ function parseGroups (tokenGroups) {
result = processPipeToken(r, r.pendingTokens)
}
if (result) {
- return { ...result, pendingTokens: [] }
+ return { ...result, isCondition: undefined, pendingTokens: [] }
}
} else if (token === ':') {
+ if (r.isCondition) {
+ return {
+ ...r,
+ mode: 'pending',
+ pendingTokens: [],
+ condition: parsePatternFragment(r.pendingTokens),
+ }
+ } else {
+ return {
+ ...r,
+ mode: 'pending',
+ pendingTokens: [],
+ match: parsePatternFragment(r.pendingTokens),
+ }
+ }
+ } else if (token === '?') {
return {
...r,
mode: 'pending',
+ isCondition: true,
pendingTokens: [],
- match: parsePatternFragment(r.pendingTokens[0]),
+ match: parsePatternFragment(r.pendingTokens),
}
} else if (token === ';') {
- let result;
- if (r.match) {
- result = processPatternMatch(r, r.pendingTokens)
- } else {
- result = processPipeToken(r, r.pendingTokens)
- }
- return {
- ...result,
- mode: null,
- pendingTokens: [],
- pendingPatterns: [],
- patterns: result.patterns.concat([result.pendingPatterns])
- }
+ return endPattern(r)
} else {
return {
...r,
@@ 294,6 322,9 @@ function parseGroups (tokenGroups) {
pendingTokens: [],
mode: null
})
+ if (result.pendingTokens.length) {
+ result = endPattern(result)
+ }
let patterns = result.patterns
if (result.pendingPatterns.length) {
patterns = patterns.concat([result.pendingPatterns])