diff --git a/.vscode/settings.json b/.vscode/settings.json
index b396049..c62565e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,10 +1,11 @@
 {
-  // The path to the `bun` executable.
-  "bun.runtime": "/home/rolfmg/.bun/bin/bun",
+    // The path to the `bun` executable.
+    "bun.runtime": "/home/rolfmg/.bun/bin/bun",
 
-  // If support for Bun should be added to the default "JavaScript Debug Terminal".
-  "bun.debugTerminal.enabled": true,
-  
-  // If the debugger should stop on the first line of the program.
-  "bun.debugTerminal.stopOnEntry": true,
-}
\ No newline at end of file
+    // If support for Bun should be added to the default "JavaScript Debug Terminal".
+    "bun.debugTerminal.enabled": true,
+
+    // If the debugger should stop on the first line of the program.
+    "bun.debugTerminal.stopOnEntry": true,
+    "cSpell.words": ["babelparser"]
+}
diff --git a/babel b/babel
index 380d186..2f9c48d 160000
--- a/babel
+++ b/babel
@@ -1 +1 @@
-Subproject commit 380d186b77d32734c595652a40cbda5e4e109c5c
+Subproject commit 2f9c48d4eda2d69908fc53ea285f47ed2c540f7e
diff --git a/bun.lockb b/bun.lockb
index 4d1deda..5aaca4d 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/demo-site/index.html b/demo-site/index.html
new file mode 100644
index 0000000..ed0b63f
--- /dev/null
+++ b/demo-site/index.html
@@ -0,0 +1,19 @@
+ <!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Page Title</title>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<style>
+body {
+  font-family: Arial, Helvetica, sans-serif;
+}
+</style>
+</head>
+<body>
+
+<h1>Demo site</h1>
+<p></p>
+
+</body>
+</html> 
\ No newline at end of file
diff --git a/didactic-chainsaw-dsl/src/language/js-transform-lang copy.langium b/didactic-chainsaw-dsl/src/language/js-transform-lang copy.langium
new file mode 100644
index 0000000..dcf393c
--- /dev/null
+++ b/didactic-chainsaw-dsl/src/language/js-transform-lang copy.langium	
@@ -0,0 +1,18 @@
+grammar JsTransformLang
+
+
+terminal ID:  /[_a-zA-Z][\w_]*/;
+terminal STRING: /"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/;
+entry Model:
+    proposals+=Proposal*;
+
+
+Proposal:
+    "proposal" proposalName=ID "{"
+        "applicable" "to" "{"
+            code=STRING
+        "}"
+        "replace" "with" "{"
+            code=STRING
+        "}"
+    "}";
diff --git a/didactic-chainsaw-dsl/src/language/js-transform-lang-validator.ts b/didactic-chainsaw-dsl/src/language/js-transform-lang-validator.ts
index 44e7cc4..9464b33 100644
--- a/didactic-chainsaw-dsl/src/language/js-transform-lang-validator.ts
+++ b/didactic-chainsaw-dsl/src/language/js-transform-lang-validator.ts
@@ -1,5 +1,5 @@
-import type { ValidationAcceptor, ValidationChecks } from "langium";
-import type { JsTransformLangAstType, Proposal } from "./generated/ast.js";
+import type { ValidationChecks } from "langium";
+import type { JsTransformLangAstType } from "./generated/ast.js";
 import type { JsTransformLangServices } from "./js-transform-lang-module.js";
 
 /**
@@ -9,7 +9,7 @@ export function registerValidationChecks(services: JsTransformLangServices) {
     const registry = services.validation.ValidationRegistry;
     const validator = services.validation.JsTransformLangValidator;
     const checks: ValidationChecks<JsTransformLangAstType> = {
-        Proposal: validator.checkPersonStartsWithCapital,
+        //Person: validator.checkPersonStartsWithCapital,
     };
     registry.register(checks, validator);
 }
@@ -18,6 +18,7 @@ export function registerValidationChecks(services: JsTransformLangServices) {
  * Implementation of custom validations.
  */
 export class JsTransformLangValidator {
+    /*
     checkPersonStartsWithCapital(
         proposal: Proposal,
         accept: ValidationAcceptor
@@ -31,4 +32,5 @@ export class JsTransformLangValidator {
             }
         }
     }
+    */
 }
diff --git a/didactic-chainsaw-dsl/src/language/js-transform-lang.langium b/didactic-chainsaw-dsl/src/language/js-transform-lang.langium
index 71cd962..5fd636f 100644
--- a/didactic-chainsaw-dsl/src/language/js-transform-lang.langium
+++ b/didactic-chainsaw-dsl/src/language/js-transform-lang.langium
@@ -1,18 +1,32 @@
 grammar JsTransformLang
 
-
-terminal PROPOSALNAME:  /[_a-zA-Z]+/;
-terminal STRING: /"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/;
 entry Model:
-    (proposals+=Proposal);
-
+    (proposals+=Proposal)*;
 
 Proposal:
-    "proposal" "(" proposalName=PROPOSALNAME ")" "{"
+    'proposal' name=ID "{"
         "applicable" "to" "{"
-            code=STRING
+            code=RICH_TEXT
         "}"
         "replace" "with" "{"
-            code=STRING
+
         "}"
     "}";
