UNPKG

functionalscript

Version:

FunctionalScript is a purely functional subset of JavaScript

59 lines (58 loc) 2.54 kB
import { error, ok } from "../../types/result/module.f.js"; import { fold, drop, map as listMap, toArray, includes } from "../../types/list/module.f.js"; import { tokenize } from "../tokenizer/module.f.js"; import { setReplace, at } from "../../types/ordered_map/module.f.js"; import { stringToList } from "../../text/utf16/module.f.js"; import { concat as pathConcat } from "../../path/module.f.js"; import { parseFromTokens } from "../parser/module.f.js"; import { run } from "../ast/module.f.js"; const mapDjs = context => path => { const res = at(path)(context.complete); if (res === null) { throw 'unexpected behaviour'; } return res.djs; }; const transpileWithImports = path => parseModuleResult => context => { if (parseModuleResult[0] === 'ok') { const dir = pathConcat(path)('..'); const pathsCombine = listMap(pathConcat(dir))(parseModuleResult[1][0]); const contextWithImports = fold(foldNextModuleOp)({ ...context, stack: { first: path, tail: context.stack } })(pathsCombine); if (contextWithImports.error !== null) { return contextWithImports; } const args = toArray(listMap(mapDjs(contextWithImports))(pathsCombine)); const djs = { djs: run(parseModuleResult[1][1])(args) }; return { ...contextWithImports, stack: drop(1)(contextWithImports.stack), complete: setReplace(path)(djs)(contextWithImports.complete) }; } return { ...context, error: parseModuleResult[1] }; }; const parseModule = path => context => { const content = context.fs.readFileSync(path, 'utf8'); if (content === null) { return error({ message: 'file not found', metadata: null }); } const tokens = tokenize(stringToList(content))(path); return parseFromTokens(tokens); }; const foldNextModuleOp = path => context => { if (context.error !== null) { return context; } if (includes(path)(context.stack)) { return { ...context, error: { message: 'circular dependency', metadata: null } }; } if (at(path)(context.complete) !== null) { return context; } const parseModuleResult = parseModule(path)(context); return transpileWithImports(path)(parseModuleResult)(context); }; export const transpile = fs => path => { const context = foldNextModuleOp(path)({ fs, stack: null, complete: null, error: null }); if (context.error !== null) { return error(context.error); } const result = at(path)(context.complete)?.djs; return ok(result); };