UNPKG

derw

Version:

An Elm-inspired language that transpiles to TypeScript

1,038 lines (1,037 loc) 44.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.rootTypeTokensToString = exports.tokensToString = exports.tokenizeType = exports.tokenize = exports.checkKeywordToken = exports.FunctionTypeToken = exports.BaseTypeToken = exports.WhitespaceToken = exports.OperatorToken = exports.PipeToken = exports.CloseBracketToken = exports.OpenBracketToken = exports.CloseCurlyBracesToken = exports.OpenCurlyBracesToken = exports.CommaToken = exports.AssignToken = exports.MultilineCommentToken = exports.CommentToken = exports.ArrowToken = exports.ColonToken = exports.LiteralToken = exports.IdentifierToken = exports.KeywordToken = exports.FormatStringToken = exports.StringToken = void 0; const Tokens_types_kernel_1 = require("./Tokens_types_kernel"); Object.defineProperty(exports, "BaseTypeToken", { enumerable: true, get: function () { return Tokens_types_kernel_1.BaseTypeToken; } }); Object.defineProperty(exports, "FunctionTypeToken", { enumerable: true, get: function () { return Tokens_types_kernel_1.FunctionTypeToken; } }); const List = __importStar(require("./stdlib/List")); function Empty(args) { return Object.assign({ kind: "Empty" }, args); } function InString(args) { return Object.assign({ kind: "InString" }, args); } function InFormatString(args) { return Object.assign({ kind: "InFormatString" }, args); } function InBracket(args) { return Object.assign({ kind: "InBracket" }, args); } function InSquareBracket(args) { return Object.assign({ kind: "InSquareBracket" }, args); } function InWhitespace(args) { return Object.assign({ kind: "InWhitespace" }, args); } function Keyword(args) { return Object.assign({ kind: "Keyword" }, args); } const keywords = ["if", "then", "else", "type", "alias", "import", "exposing", "as", "let", "in", "case", "of", "do", "return", "typeclass", "impl"]; function StringToken(args) { return Object.assign({ kind: "StringToken" }, args); } exports.StringToken = StringToken; function FormatStringToken(args) { return Object.assign({ kind: "FormatStringToken" }, args); } exports.FormatStringToken = FormatStringToken; function KeywordToken(args) { return Object.assign({ kind: "KeywordToken" }, args); } exports.KeywordToken = KeywordToken; function IdentifierToken(args) { return Object.assign({ kind: "IdentifierToken" }, args); } exports.IdentifierToken = IdentifierToken; function LiteralToken(args) { return Object.assign({ kind: "LiteralToken" }, args); } exports.LiteralToken = LiteralToken; function ColonToken(args) { return Object.assign({ kind: "ColonToken" }, args); } exports.ColonToken = ColonToken; function ArrowToken(args) { return Object.assign({ kind: "ArrowToken" }, args); } exports.ArrowToken = ArrowToken; function CommentToken(args) { return Object.assign({ kind: "CommentToken" }, args); } exports.CommentToken = CommentToken; function MultilineCommentToken(args) { return Object.assign({ kind: "MultilineCommentToken" }, args); } exports.MultilineCommentToken = MultilineCommentToken; function AssignToken(args) { return Object.assign({ kind: "AssignToken" }, args); } exports.AssignToken = AssignToken; function CommaToken(args) { return Object.assign({ kind: "CommaToken" }, args); } exports.CommaToken = CommaToken; function OpenCurlyBracesToken(args) { return Object.assign({ kind: "OpenCurlyBracesToken" }, args); } exports.OpenCurlyBracesToken = OpenCurlyBracesToken; function CloseCurlyBracesToken(args) { return Object.assign({ kind: "CloseCurlyBracesToken" }, args); } exports.CloseCurlyBracesToken = CloseCurlyBracesToken; function OpenBracketToken(args) { return Object.assign({ kind: "OpenBracketToken" }, args); } exports.OpenBracketToken = OpenBracketToken; function CloseBracketToken(args) { return Object.assign({ kind: "CloseBracketToken" }, args); } exports.CloseBracketToken = CloseBracketToken; function PipeToken(args) { return Object.assign({ kind: "PipeToken" }, args); } exports.PipeToken = PipeToken; function OperatorToken(args) { return Object.assign({ kind: "OperatorToken" }, args); } exports.OperatorToken = OperatorToken; function WhitespaceToken(args) { return Object.assign({ kind: "WhitespaceToken" }, args); } exports.WhitespaceToken = WhitespaceToken; function isLiteral(body) { if (body === "true" || body === "false") { return true; } else { if (isNaN(parseFloat(body))) { return false; } else { return true; } ; } } const operators = ["<", "<=", ">", ">=", "==", "!=", "-", "+", "*", "/", "%", "|>", "<|", "&&", "||"]; function isOperator(body) { if (operators.indexOf(body) === -1) { return false; } else { return true; } } function checkKeywordToken(currentToken) { switch (currentToken) { case "=": { return [AssignToken({})]; } case "{": { return [OpenCurlyBracesToken({})]; } case "}": { return [CloseCurlyBracesToken({})]; } case "{}": { return [OpenCurlyBracesToken({}), CloseCurlyBracesToken({})]; } case "--": { return [CommentToken({})]; } case "{-": { return [MultilineCommentToken({ body: "{-" })]; } case "-}": { return [MultilineCommentToken({ body: "-}" })]; } default: { if (keywords.indexOf(currentToken) > -1) { return [KeywordToken({ body: currentToken })]; } else { if (isLiteral(currentToken)) { return [LiteralToken({ body: currentToken })]; } else { if (isOperator(currentToken)) { return [OperatorToken({ body: currentToken })]; } else { return [IdentifierToken({ body: currentToken })]; } ; } ; } ; } } } exports.checkKeywordToken = checkKeywordToken; function TokenizeInfo(args) { return Object.assign({}, args); } function isEscape(char) { return char.charCodeAt(0) === 92; } function not(a) { if (a) { return false; } else { return true; } } function findIndentLevelHelper(tokens) { switch (tokens.length) { case tokens.length: { if (tokens.length === 1) { const [token] = tokens; switch (token.kind) { case "WhitespaceToken": { const { body } = token; if (body.indexOf("\n") > -1) { const split = body.split("\n"); const last = split[split.length - 1]; return last.length; } else { return body.length; } ; } default: { return 0; } } ; } } case tokens.length: { if (tokens.length >= 1) { const [token, ...rest] = tokens; switch (token.kind) { case "WhitespaceToken": { const { body } = token; if (body.indexOf("\n") > -1) { const split = body.split("\n"); const last = split[split.length - 1]; return last.length; } else { return findIndentLevelHelper(rest); } ; } default: { return findIndentLevelHelper(rest); } } ; } } default: { return 0; } } } function findIndentLevel(info) { return findIndentLevelHelper(List.reverse(info.tokens)); } function tokenizeHelpInWhitespaceOrEmpty(initialInfo) { const char = initialInfo.body[initialInfo.index]; const info = char !== " " && char !== "\n" && initialInfo.currentToken.length > 0 ? Object.assign(Object.assign({}, initialInfo), { currentToken: "", state: Empty({}), tokens: List.append(initialInfo.tokens, [WhitespaceToken({ body: initialInfo.currentToken })]) }) : initialInfo; const previousChar = info.index === 0 ? "" : info.body[info.index - 1]; const isLast = info.body.length - 1 === info.index; const nextInfo = (function () { switch (char) { case `"`: { return Object.assign(Object.assign({}, info), { state: InString({}), currentToken: info.currentToken + char }); } case "`": { return Object.assign(Object.assign({}, info), { state: InFormatString({ indentLevel: findIndentLevel(info) }), currentToken: info.currentToken + char }); } case "(": { return Object.assign(Object.assign({}, info), { state: InBracket({ depth: 0 }), tokens: List.append(info.tokens, [OpenBracketToken({})]) }); } case ")": { return Object.assign(Object.assign({}, info), { state: Empty({}), tokens: List.append(info.tokens, [CloseBracketToken({})]) }); } case "[": { return Object.assign(Object.assign({}, info), { state: InSquareBracket({ depth: 0 }), currentToken: info.currentToken + char }); } case "\n": { return Object.assign(Object.assign({}, info), { state: InWhitespace({}), currentToken: info.currentToken + char }); } case " ": { return Object.assign(Object.assign({}, info), { state: InWhitespace({}), currentToken: info.currentToken + char }); } case ":": { if (info.body[info.index + 1] === ":") { const token = OperatorToken({ body: "::" }); return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [token]), index: info.index + 1 }); } else { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [ColonToken({})]) }); } ; } case "-": { if (info.body[info.index + 1] === ">") { return info; } else { return Object.assign(Object.assign({}, info), { state: Keyword({}), currentToken: info.currentToken + char }); } ; } case ">": { switch (previousChar) { case "-": { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [ArrowToken({})]), currentToken: "" }); } case "|": { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [OperatorToken({ body: "|>" })]), currentToken: "" }); } default: { return Object.assign(Object.assign({}, info), { state: Keyword({}), currentToken: info.currentToken + char }); } } ; } case ",": { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [CommaToken({})]) }); } case "|": { if (info.body[info.index + 1] === ">" || info.body[info.index + 1] === "|") { return info; } else { if (previousChar === "|") { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [OperatorToken({ body: "||" })]), currentToken: "" }); } else { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [PipeToken({})]) }); } ; } ; } case "{": { if (info.body[info.index + 1] === "-") { return Object.assign(Object.assign({}, info), { currentToken: info.currentToken + char, state: Keyword({}) }); } else { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [OpenCurlyBracesToken({})]), currentToken: "" }); } ; } case "}": { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [CloseCurlyBracesToken({})]), currentToken: "" }); } default: { if (isEscape(char)) { return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, [OperatorToken({ body: char })]), currentToken: "" }); } else { const otherTokens = isLast ? checkKeywordToken(info.currentToken + char) : []; return Object.assign(Object.assign({}, info), { tokens: List.append(info.tokens, otherTokens), currentToken: info.currentToken + char, state: Keyword({}) }); } ; } } })(); return Object.assign(Object.assign({}, nextInfo), { index: nextInfo.index + 1 }); } function tokenizeHelp(info) { const char = info.body[info.index]; const previousChar = info.index === 0 ? "" : info.body[info.index - 1]; const isLast = info.body.length - 1 === info.index; if (info.index >= info.body.length) { return info; } else { switch (info.state.kind) { case "InWhitespace": { return tokenizeHelpInWhitespaceOrEmpty(info); } case "Empty": { return tokenizeHelpInWhitespaceOrEmpty(info); } case "InString": { if (char === `"` && not(isEscape(previousChar))) { const token = StringToken({ body: info.currentToken + `"` }); return Object.assign(Object.assign({}, info), { state: Empty({}), currentToken: "", tokens: List.append(info.tokens, [token]), index: info.index + 1 }); } else { return Object.assign(Object.assign({}, info), { currentToken: info.currentToken + char, index: info.index + 1 }); } ; } case "InFormatString": { const { indentLevel } = info.state; if (char === "`" && not(isEscape(previousChar))) { const token = FormatStringToken({ body: info.currentToken + "`", indentLevel }); return Object.assign(Object.assign({}, info), { state: Empty({}), currentToken: "", tokens: List.append(info.tokens, [token]), index: info.index + 1 }); } else { return Object.assign(Object.assign({}, info), { currentToken: info.currentToken + char, index: info.index + 1 }); } ; } case "InBracket": { const { depth } = info.state; if (char === ")") { if (depth === 0) { const otherTokens = tokenize(info.currentToken); const allTokens = (function (x) { return List.append(x, [CloseBracketToken({})]); })(List.append(info.tokens, otherTokens)); return Object.assign(Object.assign({}, info), { state: Empty({}), currentToken: "", tokens: allTokens, index: info.index + 1 }); } else { return Object.assign(Object.assign({}, info), { state: InBracket({ depth: depth - 1 }), currentToken: info.currentToken + ")", index: info.index + 1 }); } ; } else { if (char === "(") { return Object.assign(Object.assign({}, info), { state: InBracket({ depth: depth + 1 }), currentToken: info.currentToken + "(", index: info.index + 1 }); } else { return Object.assign(Object.assign({}, info), { currentToken: info.currentToken + char, index: info.index + 1 }); } ; } ; } case "InSquareBracket": { const { depth } = info.state; if (char === "]") { if (depth === 0) { const newToken = LiteralToken({ body: info.currentToken + "]" }); const allTokens = List.append(info.tokens, [newToken]); return Object.assign(Object.assign({}, info), { state: Empty({}), currentToken: "", tokens: allTokens, index: info.index + 1 }); } else { return Object.assign(Object.assign({}, info), { state: InSquareBracket({ depth: depth - 1 }), currentToken: info.currentToken + char, index: info.index + 1 }); } ; } else { if (char === "[") { return Object.assign(Object.assign({}, info), { state: InSquareBracket({ depth: depth + 1 }), currentToken: info.currentToken + char, index: info.index + 1 }); } else { return Object.assign(Object.assign({}, info), { currentToken: info.currentToken + char, index: info.index + 1 }); } ; } ; } case "Keyword": { const isWhitespace = char === "\n" || char === " "; if (isLast) { if (char === ")") { const otherTokens = checkKeywordToken(info.currentToken); const allTokens = (function (x) { return List.append(x, [CloseBracketToken({})]); })(List.append(info.tokens, otherTokens)); return Object.assign(Object.assign({}, info), { state: Empty({}), currentToken: "", tokens: allTokens, index: info.index + 1 }); } else { const currentToken = isWhitespace ? info.currentToken : info.currentToken + char; const otherTokens = checkKeywordToken(currentToken); const maybeWhiteSpaceToken = isLast && isWhitespace ? [WhitespaceToken({ body: char })] : []; const allTokens = (function (x) { return List.append(x, maybeWhiteSpaceToken); })(List.append(info.tokens, otherTokens)); return Object.assign(Object.assign({}, info), { state: Empty({}), currentToken: "", tokens: allTokens, index: info.index + 1 }); } ; } else { if (isWhitespace) { const otherTokens = checkKeywordToken(info.currentToken); const maybeWhiteSpaceToken = isLast ? [WhitespaceToken({ body: char })] : []; const allTokens = (function (x) { return List.append(x, maybeWhiteSpaceToken); })(List.append(info.tokens, otherTokens)); const currentToken = isLast ? "" : char; return Object.assign(Object.assign({}, info), { state: Empty({}), currentToken, tokens: allTokens, index: info.index + 1 }); } else { switch (char) { case ":": { if (info.body[info.index + 1] === ":") { const allTokens = List.append(info.tokens, [IdentifierToken({ body: info.currentToken }), OperatorToken({ body: "::" })]); return Object.assign(Object.assign({}, info), { currentToken: "", tokens: allTokens, state: Empty({}), index: info.index + 2 }); } else { const allTokens = List.append(info.tokens, [IdentifierToken({ body: info.currentToken }), ColonToken({})]); return Object.assign(Object.assign({}, info), { currentToken: "", tokens: allTokens, state: Empty({}), index: info.index + 1 }); } ; } case ",": { const allTokens = List.append(info.tokens, [IdentifierToken({ body: info.currentToken }), CommaToken({})]); return Object.assign(Object.assign({}, info), { currentToken: "", tokens: allTokens, state: Empty({}), index: info.index + 1 }); } case "(": { const otherTokens = checkKeywordToken(info.currentToken); const allTokens = (function (x) { return List.append(x, [OpenBracketToken({})]); })(List.append(info.tokens, otherTokens)); return Object.assign(Object.assign({}, info), { currentToken: "", tokens: allTokens, state: Empty({}), index: info.index + 1 }); } case ")": { const allTokens = List.append(info.tokens, [IdentifierToken({ body: info.currentToken }), CloseBracketToken({})]); return Object.assign(Object.assign({}, info), { currentToken: "", tokens: allTokens, state: Empty({}), index: info.index + 1 }); } default: { return Object.assign(Object.assign({}, info), { currentToken: info.currentToken + char, index: info.index + 1 }); } } ; } ; } ; } } ; } } function tokenize(body) { const initialState = { state: Empty({}), currentToken: "", tokens: [], body, index: 0 }; const chars = body.split(""); const calculatedState = List.statefulFold(function (item, state) { return tokenizeHelp(state); }, initialState, chars); return calculatedState.tokens; } exports.tokenize = tokenize; function tokenToString(token) { switch (token.kind) { case "ArrowToken": { return "->"; } case "AssignToken": { return "="; } case "CloseBracketToken": { return ")"; } case "CloseCurlyBracesToken": { return "}"; } case "ColonToken": { return ":"; } case "CommaToken": { return ","; } case "CommentToken": { return "--"; } case "FormatStringToken": { const { body } = token; return body; } case "IdentifierToken": { const { body } = token; return body; } case "MultilineCommentToken": { const { body } = token; return body; } case "KeywordToken": { const { body } = token; return body; } case "LiteralToken": { const { body } = token; return body; } case "OpenBracketToken": { return "("; } case "OpenCurlyBracesToken": { return "{"; } case "OperatorToken": { const { body } = token; return body; } case "PipeToken": { return "|"; } case "StringToken": { const { body } = token; return body; } case "WhitespaceToken": { const { body } = token; return body; } } } function tokensToString(tokens) { return (function (x) { return x.join(""); })(List.map(tokenToString, tokens)); } exports.tokensToString = tokensToString; function Ok(args) { return Object.assign({ kind: "Ok" }, args); } function Err(args) { return Object.assign({ kind: "Err" }, args); } function TokenizeTypeInfo(args) { return Object.assign({}, args); } function ComposeTypeInfo(args) { return Object.assign({}, args); } function finalCompose(info) { if (info.error.length > 0) { return Err({ error: info.error[0] }); } else { const flattened = List.foldl(function (x, xs) { return xs.concat(x); }, [], info.collectedInners); return Ok({ value: [(0, Tokens_types_kernel_1.BaseTypeToken)({ body: [info.buffer[0], ...flattened] })] }); } } function composeType(info) { if (info.index >= info.buffer.length || info.error.length > 0) { return info; } else { const t = info.buffer[info.index]; switch (t.kind) { case "OpenBracketToken": { if (info.depth > 0) { return composeType(Object.assign(Object.assign({}, info), { inner: List.append(info.inner, [t]), depth: info.depth + 1, index: info.index + 1 })); } else { return composeType(Object.assign(Object.assign({}, info), { depth: info.depth + 1, index: info.index + 1 })); } ; } case "CloseBracketToken": { if (info.depth === 1) { const innerTokenized = tokenizeType(info.inner); switch (innerTokenized.kind) { case "Err": { const { error } = innerTokenized; return composeType(Object.assign(Object.assign({}, info), { error: [error] })); } case "Ok": { const { value } = innerTokenized; return composeType(Object.assign(Object.assign({}, info), { collectedInners: List.append(info.collectedInners, [value]), inner: [], depth: 0, index: info.index + 1 })); } } ; } else { if (info.depth === 0) { return composeType(Object.assign(Object.assign({}, info), { index: info.index + 1 })); } else { return composeType(Object.assign(Object.assign({}, info), { index: info.index + 1, inner: List.append(info.inner, [t]), depth: info.depth - 1 })); } ; } ; } case "IdentifierToken": { const { body } = t; if (info.depth === 0) { const tokenized = tokenizeType(tokenize(body)); switch (tokenized.kind) { case "Err": { const { error } = tokenized; return composeType(Object.assign(Object.assign({}, info), { error: [error] })); } case "Ok": { const { value } = tokenized; return composeType(Object.assign(Object.assign({}, info), { index: info.index + 1, collectedInners: List.append(info.collectedInners, [value]) })); } } ; } else { return composeType(Object.assign(Object.assign({}, info), { index: info.index + 1, inner: List.append(info.inner, [t]) })); } ; } case "ArrowToken": { if (info.depth === 0) { return composeType(Object.assign(Object.assign({}, info), { index: info.index + 1 })); } else { return composeType(Object.assign(Object.assign({}, info), { index: info.index + 1, inner: List.append(info.inner, [t]) })); } ; } default: { return composeType(Object.assign(Object.assign({}, info), { index: info.index + 1 })); } } ; } } function processTokenizeTypeInfo(info) { const hasOpenBracketToken = info.currentBuffer.find(function (t) { return t.kind === "OpenBracketToken"; }) ? true : false; const isFunction = info.currentBuffer.find(function (t) { return t.kind === "ArrowToken"; }) ? true : false; switch (info.currentBuffer.length) { case info.currentBuffer.length: { if (info.currentBuffer.length >= 1) { const [first, ...rest] = info.currentBuffer; if (hasOpenBracketToken) { const tokenized = first.kind === "IdentifierToken" && not(isFunction) ? finalCompose(composeType({ buffer: info.currentBuffer, index: 1, depth: 0, inner: [], collectedInners: [], error: [] })) : tokenizeType(info.currentBuffer); switch (tokenized.kind) { case "Err": { const { error } = tokenized; return Err({ error }); } case "Ok": { const { value } = tokenized; if (isFunction) { return Ok({ value: List.append(info.rootTypeTokens, [(0, Tokens_types_kernel_1.FunctionTypeToken)({ body: value })]) }); } else { return Ok({ value: List.append(info.rootTypeTokens, value) }); } ; } } ; } else { if (isFunction) { const tokenized = tokenizeType(info.currentBuffer); switch (tokenized.kind) { case "Err": { const { error } = tokenized; return Err({ error }); } case "Ok": { const { value } = tokenized; return Ok({ value: List.append(info.rootTypeTokens, [(0, Tokens_types_kernel_1.FunctionTypeToken)({ body: value })]) }); } } ; } else { function innerHelp(tokens) { switch (tokens.length) { case 0: { return Ok({ value: [] }); } case tokens.length: { if (tokens.length >= 1) { const [x, ...rest] = tokens; const tokenized = tokenizeType([x]); switch (tokenized.kind) { case "Err": { const { error } = tokenized; return Err({ error }); } case "Ok": { const { value } = tokenized; const _res832456996 = innerHelp(rest); switch (_res832456996.kind) { case "Ok": { const { value: other } = _res832456996; return Ok({ value: List.append(value, other) }); } case "Err": { const { error } = _res832456996; return Err({ error }); } } ; } } ; } } default: { return Ok({ value: [] }); } } } const inner = info.currentBuffer.length > 1 ? innerHelp(info.currentBuffer.slice(1)) : Ok({ value: [] }); const otherTokens = (function () { switch (inner.kind) { case "Ok": { const { value } = inner; return (0, Tokens_types_kernel_1.BaseTypeToken)({ body: List.append([info.currentBuffer[0]], value) }); } case "Err": { const { error } = inner; return []; } } })(); switch (inner.kind) { case "Err": { const { error } = inner; return inner; } case "Ok": { const { value } = inner; return (function (x) { return Ok({ value: x }); })(List.append(info.rootTypeTokens, otherTokens)); } } ; } ; } ; } } default: { return Ok({ value: info.rootTypeTokens }); } } } function finalTokenizeType(info) { if (info.error.length > 0) { return Err({ error: info.error[0] }); } else { return processTokenizeTypeInfo(info); } } function tokenizeTypeHelp(info) { if (info.index >= info.tokens.length || info.error.length > 0) { return info; } else { const token = info.tokens[info.index]; const nextInfo = (function () { switch (token.kind) { case "OpenBracketToken": { if (info.indent > 0 || info.currentBuffer.length > 0) { return Object.assign(Object.assign({}, info), { index: info.index + 1, indent: info.indent + 1, currentBuffer: List.append(info.currentBuffer, [token]) }); } else { return Object.assign(Object.assign({}, info), { index: info.index + 1, indent: info.indent + 1 }); } ; } case "CloseBracketToken": { if (info.indent > 0) { return Object.assign(Object.assign({}, info), { indent: info.indent - 1, index: info.index + 1, currentBuffer: List.append(info.currentBuffer, [token]) }); } else { return Object.assign(Object.assign({}, info), { indent: info.indent - 1, index: info.index + 1 }); } ; } case "ArrowToken": { if (info.indent === 0) { const isFunction = info.currentBuffer.find(function (t) { return t.kind === "ArrowToken"; }) ? true : false; const tokenized = tokenizeType(info.currentBuffer); switch (tokenized.kind) { case "Err": { const { error } = tokenized; return Object.assign(Object.assign({}, info), { error: [error] }); } case "Ok": { const { value } = tokenized; if (isFunction) { return Object.assign(Object.assign({}, info), { index: info.index + 1, rootTypeTokens: List.append(info.rootTypeTokens, [(0, Tokens_types_kernel_1.FunctionTypeToken)({ body: value })]), currentBuffer: [] }); } else { return Object.assign(Object.assign({}, info), { index: info.index + 1, rootTypeTokens: List.append(info.rootTypeTokens, value), currentBuffer: [] }); } ; } } ; } else { return Object.assign(Object.assign({}, info), { index: info.index + 1, currentBuffer: List.append(info.currentBuffer, [token]) }); } ; } case "IdentifierToken": { return Object.assign(Object.assign({}, info), { index: info.index + 1, currentBuffer: List.append(info.currentBuffer, [token]) }); } case "StringToken": { return Object.assign(Object.assign({}, info), { index: info.index + 1, currentBuffer: List.append(info.currentBuffer, [token]) }); } default: { return Object.assign(Object.assign({}, info), { index: info.index + 1 }); } } })(); return nextInfo; } } function tokenizeType(tokens) { const initialState = { rootTypeTokens: [], currentBuffer: [], indent: 0, index: 0, tokens, error: [] }; const calculatedState = List.statefulFold(function (item, state) { return tokenizeTypeHelp(state); }, initialState, tokens); return finalTokenizeType(calculatedState); } exports.tokenizeType = tokenizeType; function typeTokenToString(token) { switch (token.kind) { case "ArrowToken": { return "->"; } case "BaseTypeToken": { return rootTypeTokensToString([token]); } case "CloseBracketToken": { return ")"; } case "FunctionTypeToken": { return rootTypeTokensToString([token]); } case "IdentifierToken": { return token.body; } case "OpenBracketToken": { return "("; } case "StringToken": { return `${token.body}`; } } } function isNested(token) { switch (token.kind) { case "BaseTypeToken": { const { body } = token; return body.length !== 1; } case "FunctionTypeToken": { return true; } } } function rootTypeTokenToString(token) { switch (token.kind) { case "BaseTypeToken": { function valueToString(value) { switch (value.kind) { case "BaseTypeToken": { const { body } = value; const inner = List.map(typeTokenToString, body); if (isNested(value)) { return (function (x) { return x.join(" "); })((function (x) { return List.append(x, [typeTokenToString(CloseBracketToken({}))]); })(List.append([typeTokenToString(OpenBracketToken({}))], inner))); } else { return (function (x) { return x.join(" "); })(inner); } ; } default: { return typeTokenToString(value); } } } return (function (x) { return x.join(" "); })(List.map(valueToString, token.body)); } case "FunctionTypeToken": { function valueToString(value, index) { if (index < token.body.length - 1) { return (function (x) { return x.join(" "); })([typeTokenToString(value), typeTokenToString(ArrowToken({}))]); } else { return (function (x) { return x.join(" "); })([typeTokenToString(value)]); } } const mapped = List.indexedMap(valueToString, token.body); return (function (xs) { return xs.join(" "); })((function (xs) { return List.append(xs, [typeTokenToString(CloseBracketToken({}))]); })(List.append([typeTokenToString(OpenBracketToken({}))], mapped))); } } } function rootTypeTokensToString(tokens) { const arrow = typeTokenToString(ArrowToken({})); return (function (x) { return x.join(` ${arrow} `); })(List.map(rootTypeTokenToString, tokens)); } exports.rootTypeTokensToString = rootTypeTokensToString;