+
+hidden terminal WS: /\s+/;
+terminal ID: /[_a-zA-Z][\w_]*/;
+
+terminal fragment IN_RICH_STRING:
+      "''" !('«'|"'")
+    | "'" !('«'|"'");
+//| !('«'|"'");
+terminal STRING: /"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/;
+hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//;
+hidden terminal SL_COMMENT: /\/\/[^\n\r]*/;
+terminal RICH_TEXT: "'''" IN_RICH_STRING* ("'''"| ("'" "'"?)? );
+terminal RICH_TEXT_START: "'''" IN_RICH_STRING* ("'" "'"?)? '«';
+terminal RICH_TEXT_END: '»' IN_RICH_STRING* ("'''"| ("'" "'"?)? );
+terminal RICH_TEXT_INBETWEEN: '»' IN_RICH_STRING* ("'" "'"?)? '«';
+terminal COMMENT_RICH_TEXT_INBETWEEN: "««" !('\n'|'\r')* ('\r'? '\n' IN_RICH_STRING* ("'" "'"?)? '«')?;
+terminal COMMENT_RICH_TEXT_END: "««" !('\n'|'\r')* (('\r'? '\n' IN_RICH_STRING* ("'''"| ("'" "'"?)? )) );
+
diff --git a/dsl_files/test.jstl b/dsl_files/test.jstl
index 3d20c5e..b55cb1d 100644
--- a/dsl_files/test.jstl
+++ b/dsl_files/test.jstl
@@ -1,4 +1,7 @@
-proposal (async) {
+
+
+
+proposal async {
     applicable to {
         let _$_a_$_ = await _$_expr_$_();
         console.log(_$_a_$_);
diff --git a/dsl_files/test_hello.jstl b/dsl_files/test_hello.jstl
new file mode 100644
index 0000000..ed3b330
--- /dev/null
+++ b/dsl_files/test_hello.jstl
@@ -0,0 +1,19 @@
+proposal p1 {
+    applicable to {
+        "let a = 0;"
+    }
+    replace with {
+        "SOMETHING"
+    }
+}
+
+
+proposal p2 {
+    applicable to {
+        "let a = 0;"
+    }
+    replace with {
+        "SOMETHING"
+    }
+}
+
diff --git a/output.js b/output.js
new file mode 100644
index 0000000..3f2d1e0
--- /dev/null
+++ b/output.js
@@ -0,0 +1,120 @@
+require("@risingstack/trace");
+const Discord = require("discord.js");
+const ytdl = require("ytdl-core");
+const bot = new Discord.Client();
+const fs = new require("fs");
+const path = require("path");
+const probe = require("pmx").probe();
+const jsonfile = require("jsonfile");
+const commandCooldown = require("./helpers/commandCooldown.js");
+let cleverbot = require("cleverbot.io"),
+  clever = new cleverbot("jp6wu9XZbYdoICmo", "54jV1VcMNxGQyc2cdKUFUpjkPVo3bTr2");
+const log = require("./helpers/log.js");
+bot.on("ready", () => {
+  bot.user.setGame(".help");
+  (function loop(i) {
+    setTimeout(function () {
+      bot.guilds.size |> guilds.set(%);
+      if (true) {
+        loop(i);
+      }
+    }, 1000);
+  })(10);
+  log(`Ready to serve ${bot.users.size} users, in ${bot.channels.size} channels of ${bot.guilds.size} servers.`);
+});
+fs.readFile("config.json", (err, data) => {
+  if (err) {
+    log("Config file does not exist, creating one.");
+    let obj = {
+      discordToken: "TOKEN",
+      discordBotsToken: "TOKEN"
+    };
+    jsonfile.spaces = 4;
+    jsonfile.writeFile("config.json", obj, err => {
+      err |> console.log(%);
+    });
+    process.exit(1);
+  } else {
+    config = require("./config.json");
+    config.discordToken |> bot.login(%);
+  }
+});
+global.skips = {};
+global.queue = {
+  test: "test"
+};
+global.dispatchers = new Map();
+global.connections = new Map();
+global.voices = new Map();
+global.streams = new Map();
+let config = "ERR";
+global.allstreams = 0;
+global.counter = probe.counter({
+  name: "Streams"
+});
+let guilds = probe.metric({
+  name: "Guilds"
+});
+let userCooldown = new Map();
+bot.commands = new Discord.Collection();
+bot.aliases = new Discord.Collection();
+fs.readdir("./commands/", (err, files) => {
+  if (err) err |> console.error(%);
+  log(`Loading a total of ${files.length} commands.`);
+  files.forEach(f => {
+    let props = require(`./commands/${f}`);
+    log(`Loading Command: ${props.info.name}. :ok_hand:`);
+    bot.commands.set(props.info.name, props);
+    /*
+    props.conf.aliases.forEach(alias => {
+    bot.aliases.set(alias, props.info.name);
+    });
+    */
+  });
+});
+
+bot.on("message", msg => {
+  const prefix = ".";
+  let id = bot.user.id;
+  let clevername = new RegExp(`^<@!?${id}>`);
+  if (msg.content.startsWith(prefix)) {} else if (clevername.test(msg.content)) {} else return;
+  if (msg.author.bot) return;
+  if (msg.guild) {
+    if (!queue[msg.guild.id]) {
+      queue[msg.guild.id] = [];
+    }
+  } else return;
+  let command = msg.content.split(" ")[0].slice(prefix.length);
+  let params = msg.content.split(" ").slice(1);
+  //let perms = bot.elevation(msg);
+  let cmd;
+  if (!userCooldown.get(msg.author.id)) {
+    userCooldown.set(msg.author.id, 0);
+  }
+  if (bot.commands.has(command)) {
+    if (!commandCooldown(userCooldown.get(msg.author.id))) {
+      userCooldown.set(msg.author.id, Date.now());
+      cmd = bot.commands.get(command);
+    } else msg.channel.sendMessage("You're sending commands too quickly!");
+  } else if (bot.aliases.has(command)) {
+    cmd = bot.commands.get(bot.aliases.get(command));
+  }
+  if (cmd) {
+    cmd.run(bot, msg, params);
+  }
+  if (clevername.test(msg.content)) {
+    msg.author.username + " (" + msg.author.id + ") issued command: " + msg.content |> console.log(%);
+    let string = msg.content;
+    string = msg.content.split(" ");
+    string.shift();
+    " " |> string.join(%);
+    msg.author.username |> clever.setNick(%);
+    clever.create(function (err, session) {
+      if (err) log(err);
+      clever.ask(string, function (err, response) {
+        if (err) log(err);
+        msg.channel.sendMessage(response).then(msg => log(`Sent message: ${msg.content}`)).catch(console.error);
+      });
+    });
+  }
+});
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 298c048..1b84bbc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7,6 +7,7 @@
         "": {
             "name": "didactic-chainsaw",
             "dependencies": {
+                "@babel/core": "^7.23.7",
                 "@babel/generator": "^7.23.0",
                 "@babel/parser": "^7.23.0",
                 "@babel/traverse": "^7.23.0",
@@ -16,30 +17,88 @@
                 "ts-node": "^10.9.1"
             },
             "devDependencies": {
+                "@babel/plugin-proposal-pipeline-operator": "^7.23.3",
                 "@swc/cli": "^0.1.62",
                 "@types/node": "^20.5.9",
                 "bun-types": "latest",
                 "typescript": "^5.2.2"
             }
         },
-        "node_modules/@babel/code-frame": {
-            "version": "7.22.13",
-            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
-            "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+        "node_modules/@ampproject/remapping": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+            "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
             "dependencies": {
-                "@babel/highlight": "^7.22.13",
+                "@jridgewell/gen-mapping": "^0.3.0",
+                "@jridgewell/trace-mapping": "^0.3.9"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/@babel/code-frame": {
+            "version": "7.23.5",
+            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+            "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+            "dependencies": {
+                "@babel/highlight": "^7.23.4",
                 "chalk": "^2.4.2"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
-        "node_modules/@babel/generator": {
-            "version": "7.23.0",
-            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
-            "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+        "node_modules/@babel/compat-data": {
+            "version": "7.23.5",
+            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
+            "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/core": {
+            "version": "7.23.7",
+            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz",
+            "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==",
             "dependencies": {
-                "@babel/types": "^7.23.0",
+                "@ampproject/remapping": "^2.2.0",
+                "@babel/code-frame": "^7.23.5",
+                "@babel/generator": "^7.23.6",
+                "@babel/helper-compilation-targets": "^7.23.6",
+                "@babel/helper-module-transforms": "^7.23.3",
+                "@babel/helpers": "^7.23.7",
+                "@babel/parser": "^7.23.6",
+                "@babel/template": "^7.22.15",
+                "@babel/traverse": "^7.23.7",
+                "@babel/types": "^7.23.6",
+                "convert-source-map": "^2.0.0",
+                "debug": "^4.1.0",
+                "gensync": "^1.0.0-beta.2",
+                "json5": "^2.2.3",
+                "semver": "^6.3.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/babel"
+            }
+        },
+        "node_modules/@babel/core/node_modules/semver": {
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
+        "node_modules/@babel/generator": {
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
+            "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+            "dependencies": {
+                "@babel/types": "^7.23.6",
                 "@jridgewell/gen-mapping": "^0.3.2",
                 "@jridgewell/trace-mapping": "^0.3.17",
                 "jsesc": "^2.5.1"
@@ -57,6 +116,42 @@
                 "@jridgewell/sourcemap-codec": "^1.4.14"
             }
         },
+        "node_modules/@babel/helper-compilation-targets": {
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
+            "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+            "dependencies": {
+                "@babel/compat-data": "^7.23.5",
+                "@babel/helper-validator-option": "^7.23.5",
+                "browserslist": "^4.22.2",
+                "lru-cache": "^5.1.1",
+                "semver": "^6.3.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+            "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+            "dependencies": {
+                "yallist": "^3.0.2"
+            }
+        },
+        "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
+        "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+            "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+        },
         "node_modules/@babel/helper-environment-visitor": {
             "version": "7.22.20",
             "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
@@ -88,6 +183,55 @@
                 "node": ">=6.9.0"
             }
         },
+        "node_modules/@babel/helper-module-imports": {
+            "version": "7.22.15",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+            "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+            "dependencies": {
+                "@babel/types": "^7.22.15"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-module-transforms": {
+            "version": "7.23.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+            "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+            "dependencies": {
+                "@babel/helper-environment-visitor": "^7.22.20",
+                "@babel/helper-module-imports": "^7.22.15",
+                "@babel/helper-simple-access": "^7.22.5",
+                "@babel/helper-split-export-declaration": "^7.22.6",
+                "@babel/helper-validator-identifier": "^7.22.20"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/helper-plugin-utils": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+            "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+            "dev": true,
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-simple-access": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+            "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+            "dependencies": {
+                "@babel/types": "^7.22.5"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
         "node_modules/@babel/helper-split-export-declaration": {
             "version": "7.22.6",
             "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
@@ -100,9 +244,9 @@
             }
         },
         "node_modules/@babel/helper-string-parser": {
-            "version": "7.22.5",
-            "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
-            "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+            "version": "7.23.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+            "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
             "engines": {
                 "node": ">=6.9.0"
             }
@@ -115,10 +259,31 @@
                 "node": ">=6.9.0"
             }
         },
+        "node_modules/@babel/helper-validator-option": {
+            "version": "7.23.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
+            "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helpers": {
+            "version": "7.23.7",
+            "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz",
+            "integrity": "sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==",
+            "dependencies": {
+                "@babel/template": "^7.22.15",
+                "@babel/traverse": "^7.23.7",
+                "@babel/types": "^7.23.6"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
         "node_modules/@babel/highlight": {
-            "version": "7.22.20",
-            "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
-            "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+            "version": "7.23.4",
+            "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+            "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
             "dependencies": {
                 "@babel/helper-validator-identifier": "^7.22.20",
                 "chalk": "^2.4.2",
@@ -129,9 +294,9 @@
             }
         },
         "node_modules/@babel/parser": {
-            "version": "7.23.0",
-            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
-            "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
+            "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
             "bin": {
                 "parser": "bin/babel-parser.js"
             },
@@ -139,6 +304,37 @@
                 "node": ">=6.0.0"
             }
         },
+        "node_modules/@babel/plugin-proposal-pipeline-operator": {
+            "version": "7.23.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-pipeline-operator/-/plugin-proposal-pipeline-operator-7.23.3.tgz",
+            "integrity": "sha512-8TDc1vEx+YRaGiF8J8w/XcADaBuqc0RnokaMRrHdX7Vx74WhmxPU8wtM/OHSXvgw45P9tlHS/l0YDpNXwLghmQ==",
+            "dev": true,
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-pipeline-operator": "^7.23.3"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-syntax-pipeline-operator": {
+            "version": "7.23.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-pipeline-operator/-/plugin-syntax-pipeline-operator-7.23.3.tgz",
+            "integrity": "sha512-xypNE8ptJ5buVtgAAOZzN3gIV6McZfMA27GMhy70a8auQIxbLW9g/uKsaoWqUHdPJgpsXYjVD+5oDyS6pRvraA==",
+            "dev": true,
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
         "node_modules/@babel/template": {
             "version": "7.22.15",
             "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
@@ -153,19 +349,19 @@
             }
         },
         "node_modules/@babel/traverse": {
-            "version": "7.23.0",
-            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz",
-            "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==",
+            "version": "7.23.7",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
+            "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
             "dependencies": {
-                "@babel/code-frame": "^7.22.13",
-                "@babel/generator": "^7.23.0",
+                "@babel/code-frame": "^7.23.5",
+                "@babel/generator": "^7.23.6",
                 "@babel/helper-environment-visitor": "^7.22.20",
                 "@babel/helper-function-name": "^7.23.0",
                 "@babel/helper-hoist-variables": "^7.22.5",
                 "@babel/helper-split-export-declaration": "^7.22.6",
-                "@babel/parser": "^7.23.0",
-                "@babel/types": "^7.23.0",
-                "debug": "^4.1.0",
+                "@babel/parser": "^7.23.6",
+                "@babel/types": "^7.23.6",
+                "debug": "^4.3.1",
                 "globals": "^11.1.0"
             },
             "engines": {
@@ -173,11 +369,11 @@
             }
         },
         "node_modules/@babel/types": {
-            "version": "7.23.0",
-            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
-            "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
+            "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
             "dependencies": {
-                "@babel/helper-string-parser": "^7.22.5",
+                "@babel/helper-string-parser": "^7.23.4",
                 "@babel/helper-validator-identifier": "^7.22.20",
                 "to-fast-properties": "^2.0.0"
             },
@@ -957,6 +1153,37 @@
                 "node": ">=8"
             }
         },
+        "node_modules/browserslist": {
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
+            "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+            "funding": [
+                {
+                    "type": "opencollective",
+                    "url": "https://opencollective.com/browserslist"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/funding/github/npm/browserslist"
+                },
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/ai"
+                }
+            ],
+            "dependencies": {
+                "caniuse-lite": "^1.0.30001565",
+                "electron-to-chromium": "^1.4.601",
+                "node-releases": "^2.0.14",
+                "update-browserslist-db": "^1.0.13"
+            },
+            "bin": {
+                "browserslist": "cli.js"
+            },
+            "engines": {
+                "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+            }
+        },
         "node_modules/bun": {
             "version": "1.0.4",
             "resolved": "https://registry.npmjs.org/bun/-/bun-1.0.4.tgz",
@@ -1031,6 +1258,25 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/caniuse-lite": {
+            "version": "1.0.30001574",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz",
+            "integrity": "sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg==",
+            "funding": [
+                {
+                    "type": "opencollective",
+                    "url": "https://opencollective.com/browserslist"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+                },
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/ai"
+                }
+            ]
+        },
         "node_modules/chalk": {
             "version": "2.4.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -1098,6 +1344,11 @@
                 "node": ">= 0.6"
             }
         },
+        "node_modules/convert-source-map": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+            "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
+        },
         "node_modules/create-require": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -1174,6 +1425,11 @@
                 "node": ">=0.3.1"
             }
         },
+        "node_modules/electron-to-chromium": {
+            "version": "1.4.623",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz",
+            "integrity": "sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A=="
+        },
         "node_modules/end-of-stream": {
             "version": "1.4.4",
             "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -1183,6 +1439,14 @@
                 "once": "^1.4.0"
             }
         },
