IT WORKS
This commit is contained in:
parent
b740b469d4
commit
438d4589d4
13 changed files with 232 additions and 167 deletions
BIN
JSTQL/JSTQL-0.0.1.vsix
Normal file
BIN
JSTQL/JSTQL-0.0.1.vsix
Normal file
Binary file not shown.
17
JSTQL/src/JSTQL_interface/api.ts
Normal file
17
JSTQL/src/JSTQL_interface/api.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import type { Model } from "../language/generated/ast.js";
|
||||||
|
|
||||||
|
import { AstNode, EmptyFileSystem, LangiumDocument } from "langium";
|
||||||
|
import { parseDocument } from "langium/test";
|
||||||
|
import { createJstqlServices } from "../language/jstql-module.js";
|
||||||
|
const services = createJstqlServices(EmptyFileSystem).Jstql;
|
||||||
|
|
||||||
|
export async function parseDSLtoAST(modelText: string): Promise<Model> {
|
||||||
|
var doc: LangiumDocument<AstNode> = await parseDocument(
|
||||||
|
services,
|
||||||
|
modelText
|
||||||
|
);
|
||||||
|
const db = services.shared.workspace.DocumentBuilder;
|
||||||
|
await db.build([doc], { validation: true });
|
||||||
|
const model = doc.parseResult.value as Model;
|
||||||
|
return model;
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ export function registerValidationChecks(services: JstqlServices) {
|
||||||
const registry = services.validation.ValidationRegistry;
|
const registry = services.validation.ValidationRegistry;
|
||||||
const validator = services.validation.JstqlValidator;
|
const validator = services.validation.JstqlValidator;
|
||||||
const checks: ValidationChecks<JstqlAstType> = {
|
const checks: ValidationChecks<JstqlAstType> = {
|
||||||
Pair: validator.validateWildcardAplTo,
|
Pair: validator.validateWildcards,
|
||||||
};
|
};
|
||||||
registry.register(checks, validator);
|
registry.register(checks, validator);
|
||||||
}
|
}
|
||||||
|
@ -18,28 +18,30 @@ export function registerValidationChecks(services: JstqlServices) {
|
||||||
* Implementation of custom validations.
|
* Implementation of custom validations.
|
||||||
*/
|
*/
|
||||||
export class JstqlValidator {
|
export class JstqlValidator {
|
||||||
validateWildcardAplTo(pair: Pair, accept: ValidationAcceptor): void {
|
validateWildcards(pair: Pair, accept: ValidationAcceptor): void {
|
||||||
let validationResultAplTo = validateWildcardAplTo(
|
try {
|
||||||
collectWildcard(pair.aplTo.apl_to_code.split(""))
|
let validationResultAplTo = validateWildcardAplTo(
|
||||||
);
|
collectWildcard(pair.aplTo.apl_to_code.split(""))
|
||||||
if (validationResultAplTo.errors.length != 0) {
|
);
|
||||||
accept("error", validationResultAplTo.errors.join("\n"), {
|
if (validationResultAplTo.errors.length != 0) {
|
||||||
node: pair.aplTo,
|
accept("error", validationResultAplTo.errors.join("\n"), {
|
||||||
property: "apl_to_code",
|
node: pair.aplTo,
|
||||||
});
|
property: "apl_to_code",
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let validationResultTraTo = validateWildcardTraTo(
|
let validationResultTraTo = validateWildcardTraTo(
|
||||||
collectWildcard(pair.traTo.transform_to_code.split("")),
|
collectWildcard(pair.traTo.transform_to_code.split("")),
|
||||||
validationResultAplTo.env
|
validationResultAplTo.env
|
||||||
);
|
);
|
||||||
|
|
||||||
if (validationResultTraTo.length != 0) {
|
if (validationResultTraTo.length != 0) {
|
||||||
accept("error", validationResultTraTo.join("\n"), {
|
accept("error", validationResultTraTo.join("\n"), {
|
||||||
node: pair.traTo,
|
node: pair.traTo,
|
||||||
property: "transform_to_code",
|
property: "transform_to_code",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,26 +101,5 @@ function collectWildcard(code: string[]): string[] {
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(wildcards);
|
|
||||||
return wildcards;
|
return wildcards;
|
||||||
}
|
}
|
||||||
function testValidator() {
|
|
||||||
let res = validateWildcardAplTo(
|
|
||||||
collectWildcard(
|
|
||||||
`() => {
|
|
||||||
<<blockStatements: anyStatementList>>
|
|
||||||
return << returnExpr: Expr >>
|
|
||||||
}`.split("")
|
|
||||||
)
|
|
||||||
);
|
|
||||||
console.log(res);
|
|
||||||
let res2 = validateWildcardTraTo(
|
|
||||||
collectWildcard(
|
|
||||||
`<< blockStatements >>
|
|
||||||
<< returnExpr >>`.split("")
|
|
||||||
),
|
|
||||||
res.env
|
|
||||||
);
|
|
||||||
console.log(res2);
|
|
||||||
}
|
|
||||||
testValidator();
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ proposal DoExpression{
|
||||||
pair arrowFunction{
|
pair arrowFunction{
|
||||||
applicable to {
|
applicable to {
|
||||||
"() => {
|
"() => {
|
||||||
<<blockStatements: anyStatementList>>
|
<<blockStatements: anyStatementList | hello >>
|
||||||
return << returnExpr: Expr >>
|
return << returnExpr: Expr >>
|
||||||
}"
|
}"
|
||||||
}
|
}
|
||||||
transform to {
|
transform to {
|
||||||
"do {
|
"do {
|
||||||
<< blockStatementsss >>
|
<< blockStatements >>
|
||||||
<< returnExpr >>
|
<< returnExpr >>
|
||||||
}"
|
}"
|
||||||
}
|
}
|
24
dsl_files/pipeline.jstql
Normal file
24
dsl_files/pipeline.jstql
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
proposal Pipeline{
|
||||||
|
pair SingleArgument {
|
||||||
|
applicable to {
|
||||||
|
"<<someFunctionIdent:Identifier | MemberExpression>>(<<someFunctionParam: Expression | Identifier>>);"
|
||||||
|
}
|
||||||
|
|
||||||
|
transform to {
|
||||||
|
"<<someFunctionParam>> |> <<someFunctionIdent>>(%);"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pair MultiArgument {
|
||||||
|
applicable to {
|
||||||
|
"<<someFunctionIdent:Identifier>>(
|
||||||
|
<<firstFunctionParam : Expression | Identifier>>,
|
||||||
|
<<restOfFunctionParams: anyRest>>
|
||||||
|
);"
|
||||||
|
}
|
||||||
|
|
||||||
|
transform to {
|
||||||
|
"<<firstFunctionParam>> |> <<someFunctionIdent>>(%, <<restOfFunctionParams>>);"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
output.js
Normal file
90
output.js
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
function parse() {
|
||||||
|
const input = ("input" |> document.getElementById(%)).value;
|
||||||
|
const data = 32 |> input.slice(%);
|
||||||
|
const compressedData = data |> decode_base64(%);
|
||||||
|
const uncompressed = compressedData |> pako.inflate(%);
|
||||||
|
const json = uncompressed |> JSON.parse(%);
|
||||||
|
json |> console.log(%);
|
||||||
|
json |> convertToDesktop(%);
|
||||||
|
}
|
||||||
|
function convertToDesktop(json) {
|
||||||
|
const newValues = {
|
||||||
|
crb: false,
|
||||||
|
newClanRaidClassId: 0,
|
||||||
|
newClanRaidClassLevel: 0,
|
||||||
|
pendingImmortalSouls: 0,
|
||||||
|
pendingRaidRubies: 0,
|
||||||
|
immortalSouls: 0,
|
||||||
|
lastPurchaseTime: 0,
|
||||||
|
lastRaidAttemptTimestamp: 0,
|
||||||
|
lastRaidRewardCheckTimestamp: 0,
|
||||||
|
shouldShowHZERoster: false,
|
||||||
|
lastBonusRewardCheckTimestamp: 0
|
||||||
|
};
|
||||||
|
const mappedValues = {
|
||||||
|
rubies: json.rubies / 10 |> Math.round(%)
|
||||||
|
};
|
||||||
|
const pcSpecificValues = {
|
||||||
|
readPatchNumber: "1.0e12",
|
||||||
|
saveOrigin: "pc"
|
||||||
|
};
|
||||||
|
const hash = "7a990d405d2c6fb93aa8fbb0ec1a3b23";
|
||||||
|
const newData = {
|
||||||
|
...newValues,
|
||||||
|
...json,
|
||||||
|
...mappedValues,
|
||||||
|
...pcSpecificValues
|
||||||
|
};
|
||||||
|
const compressed = newData |> JSON.stringify(%) |> pako.deflate(%);
|
||||||
|
const base64 = compressed |> btoa(%);
|
||||||
|
const finalSaveString = hash + base64;
|
||||||
|
("output_output" |> document.getElementById(%)).innerText = finalSaveString;
|
||||||
|
showOutput();
|
||||||
|
}
|
||||||
|
function showOutput() {
|
||||||
|
("outputs" |> document.getElementById(%)).style.visibility = "visible";
|
||||||
|
}
|
||||||
|
function copyOutput() {
|
||||||
|
const output = "output_output" |> document.getElementById(%);
|
||||||
|
output.disabled = false;
|
||||||
|
output.focus();
|
||||||
|
output.select();
|
||||||
|
"copy" |> document.execCommand(%);
|
||||||
|
output.disabled = true;
|
||||||
|
const successElement = "copy_success_msg" |> document.getElementById(%);
|
||||||
|
successElement.style.visibility = "visible";
|
||||||
|
setTimeout(() => successElement.style.visibility = "hidden", 4000);
|
||||||
|
}
|
||||||
|
function decode_base64(s) {
|
||||||
|
let e = {},
|
||||||
|
i,
|
||||||
|
k,
|
||||||
|
v = [],
|
||||||
|
r = "",
|
||||||
|
w = String.fromCharCode;
|
||||||
|
let n = [[65, 91], [97, 123], [48, 58], [43, 44], [47, 48]];
|
||||||
|
for (z in n) {
|
||||||
|
for (i = n[z][0]; i < n[z][1]; i++) {
|
||||||
|
i |> w(%) |> v.push(%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
e[v[i]] = i;
|
||||||
|
}
|
||||||
|
for (i = 0; i < s.length; i += 72) {
|
||||||
|
let b = 0,
|
||||||
|
c,
|
||||||
|
x,
|
||||||
|
l = 0,
|
||||||
|
o = i |> s.substring(%);
|
||||||
|
for (x = 0; x < o.length; x++) {
|
||||||
|
c = e[x |> o.charAt(%)];
|
||||||
|
b = (b << 6) + c;
|
||||||
|
l += 6;
|
||||||
|
while (l >= 8) {
|
||||||
|
r += (b >>> (l -= 8)) % 256 |> w(%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
|
@ -24,9 +24,6 @@ export const makeTree = (
|
||||||
let first: TreeNode<t.Node> | null = null;
|
let first: TreeNode<t.Node> | null = null;
|
||||||
traverse(ast, {
|
traverse(ast, {
|
||||||
enter(path: any) {
|
enter(path: any) {
|
||||||
//console.log(path.node);
|
|
||||||
//console.log("Entered: ", path.node.type);
|
|
||||||
|
|
||||||
let node: TreeNode<t.Node> = new TreeNode<t.Node>(
|
let node: TreeNode<t.Node> = new TreeNode<t.Node>(
|
||||||
last,
|
last,
|
||||||
path.node as t.Node
|
path.node as t.Node
|
||||||
|
@ -43,12 +40,8 @@ export const makeTree = (
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
//console.log(first.children);
|
|
||||||
|
|
||||||
if (first != null) {
|
if (first != null) {
|
||||||
return first;
|
return first;
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const showTree = (tree: TreeNode<t.Node>, idents: number = 0) => {
|
export const showTree = (tree: TreeNode<t.Node>, idents: number = 0) => {
|
||||||
|
|
14
src/index.ts
14
src/index.ts
|
@ -139,16 +139,16 @@ const main = async () => {
|
||||||
//transform(selfHostedTransformExampleMultiStmt, codeFromFile);
|
//transform(selfHostedTransformExampleMultiStmt, codeFromFile);
|
||||||
|
|
||||||
const jstql_file =
|
const jstql_file =
|
||||||
"/home/rolfmg/Coding/Master/didactic-chainsaw/dsl_files/test_hello.jstl";
|
"/home/rolfmg/Coding/Master/didactic-chainsaw/dsl_files/pipeline.jstql";
|
||||||
const test_file = Bun.file(jstql_file);
|
const test_file = Bun.file(jstql_file);
|
||||||
const test_JSTQL = await test_file.text();
|
const test_JSTQL = await test_file.text();
|
||||||
console.log(parseJSTQL(test_JSTQL));
|
let proposals = await parseJSTQL(test_JSTQL);
|
||||||
/*
|
|
||||||
await Bun.write(
|
|
||||||
"../output.js",
|
|
||||||
transform(selfHostedTransformExampleMultiStmt, codeFromFile)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
await Bun.write(
|
||||||
|
"output.js",
|
||||||
|
transform(proposals[0].pairs[0], codeFromFile)
|
||||||
|
);
|
||||||
|
/*
|
||||||
console.log(
|
console.log(
|
||||||
transform(selfHostedTransformExampleMultiStmt, selfHostedTestMultiStmt)
|
transform(selfHostedTransformExampleMultiStmt, selfHostedTestMultiStmt)
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
import { TransformRecipe } from "../transform/transform";
|
import { TransformRecipe, Proposal as LocalProp } from "../transform/transform";
|
||||||
|
import { parseDSLtoAST } from "../../JSTQL/src/JSTQL_interface/api";
|
||||||
|
import { Model, Proposal } from "../../JSTQL/src/language/generated/ast";
|
||||||
|
|
||||||
export function parseJSTQL(jstql: string): TransformRecipe {
|
export async function parseJSTQL(jstql: string): Promise<LocalProp[]> {
|
||||||
console.log((await parseDSLtoAST(test_JSTQL)).proposals[0].code);
|
let model: Model = await parseDSLtoAST(jstql);
|
||||||
|
let proposals: LocalProp[] = [];
|
||||||
|
for (let proposal of model.proposals) {
|
||||||
|
let pairs: TransformRecipe[] = [];
|
||||||
|
for (let pair of proposal.pair) {
|
||||||
|
pairs.push({
|
||||||
|
applicableTo: pair.aplTo.apl_to_code,
|
||||||
|
transformTo: pair.traTo.transform_to_code,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
proposals.push({ pairs });
|
||||||
|
}
|
||||||
|
return proposals;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,9 +97,7 @@ export class Matcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is broken
|
// This is broken
|
||||||
multiStatementMatcher(code: TreeNode<t.Node>, aplTo: TreeNode<t.Node>) {
|
multiStatementMatcher(code: TreeNode<t.Node>, aplTo: TreeNode<t.Node>) {}
|
||||||
console.log("Currently unsupported");
|
|
||||||
}
|
|
||||||
|
|
||||||
match(code: TreeNode<t.Node>, aplTo: TreeNode<t.Node>) {}
|
match(code: TreeNode<t.Node>, aplTo: TreeNode<t.Node>) {}
|
||||||
private checkCodeNode(code_node: t.Node, aplTo: t.Node): boolean {
|
private checkCodeNode(code_node: t.Node, aplTo: t.Node): boolean {
|
||||||
|
@ -139,27 +137,4 @@ export class Matcher {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildPairTree(
|
|
||||||
code: TreeNode<t.Node>,
|
|
||||||
aplTo: TreeNode<t.Node>
|
|
||||||
): TreeNode<PairedNodes> {
|
|
||||||
let temp: TreeNode<PairedNodes> = new TreeNode(null, {
|
|
||||||
codeNode: code.element,
|
|
||||||
aplToNode: aplTo.element,
|
|
||||||
});
|
|
||||||
if (code.children.length >= aplTo.children.length) {
|
|
||||||
for (let i = 0; i < aplTo.children.length; i++) {
|
|
||||||
let child = this.buildPairTree(
|
|
||||||
code.children[i],
|
|
||||||
aplTo.children[i]
|
|
||||||
);
|
|
||||||
temp.children.push(child);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("ERROR");
|
|
||||||
}
|
|
||||||
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ function parseInternalString(dslString: string): {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
identifier,
|
identifier,
|
||||||
types: typeString.length > 0 ? typeString.split("|") : [""],
|
types: typeString ? typeString.split("|") : [""],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,10 +73,3 @@ export function parse_with_plugins(
|
||||||
plugins: [["pipelineOperator", { proposal: "hack", topicToken: "%" }]],
|
plugins: [["pipelineOperator", { proposal: "hack", topicToken: "%" }]],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function testParseInternal() {
|
|
||||||
parseInternal(`
|
|
||||||
<<a:Identifier>>(<< b : Identifier | MemberExpression >>);
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
testParseInternal();
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import traverse from "@babel/traverse";
|
import traverse from "@babel/traverse";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
import generate from "@babel/generator";
|
import generate from "@babel/generator";
|
||||||
import { parseInternal, parse_with_plugins } from "../parser/parse";
|
import {
|
||||||
|
InternalDSLVariable,
|
||||||
|
parseInternal,
|
||||||
|
parse_with_plugins,
|
||||||
|
} from "../parser/parse";
|
||||||
import {
|
import {
|
||||||
TreeNode,
|
TreeNode,
|
||||||
makeTree,
|
makeTree,
|
||||||
|
@ -11,6 +15,11 @@ import {
|
||||||
import { runMatch } from "../matcher/matcher";
|
import { runMatch } from "../matcher/matcher";
|
||||||
import { transformMatch, transformer } from "./transformMatch";
|
import { transformMatch, transformer } from "./transformMatch";
|
||||||
import { preludeBuilder } from "../parser/preludeBuilder";
|
import { preludeBuilder } from "../parser/preludeBuilder";
|
||||||
|
|
||||||
|
export interface Proposal {
|
||||||
|
pairs: TransformRecipe[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface TransformRecipe {
|
export interface TransformRecipe {
|
||||||
applicableTo: string;
|
applicableTo: string;
|
||||||
transformTo: string;
|
transformTo: string;
|
||||||
|
@ -21,16 +30,39 @@ export interface SelfHostedRecipe extends TransformRecipe {
|
||||||
export function transform(recipe: TransformRecipe, code: string) {
|
export function transform(recipe: TransformRecipe, code: string) {
|
||||||
if ((<SelfHostedRecipe>recipe).prelude !== undefined) {
|
if ((<SelfHostedRecipe>recipe).prelude !== undefined) {
|
||||||
// We are using the self hosted version
|
// We are using the self hosted version
|
||||||
return transformSelfHosted(<SelfHostedRecipe>recipe, code);
|
return transformSelfHosted(
|
||||||
|
{
|
||||||
|
applicableTo: recipe.applicableTo,
|
||||||
|
transformTo: recipe.transformTo,
|
||||||
|
},
|
||||||
|
preludeBuilder((recipe as SelfHostedRecipe).prelude),
|
||||||
|
code
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// We are using JSTQL
|
// We are using JSTQL
|
||||||
return transformJSTQL(recipe, code);
|
// We have to parse JSTQL to the self hosted version
|
||||||
|
|
||||||
|
let { cleanedJS: applicableTo, prelude } = parseInternal(
|
||||||
|
recipe.applicableTo
|
||||||
|
);
|
||||||
|
let { cleanedJS: transformTo, prelude: _ } = parseInternal(
|
||||||
|
recipe.transformTo
|
||||||
|
);
|
||||||
|
|
||||||
|
return transformSelfHosted(
|
||||||
|
{ applicableTo, transformTo },
|
||||||
|
prelude,
|
||||||
|
code
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformSelfHosted(recipe: SelfHostedRecipe, code: string) {
|
function transformSelfHosted(
|
||||||
let internals = preludeBuilder(recipe.prelude);
|
recipe: TransformRecipe,
|
||||||
|
internals: InternalDSLVariable,
|
||||||
|
code: string
|
||||||
|
) {
|
||||||
|
console.log(recipe);
|
||||||
let codeAST = parse_with_plugins(code);
|
let codeAST = parse_with_plugins(code);
|
||||||
let codeTree = makeTree(codeAST);
|
let codeTree = makeTree(codeAST);
|
||||||
let applicabelToAST = parse_with_plugins(recipe.applicableTo);
|
let applicabelToAST = parse_with_plugins(recipe.applicableTo);
|
||||||
|
@ -54,8 +86,7 @@ function transformSelfHosted(recipe: SelfHostedRecipe, code: string) {
|
||||||
console.log(generate(match.element.codeNode).code);
|
console.log(generate(match.element.codeNode).code);
|
||||||
}
|
}
|
||||||
console.log(matches.length);
|
console.log(matches.length);
|
||||||
return;
|
for (let match of matches.reverse()) {
|
||||||
for (let match of matches) {
|
|
||||||
//console.log(transformToTree.element);
|
//console.log(transformToTree.element);
|
||||||
let output = structuredClone(transformToTree.element);
|
let output = structuredClone(transformToTree.element);
|
||||||
try {
|
try {
|
||||||
|
@ -63,56 +94,6 @@ function transformSelfHosted(recipe: SelfHostedRecipe, code: string) {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("We failed to transform an element!");
|
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);
|
|
||||||
|
|
||||||
if (
|
|
||||||
codeTree == undefined ||
|
|
||||||
applicableToTree == undefined ||
|
|
||||||
transformToTree == undefined
|
|
||||||
) {
|
|
||||||
throw new Error("This no worky LOL");
|
|
||||||
}
|
|
||||||
|
|
||||||
let matches = runMatch(codeTree, applicableToTree, prelude);
|
|
||||||
|
|
||||||
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");
|
console.log("Final generated code: \n");
|
||||||
|
|
|
@ -9,31 +9,28 @@ import {
|
||||||
showTreePaired,
|
showTreePaired,
|
||||||
} from "../data_structures/tree";
|
} from "../data_structures/tree";
|
||||||
import { InternalDSLVariable } from "../parser/parse";
|
import { InternalDSLVariable } from "../parser/parse";
|
||||||
import { Match, MatchedTreeNode, PairedNodes } from "../matcher/matcher";
|
import { MatchedTreeNode, PairedNodes } from "../matcher/matcher";
|
||||||
import traverse from "@babel/traverse";
|
import traverse from "@babel/traverse";
|
||||||
|
|
||||||
export function transformer(
|
export function transformer(
|
||||||
matches: Match,
|
match: TreeNode<PairedNodes>,
|
||||||
trnTo: TreeNode<t.Node>,
|
trnTo: TreeNode<t.Node>,
|
||||||
output: t.Node,
|
output: t.Node,
|
||||||
inputCode: t.Node
|
inputCode: t.Node
|
||||||
) {
|
) {
|
||||||
for (let match of matches.statements) {
|
transformMatch(match, trnTo, output);
|
||||||
transformMatch(match, trnTo, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output.type == "Program") {
|
if (output.type == "Program") {
|
||||||
output = output.body[0];
|
output = output.body[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let match of matches.statements)
|
traverse(inputCode, {
|
||||||
traverse(inputCode, {
|
enter(path) {
|
||||||
enter(path) {
|
if (path.node === match.element.codeNode) {
|
||||||
if (path.node === match.element.codeNode) {
|
path.replaceWith(output);
|
||||||
path.replaceWith(output);
|
}
|
||||||
}
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformMatch(
|
export function transformMatch(
|
||||||
|
@ -51,7 +48,7 @@ export function transformMatch(
|
||||||
traverse(output, {
|
traverse(output, {
|
||||||
enter(path) {
|
enter(path) {
|
||||||
if (path.isIdentifier({ name: trnTo.element.name })) {
|
if (path.isIdentifier({ name: trnTo.element.name })) {
|
||||||
//console.log(match.element.codeNode);
|
console.log(match.element.codeNode);
|
||||||
if (match.element.codeNode) {
|
if (match.element.codeNode) {
|
||||||
path.replaceWith(match.element.codeNode);
|
path.replaceWith(match.element.codeNode);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue