derw
Version:
An Elm-inspired language that transpiles to TypeScript
556 lines (555 loc) • 18.1 kB
JavaScript
;
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 () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.blockKind = blockKind;
exports.createUnparsedBlock = createUnparsedBlock;
exports.intoBlocks = intoBlocks;
exports.typeBlocks = typeBlocks;
exports.exportTests = exportTests;
const Utils_1 = require("./Utils");
const List = __importStar(require("./stdlib/List"));
function Validator(args) {
return {
...args,
};
}
function Ok(args) {
return {
kind: "Ok",
...args,
};
}
function Err(args) {
return {
kind: "Err",
...args,
};
}
function ImportBlock(args) {
return {
kind: "ImportBlock",
...args,
};
}
function ExportBlock(args) {
return {
kind: "ExportBlock",
...args,
};
}
function UnionTypeBlock(args) {
return {
kind: "UnionTypeBlock",
...args,
};
}
function UnionUntaggedTypeBlock(args) {
return {
kind: "UnionUntaggedTypeBlock",
...args,
};
}
function TypeAliasBlock(args) {
return {
kind: "TypeAliasBlock",
...args,
};
}
function TypeclassBlock(args) {
return {
kind: "TypeclassBlock",
...args,
};
}
function ImplBlock(args) {
return {
kind: "ImplBlock",
...args,
};
}
function FunctionBlock(args) {
return {
kind: "FunctionBlock",
...args,
};
}
function ConstBlock(args) {
return {
kind: "ConstBlock",
...args,
};
}
function CommentBlock(args) {
return {
kind: "CommentBlock",
...args,
};
}
function MultilineCommentBlock(args) {
return {
kind: "MultilineCommentBlock",
...args,
};
}
function UnknownBlock(args) {
return {
kind: "UnknownBlock",
...args,
};
}
function hasTypeLine(block) {
const _res1328002030 = block.split(":");
switch (_res1328002030.length) {
case _res1328002030.length: {
if (_res1328002030.length === 1) {
const [x] = _res1328002030;
return false;
}
}
case _res1328002030.length: {
if (_res1328002030.length >= 1) {
const [x, ...xs] = _res1328002030;
const trimmed = x.trim();
const split = trimmed.split(" ");
const length = split.length;
return length === 1;
}
}
default: {
return false;
}
}
}
function isAFunction(block) {
const _res1780524276 = block.split("\n");
switch (_res1780524276.length) {
case _res1780524276.length: {
if (_res1780524276.length >= 1) {
const [firstLine, ...xs] = _res1780524276;
return (function (y) {
return y.length > 1;
})(firstLine.split("->"));
}
}
default: {
return false;
}
}
}
const validators = [{
test: function (x) {
return x.startsWith("--");
},
blockKind: "Comment",
}, {
test: function (x) {
return x.startsWith("{-");
},
blockKind: "MultilineComment",
}, {
test: function (x) {
return x.startsWith("type alias");
},
blockKind: "TypeAlias",
}, {
test: function (x) {
return x.startsWith("typeclass ");
},
blockKind: "Typeclass",
}, {
test: function (x) {
return x.startsWith("impl ");
},
blockKind: "Impl",
}, {
test: function (x) {
return x.startsWith("type ") && x.includes(`"`);
},
blockKind: "UnionUntaggedType",
}, {
test: function (x) {
return x.startsWith("type ");
},
blockKind: "UnionType",
}, {
test: function (x) {
return x.startsWith(" ") || x.startsWith("}");
},
blockKind: "Indent",
}, {
test: function (x) {
return x.startsWith("import");
},
blockKind: "Import",
}, {
test: function (x) {
return x.startsWith("exposing");
},
blockKind: "Export",
}, {
test: function (x) {
return hasTypeLine(x) && isAFunction(x);
},
blockKind: "Function",
}, {
test: function (x) {
return hasTypeLine(x);
},
blockKind: "Const",
}, {
test: function (x) {
return (function (y) {
return y.length > 1;
})(x.split("="));
},
blockKind: "Definition",
}];
function blockKindStep(block, validators) {
switch (validators.length) {
case validators.length: {
if (validators.length >= 1) {
const [validator, ...ys] = validators;
if (validator.test(block)) {
return Ok({ value: validator.blockKind });
}
else {
return blockKindStep(block, ys);
}
;
}
}
default: {
return Err({ error: "Unknown block type" });
}
}
}
function blockKind(block) {
return blockKindStep(block, validators);
}
function createUnparsedBlock(blockKind, lineStart, lines) {
switch (blockKind) {
case "Import": {
return ImportBlock({
lineStart,
lines,
});
}
case "Export": {
return ExportBlock({
lineStart,
lines,
});
}
case "Const": {
return ConstBlock({
lineStart,
lines,
});
}
case "Function": {
return FunctionBlock({
lineStart,
lines,
});
}
case "UnionType": {
return UnionTypeBlock({
lineStart,
lines,
});
}
case "UnionUntaggedType": {
return UnionUntaggedTypeBlock({
lineStart,
lines,
});
}
case "TypeAlias": {
return TypeAliasBlock({
lineStart,
lines,
});
}
case "Typeclass": {
return TypeclassBlock({
lineStart,
lines,
});
}
case "Impl": {
return ImplBlock({
lineStart,
lines,
});
}
case "Indent": {
return UnknownBlock({
lineStart,
lines,
});
}
case "Definition": {
return UnknownBlock({
lineStart,
lines,
});
}
case "Comment": {
return CommentBlock({
lineStart,
lines,
});
}
case "MultilineComment": {
return MultilineCommentBlock({
lineStart,
lines,
});
}
case "Unknown": {
return UnknownBlock({
lineStart,
lines,
});
}
}
}
function IntoBlockInfo(args) {
return {
...args,
};
}
function stepMultilineComment(lineNumber, info, line, lines) {
if (line === "-}") {
const infoWithCurrentLine = {
...info,
previousLine: line,
currentBlock: List.append(info.currentBlock, [line]),
};
const block = createUnparsedBlock("MultilineComment", infoWithCurrentLine.lineStart, infoWithCurrentLine.currentBlock);
const nextInfo = {
currentBlock: [],
previousLine: line,
lineStart: lineNumber,
currentBlockKind: Err({ error: "Nothing" }),
};
return [block, ...intoBlocksStep(lineNumber + 1, nextInfo, lines)];
}
else {
const infoWithCurrentLine = {
...info,
previousLine: line,
currentBlock: List.append(info.currentBlock, [line]),
};
return intoBlocksStep(lineNumber + 1, infoWithCurrentLine, lines);
}
}
function indentOrDefinitionStep(lineNumber, info, line, lines) {
const nextLines = lineNumber > 0 && info.previousLine.trim() === "" ? [info.previousLine, line] : [line];
const nextInfo = {
...info,
currentBlock: List.append(info.currentBlock, nextLines),
previousLine: line,
};
return intoBlocksStep(lineNumber + 1, nextInfo, lines);
}
function intoBlocksStep(lineNumber, info, lines) {
switch (lines.length) {
case lines.length: {
if (lines.length >= 1) {
const [line, ...xs] = lines;
if (line.trim().length === 0) {
const nextInfo = { ...info, previousLine: line };
return intoBlocksStep(lineNumber + 1, nextInfo, xs);
}
else {
switch (info.currentBlock.length) {
case 0: {
const nextInfo = {
previousLine: line,
currentBlock: [line],
lineStart: lineNumber,
currentBlockKind: blockKind(line),
};
return intoBlocksStep(lineNumber + 1, nextInfo, xs);
}
default: {
const isInMultilineComment = info.currentBlockKind.kind === "Ok" && info.currentBlockKind.value === "MultilineComment";
if (isInMultilineComment) {
return stepMultilineComment(lineNumber, info, line, xs);
}
else {
const currentLineBlockKind = blockKind(line);
const isIndent = currentLineBlockKind.kind === "Ok" && currentLineBlockKind.value === "Indent";
const isDefinition = currentLineBlockKind.kind === "Ok" && currentLineBlockKind.value === "Definition";
if (isIndent || isDefinition) {
return indentOrDefinitionStep(lineNumber, info, line, xs);
}
else {
switch (info.currentBlockKind.kind) {
case "Ok": {
const { value } = info.currentBlockKind;
const hasSpeech = (function (y) {
return y.length > 0;
})(info.currentBlock.filter(function (line) {
return line.indexOf(`"`) > -1;
}));
const kind = (function () {
switch (value) {
case "UnionType": {
if (hasSpeech) {
return "UnionUntaggedType";
}
else {
return value;
}
;
}
default: {
return value;
}
}
})();
const block = createUnparsedBlock(kind, info.lineStart, info.currentBlock);
const nextInfo = {
previousLine: line,
currentBlock: [line],
lineStart: lineNumber,
currentBlockKind: currentLineBlockKind,
};
return [block, ...intoBlocksStep(lineNumber + 1, nextInfo, xs)];
}
case "Err": {
const nextInfo = {
...info,
previousLine: line,
currentBlock: List.append(info.currentBlock, [line]),
};
return intoBlocksStep(lineNumber + 1, nextInfo, xs);
}
}
;
}
;
}
;
}
}
;
}
;
}
}
default: {
if (info.currentBlock.length > 0) {
switch (info.currentBlockKind.kind) {
case "Ok": {
const { value } = info.currentBlockKind;
const hasSpeech = (function (y) {
return y.length > 0;
})(info.currentBlock.filter(function (line) {
return line.indexOf(`"`) > -1;
}));
const kind = (function () {
switch (value) {
case "UnionType": {
if (hasSpeech) {
return "UnionUntaggedType";
}
else {
return value;
}
;
}
default: {
return value;
}
}
})();
return [createUnparsedBlock(kind, info.lineStart, info.currentBlock)];
}
case "Err": {
return [createUnparsedBlock("Unknown", info.lineStart, info.currentBlock)];
}
}
;
}
else {
return [];
}
;
}
}
}
function intoBlocks(body) {
const lines = body.split("\n");
return intoBlocksStep(0, {
previousLine: "",
currentBlock: [],
currentBlockKind: Err({ error: "Nothing" }),
lineStart: 0,
}, lines);
}
function typeBlocks(blocks) {
return List.filter(function (block) {
return block.kind === "UnionType" || block.kind === "TypeAlias" || block.kind === "UnionUntaggedType";
}, blocks);
}
function Export(args) {
return {
kind: "Export",
...args,
};
}
function exportTests(module) {
const isTest = (0, Utils_1.isTestFile)(module.name);
const namesToExpose = isTest ? List.filter(function (name) {
return name.startsWith("test") || name.startsWith("snapshot");
}, List.map(function (block) {
return block.name;
}, List.filter(function (block) {
return block.kind === "Function" || block.kind === "Const";
}, module.body))) : [];
const exports = List.filter(function (block) {
return block.kind === "Export";
}, module.body);
const exportNames = List.foldl(function (export_, allNames) {
return List.append(export_.names, allNames);
}, [], exports);
const exposeWithoutDuplicates = List.filter(function (name) {
return !exportNames.includes(name);
}, namesToExpose);
return Export({ names: exposeWithoutDuplicates });
}