+        "node_modules/escalade": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+            "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
         "node_modules/escape-string-regexp": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
@@ -1348,6 +1612,14 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/gensync": {
+            "version": "1.0.0-beta.2",
+            "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+            "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
         "node_modules/get-stream": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
@@ -1540,6 +1812,17 @@
             "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
             "dev": true
         },
+        "node_modules/json5": {
+            "version": "2.2.3",
+            "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+            "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+            "bin": {
+                "json5": "lib/cli.js"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
         "node_modules/keyv": {
             "version": "4.5.3",
             "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz",
@@ -1633,6 +1916,11 @@
             "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
             "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
         },
+        "node_modules/node-releases": {
+            "version": "2.0.14",
+            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+            "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
+        },
         "node_modules/normalize-url": {
             "version": "6.1.0",
             "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
@@ -1733,6 +2021,11 @@
                 "url": "https://github.com/sponsors/Borewit"
             }
         },
+        "node_modules/picocolors": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+            "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+        },
         "node_modules/picomatch": {
             "version": "2.3.1",
             "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@@ -2202,6 +2495,35 @@
                 "node": ">=14.17"
             }
         },
+        "node_modules/update-browserslist-db": {
+            "version": "1.0.13",
+            "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+            "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+            "funding": [
+                {
+                    "type": "opencollective",
+                    "url": "https://opencollective.com/browserslist"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/funding/github/npm/browserslist"
+                },
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/ai"
+                }
+            ],
+            "dependencies": {
+                "escalade": "^3.1.1",
+                "picocolors": "^1.0.0"
+            },
+            "bin": {
+                "update-browserslist-db": "cli.js"
+            },
+            "peerDependencies": {
+                "browserslist": ">= 4.21.0"
+            }
+        },
         "node_modules/util-deprecate": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/package.json b/package.json
