functionalscript
Version:
FunctionalScript is a purely functional subset of JavaScript
53 lines (52 loc) • 1.85 kB
JavaScript
import * as list from "../../types/list/module.f.js";
const { empty, flat, stateScan } = list;
import * as bf from "../../types/bigfloat/module.f.js";
const { multiply } = bf;
import * as jsTokenizer from "../../js/tokenizer/module.f.js";
const mapToken = input => {
switch (input.kind) {
case '{':
case '}':
case ':':
case ',':
case '[':
case ']':
case 'true':
case 'false':
case 'null':
case 'string':
case 'number':
case 'eof':
case 'error': return [input];
case 'ws':
case 'nl': return empty;
default: return [{ kind: 'error', message: 'invalid token' }];
}
};
const parseDefaultState = input => {
if (input === null)
return [empty, { kind: 'def' }];
switch (input.token.kind) {
case '-': return [empty, { kind: '-' }];
default: return [mapToken(input.token), { kind: 'def' }];
}
};
const parseMinusState = input => {
if (input === null)
return [[{ kind: 'error', message: 'invalid token' }], { kind: 'def' }];
switch (input.token.kind) {
case '-': return [[{ kind: 'error', message: 'invalid token' }], { kind: '-' }];
case 'number': return [[{ kind: 'number', bf: multiply(input.token.bf)(-1n), value: `-${input.token.value}` }], { kind: 'def' }];
default: return [{ first: { kind: 'error', message: 'invalid token' }, tail: mapToken(input.token) }, { kind: 'def' }];
}
};
const scanToken = state => input => {
switch (state.kind) {
case '-': return parseMinusState(input);
default: return parseDefaultState(input);
}
};
export const tokenize = (input) => {
const jsTokens = jsTokenizer.tokenize(input)('');
return flat(stateScan(scanToken)({ kind: 'def' })(list.concat(jsTokens)([null])));
};