@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
{
today: {
temperatures: [19, 18.5, 18, 18.5, 17, /* ... */]
},
future: [
{ high: 21, low: 13, chanceOfSnow: 0.05 },
{ high: 21, low: 14, chanceOfSnow: 0.03 },
{ high: 21, low: 16, chanceOfSnow: 0.04 },
{ high: 19, low: 16, chanceOfSnow: 0.04 },
/* ... */
]
}
@phenomnominal 2020
<h2>Weather result</h2>
<h3>
<p>Arendelle, Norway</p>
<p>Sunday 19:00</p>
<span>Sunny</span>
</h3>
<img alt="Sunny" src="//arendelle.info/weather/64/sunny.png">
<h3>
19<button aria-label="°Celsius">°C</button>
</h3>
<p>Precipitation: <span>0%</span></p>
<p>Humidity: <span>75%</span></p>
<p>Wind: <span>1 m/s</span></p>
<ol>
<li>
<p aria-label="Sunday">Sun</p>
<img alt="Clear" src="//arendelle.info/weather/48/sunny.png">
<span>21</span>°
<span>13</span>°
</li>
<!-- ... -->
</ol>
@phenomnominal 2020
const response = await fetch('https://arendelle.info/weather.json');
const data = await response.json();
// {
// today: {
// temperatures: [19, 18.5, 18, 18.5, 17, /* ... */]
// },
// future: [
// { high: 21, low: 13, chanceOfSnow: 0.05 },
// { high: 21, low: 14, chanceOfSnow: 0.03 },
// { high: 21, low: 16, chanceOfSnow: 0.04 },
// { high: 19, low: 16, chanceOfSnow: 0.04 },
// /* ... */
// ]
// }
const SATURDAY = 6;
const today = new Date().getDay();
const chanceOfSnowOnSaturday = data.future[SATURDAY - today].chanceOfSnow * 100;
h1 {
// ...
}
h3 > p {
// ...
}
button:active,
button:hover {
// ...
}
li:first-child {
// ...
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
fs.watch
fs.link
fs.copyFile
fs.chmod
fs.access
@phenomnominal 2020
fs.writeFile
fs.mkdir
fs.readFile
@phenomnominal 2020
// snowflake.txt
()
/\
//\\
<< >>
() \\// ()
()._____ /\ \\ /\ _____.()
\.--.\ //\\ //\\ //\\ /.--./
\\__\\/__\//__\//__\\/__//
'--/\\--//\--//\--/\\--'
\\\\///\\//\\\////
()-= >>\\< <\\> >\\<< =-()
////\\\//\\///\\\\
.--\\/--\//--/\\--/\\--.
//""/\\""//\""//\""//\""\\
/'--'/ \\// \\// \\// \'--'\
()`"""` \/ // \/ `"""`()
() //\\ ()
<< >>
\\//
\/
()
@phenomnominal 2020
import { promises as fs } from 'fs';
async function readSnowflake () {
return fs.readFile('./snowflake.txt', 'utf8');
}
console.log(await readSnowflake());
@phenomnominal 2020
Weaseltown:dywbabt queenelsa$ node index.js
()
/\
//\\
<< >>
() \\// ()
()._____ /\ \\ /\ _____.()
\.--.\ //\\ //\\ //\\ /.--./
\\__\\/__\//__\//__\\/__//
'--/\\--//\--//\--/\\--'
\\\\///\\//\\\////
()-= >>\\< <\\> >\\<< =-()
////\\\//\\///\\\\
.--\\/--\//--/\\--/\\--.
//""/\\""//\""//\""//\""\\
/'--'/ \\// \\// \\// \'--'\
()`"""` \/ // \/ `"""`()
() //\\ ()
<< >>
\\//
\/
()
@phenomnominal 2020
import { promises as fs } from 'fs';
async function readSnowflake () {
return fs.readFile('./snowflake.txt', 'utf8');
}
async function saveSnowflake (data: string) {
await fs.mkdir('./saved/snowflakes', { recursive: true });
await fs.writeFile('./saved/snowflakes/snowflake.txt', data);
}
const snowflake = await readSnowflake();
await saveSnowflake(snowflake);
@phenomnominal 2020
path.resolve
path.parse
@phenomnominal 2020
import * as path from 'path';
const relativeToThisFile = path.resolve(__dirname, './snowflake.txt');
const parsed = path.parse(relativeToThisFile);
// interface ParsedPath {
// root: string;
// dir: string;
// base: string;
// ext: string;
// name: string;
// }
import { promises as fs } from 'fs';
import * as path from 'path';
export async function readSnowflake () {
const relativePath = path.resolve(__dirname, './snowflake.txt');
const relativePath = path.resolve(process.cwd(), './snowflake.txt');
return fs.readFile(relativePath, 'utf8');
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { promises as fs } from 'fs';
import * as path from 'path';
async function readSnowflakes () {
const snowflakePath = path.resolve(__dirname, './snowflakes.json');
const json = await fs.readFile(snowflakePath, 'utf8');
return JSON.parse(json);
}
console.log(await readSnowflakes());
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
const SNOW_CODE_PATH = path.resolve(
__dirname,
'./elsa',
process.env.SECRET_SNOW_FILE
);
@phenomnominal 2020
const SNOW_CODE_PATH = path.resolve(
__dirname,
'./elsa',
process.env.SECRET_SNOW_FILE
);
@phenomnominal 2020
@phenomnominal 2020
import { promises as fs } from 'fs';
export async function readSnowCode () {
return fs.readFile(SNOW_CODE_PATH, 'utf8');
}
console.log(await readSnowCode());
@phenomnominal 2020
Weaseltown:dywbabt queenelsa$ node secret_snow_code_file_dont_touch.js
import { doPhysics, WaterMolecule } from './physics';
requestAnimationFrame(() => {
for (let lat = -90; lat < 90; lat += 0.000000001) {
for (let long = -180; long < 180; long += 0.000000001) {
for (let alt = 0; alt < 80000; alt += 0.000000001) {
const updated = update(lat, long, alt);
render(updated);
}
}
}
});
function update (lat, long, alt) {
const molecule = global.waterMolecules[lat][long][alt];
return doPhysics(molecule);
}
@phenomnominal 2020
@phenomnominal 2020
// kristoff.js
import { promises as fs } from 'fs';
import { readSnowCode } from './read-snow-code';
const code = await readSnowCode();
code += `; console.log('Kristoff is the best!');`
await fs.writeFile('./kristoffs-cool-new-snow-code.js', code);
@phenomnominal 2020
// olaf.js
import { promises as fs } from 'fs';
const code = await fs.readFile('./kristoffs-cool-new-snow-code.js');
code = code.replace(/Kristoff/, 'Olaf');
await fs.writeFile('./kristoffs-cool-new-snow-code.js', code);
@phenomnominal 2020
// sven.js
import { promises as fs } from 'fs';
const code = await fs.readFile('./kristoffs-cool-new-snow-code.js');
code = code.replace(/Olaf/, 'Sven');
code = code.replace(/best!/, 'bestest!!!!');
code = code.replace(/console.log\((.*)\)/, 'console.log($1.toUpperCase())');
await fs.writeFile('./kristoffs-cool-new-snow-code.js', code);
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import * as path from 'path';
const parsed = path.parse('/some/path/to/some/file.txt');
// interface ParsedPath {
// root: string;
// dir: string;
// base: string;
// ext: string;
// name: string;
// }
console.log(parsed.ext);
// read-snowflakes.js
import { promises as fs } from 'fs';
import * as path from 'path';
export async function readSnowflakes () {
const snowflakePath = path.resolve(__dirname, './snowflakes.json');
const data = await fs.readFile(snowflakePath, 'utf8');
const snowflakes = JSON.parse(data);
console.log(snowFlakes[0].velocity.x)
}
@phenomnominal 2020
import { parseScript } from 'esprima';
import { readSnowCode } from './read-snow-code';
const code = await readSnowCode();
const ast = parseScript(code);
console.log(ast);
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
data structure made up of vertices and edges without any cycles
the way in which linguistic elements are put together
Not associated with any specific instance
@phenomnominal 2020
@phenomnominal 2020
An Abstract Syntax Tree is a data structure that represents the structure of code, but without any actual syntax.
let it = go('let it go');
it = go 'let it go'
it <= go ['let it go']
'let it go' -> go => it
@phenomnominal 2020
{
type: 'Program',
body: [{
type: 'VariableDeclaration',
declarations: [{
type: 'VariableDeclarator',
id: {
type: 'Identifier',
name: 'it'
},
init: {
type: 'CallExpression',
callee: {
type: 'Identifier',
name: 'go'
},
arguments: [{
type: Literal',
value: 'let it go'
}]
}
}],
kind: 'let'
}]
}
@phenomnominal 2020
'let it go'
Literal
Identifier
CallExpression
Identifier
VariableDeclarator
VariableDeclaration
go
go('let it go')
it
it = go('let it go')
let it = go('let it go');
@phenomnominal 2020
Identifier
IfStatement
ImportDeclaration
Literal
CallExpression
ClassDeclaration
FunctionDeclaration
VariableDeclaration
ExpressionStatement
AwaitExpression
ForStatement
WhileStatement
DoWhileStatement
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parseScript } from 'esprima';
const code = `let it = go('let it go');`
const ast = parseScript(code);
const arg = ast.body[0].declarations[0].init.arguments[0];
console.log(arg);
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
{
"kind": "document",
"children": [{
"kind": "h2",
"children": [{
"kind": "text",
"text": "Weather result"
}]
}, {
"kind": "h3",
"children": [{
"kind": "p",
"children": [{
"kind": "text",
"text": "Arendelle, Norway"
}]
}, {
"kind": "p",
"children": [{
"kind": "text",
"text": "Sunday 19:00"
}]
}, {
"kind": "span",
"children": [{
"kind": "text",
"text": "Sunny"
}]
}]
}, {
"kind": "img",
"alt": "Sunny",
"src": "//arendelle.info/weather/64/sunny.png"
}]
}
@phenomnominal 2020
@phenomnominal 2020
{
"kind": "document",
"children": [{
"kind": "h2",
"children": [{
"kind": "text",
"text": "Weather result"
}]
}, {
"kind": "h3",
"children": [{
"kind": "p",
"children": [{
"kind": "text",
"text": "Arendelle, Norway"
}]
}, {
"kind": "p",
"children": [{
"kind": "text",
"text": "Sunday 19:00"
}]
}, {
"kind": "span",
"children": [{
"kind": "text",
"text": "Sunny"
}]
}]
}, {
"kind": "img",
"alt": "Sunny",
"src": "//arendelle.info/weather/64/sunny.png"
}]
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parse } from './parse-html';
const HTML = `
<h3>...</h3>
...
`;
const dom = parse(HTML);
const node = dom.children[1].children[3].children[0];
console.log(node);
@phenomnominal 2020
const dom = parse(HTML);
const node = $(dom, 'body > h3 > span:last-child');
console.log(node);
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parseScript } from 'esprima';
import { query } from 'esquery';
const code = `let it = go('let it go');`;
const ast = parseScript(code);
const query = 'CallExpression:has(Identifier[name="go"]) > Literal';
const nodes = query(ast, query);
console.log(nodes);
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parseScript } from 'esprima';
import { query } from 'esquery';
const code = `Object.freeze()`;
const ast = parseScript(code);
const query =
'CallExpression:has(MemberExpression[object.name="Object"][property.name="freeze"])';
const nodes = query(ast, query);
if (nodes.length !== 0) {
throw new Error(`Don't use Object.freeze!`);
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { doPhysics } from './physics';
requestAnimationFrame(() => {
for (let lat = -90; lat < 90; lat += 0.000000001) {
for (let long = -180; long < 180; long += 0.000000001) {
for (let alt = 0; alt < 80000; alt += 0.000000001) {
const updated = update(lat, long, alt);
render(updated);
}
}
}
});
function update (lat, long, alt) {
const molecule = global.waterMolecules[lat][long][alt];
return doPhysics(molecule);
}
@phenomnominal 2020
import { parseScript } from 'esprima';
import { query } from 'esquery';
import { readSnowCode } from './read-snow-code';
const PHYSICS_CALL_QUERY = 'CallExpression:has(Identifier[name="doPhysics"])';
const snowCode = await readSnowCode();
const ast = parseScript(snowCode);
const doPhysicsCalls = query(ast, PHYSICS_CALL_QUERY);
doPhysicsCalls.forEach(doPhysicsCall => {
doPhysicsCall.expression.name = 'doMagic';
const doMagicCall = doPhysicsCall;
doMagicCall.arguments = [{
type: 'CallExpression',
callee: {
type: 'Identifier',
name: 'doPhysics'
},
arguments: [{
type: 'Identifier',
name: 'molecule'
}]
}];
});
@phenomnominal 2020
import { doPhysics, WaterMolecule } from './physics';
requestAnimationFrame(() => {
for (let lat = -90; lat < 90; lat += 0.000000001) {
for (let long = -180; long < 180; long += 0.000000001) {
for (let alt = 0; alt < 80000; alt += 0.000000001) {
const updated = update(lat, long, alt);
render(updated);
}
}
}
});
function update (lat, long, alt) {
const molecule = global.waterMolecules[lat][long][alt];
return doMagic(doPhysics(molecule));
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
// function doMagic (molecule) {
// molecule.setTemperature(-10);
// return molecule;
// }
function createMagicFunction (ast) {
return {
type: "FunctionDeclaration",
id: {
type: "Identifier",
name: "doMagic"
},
params: [{
type: "Identifier",
name: "molecule",
}],
body: {
type: "BlockStatement",
body: [{
type: "ExpressionStatement",
expression: {
type: "CallExpression",
callee: {
type: "MemberExpression",
object: {
type: "Identifier",
name: "molecule"
},
property: {
type: "Identifier",
name: "setTemperature",
},
},
arguments: [{
type: "UnaryExpression",
operator: "-",
argument: {
type: "Literal",
value: 10
}
}]
}
}, {
type: "ReturnStatement",
argument: {
type: "Identifier",
name: "molecule"
}
}]
}
}
@phenomnominal 2020
@phenomnominal 2020
const h2 = document.createElement('h2');
h2.innerText = 'Weather result';
const h3 = document.createElement('h3');
const p1 = document.createElement('p');
p1.innerText = 'Arendelle, Norway';
const p2 = document.createElement('p');
p2.innerText = 'Sunday 19:00';
const span = document.createElement('span');
span.innerText = 'Sunny';
h3.appendChild(p1);
h3.appendChild(p2);
h3.appendChild(span);
const img = document.createElement('img');
img.setAttribute('alt', 'Sunny');
img.setAttribute('src', '//arendelle.info/weather/64/sunny.png');
@phenomnominal 2020
const template = `
<h2>Weather result</h2>
<h3>
<p>{{ location }}</p>
<p>{{ time }}</p>
<span>{{ weather }}</span>
</h3>
<img
alt="{{ weather }}"
src="//arendelle.info/weather/64/{{ weather }}.png">
`;
render(template, {
location: 'Arendelle, Norway',
time: 'Sunday 19:00',
weather: 'Sunny'
});
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { query } from 'esquery';
import { compile } from 'estemplate';
const DO_MAGIC_TEMPLATE = tstemplate.compile(`
function doMagic (molecule) {
molecule.setTemperature(-<%= temperature %>);
return molecule;
}
`);
function createMagicFunction () {
const doMagicAst = DO_MAGIC_TEMPLATE({
temperature: createNumericLiteral('10')
});
const [doMagicFunction] = query(doMagicAst, 'FunctionDeclaration');
return doMagicFunction;
}
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
import { parseScript } from 'esprima';
import { query } from 'esquery';
import { generate } from 'escodegen';
const code = `let it = go('let it go');`;
const ast = parseScript(code);
const query = 'CallExpression:has(Identifier[name="go"]) > Literal';
const [literal] = query(ast, query);
literal.value = 'LET IT GO!';
const updatedCode = generate(ast);
console.log(updatedCode); // let it = go('LET IT GO!');
@phenomnominal 2020
@phenomnominal 2020
import { readSnowCode } from './read-snow-code';
const snowCode = await readSnowCode();
import { parseScript } from 'esprima';
const ast = parseScript(snowCode);
import { query } from 'esquery';
const doPhysicsCalls = query(ast,
'CallExpression:has(Identifier[name="doPhysics"])'
);
import { template } from 'estemplate';
doPhysicsCalls.forEach(oldDoPhysicsCall => {
oldDoPhysicsCall.expression.name = 'doMagic';
const doMagicCall = oldDoPhysicsCall;
const newDoPhysicsAst = template('doPhysics(molecule)');
const [newDoPhysicsCall] = query(newDoPhysicsAst, 'CallExpression');
doMagicCall.arguments = [newDoPhysicsCall];
});
const doMagicAst = template(`
function doMagic (molecule) {
molecule.setTemperature(-<%= temperature %>);
return molecule;
}
`, {
temperature: createNumericLiteral('10')
});
const [doMagicFunction] = query(doMagicAst, 'FunctionDeclaration');
ast.statements.push(doMagicFunction);
import { generate } from 'escodegen';
const updatedSnowCode = generate(ast);
import { writeSnowCode } from './write-snow-code';
await writeSnowCode(updatedSnowCode);
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020
@phenomnominal 2020