index 297c2e5..612c499 100644
--- a/package.json
+++ b/package.json
@@ -1,24 +1,27 @@
 {
-    "name": "didactic-chainsaw",
-    "module": "index.ts",
-    "type": "module",
-    "scripts": {
-        "run": "bun run src/index.ts",
-        "watch": "bun --watch src/index.ts"
-    },
-    "devDependencies": {
-        "@swc/cli": "^0.1.62",
-        "@types/node": "^20.5.9",
-        "bun-types": "latest",
-        "typescript": "^5.2.2"
-    },
-    "dependencies": {
-        "@babel/generator": "^7.23.0",
-        "@babel/parser": "^7.23.0",
-        "@babel/traverse": "^7.23.0",
-        "@types/babel-traverse": "^6.25.10",
-        "babel": "^6.23.0",
-        "bun": "^1.0.4",
-        "ts-node": "^10.9.1"
-    }
+  "name": "didactic-chainsaw",
+  "module": "index.ts",
+  "type": "module",
+  "scripts": {
+    "": "bun run src/index.ts",
+    "watch": "bun --watch src/index.ts"
+  },
+  "devDependencies": {
+    "@babel/plugin-proposal-pipeline-operator": "^7.23.3",
+    "@swc/cli": "^0.1.62",
+    "@types/node": "^20.5.9",
+    "bun-types": "latest",
+    "typescript": "^5.2.2"
+  },
+  "dependencies": {
+    "@babel/core": "^7.23.7",
+    "@babel/generator": "^7.23.0",
+    "@babel/parser": "^7.23.0",
+    "@babel/traverse": "^7.23.0",
+    "@types/babel-traverse": "^6.25.10",
+    "@types/babel__traverse": "^7.20.5",
+    "babel": "^6.23.0",
+    "bun": "^1.0.4",
+    "ts-node": "^10.9.1"
+  }
 }
