summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2022-12-05 17:53:26 +0100
committerMinteck <contact@minteck.org>2022-12-05 17:53:26 +0100
commitd4d1b63391be8a8ef8f1764e2d1a41810c8b2901 (patch)
treefa4ed7b3af6221e930de6641a0c8d47a44e220eb
parent9b2074a84944d928cb64b9800ccbf0023316483b (diff)
downloadwing-d4d1b63391be8a8ef8f1764e2d1a41810c8b2901.tar.gz
wing-d4d1b63391be8a8ef8f1764e2d1a41810c8b2901.tar.bz2
wing-d4d1b63391be8a8ef8f1764e2d1a41810c8b2901.zip
Lists and stuff
-rw-r--r--.build1
-rw-r--r--package.json9
-rw-r--r--src/debug.js3
-rw-r--r--src/functions/list_personalities.js9
-rw-r--r--src/index.ts10
-rw-r--r--src/operators/append.js12
-rw-r--r--src/operators/item.js18
-rw-r--r--src/operators/length.js11
-rw-r--r--src/operators/list.js7
-rw-r--r--src/operators/overwrite.js19
-rw-r--r--src/operators/pop.js8
-rw-r--r--src/operators/shift.js8
-rw-r--r--src/operators/unshift.js12
-rw-r--r--src/release.js3
-rw-r--r--src/version.js18
-rw-r--r--src/wing/WingConditions.ts23
-rw-r--r--src/wing/WingErrors.ts2
-rw-r--r--src/wing/WingInterpreter.ts122
-rw-r--r--src/wing/WingMetadata.ts2
-rw-r--r--src/wing/WingOperators.ts25
-rw-r--r--src/wing/WingPersonalities.ts8
21 files changed, 297 insertions, 33 deletions
diff --git a/.build b/.build
new file mode 100644
index 0000000..c7471f0
--- /dev/null
+++ b/.build
@@ -0,0 +1 @@
+8.33.20221205 \ No newline at end of file
diff --git a/package.json b/package.json
index 323ee27..10bcad9 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,12 @@
"typescript": "^4.9.3"
},
"scripts": {
- "compile": "cp src/index.ts src/.index.ts.bak && cd src && node version.js && cd .. && tsc -p ./tsconfig.json && cp -r node_modules dist && cp -r src/sourcegen.js dist && cp -r src/operators dist && cp -r src/functions dist && cp -r src/modules dist && cp -r src/conditions dist && cd dist && node sourcegen.js && cd .. && rm src/index.ts && mv src/.index.ts.bak src/index.ts",
- "build": "npm run compile && cd dist && pkg -t node18-linux-arm64 -o ../bin/wing-linux-glibc-arm64 -C GZip index.js && pkg -t node18-linux-x64 -o ../bin/wing-linux-glibc-x64 -C GZip index.js && pkg -t node18-linuxstatic-arm64 -o ../bin/wing-linux-arm64 -C GZip index.js && pkg -t node18-linuxstatic-x64 -o ../bin/wing-linux-x64 -C GZip index.js && pkg -t node18-alpine-arm64 -o ../bin/wing-linux-musl-arm64 -C GZip index.js && pkg -t node18-alpine-x64 -o ../bin/wing-linux-musl-x64 -C GZip index.js && pkg -t node18-win-arm64 -o ../bin/wing-win32-arm64 -C GZip index.js && pkg -t node18-win-x64 -o ../bin/wing-win32-x64 -C GZip index.js && pkg -t node18-macos-arm64 -o ../bin/wing-mac-arm64 -C GZip index.js && pkg -t node18-mac-x64 -o ../bin/wing-mac-x64 -C GZip index.js"
+ "compile": "npm run compile-debug",
+ "compile-debug": "cp src/index.ts src/.index.ts.bak && cd src && node version.js && node debug.js && cd .. && tsc -p ./tsconfig.json && cp -r node_modules dist && cp -r src/sourcegen.js dist && cp -r src/operators dist && cp -r src/functions dist && cp -r src/modules dist && cp -r src/conditions dist && cd dist && node sourcegen.js && cd .. && rm src/index.ts && mv src/.index.ts.bak src/index.ts",
+ "compile-release": "cp src/index.ts src/.index.ts.bak && cd src && node version.js && node release.js && cd .. && tsc -p ./tsconfig.json && cp -r node_modules dist && cp -r src/sourcegen.js dist && cp -r src/operators dist && cp -r src/functions dist && cp -r src/modules dist && cp -r src/conditions dist && cd dist && node sourcegen.js && cd .. && rm src/index.ts && mv src/.index.ts.bak src/index.ts",
+ "debug": "npm run compile-debug && cd dist && pkg -t node18-macos-arm64 --public --no-bytecode -o ../bin/wing-debug-mac-arm64 -C GZip index.js",
+ "build": "npm run build-debug && npm run build-release",
+ "build-debug": "npm run compile-debug && cd dist && pkg -t node18-linux-arm64 --public --no-bytecode -o ../bin/wing-debug-linux-glibc-arm64 -C GZip index.js && pkg -t node18-linux-x64 --public --no-bytecode -o ../bin/wing-debug-linux-glibc-x64 -C GZip index.js && pkg -t node18-linuxstatic-arm64 --public --no-bytecode -o ../bin/wing-debug-linux-arm64 -C GZip index.js && pkg -t node18-linuxstatic-x64 --public --no-bytecode -o ../bin/wing-debug-linux-x64 -C GZip index.js && pkg -t node18-alpine-arm64 --public --no-bytecode -o ../bin/wing-debug-linux-musl-arm64 -C GZip index.js && pkg -t node18-alpine-x64 --public --no-bytecode -o ../bin/wing-debug-linux-musl-x64 -C GZip index.js && pkg -t node18-win-arm64 --public --no-bytecode -o ../bin/wing-debug-win32-arm64 -C GZip index.js && pkg -t node18-win-x64 --public --no-bytecode -o ../bin/wing-debug-win32-x64 -C GZip index.js && pkg -t node18-macos-arm64 --public --no-bytecode -o ../bin/wing-debug-mac-arm64 -C GZip index.js && pkg -t node18-mac-x64 --public --no-bytecode -o ../bin/wing-debug-mac-x64 -C GZip index.js",
+ "build-release": "npm run compile-release && cd dist && pkg -t node18-linux-arm64 -o ../bin/wing-release-linux-glibc-arm64 -C GZip index.js && pkg -t node18-linux-x64 -o ../bin/wing-release-linux-glibc-x64 -C GZip index.js && pkg -t node18-linuxstatic-arm64 -o ../bin/wing-release-linux-arm64 -C GZip index.js && pkg -t node18-linuxstatic-x64 -o ../bin/wing-release-linux-x64 -C GZip index.js && pkg -t node18-alpine-arm64 -o ../bin/wing-release-linux-musl-arm64 -C GZip index.js && pkg -t node18-alpine-x64 -o ../bin/wing-release-linux-musl-x64 -C GZip index.js && pkg -t node18-win-arm64 -o ../bin/wing-release-win32-arm64 -C GZip index.js && pkg -t node18-win-x64 -o ../bin/wing-release-win32-x64 -C GZip index.js && pkg -t node18-macos-arm64 -o ../bin/wing-release-mac-arm64 -C GZip index.js && pkg -t node18-mac-x64 -o ../bin/wing-release-mac-x64 -C GZip index.js"
}
}
diff --git a/src/debug.js b/src/debug.js
new file mode 100644
index 0000000..4bbba34
--- /dev/null
+++ b/src/debug.js
@@ -0,0 +1,3 @@
+const fs = require('fs');
+
+fs.writeFileSync("index.ts", fs.readFileSync("index.ts").toString().replaceAll("global.debugBuild = true;", "global.debugBuild = true;").replaceAll("global.debugBuild = false;", "global.debugBuild = true;")); \ No newline at end of file
diff --git a/src/functions/list_personalities.js b/src/functions/list_personalities.js
new file mode 100644
index 0000000..28d1ee2
--- /dev/null
+++ b/src/functions/list_personalities.js
@@ -0,0 +1,9 @@
+WingAPI.createFunction("lspers", true, (parameter, error) => {
+ if (!Object.keys(variables).includes(parameter)) {
+ error("Invalid parameter");
+ return;
+ }
+
+ console.log(personalities[parameter].join(", "))
+})
+
diff --git a/src/index.ts b/src/index.ts
index 62e908a..9eaae8c 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,9 +4,13 @@ import WingParameters from "./wing/WingParameters";
import WingFileLoader from "./wing/WingFileLoader";
import WingAPI from "./wing/WingAPI";
-global.version = "next-%%V";
+global.version = "next";
+global.advancedBuild = "%%V";
+global.build = "%BUILD:dev%";
+global.debugBuild = true;
+global.buildDate = "%%D";
global.wingRoot = __dirname;
-global._debug = WingParameters.get("debug");
+global._debug = WingParameters.get("debug") && global.debugBuild;
global.variables = {};
global.functions = {};
@@ -15,6 +19,8 @@ global.conditions = {};
global.operators = {};
global.constants = [];
global.modules = {};
+global.lists = {};
+global.foreach = {};
global.strictMode = false;
global.WingAPI = new WingAPI();
diff --git a/src/operators/append.js b/src/operators/append.js
new file mode 100644
index 0000000..f8c499f
--- /dev/null
+++ b/src/operators/append.js
@@ -0,0 +1,12 @@
+WingAPI.createOperator("append", [
+ {
+ type: "variable"
+ }
+], (parameters, value, name, error) => {
+ if (personalities[name].includes("list")) {
+ lists[value].push(variables[parameters[0]]);
+ return value;
+ } else {
+ error("Variable does not have the list personality");
+ }
+}) \ No newline at end of file
diff --git a/src/operators/item.js b/src/operators/item.js
new file mode 100644
index 0000000..17ff3a2
--- /dev/null
+++ b/src/operators/item.js
@@ -0,0 +1,18 @@
+WingAPI.createOperator("item", [
+ {
+ type: "variable"
+ },
+ {
+ type: "number"
+ }
+], (parameters, value, error) => {
+ if (personalities[parameters[0]].includes("list")) {
+ if (lists[variables[parameters[0]]][parameters[1]]) {
+ return lists[variables[parameters[0]]][parameters[1]];
+ } else {
+ error("List index out of range");
+ }
+ } else {
+ error("Variable does not have the list personality");
+ }
+}) \ No newline at end of file
diff --git a/src/operators/length.js b/src/operators/length.js
new file mode 100644
index 0000000..b8b408c
--- /dev/null
+++ b/src/operators/length.js
@@ -0,0 +1,11 @@
+WingAPI.createOperator("length", [
+ {
+ type: "variable"
+ }
+], (parameters) => {
+ if (personalities[parameters[0]].includes("list")) {
+ return lists[variables[parameters[0]]].length;
+ } else {
+ return variables[parameters[0]].length;
+ }
+}) \ No newline at end of file
diff --git a/src/operators/list.js b/src/operators/list.js
new file mode 100644
index 0000000..51e3a9b
--- /dev/null
+++ b/src/operators/list.js
@@ -0,0 +1,7 @@
+const { randomUUID } = require('crypto');
+
+WingAPI.createOperator("list", [], () => {
+ let name = "[List '" + randomUUID() + "']";
+ lists[name] = [];
+ return name;
+}) \ No newline at end of file
diff --git a/src/operators/overwrite.js b/src/operators/overwrite.js
new file mode 100644
index 0000000..37c049b
--- /dev/null
+++ b/src/operators/overwrite.js
@@ -0,0 +1,19 @@
+WingAPI.createOperator("overwrite", [
+ {
+ type: "number"
+ },
+ {
+ type: "variable"
+ }
+], (parameters, value, name, error) => {
+ if (personalities[name].includes("list")) {
+ if (lists[value][parameters[0]]) {
+ lists[value][parameters[0]] = variables[parameters[1]];
+ return value;
+ } else {
+ error("List index " + parameters[0] + " is out of range");
+ }
+ } else {
+ error("Variable does not have the list personality");
+ }
+}) \ No newline at end of file
diff --git a/src/operators/pop.js b/src/operators/pop.js
new file mode 100644
index 0000000..51ec4a2
--- /dev/null
+++ b/src/operators/pop.js
@@ -0,0 +1,8 @@
+WingAPI.createOperator("pop", [], (parameters, value, name, error) => {
+ if (personalities[name].includes("list")) {
+ lists[value].pop();
+ return value;
+ } else {
+ error("Variable does not have the list personality");
+ }
+}) \ No newline at end of file
diff --git a/src/operators/shift.js b/src/operators/shift.js
new file mode 100644
index 0000000..ce89021
--- /dev/null
+++ b/src/operators/shift.js
@@ -0,0 +1,8 @@
+WingAPI.createOperator("shift", [], (parameters, value, name, error) => {
+ if (personalities[name].includes("list")) {
+ lists[value].shift();
+ return value;
+ } else {
+ error("Variable does not have the list personality");
+ }
+}) \ No newline at end of file
diff --git a/src/operators/unshift.js b/src/operators/unshift.js
new file mode 100644
index 0000000..c572af0
--- /dev/null
+++ b/src/operators/unshift.js
@@ -0,0 +1,12 @@
+WingAPI.createOperator("unshift", [
+ {
+ type: "variable"
+ }
+], (parameters, value, name, error) => {
+ if (personalities[name].includes("list")) {
+ lists[value].unshift(variables[parameters[0]]);
+ return value;
+ } else {
+ error("Variable does not have the list personality");
+ }
+}) \ No newline at end of file
diff --git a/src/release.js b/src/release.js
new file mode 100644
index 0000000..2a23ac1
--- /dev/null
+++ b/src/release.js
@@ -0,0 +1,3 @@
+const fs = require('fs');
+
+fs.writeFileSync("index.ts", fs.readFileSync("index.ts").toString().replaceAll("global.debugBuild = true;", "global.debugBuild = false;").replaceAll("global.debugBuild = false;", "global.debugBuild = false;")); \ No newline at end of file
diff --git a/src/version.js b/src/version.js
index 5936ecf..5315581 100644
--- a/src/version.js
+++ b/src/version.js
@@ -4,7 +4,19 @@ function fix(text) {
return "0".repeat(10 - text.length) + text;
}
-let parts = new Date().toISOString().replaceAll("T", "-").replace("Z", "-").replaceAll(".", "-").replaceAll(":", "-").split("-");
-let version = parts[0] + parts[1] + parts[2] + "-" + fix(parseInt(parts[3]).toString(16) + parseInt(parts[4]).toString(16) + parseInt(parts[5]).toString(16) + parseInt(parts[6]).toString(16));
+let version = new Date(new Date().toISOString().split("T")[0]).getTime() / 1000 / 3600 + "-" + Math.round((new Date().getTime() - new Date(new Date().toISOString().split("T")[0]).getTime()) / 1000);
-fs.writeFileSync("index.ts", fs.readFileSync("index.ts").toString().replaceAll("%%V", version)); \ No newline at end of file
+let today = new Date().toISOString().replaceAll("T", "-").replace("Z", "-").replaceAll(".", "-").replaceAll(":", "-").split("-").join("").substring(0, 8);
+let build = fs.readFileSync("../.build").toString().trim().split(".");
+
+if (build[2] !== today) {
+ build[2] = today;
+ build[1] = "0";
+ build[0] = parseInt(build[0]) + 1;
+} else {
+ build[1] = parseInt(build[1]) + 1;
+}
+
+fs.writeFileSync("../.build", build.join("."));
+
+fs.writeFileSync("index.ts", fs.readFileSync("index.ts").toString().replaceAll("%%V", version).replace(/^(global\.build = "%BUILD:)(.*)(%";)$/gm, "$1" + build[0] + "." + build[1] + "$3").replaceAll("%%D", (new Date().toLocaleDateString('en-uk',{weekday: 'short',year:'numeric',month:'short',day:'numeric'}).split(",").join("")) + " " + new Date().toLocaleTimeString('en-uk',{timeZoneName:'short'}))); \ No newline at end of file
diff --git a/src/wing/WingConditions.ts b/src/wing/WingConditions.ts
index 0445634..c877455 100644
--- a/src/wing/WingConditions.ts
+++ b/src/wing/WingConditions.ts
@@ -27,7 +27,12 @@ export default class WingConditions extends Wing {
switch (parameter.type) {
case "variable":
if (local.match(/^\$([a-zA-Z0-9-_]+)$/gm)) {
- params[index] = params[index].substring(1);
+ if (Object.keys(variables).includes(params[index].substring(1))) {
+ params[index] = params[index].substring(1);
+ } else {
+ error("Unresolved reference ($" + params[index].substring(1) + ")", line, globalLines, currentFunction, lines, file, "ERR_VARIABLE_NOENT");
+ return false;
+ }
} else {
error("Syntax error", line, globalLines, currentFunction, lines, file, "ERR_CONDITION_SYNTAX");
return false;
@@ -46,7 +51,12 @@ export default class WingConditions extends Wing {
let v = vars[i];
if (v.match(/^\$([a-zA-Z0-9-_]+)$/gm)) {
- params[index + i] = params[index + i].substring(1);
+ if (Object.keys(variables).includes(params[index + i].substring(1))) {
+ params[index + i] = params[index + i].substring(1);
+ } else {
+ error("Unresolved reference ($" + params[index + i].substring(1) + ")", line, globalLines, currentFunction, lines, file, "ERR_VARIABLE_NOENT");
+ return false;
+ }
} else {
error("Syntax error", line, globalLines, currentFunction, lines, file, "ERR_CONDITION_SYNTAX");
return false;
@@ -87,7 +97,13 @@ export default class WingConditions extends Wing {
if (linter) {
return true;
} else {
- return conditions[name]["runtime"](params);
+ return conditions[name]["runtime"](params, (message) => {
+ error(message, index, globalLines, currentFunction, lines, file, "ERR_CONDITION_WARNING");
+ }, (message) => {
+ crash(message, index, globalLines, currentFunction, lines, file, "ERR_CONDITION_ERROR");
+ }, (message) => {
+ deprecation(message, index, globalLines, currentFunction, lines, file, "ERR_CONDITION_DEPRECATION");
+ });
}
} else {
error("Unresolved reference (condition " + name + ")", line, globalLines, currentFunction, lines, file, "ERR_CONDITION_NOENT");
@@ -102,6 +118,7 @@ let contexts = global.contexts;
let variables = global.variables;
let constants = global.constants;
let functions = global.functions;
+let lists = global.lists;
let personalities = global.personalities;
let conditions = global.conditions;
let linter = global.linter.enabled;
diff --git a/src/wing/WingErrors.ts b/src/wing/WingErrors.ts
index 2c0c467..80437c4 100644
--- a/src/wing/WingErrors.ts
+++ b/src/wing/WingErrors.ts
@@ -109,7 +109,7 @@ export default class WingErrors extends Wing {
}
if (showTrace) {
- let lns = [(globalLine - 1).toString().length, globalLine.toString().length, (globalLine + 1).toString().length].reduce((a, b) => a.length > b.length ? a : b, '').length;
+ let lns = Math.max((globalLine - 1).toString().length, globalLine.toString().length, (globalLine + 1).toString().length);
console.log("");
diff --git a/src/wing/WingInterpreter.ts b/src/wing/WingInterpreter.ts
index ac5f40a..71cc3ee 100644
--- a/src/wing/WingInterpreter.ts
+++ b/src/wing/WingInterpreter.ts
@@ -5,6 +5,7 @@ import WingErrors from "./WingErrors";
import WingConditions from "./WingConditions";
import WingOperators from "./WingOperators";
import WingPersonalities from "./WingPersonalities";
+import {randomUUID} from "crypto";
export default class WingInterpreter extends Wing {
public static interpret(lines: string[], globalLines: number|null|undefined, currentFunction: string|null|undefined, file: string) {
@@ -89,12 +90,51 @@ export default class WingInterpreter extends Wing {
}
if (line === "end") {
+ let pop = true;
+
if (contexts.length > 0) {
if (currentContext && currentContext.type === "function") {
if (contexts.length > 1) functions[currentContext.target] += line + "\n";
}
- contexts.pop();
+ if (currentContext && currentContext.type === "foreach") {
+ if (contexts.length > 1) {
+ foreach[currentContext.target] += line + "\n";
+ } else {
+ contexts.pop();
+ pop = false;
+ let list = variables[currentContext.variable].split("");
+
+ if (lists[variables[currentContext.variable]]) {
+ list = lists[variables[currentContext.variable]];
+ }
+
+ for (let index in list) {
+ variables["_index"] = index.toString();
+ if (!constants.includes("_index")) constants.push("_index");
+ personalities["_index"] = WingPersonalities.get(index.toString());
+
+ let item = list[index];
+
+ variables["_item"] = item.toString();
+ if (!constants.includes("_item")) constants.push("_item");
+ personalities["_item"] = WingPersonalities.get(item.toString());
+
+ let lines = foreach[currentContext.target].split("\n");
+ let initialIndex = parseInt(lines[0].substring(2));
+ lines.shift();
+ interpret(lines, initialIndex, "_foreach:$" + currentContext.variable + ":" + index, file);
+ }
+
+ try {
+ delete foreach[currentContext.target];
+ constants.splice(constants.indexOf("_item"), 1);
+ constants.splice(constants.indexOf("_index"), 1);
+ } catch (e) {}
+ }
+ }
+
+ if (pop) contexts.pop();
} else {
error("Attempted to leave primary context", index, globalLines, currentFunction, lines, file, "ERR_END_PRIMARY");
}
@@ -117,6 +157,13 @@ export default class WingInterpreter extends Wing {
continue;
}
+ if (currentContext && currentContext.type === "foreach") {
+ foreach[currentContext.target] += line + "\n";
+ index++; globalLines++;
+ if (_debug) console.log("-------------------");
+ continue;
+ }
+
if (line.trim() === "" || line.trim().startsWith("--") || line.trim().startsWith("#!")) {
index++;
globalLines++;
@@ -128,11 +175,21 @@ export default class WingInterpreter extends Wing {
if (constants.includes(name)) {
error("Attempted to run operation on constant " + name, index, globalLines, currentFunction, lines, file, "ERR_OPERATOR_CONST");
} else {
- evaluateOperation(name, operation, variables, functions, contexts, index, globalLines, currentFunction, lines, file);
+ if (!Object.keys(variables).includes(name)) {
+ error("Unresolved reference ($" + name + ")", index, globalLines, currentFunction, lines, file, "ERR_VARIABLE_NOENT");
+ } else {
+ evaluateOperation(name, operation, variables, functions, contexts, index, globalLines, currentFunction, lines, file);
+ }
}
personalities[name] = WingPersonalities.get(variables[name]);
} else if (line.match(/^\$([a-zA-Z0-9-_]+)(!|) *= *(.*)$/gm)) {
let name = /\$([a-zA-Z0-9-_]+)(!|) *= *(.*)/gm.exec(line)[1];
+ let execute = true;
+
+ if (name.startsWith("_")) {
+ error("Variable names starting with an underscore are reserved", index, globalLines, currentFunction, lines, file, "ERR_VARIABLE_RESERVED");
+ execute = false;
+ }
if (constants.includes(name)) {
error("Attempted to reassign constant " + name, index, globalLines, currentFunction, lines, file, "ERR_CONST_ASSIGN");
@@ -140,7 +197,6 @@ export default class WingInterpreter extends Wing {
if (line.match(/^\$([a-zA-Z0-9-_]+)! *= *(.*)$/gm)) constants.push(name);
let assignment = /\$([a-zA-Z0-9-_]+)(!|) *= *(.*)/gm.exec(line)[3];
- let execute = true;
while (assignment.match(/\w*(?<!\\)\$([a-zA-Z0-9-_]+)/m)) {
let vars = /\w*(?<!\\)\$([a-zA-Z0-9-_]+)/m.exec(assignment);
@@ -160,19 +216,50 @@ export default class WingInterpreter extends Wing {
personalities[name] = WingPersonalities.get(variables[name]);
}
}
- } else if (line.match(/^function ([a-zA-Z0-9-_]+)( (\$([a-zA-Z0-9-_]+))*)?$/m)) {
- let match = /^function ([a-zA-Z0-9-_]+)( (\$([a-zA-Z0-9-_]+))*)?$/m.exec(line);
- let name = match[1];
- let parameter = match[4];
- contexts.push({
- type: "function",
- target: name
- });
-
- if (parameter) {
- functions[name] = "@@$" + parameter + "\n@@" + index + "\n";
+ } else if (line.match(/^foreach( (\$([a-zA-Z0-9-_]+)))( +do|)$/m)) {
+ let match = /^foreach( (\$([a-zA-Z0-9-_]+)))( +do|)$/m.exec(line);
+ let name = match[3];
+
+ if (!Object.keys(variables).includes(name)) {
+ error("Unresolved reference ($" + name + ")", index, globalLines, currentFunction, lines, file, "ERR_VARIABLE_NOENT");
} else {
- functions[name] = "@@\n@@" + index + "\n";
+ let id = randomUUID();
+
+ contexts.push({
+ type: "foreach",
+ variable: name,
+ target: id
+ });
+
+ foreach[id] = "@@" + index + "\n";
+ }
+ } else if (line.match(/^function ([a-zA-Z0-9-_]+)( (\$([a-zA-Z0-9-_]+)))?( +do|)$/m)) {
+ let match = /^function ([a-zA-Z0-9-_]+)( (\$([a-zA-Z0-9-_]+))*)?( +do|)$/m.exec(line);
+ let name = match[1];
+ let execute = true;
+
+ if (name.startsWith("_")) {
+ error("Function names starting with an underscore are reserved", index, globalLines, currentFunction, lines, file, "ERR_FUNCTION_RESERVED");
+ execute = false;
+ }
+
+ if (Object.keys(functions).includes(name)) {
+ error("Attempted to override existing function " + name, index, globalLines, currentFunction, lines, file, "ERR_FUNCTION_OVERRIDE");
+ execute = false;
+ }
+
+ if (execute) {
+ let parameter = match[4];
+ contexts.push({
+ type: "function",
+ target: name
+ });
+
+ if (parameter) {
+ functions[name] = "@@$" + parameter + "\n@@" + index + "\n";
+ } else {
+ functions[name] = "@@\n@@" + index + "\n";
+ }
}
} else if (line.match(/^([a-zA-Z0-9-_]+)( (.*)|)$/gm)) {
let execute = true;
@@ -181,9 +268,10 @@ export default class WingInterpreter extends Wing {
if (!Object.keys(functions).includes(func)) {
error("Unresolved reference (function " + func + ")", index, globalLines, currentFunction, lines, file, "ERR_FUNCTION_NOENT");
+ execute = false;
}
- if (parameters) {
+ if (parameters && execute) {
while (parameters.match(/\w*(?<!\\)\$([a-zA-Z0-9-_]+)/m)) {
let vars = /\w*(?<!\\)\$([a-zA-Z0-9-_]+)/m.exec(parameters);
let name = vars[1];
@@ -358,6 +446,8 @@ let personalities = global.personalities;
let constants = global.constants;
let functions = global.functions;
let linter = global.linter.enabled;
+let lists = global.lists;
+let foreach = global.foreach;
let modules = global.modules;
let interpret = WingInterpreter.interpret;
let wingRoot = global.wingRoot;
diff --git a/src/wing/WingMetadata.ts b/src/wing/WingMetadata.ts
index a0f18ba..26e27a6 100644
--- a/src/wing/WingMetadata.ts
+++ b/src/wing/WingMetadata.ts
@@ -4,7 +4,7 @@ import WingParameters from "./WingParameters";
export default class WingMetadata extends Wing {
constructor() {
if (WingParameters.get("version")) {
- console.log("wing-" + global.version);
+ console.log("Wing " + global.version + " (build " + global.build.replace(/^(%BUILD:)(.*)(%)$/gm, "$2") + "." + (global.debugBuild ? "debug" : "release") + "." + global.advancedBuild + "; " + global.buildDate + ")");
process.exit();
}
diff --git a/src/wing/WingOperators.ts b/src/wing/WingOperators.ts
index ee15a4e..7f5b07e 100644
--- a/src/wing/WingOperators.ts
+++ b/src/wing/WingOperators.ts
@@ -28,7 +28,12 @@ export default class WingOperators extends Wing {
switch (parameter.type) {
case "variable":
if (local.match(/^\$([a-zA-Z0-9-_]+)$/gm)) {
- params[index] = params[index].substring(1);
+ if (Object.keys(variables).includes(params[index].substring(1))) {
+ params[index] = params[index].substring(1);
+ } else {
+ error("Unresolved reference ($" + params[index].substring(1) + ")", line, globalLines, currentFunction, lines, file, "ERR_VARIABLE_NOENT");
+ return false;
+ }
} else {
error("Syntax error", line, globalLines, currentFunction, lines, file, "ERR_OPERATOR_SYNTAX");
return false;
@@ -48,7 +53,12 @@ export default class WingOperators extends Wing {
let v = vars[i];
if (v.match(/^\$([a-zA-Z0-9-_]+)$/gm)) {
- params[index + i] = params[index + i].substring(1);
+ if (Object.keys(variables).includes(params[index + i].substring(1))) {
+ params[index + i] = params[index + i].substring(1);
+ } else {
+ error("Unresolved reference ($" + params[index + i].substring(1) + ")", line, globalLines, currentFunction, lines, file, "ERR_VARIABLE_NOENT");
+ return false;
+ }
} else {
error("Syntax error", line, globalLines, currentFunction, lines, file, "ERR_OPERATOR_SYNTAX");
return false;
@@ -79,7 +89,7 @@ export default class WingOperators extends Wing {
break;
default:
- throw new Error("Invalid operator parameter type");
+ break;
}
} else {
error("Missing parameter for operator " + name, line, globalLines, currentFunction, lines, file, "ERR_MISSING_OPERATOR_PARAM");
@@ -88,7 +98,13 @@ export default class WingOperators extends Wing {
}
if (!linter) {
- variables[variable] = operators[name]["runtime"](params);
+ variables[variable] = operators[name]["runtime"](params, variables[variable], variable, (message) => {
+ error(message, index, globalLines, currentFunction, lines, file, "ERR_OPERATOR_WARNING");
+ }, (message) => {
+ crash(message, index, globalLines, currentFunction, lines, file, "ERR_OPERATOR_ERROR");
+ }, (message) => {
+ deprecation(message, index, globalLines, currentFunction, lines, file, "ERR_OPERATOR_DEPRECATION");
+ });
if (typeof variables[variable] !== "string") {
variables[variable] = String(variables[variable]);
@@ -113,4 +129,5 @@ let functions = global.functions;
let operators = global.operators;
let linter = global.linter.enabled;
let modules = global.modules;
+let lists = global.lists;
let wingRoot = global.wingRoot; \ No newline at end of file
diff --git a/src/wing/WingPersonalities.ts b/src/wing/WingPersonalities.ts
index eeb6760..d599949 100644
--- a/src/wing/WingPersonalities.ts
+++ b/src/wing/WingPersonalities.ts
@@ -4,6 +4,10 @@ export default class WingPersonalities extends Wing {
public static get(content: string) {
let personalities = [ "string" ];
+ if (Object.keys(lists).includes(content)) {
+ personalities.unshift("list");
+ }
+
if (!isNaN(parseFloat(content)) && isFinite(parseInt(content))) {
personalities.unshift("number");
@@ -57,4 +61,6 @@ export default class WingPersonalities extends Wing {
return personalities;
}
-} \ No newline at end of file
+}
+
+let lists = global.lists; \ No newline at end of file