2023-12-11 18:38:30 +00:00
|
|
|
import traverse from "@babel/traverse";
|
|
|
|
import * as t from "@babel/types";
|
2024-02-24 21:30:30 +00:00
|
|
|
import generate from "@babel/generator";
|
|
|
|
import { parseInternal, parse_with_plugins } from "../parser/parse";
|
|
|
|
import {
|
|
|
|
TreeNode,
|
|
|
|
makeTree,
|
|
|
|
showTree,
|
|
|
|
showTreePaired,
|
|
|
|
} from "../data_structures/tree";
|
|
|
|
import { runMatch } from "../matcher/matcher";
|
|
|
|
import { transformMatch, transformer } from "./transformMatch";
|
2024-05-11 14:09:03 +00:00
|
|
|
import { preludeBuilder } from "../parser/preludeBuilder";
|
2024-02-24 21:30:30 +00:00
|
|
|
export interface TransformRecipe {
|
|
|
|
applicableTo: string;
|
|
|
|
transformTo: string;
|
2023-12-11 18:38:30 +00:00
|
|
|
}
|
2024-05-11 14:09:03 +00:00
|
|
|
export interface SelfHostedRecipe extends TransformRecipe {
|
|
|
|
prelude: string;
|
|
|
|
}
|
2024-02-24 21:30:30 +00:00
|
|
|
export function transform(recipe: TransformRecipe, code: string) {
|
2024-05-11 14:09:03 +00:00
|
|
|
if ((<SelfHostedRecipe>recipe).prelude !== undefined) {
|
|
|
|
// We are using the self hosted version
|
|
|
|
return transformSelfHosted(<SelfHostedRecipe>recipe, code);
|
|
|
|
} else {
|
|
|
|
// We are using JSTQL
|
|
|
|
return transformJSTQL(recipe, code);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function transformSelfHosted(recipe: SelfHostedRecipe, code: string) {
|
|
|
|
let internals = preludeBuilder(recipe.prelude);
|
|
|
|
|
2024-02-24 21:30:30 +00:00
|
|
|
let codeAST = parse_with_plugins(code);
|
|
|
|
let codeTree = makeTree(codeAST);
|
2024-05-11 14:09:03 +00:00
|
|
|
let applicabelToAST = parse_with_plugins(recipe.applicableTo);
|
|
|
|
|
2024-02-24 21:30:30 +00:00
|
|
|
let applicableToTree = makeTree(applicabelToAST);
|
|
|
|
let transformTo = parse_with_plugins(recipe.transformTo);
|
|
|
|
let transformToTree = makeTree(transformTo);
|
2024-05-11 14:09:03 +00:00
|
|
|
if (
|
|
|
|
codeTree == undefined ||
|
|
|
|
applicableToTree == undefined ||
|
|
|
|
transformToTree == undefined
|
|
|
|
) {
|
|
|
|
throw new Error("This no worky LOL");
|
|
|
|
}
|
|
|
|
showTree(applicableToTree);
|
2024-02-24 21:30:30 +00:00
|
|
|
|
2024-05-11 14:09:03 +00:00
|
|
|
let matches = runMatch(codeTree, applicableToTree, internals);
|
|
|
|
|
|
|
|
for (let match of matches) {
|
|
|
|
showTreePaired(match);
|
|
|
|
console.log(generate(match.element.codeNode).code);
|
|
|
|
}
|
|
|
|
console.log(matches.length);
|
|
|
|
return;
|
|
|
|
for (let match of matches) {
|
|
|
|
//console.log(transformToTree.element);
|
|
|
|
let output = structuredClone(transformToTree.element);
|
|
|
|
try {
|
|
|
|
transformer(match, transformToTree, output, codeAST);
|
|
|
|
} catch (error) {
|
|
|
|
console.log("We failed to transform an element!");
|
|
|
|
}
|
|
|
|
//let result = generate(transformToTreeClone.element);
|
|
|
|
//console.log(output);
|
|
|
|
console.log(generate(match.element.codeNode).code, "is turned into:");
|
|
|
|
console.log(generate(output, { topicToken: "%" }).code);
|
|
|
|
//console.log(generate(codeAST, { topicToken: "%" }).code);
|
|
|
|
console.log("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("Final generated code: \n");
|
|
|
|
|
|
|
|
let output = generate(codeAST, { topicToken: "%" }).code;
|
|
|
|
//showTree(transformToTree);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
function transformJSTQL(recipe: TransformRecipe, code: string) {
|
|
|
|
let { prelude, cleanedJS } = parseInternal(recipe.applicableTo);
|
|
|
|
let codeAST = parse_with_plugins(code);
|
|
|
|
let codeTree = makeTree(codeAST);
|
|
|
|
let applicabelToAST = parse_with_plugins(cleanedJS);
|
|
|
|
console.dir(applicabelToAST, { depth: null });
|
|
|
|
let applicableToTree = makeTree(applicabelToAST);
|
|
|
|
let transformTo = parse_with_plugins(recipe.transformTo);
|
|
|
|
let transformToTree = makeTree(transformTo);
|
2024-02-24 21:30:30 +00:00
|
|
|
|
|
|
|
if (
|
|
|
|
codeTree == undefined ||
|
|
|
|
applicableToTree == undefined ||
|
|
|
|
transformToTree == undefined
|
|
|
|
) {
|
|
|
|
throw new Error("This no worky LOL");
|
|
|
|
}
|
|
|
|
|
2024-05-11 14:09:03 +00:00
|
|
|
let matches = runMatch(codeTree, applicableToTree, prelude);
|
2024-02-24 21:30:30 +00:00
|
|
|
|
|
|
|
for (let match of matches) {
|
|
|
|
//console.log(transformToTree.element);
|
|
|
|
let output = structuredClone(transformToTree.element);
|
|
|
|
try {
|
|
|
|
transformer(match, transformToTree, output, codeAST);
|
|
|
|
} catch (error) {
|
|
|
|
console.log("We failed to transform an element!");
|
2023-12-11 18:38:30 +00:00
|
|
|
}
|
2024-02-24 21:30:30 +00:00
|
|
|
//let result = generate(transformToTreeClone.element);
|
|
|
|
//console.log(output);
|
|
|
|
console.log(generate(match.element.codeNode).code, "is turned into:");
|
|
|
|
console.log(generate(output, { topicToken: "%" }).code);
|
|
|
|
//console.log(generate(codeAST, { topicToken: "%" }).code);
|
|
|
|
console.log("\n");
|
|
|
|
}
|
2023-12-11 18:38:30 +00:00
|
|
|
|
2024-02-24 21:30:30 +00:00
|
|
|
console.log("Final generated code: \n");
|
2023-12-11 18:38:30 +00:00
|
|
|
|
2024-02-24 21:30:30 +00:00
|
|
|
let output = generate(codeAST, { topicToken: "%" }).code;
|
|
|
|
//showTree(transformToTree);
|
2023-12-11 18:38:30 +00:00
|
|
|
|
2024-02-24 21:30:30 +00:00
|
|
|
return output;
|
|
|
|
}
|