diff --git a/src/babel.config.json b/src/babel.config.json
new file mode 100644
index 0000000..e69de29
diff --git a/src/data_structures/tree.ts b/src/data_structures/tree.ts
new file mode 100644
index 0000000..283e6e6
--- /dev/null
+++ b/src/data_structures/tree.ts
@@ -0,0 +1,72 @@
+import * as babelparser from "@babel/parser";
+
+import traverse from "@babel/traverse";
+import * as t from "@babel/types";
+import { PairedNodes } from "../matcher/matcher";
+
+export class TreeNode<T> {
+    public parent: TreeNode<T> | null;
+    public element: T;
+    public children: TreeNode<T>[] = [];
+
+    constructor(parent: TreeNode<T> | null, element: T) {
+        this.parent = parent;
+        this.element = element;
+        if (this.parent) this.parent.children.push(this);
+    }
+}
+
+export const makeTree = (
+    ast: babelparser.ParseResult<t.File>
+): TreeNode<t.Node> | undefined => {
+    let last: TreeNode<t.Node> | null = null;
+
+    let first: TreeNode<t.Node> | null = null;
+    traverse(ast, {
+        enter(path: any) {
+            //console.log(path.node);
+            //console.log("Entered: ", path.node.type);
+
+            let node: TreeNode<t.Node> = new TreeNode<t.Node>(
+                last,
+                path.node as t.Node
+            );
+
+            if (last == null) {
+                first = node;
+            }
+            last = node;
+        },
+        exit(path: any) {
+            if (last && last?.element?.type != "Program") {
+                last = last.parent;
+            }
+        },
+    });
+    //console.log(first.children);
+
+    if (first != null) {
+        return first;
+    } else {
+        return undefined;
+    }
+};
+export const showTree = (tree: TreeNode<t.Node>, idents: number = 0) => {
+    console.log("   ".repeat(idents) + tree.element?.type);
+    tree.children.forEach((child) => {
+        showTree(child, idents + 1);
+    });
+};
+export const showTreePaired = (
+    tree: TreeNode<PairedNodes>,
+    idents: number = 0
+) => {
+    console.log(
+        "   ".repeat(idents),
+        tree.element.aplToNode.type,
+        tree.element.codeNode.type
+    );
+    tree.children.forEach((child) => {
+        showTreePaired(child, idents + 1);
+    });
+};
diff --git a/src/index.ts b/src/index.ts
index 677e837..f4f2bc3 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,36 +1,101 @@
-import * as babelparser from "../babel/packages/babel-parser";
-import { parseApplicableTo } from "./parser/parse";
+//import * as babelparser from "../babel/packages/babel-parser";
+import * as babelparser from "@babel/parser";
+//import core from "../babel/packages/babel-core";
+import { parse_with_plugins } from "./parser/parse";
 import { TransformRecipe, transform } from "./transform/transform";
 /*
 proposal await_to_promise {
     applicable to {
         let a = await b();
-        <<CONSUME>>
+        <<REST:rest>>
     }
 
     transform to {
         b().then((a) => {
-            console.log(a);
+            <<REST:rest>>
         })
     }
 
 }
 */
 
