M src/game.js => src/game.js +2 -2
@@ 199,7 199,7 @@ export function addBox(data, gameData, gs) {
} catch (e) {
box.failed = true;
drawBox(box);
- throw e;
+ console.error(e);
}
}
@@ 310,7 310,7 @@ export function evaluateNewPieces (newKey, gameData, gs) {
} catch (e) {
box.failed = true;
drawBox(box);
- throw e;
+ console.error(e);
}
});
box.inputQueue = [];
M src/lang.js => src/lang.js +38 -3
@@ 34,7 34,7 @@ export function parse (code) {
queuedBranch: {
...r.queuedBranch,
contents: r.queuedBranch.contents
- ? [r.queuedBranch.contents, newContents].join(' ')
+ ? [r.queuedBranch.contents, newContents].join('\n')
: newContents
}
}
@@ 91,10 91,26 @@ export function interpret (expression, initial = null) {
const result = a === b;
return { push: [result], pop: 2 }
}
+ else if (code === 'lth') {
+ const b = r.stack[0];
+ const a = r.stack[1];
+ const result = a < b;
+ return { push: [result], pop: 2 }
+ }
+ else if (code === 'gth') {
+ const b = r.stack[0];
+ const a = r.stack[1];
+ const result = a > b;
+ return { push: [result], pop: 2 }
+ }
else if (code === 'int') {
const value = parseInt(r.stack[0]);
return { push: [value], pop: 1 }
}
+ else if (code === 'flt') {
+ const value = parseFloat(r.stack[0]);
+ return { push: [value], pop: 1 }
+ }
else if (code === 'vec') {
const y = r.stack[0];
const x = r.stack[1];
@@ 105,6 121,11 @@ export function interpret (expression, initial = null) {
const b = r.stack[1];
return { push: [a.add(b)], pop: 2 }
}
+ else if (code === 'vecmul') {
+ const b = r.stack[0];
+ const a = r.stack[1];
+ return { push: [a.mul(b)], pop: 2 }
+ }
else if (code === 'vecx') {
const vec = r.stack[0];
return { push: [vec.x], pop: 2 }
@@ 123,6 144,11 @@ export function interpret (expression, initial = null) {
const b = r.stack[1];
return { push: [a * b], pop: 2 }
}
+ else if (code === 'div') {
+ const a = r.stack[0];
+ const b = r.stack[1];
+ return { push: [a / b], pop: 2 }
+ }
else if (code === 'sub') {
const a = r.stack[0];
const b = r.stack[1];
@@ 142,6 168,10 @@ export function interpret (expression, initial = null) {
const branch = r.stack[0];
return {jump: condition ? branches[branch] : null, pop: 2};
}
+ else if (code === 'jmp') {
+ const branch = r.stack[0];
+ return {jump: branches[branch], pop: 1};
+ }
else if (code === 'kep') {
const value = r.stack[1];
const key = r.stack[0];
@@ 160,8 190,8 @@ export function interpret (expression, initial = null) {
return {pop: 3};
}
else if (code === 'at') {
- const key = r.stack[1];
- const index = r.stack[0];
+ const key = r.stack[0];
+ const index = r.stack[1];
return {push: [r.data[key][index]], pop: 2};
}
else if (code === 'dup') {
@@ 173,6 203,11 @@ export function interpret (expression, initial = null) {
const b = r.stack[1];
return {push: [b, a], pop: 2};
}
+ else if (code === 'arr') {
+ const key = r.stack[0];
+ r.data[key] = [];
+ return {pop: 1};
+ }
else if (code === 'que') {
const key = r.stack[0];
const value = r.stack[1];
M src/main.js => src/main.js +36 -23
@@ 15,7 15,7 @@ PIXI.Loader.shared.add('CompassPro', 'compasspro_medium_12.fnt')
PIXI.Loader.shared.add('MatchupPro', 'matchuppro_medium_12.fnt')
const $ = (selector) => document.querySelector(selector);
-const el = ({ kind, children, text, value, attributes, classes }) => {
+const el = ({ kind, children, text, value, attributes, classes, style }) => {
const element = document.createElement(kind || 'div');
if (text) {
element.textContent = text;
@@ 29,6 29,9 @@ const el = ({ kind, children, text, value, attributes, classes }) => {
(Object.keys(attributes || {})).forEach(key => {
element.setAttribute(key, attributes[key]);
});
+ Object.keys(style || {}).forEach(key => {
+ element.style[key] = style[key];
+ });
element.classNames = classes || '';
return element;
}
@@ 157,13 160,14 @@ function save () {
});
}
-function load () {
- const rawSave = localStorage.save;
+function load (rawSave) {
if (!rawSave) {
return;
}
const save = JSON.parse(rawSave);
- gameData.customDefinitions = save.customDefinitions;
+ gameData.customDefinitions = {
+ ...gameData.customDefinitions, ...save.customDefinitions
+ };
save.boxes.forEach(box => addBox(box, gameData, gs));
save.connections.map(connection => ({
...connection,
@@ 178,7 182,7 @@ function reset () {
gameData.dataPieces.forEach(piece => gs.dataPieces.removeChild(piece.g));
gameData.dataPieces = [];
Array.from(gameData.connections).forEach(connection => removeConnection(piece, gameData, gs))
- load();
+ load(localStorage.save);
}
window.save = save;
@@ 189,6 193,7 @@ function initUI() {
const codeTypeDropdown = el({ kind: 'select' });
function buildTypeDropdown () {
+ const lastValue = codeTypeDropdown.value;
codeTypeDropdown.innerHTML = '';
const definitions = Object.keys(gameData.boxDefinitions).concat(Object.keys(gameData.customDefinitions));
definitions.map(
@@ 196,6 201,7 @@ function initUI() {
).forEach(option => {
codeTypeDropdown.appendChild(option);
})
+ codeTypeDropdown.value = lastValue;
}
buildTypeDropdown();
toolbarEl.appendChild(codeTypeDropdown);
@@ 214,7 220,7 @@ function initUI() {
});
toolbarEl.appendChild(codeBoxButton);
- const editorTextbox = el({ kind: 'textarea' });
+ const editorTextbox = el({ kind: 'textarea', attributes: { rows: 20 }, style: { width: '15rem' } });
const editorSaveButton = el({ kind: 'button', text: 'Save' });
const codeEditorEl = el({
kind: 'div',
@@ 268,6 274,29 @@ function initUI() {
reset();
});
toolbarEl.appendChild(resetButtonEl);
+ const copyText = 'Copy all to Clipboard';
+ const copyButtonEl = el({ kind: 'button', text: copyText });
+ copyButtonEl.addEventListener('click', () => {
+ save();
+ navigator.clipboard.writeText(localStorage.save).then(function() {
+ copyButtonEl.textContent = "Program Copied to Clipboard!"
+ setTimeout(() => {
+ copyButtonEl.textContent = copyText;
+ }, 2000);
+ }, function(err) {
+ copyButtonEl.textContent = "Failed to Copy to Clipboard"
+ setTimeout(() => {
+ copyButtonEl.textContent = copyText;
+ }, 2000);
+ });
+ });
+ toolbarEl.appendChild(copyButtonEl);
+ const loadButtonEl = el({ kind: 'button', text: "Load Program" });
+ loadButtonEl.addEventListener('click', () => {
+ const program = prompt('Paste JSON program');
+ load(program);
+ });
+ toolbarEl.appendChild(loadButtonEl);
}
function setup () {
@@ 379,22 408,6 @@ flr #last swp at
v: parse(`val vecy #v out`),
}
});
- loadCodeBox({
- name: 'delay',
- data: {
- tail: [],
- number: 10,
- },
- outputs: ['v'],
- inputs: {
- v: parse(`
-val #tail que
-#tail len #number get equ #pop jcn
-def pop:
- #tail pop #v out
-`),
- }
- });
app.view.tabIndex = 0
app.view.focus()
@@ 441,7 454,7 @@ def pop:
gameData.boxDefinitions = boxDefinitions;
- load();
+ load(localStorage.save);
initUI();
setInterval(save, 10000);