-const transformExample:TransformRecipe = {
-    applicableTo: `let a = await b();<<REST_BLOCK:rest>>`,
-    consumeBlock: true,
-    identifiers: ["b", "a", "rest"],
-    transformTo: "b().then((a) => {<<REST_BLOCK:rest>>})"
+/*
+// Status quo
+var minLoc = Object.keys( grunt.config( "uglify.all.files" ) )[ 0 ];
+
+// With pipes
+var minLoc = grunt.config('uglify.all.files') |> Object.keys(%)[0];
+
+
+proposal pipeline_simple{
+    applicable to {
+        var minLoc = Object.keys( grunt.config( "uglify.all.files" ) )[ 0 ];
+    }
+
+    transform to {
+        var minLoc = grunt.config('uglify.all.files') |> Object.keys(%)[0];
+    }
 }
-const code = "let a = await b(); console.log(a);"
 
-const main = (): void => {
-    transform(transformExample, code);
+*/
 
-    
+/*
 
-    
+an example of what this will hit: 
+Unary function calls test(1);
+
+proposal pipeline_simple{
+    applicable to {
+        <<a:Callable>>(<<b>>);
+        console.log(<<b:Literal>>)
+    }
+
+    transform to {
+        b |> a(%);
+    }
+}
+
+*/
+
+const transformExample: TransformRecipe = {
+    applicableTo: `<<a>>(<<b:Expression|Identifier>>);`,
+    transformTo: "b |> a(%)",
+};
+const code =
+    "a(something);a(1+1);something(some_other_thing + 1 + 10 + 100); console.log(a)";
+
+// Expected outcome: 3 correct matches
+const secondTransformExample: TransformRecipe = {
+    applicableTo: `<<a>>.<<b>>(<<c:Expression|Identifier>>);`,
+    transformTo: "c |> a.b(%);",
+};
+const code2 = `console.log(a);something.sometingOther(b(c));some.thing(1+1);a(b)`;
+
+// Expected outcome: 1 correct match
+const thirdTransformExample: TransformRecipe = {
+    applicableTo: `myFunction(<<a:Expression|Identifier>>)`,
+    transformTo: `a |> myFunction(%)`,
+};
+const code3 = `myFunction(a);otherFunction(a); myFunction.otherfunction(a)`;
+
+// Expected outcome: 3 correct matches
+const simpleTransformExample: TransformRecipe = {
+    applicableTo: `<<a>>.<<b>>(<<something:Identifier|Expression>>)`,
+    transformTo: `something |> a.b(%)`,
+};
+
+const test: TransformRecipe = {
+    applicableTo: "let <<x>> = 0;",
+    transformTo: "if (true) {console.log(<<x>>)};",
+};
+const path = "../test.js";
+const file = Bun.file(path);
+const codeFromFile = await file.text();
+const main = async () => {
+    await Bun.write(
+        "../output.js",
+        transform(simpleTransformExample, codeFromFile)
+    );
 };
 
 main();
diff --git a/src/matcher/matcher.ts b/src/matcher/matcher.ts
new file mode 100644
index 0000000..f3e9925
--- /dev/null
+++ b/src/matcher/matcher.ts
@@ -0,0 +1,156 @@
+import * as t from "@babel/types";
+
+import * as babelparser from "@babel/parser";
+import { TreeNode, makeTree, showTree } from "../data_structures/tree";
+import { InternalDSLVariable } from "../parser/parse";
+
+const keys_to_ignore = ["loc", "start", "end", "type"];
+
+export interface MatchedTreeNode {
+    aplToNode: TreeNode<t.Node>;
+    codeNode: TreeNode<t.Node>;
+}
+
+export interface PairedNodes {
+    aplToNode: t.Node;
+    codeNode: t.Node;
+}
+
+export function runMatch(
+    code: TreeNode<t.Node>,
+    applicableTo: TreeNode<t.Node>,
+    internals: Map<string, InternalDSLVariable>
+): TreeNode<PairedNodes>[] {
+    let matches: TreeNode<t.Node>[] = [];
+
+    function checkDSLInternals(code_node: t.Node, aplTo: t.Node): boolean {
+        if (aplTo.type == "Identifier" && internals.has(aplTo.name)) {
+            let dsl_types = internals.get(aplTo.name)?.type ?? [];
+
+            for (const dsl_type of dsl_types) {
+                if (dsl_type == "Expression") {
+                    if (
+                        code_node.type.includes("Expression") ||
+                        code_node.type == "StringLiteral"
+                    ) {
+                        return true;
+                    }
+                } else if (dsl_type == "") {
+                    if (
+                        code_node.type == "Identifier" &&
+                        aplTo.type == "Identifier"
+                    ) {
+                        return true;
+                    }
+                } else if (dsl_type == "Identifier") {
+                    if (code_node.type == "Identifier") {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    function match(
+        code: TreeNode<t.Node>,
+        applicableTo: TreeNode<t.Node>
+    ): boolean {
+        if (code.element.type == "Program") {
+            code.children.forEach((code_child) => {
+                match(code_child, applicableTo);
+            });
+        }
+
+        // This is a bit wierd, as we currently do not support having ApplicableTo be multiple statements
+        if (applicableTo.element.type == "Program") {
+            match(code, applicableTo.children[0]);
+        }
+
+        let node_matches = checkCodeNode(code.element, applicableTo.element);
+
+        //If element matches DSL internals, we return right away and ignore the contents
+        if (checkDSLInternals(code.element, applicableTo.element)) {
+            return true;
+        }
+
+        if (node_matches) {
+            if (applicableTo.children.length != code.children.length) {
+                return false;
+            }
+            for (let i = 0; i < applicableTo.children.length; i++) {
+                //Verify we can actually do a match
+                if (!match(code.children[i], applicableTo.children[i])) {
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            for (let code_child of code.children) {
+                //Avoid matching on single identifier
+                if (code_child.element.type == "Identifier") {
+                    continue;
+                }
+                if (match(code_child, applicableTo)) {
+                    matches.push(code_child);
+                }
+            }
+            return false;
+        }
+    }
+    match(code, applicableTo);
+    console.log(matches.length);
+
+    return matches
+        .map((match) => pairMatch(match, applicableTo))
+        .filter((match) => match != null);
+}
+
+function pairMatch(
+    match: TreeNode<t.Node>,
+    aplTo: TreeNode<t.Node>
+): TreeNode<PairedNodes> | null {
+    if (aplTo.element.type == "Program") {
+        return pairMatch(match, aplTo.children[0]);
+    }
+    try {
+        let node: TreeNode<PairedNodes> = new TreeNode(null, {
+            codeNode: match.element,
+            aplToNode: aplTo.element,
+        });
+
+        for (let i = 0; i < aplTo.children.length; i++) {
+            let child = pairMatch(match.children[i], aplTo.children[i]);
+            child.parent = node;
+            node.children.push(child);
+        }
+
+        return node;
+    } catch (exception) {
+        return null;
+    }
+}
+
+function checkCodeNode(code_node: t.Node, aplTo: t.Node): boolean {
+    if (code_node.type != aplTo.type) {
+        return false;
+    }
+
+    //If not an internal DSL variable, gotta verify that the identifier is the same
+    if (code_node.type === "Identifier" && aplTo.type === "Identifier") {
+        if (code_node.name != aplTo.name) {
+            return false;
+        }
+    }
+    for (let key of Object.keys(aplTo)) {
+        if (key in keys_to_ignore) {
+            continue;
+        }
+
+        if (!Object.keys(code_node).includes(key)) {
+            return false;
+        }
+    }
+
+    return true;
+}
diff --git a/src/parser/internal_to_js_map.ts b/src/parser/internal_to_js_map.ts
new file mode 100644
index 0000000..84853c8
--- /dev/null
+++ b/src/parser/internal_to_js_map.ts
@@ -0,0 +1,11 @@
+
+import * as t from "@babel/types";
+
+
+export interface InternalJsMap{
+    CallExpression: 
+}
+
+
+
+
diff --git a/src/parser/parse.ts b/src/parser/parse.ts
index 4672a77..1ba7491 100644
--- a/src/parser/parse.ts
+++ b/src/parser/parse.ts
@@ -1,50 +1,78 @@
+import * as babelparser from "@babel/parser";
 
-// This needs to support multiple commands in future
+import * as t from "@babel/types";
 
-export interface Command{
-    commandName: string,
-    commandIdentifier: string,
+export interface InternalDSLVariable {
+    type: string[];
+    dsl_name: string;
 }
 
-export interface ApplicableToResult{
-    commands: Command[],
-    applicableTo: string,
+export interface InternalParseResult {
+    internals: Map<string, InternalDSLVariable>;
+    cleanedJS: string;
 }
 
-export function parseApplicableTo(applicableTo:string) :ApplicableToResult {
+export function parseInternal(applicableTo: string): InternalParseResult {
+    let lastChar: null | string = null;
+    let inDslParseMode = false;
 
-    let applicableToIter = applicableTo[Symbol.iterator]();
+    let inDslParseString = "";
 
-    let applicableToOut = "";
+    let internalParseResult: InternalParseResult = {
+        internals: new Map(),
+        cleanedJS: "",
+    };
 
-    let commands:Command[] = [];
-    let curCommandName = "";
-    let curCommandIdentifier = "";
-
-    let nextIter;
-    while(!(nextIter = applicableToIter.next()).done){
-        if (nextIter.value === "<" && applicableToIter.next().value === "<") {
-            let commandChar;
-            let commandName = "";
-            
-            while((commandChar = applicableToIter.next()).value != ":"){
-                commandName += commandChar.value;    
+    for (let char of applicableTo) {
+        if (inDslParseMode) {
+            if (char == ">" && lastChar == ">") {
+                //remove first closing >
+                inDslParseString = inDslParseString.slice(0, -1);
+                let { identifier, type, replaceWith } =
+                    parseInternalString(inDslParseString);
+                internalParseResult.cleanedJS += replaceWith;
+                internalParseResult.internals.set("___" + identifier, {
+                    type: type,
+                    dsl_name: identifier,
+                });
+                inDslParseString = "";
+                inDslParseMode = false;
+                continue;
             }
 
-            let commandIdentifier = "";
-
-            while((commandChar = applicableToIter.next()).value != ">"){
-                commandIdentifier += commandChar.value;    
+            inDslParseString += char;
+        } else {
+            if (char == "<" && lastChar == "<") {
+                //Remove previous <
+                internalParseResult.cleanedJS =
+                    internalParseResult.cleanedJS.slice(0, -1);
+                inDslParseMode = true;
+                continue;
             }
 
-            let _ = applicableToIter.next();
-
-            commands.push({commandIdentifier, commandName});
-        }else{
-            applicableToOut += nextIter.value;
+            internalParseResult.cleanedJS += char;
         }
+
+        lastChar = char;
     }
 
-    return {applicableTo:applicableToOut, commands};
-
+    return internalParseResult;
+}
+
+function parseInternalString(dslString: string) {
+    let splitted = dslString.split(":");
+
+    return {
+        identifier: splitted[0],
+        type: splitted.length > 1 ? splitted[1].split("|") : [""],
+        replaceWith: "___" + splitted[0],
+    };
+}
+
+export function parse_with_plugins(
+    code: string
+): babelparser.ParseResult<t.File> {
+    return babelparser.parse(code, {
+        plugins: [["pipelineOperator", { proposal: "hack", topicToken: "%" }]],
+    });
 }
diff --git a/src/placeholders.js b/src/placeholders.js
deleted file mode 100644
index 139597f..0000000
--- a/src/placeholders.js
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/structurizer.js b/src/structurizer.js
deleted file mode 100644
index b28b04f..0000000
--- a/src/structurizer.js
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/test/test_transform.test.ts b/src/test/test_transform.test.ts
new file mode 100644
index 0000000..42cb5d7
--- /dev/null
+++ b/src/test/test_transform.test.ts
@@ -0,0 +1,39 @@
+import { expect, test } from "bun:test";
+import { TransformRecipe, transform } from "../transform/transform";
+
+const transformExample: TransformRecipe = {
+    applicableTo: `<<a>>(<<b:Identifier|Expression>>);`,
+    transformTo: "b |> a(%)",
+};
+const code =
+    "a(something);a(1+1);something(some_other_thing + 1 + 10 + 100); console.log(a)";
+
+test("Test code: " + code + " on " + transformExample.applicableTo, () => {
+    expect(transform(transformExample, code).length).toBe(
+        "something |> a(%);1 + 1 |> a(%);some_other_thing + 1 + 10 + 100 |> something(%);console.log(a);"
+    );
+});
+// Expected outcome: 3 correct matches
+const secondTransformExample: TransformRecipe = {
+    applicableTo: `<<a>>.<<b>>(<<c:Expression|Identifier>>);`,
+    transformTo: "c |> a.b(%);",
+};
+const code2 = `console.log(a);something.sometingOther(b(c));some.thing(1+1); a(b)`;
+test(
+    "Test code: " + code2 + " on " + secondTransformExample.applicableTo,
+    () => {
+        expect(transform(secondTransformExample, code2).length).toBe(3);
+    }
+);
+// Expected outcome: 1 correct match
+const thirdTransformExample: TransformRecipe = {
+    applicableTo: `myFunction(<<a:Expression|Identifier>>)`,
+    transformTo: `a |> myFunction(%)`,
+};
+const code3 = `myFunction(a);otherFunction(a); myFunction.otherfunction(a)`;
+test(
+    "Test code: " + code3 + " on " + thirdTransformExample.applicableTo,
+    () => {
+        expect(transform(thirdTransformExample, code3)).toBe(``);
+    }
+);
diff --git a/src/transform/transform.ts b/src/transform/transform.ts
index 6d4e4cf..7a09027 100644
--- a/src/transform/transform.ts
+++ b/src/transform/transform.ts
@@ -1,50 +1,60 @@
-
-import * as babelparser from "@babel/parser";
 import traverse from "@babel/traverse";
 import * as t from "@babel/types";
-
-import { parseApplicableTo } from "../parser/parse";
-export interface TransformRecipe{
-    applicableTo: string,
-    identifiers: string[],
-    consumeBlock: boolean,
-    transformTo: string,
+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";
+export interface TransformRecipe {
+    applicableTo: string;
+    transformTo: string;
 }
-export function transform(recipe: TransformRecipe, code:string){
-    
-    let {commands, applicableTo} = parseApplicableTo(recipe.applicableTo);
-    
-    
-    //console.log(applicableTo);
+export function transform(recipe: TransformRecipe, code: string) {
+    let { internals, cleanedJS } = parseInternal(recipe.applicableTo);
+    let codeAST = parse_with_plugins(code);
+    let codeTree = makeTree(codeAST);
+    let applicabelToAST = parse_with_plugins(cleanedJS);
+    let applicableToTree = makeTree(applicabelToAST);
+    let transformTo = parse_with_plugins(recipe.transformTo);
+    let transformToTree = makeTree(transformTo);
 
-    let applicableToAST = babelparser.parse(applicableTo, {allowAwaitOutsideFunction: true});
-    console.log(applicableToAST);
+    console.log();
 
-    let codeAST = babelparser.parse(code, {allowAwaitOutsideFunction: true});
-    console.log(codeAST);
+    if (
+        codeTree == undefined ||
+        applicableToTree == undefined ||
+        transformToTree == undefined
+    ) {
+        throw new Error("This no worky LOL");
+    }
 
+    let matches = runMatch(codeTree, applicableToTree, internals);
 
-
-
-    traverse(applicableToAST, {
-        enter(path:any) {
-            traverse(codeAST, {
-                enter(codePath:any){
-                    if (codePath.node.type === "Program"){
-                        return;
-                    }
-                    if (codePath.node.type === path.node.type){
-                        console.log("We found a match with");
-                        console.log(codePath.node);
-                        
-                    }
-                }
-            })
+    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;
 }
-
-
-
-
-
diff --git a/src/transform/transformMatch.ts b/src/transform/transformMatch.ts
new file mode 100644
index 0000000..3d8b3d8
--- /dev/null
+++ b/src/transform/transformMatch.ts
@@ -0,0 +1,94 @@
+import * as t from "@babel/types";
+
+import * as babelparser from "@babel/parser";
+
+import {
+    TreeNode,
+    makeTree,
+    showTree,
+    showTreePaired,
+} from "../data_structures/tree";
+import { InternalDSLVariable } from "../parser/parse";
+import { MatchedTreeNode, PairedNodes } from "../matcher/matcher";
+import traverse from "@babel/traverse";
+
+export function transformer(
+    match: TreeNode<PairedNodes>,
+    trnTo: TreeNode<t.Node>,
+    output: t.Node,
+    inputCode: t.Node
+) {
+    transformMatch(match, trnTo, output);
+
+    if (output.type == "Program") {
+        output = output.body[0];
+    }
+    traverse(inputCode, {
+        enter(path) {
+            if (path.node === match.element.codeNode) {
+                console.log("We did stuffs?");
+                path.replaceWith(output);
+            }
+        },
+    });
+}
+
+export function transformMatch(
+    match: TreeNode<PairedNodes>,
+    trnTo: TreeNode<t.Node>,
+    output: t.Node
+) {
+    if (trnTo.element.type == "Program") {
+        return transformMatch(match, trnTo.children[0], output);
+    }
+
+    let isMatch = matchNode(match.element.aplToNode, trnTo.element);
+    if (isMatch) {
+        if (trnTo.element.type == "Identifier") {
+            traverse(output, {
+                enter(path) {
+                    if (path.isIdentifier({ name: trnTo.element.name })) {
+                        //console.log(match.element.codeNode);
+                        if (match.element.codeNode) {
+                            path.replaceWith(match.element.codeNode);
+                        }
+                    }
+                },
+            });
+        }
+    } else {
+        for (let match_child of match.children) {
+            transformMatch(match_child, trnTo, output);
+        }
+        for (let trnTo_child of trnTo.children) {
+            transformMatch(match, trnTo_child, output);
+        }
+    }
+}
+
+function matchNode(aplTo: t.Node, trnTo: t.Node): boolean {
+    //console.log(trnTo);
+
+    if (trnTo.type == "Identifier" && aplTo.type == "Identifier") {
+        let aplToName = washName(aplTo.name);
+        let trnToName = trnTo.name;
+        if (aplToName == trnToName) {
+            return true;
+        }
+    } else if (trnTo.type == "Identifier" && aplTo.type == "Identifier") {
+        let aplToName = washName(aplTo.name);
+        let trnToName = trnTo.name;
+
+        if (aplToName == trnToName) {
+            return true;
+        }
+    }
+    return false;
+}
+
+function washName(name: string): string {
+    if (name.startsWith("___")) {
+        return name.slice(3);
+    }
+    return name;
+}
diff --git a/test.js b/test.js
new file mode 100644
index 0000000..aa92a51
--- /dev/null
+++ b/test.js
@@ -0,0 +1,160 @@
+require("@risingstack/trace");
+const Discord = require("discord.js");
+const ytdl = require("ytdl-core");
+const bot = new Discord.Client();
+const fs = new require("fs");
+const path = require("path");
+const probe = require("pmx").probe();
+const jsonfile = require("jsonfile");
+const commandCooldown = require("./helpers/commandCooldown.js");
+let cleverbot = require("cleverbot.io"),
+    clever = new cleverbot(
+        "jp6wu9XZbYdoICmo",
+        "54jV1VcMNxGQyc2cdKUFUpjkPVo3bTr2"
+    );
+
+const log = require("./helpers/log.js");
+
+bot.on("ready", () => {
+    bot.user.setGame(".help");
+
+    (function loop(i) {
+        setTimeout(function () {
+            guilds.set(bot.guilds.size);
+            if (true) {
+                loop(i);
+            }
+        }, 1000);
+    })(10);
+
+    log(
+        `Ready to serve ${bot.users.size} users, in ${bot.channels.size} channels of ${bot.guilds.size} servers.`
+    );
+});
+
+fs.readFile("config.json", (err, data) => {
+    if (err) {
+        log("Config file does not exist, creating one.");
+
+        let obj = {
+            discordToken: "TOKEN",
+            discordBotsToken: "TOKEN",
+        };
+
+        jsonfile.spaces = 4;
+        jsonfile.writeFile("config.json", obj, (err) => {
+            console.log(err);
+        });
+        process.exit(1);
+    } else {
+        config = require("./config.json");
+
+        bot.login(config.discordToken);
+    }
+});
+
+global.skips = {};
+global.queue = {
+    test: "test",
+};
+
+global.dispatchers = new Map();
+global.connections = new Map();
+global.voices = new Map();
+global.streams = new Map();
+
+let config = "ERR";
+
+global.allstreams = 0;
+global.counter = probe.counter({
+    name: "Streams",
+});
+let guilds = probe.metric({
+    name: "Guilds",
+});
+
+let userCooldown = new Map();
+
+bot.commands = new Discord.Collection();
+bot.aliases = new Discord.Collection();
+fs.readdir("./commands/", (err, files) => {
+    if (err) console.error(err);
+    log(`Loading a total of ${files.length} commands.`);
+    files.forEach((f) => {
+        let props = require(`./commands/${f}`);
+        log(`Loading Command: ${props.info.name}. :ok_hand:`);
+        bot.commands.set(props.info.name, props);
+        /*
+		props.conf.aliases.forEach(alias => {
+			bot.aliases.set(alias, props.info.name);
+		});
+		*/
+    });
+});
+
+bot.on("message", (msg) => {
+    const prefix = ".";
+
+    let id = bot.user.id;
+    let clevername = new RegExp(`^<@!?${id}>`);
+
+    if (msg.content.startsWith(prefix)) {
+    } else if (clevername.test(msg.content)) {
+    } else return;
+    if (msg.author.bot) return;
+
+    if (msg.guild) {
+        if (!queue[msg.guild.id]) {
+            queue[msg.guild.id] = [];
+        }
+    } else return;
+
+    let command = msg.content.split(" ")[0].slice(prefix.length);
+    let params = msg.content.split(" ").slice(1);
+    //let perms = bot.elevation(msg);
+    let cmd;
+
+    if (!userCooldown.get(msg.author.id)) {
+        userCooldown.set(msg.author.id, 0);
+    }
+
+    if (bot.commands.has(command)) {
+        if (!commandCooldown(userCooldown.get(msg.author.id))) {
+            userCooldown.set(msg.author.id, Date.now());
+            cmd = bot.commands.get(command);
+        } else msg.channel.sendMessage("You're sending commands too quickly!");
+    } else if (bot.aliases.has(command)) {
+        cmd = bot.commands.get(bot.aliases.get(command));
+    }
+    if (cmd) {
+        cmd.run(bot, msg, params);
+    }
+
+    if (clevername.test(msg.content)) {
+        console.log(
+            msg.author.username +
+                " (" +
+                msg.author.id +
+                ") issued command: " +
+                msg.content
+        );
+
+        let string = msg.content;
+        string = msg.content.split(" ");
+        string.shift();
+        string.join(" ");
+
+        clever.setNick(msg.author.username);
+
+        clever.create(function (err, session) {
+            if (err) log(err);
+            clever.ask(string, function (err, response) {
+                if (err) log(err);
+                msg.channel
+                    .sendMessage(response)
+                    .then((msg) => log(`Sent message: ${msg.content}`))
+                    .catch(console.error);
+            });
+        });
+    }
+});
diff --git a/tsconfig.json b/tsconfig.json
index 3c12a82..19d03b7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,12 +3,13 @@
         "rootDir": "src",
         "outDir": "dist",
         "strict": true,
-        "target": "es6",
+        "target": "es2017"17",
         "module": "commonjs",
         "sourceMap": true,
         "esModuleInterop": true,
         "moduleResolution": "node",
         "types": ["bun-types"]
     },
-    "include": ["src", "babel/packages/babel-parser"]
+    "include": ["src"],
+    "exclude": ["babel"]
 }