summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2022-12-02 22:03:58 +0100
committerMinteck <contact@minteck.org>2022-12-02 22:03:58 +0100
commitf08a7afcc73bb5bd4ebab40e124dc8e56fc3960f (patch)
tree21bd91a35edf316a89e1cb02d6b0b1c6ddae4692
parent07560d746f6bf18c3e349cac89832d2a22996709 (diff)
downloadwing-f08a7afcc73bb5bd4ebab40e124dc8e56fc3960f.tar.gz
wing-f08a7afcc73bb5bd4ebab40e124dc8e56fc3960f.tar.bz2
wing-f08a7afcc73bb5bd4ebab40e124dc8e56fc3960f.zip
Conditions and other fixes
-rw-r--r--.idea/vcs.xml6
-rw-r--r--conditions/defined.js7
-rw-r--r--demo.wing1
-rw-r--r--functions/print.js4
-rw-r--r--index.js240
-rwxr-xr-xtest.wing25
-rw-r--r--test.wjs1
7 files changed, 226 insertions, 58 deletions
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="" vcs="Git" />
+ </component>
+</project> \ No newline at end of file
diff --git a/conditions/defined.js b/conditions/defined.js
new file mode 100644
index 0000000..2bf1f3e
--- /dev/null
+++ b/conditions/defined.js
@@ -0,0 +1,7 @@
+WingAPI.createCondition("defined", [
+ {
+ type: "variable"
+ }
+], (parameters) => {
+ return Object.keys(variables).includes(parameters[0]);
+}) \ No newline at end of file
diff --git a/demo.wing b/demo.wing
new file mode 100644
index 0000000..84975b3
--- /dev/null
+++ b/demo.wing
@@ -0,0 +1 @@
+print Imported file! \ No newline at end of file
diff --git a/functions/print.js b/functions/print.js
new file mode 100644
index 0000000..290eea4
--- /dev/null
+++ b/functions/print.js
@@ -0,0 +1,4 @@
+WingAPI.createFunction("print", true, (parameter) => {
+ console.log(parameter);
+})
+
diff --git a/index.js b/index.js
index 3587c55..c28cde3 100644
--- a/index.js
+++ b/index.js
@@ -1,5 +1,6 @@
const fs = require('fs');
const chalk = require('chalk');
+const path = require('path');
global._debug = false;
if (!process.argv[2]) {
@@ -13,6 +14,7 @@ if (!fs.existsSync(process.argv[2])) {
}
let file;
+let filename = path.resolve(process.argv[2]);
try {
file = fs.readFileSync(process.argv[2]).toString();
@@ -21,37 +23,139 @@ try {
process.exit(2);
}
-let variables = {};
-let functions = {
- print: (parameters) => {
- console.log(parameters);
+global.variables = {};
+global.functions = {};
+global.conditions = {};
+global.operators = {};
+
+global.WingAPI = {
+ createFunction: (name, parameter, runtime) => {
+ functions[name] = {
+ parameter,
+ runtime
+ }
+ },
+ createCondition: (name, parameters, runtime) => {
+ conditions[name] = {
+ parameters,
+ runtime
+ }
}
-};
+}
+
+process.chdir(__dirname);
+
+for (let file of fs.readdirSync("./functions")) {
+ require(__dirname + "/functions/" + file);
+}
+
+for (let file of fs.readdirSync("./conditions")) {
+ require(__dirname + "/conditions/" + file);
+}
+
let lines = file.replaceAll("\r\n", "\n").split("\n");
let contexts = [];
-interpret(lines);
+interpret(lines, undefined, null, filename);
+
+function evaluateCondition(condition, variables, functions, contexts, index, globalLines, currentFunction, lines, file) {
+ let argv = condition.split(" ");
+ let name = argv[0];
+ argv.shift(); let params = argv;
+
+ if (conditions[name]) {
+ for (let index in conditions[name]["parameters"]) {
+ let parameter = conditions[name]["parameters"][index];
+ let local = params[index];
+
+ if (params[index]) {
+ switch (parameter.type) {
+ case "variable":
+ if (local.match(/^\$([a-zA-Z0-9-_]+)$/gm)) {
+ params[index] = params[index].substring(1);
+ } else {
+ error("Syntax error", index, globalLines, currentFunction, lines, file);
+ return false;
+ }
+
+ break;
+
+ case "number":
+ if (!isNaN(parseFloat(local)) && isFinite(local)) {
+ params[index] = parseFloat(local);
+ } else {
+ error("Syntax error", index, globalLines, currentFunction, lines, file);
+ return false;
+ }
+
+ break;
-function evaluateCondition(condition, variables, functions, contexts, index) {
- return true;
+ case "values":
+ if (parameter.values.includes(local)) {
+ params[index] = local;
+ } else {
+ error("Syntax error", index, globalLines, currentFunction, lines, file);
+ return false;
+ }
+
+ break;
+
+ default:
+ throw new Error("Invalid condition parameter type");
+ }
+ } else {
+ error("Missing parameter for condition " + name, index, globalLines, currentFunction, lines, file);
+ return false;
+ }
+ }
+
+ return conditions[name]["runtime"](params);
+ } else {
+ error("Unresolved reference (condition " + name + ")", index, globalLines, currentFunction, lines, file);
+ return false;
+ }
}
-function error(message, line, globalLine, currentFunction, lines) {
+function error(message, line, globalLine, currentFunction, lines, filename) {
+ console.log(chalk.gray("------------------------------------------------------------------------"));
+
if (line === globalLine) {
- console.error(chalk.blueBright.inverse("Wing:") + " " + chalk.yellow(message + ", at line " + chalk.magenta(line)));
+ console.error(chalk.blueBright.inverse("Wing:") + " " + chalk.yellow(message + "\n * at line " + chalk.magenta(line) + "\n * in file " + chalk.magenta(filename)));
} else {
if (currentFunction) {
- console.error(chalk.blueBright.inverse("Wing:") + " " + chalk.yellow(message + ", at line " + chalk.magenta(line + "@" + currentFunction + " < " + globalLine)));
+ console.error(chalk.blueBright.inverse("Wing:") + " " + chalk.yellow(message + "\n * at local line " + chalk.magenta(line) + ", global line " + chalk.magenta(globalLine + 1) + "\n * in function " + chalk.magenta(currentFunction) + "\n * in file " + chalk.magenta(filename)));
} else {
- console.error(chalk.blueBright.inverse("Wing:") + " " + chalk.yellow(message + ", at line " + chalk.magenta(line + " < " + globalLine)));
+ console.error(chalk.blueBright.inverse("Wing:") + " " + chalk.yellow(message + "\n * at local line " + chalk.magenta(line) + ", global line " + chalk.magenta(globalLine + 1) + "\n * in file " + chalk.magenta(filename)));
+ }
+
+ if (currentFunction) {
+ globalLine++;
}
}
+
+ let lns = [(globalLine - 1).toString().length, globalLine.toString().length, (globalLine + 1).toString().length].reduce((a, b) => a.length > b.length ? a : b, '').length;
+
+ console.log("");
+
+ if (lines[line - 2] || typeof lines[line - 2] === "string") {
+ let lnp = " ".repeat(lns - (globalLine - 1).toString().length) + (globalLine - 1).toString();
+ console.log(" " + chalk.gray(lnp + " ") + chalk.gray(lines[line - 2]));
+ }
+
+ console.log(chalk.blueBright.bold(">") + " " + chalk.gray(globalLine + " ") + lines[line - 1]);
+
+ if (lines[line] || typeof lines[line] === "string") {
+ let lnn = " ".repeat(lns - (globalLine + 1).toString().length) + (globalLine + 1).toString();
+ console.log(" " + chalk.gray(lnn + " ") + chalk.gray(lines[line]));
+ }
+
+ console.log(chalk.gray("------------------------------------------------------------------------"));
}
-function interpret(lines, globalLines, currentFunction) {
+function interpret(lines, globalLines, currentFunction, file) {
let count = lines.length;
- lines = lines.map(i => i.trim()).filter(i => i !== "" && !i.startsWith("--") && !i.startsWith("#!"));
+ lines = lines.map(i => i.trim());
let stripped = count - lines.length;
let index = 1;
@@ -65,7 +169,8 @@ function interpret(lines, globalLines, currentFunction) {
try {
let currentContext = contexts[contexts.length - 1];
- line = line.split("--")[0];
+ line = !line.trim().startsWith("--") ? line.split("--")[0] : line;
+ if (_debug) console.log("--> " + index + "; " + globalLines);
if (_debug) console.log("--> " + line);
if (_debug) console.log("-->", contexts);
@@ -79,7 +184,7 @@ function interpret(lines, globalLines, currentFunction) {
} else {
let condition = /^if (.+) do$/m.exec(line)[1];
- if (!evaluateCondition(condition, variables, functions, contexts, index)) {
+ if (!evaluateCondition(condition, variables, functions, contexts, index, globalLines, currentFunction, lines, file)) {
contexts.push({
type: "unmatched",
target: null
@@ -123,7 +228,7 @@ function interpret(lines, globalLines, currentFunction) {
if (_debug) console.log("-------------------");
continue;
} else {
- error("Attempted to use 'else' while not in a condition context", index, globalLines, currentFunction, lines);
+ error("Attempted to use 'else' while not in a condition context", index, globalLines, currentFunction, lines, file);
}
}
}
@@ -136,7 +241,7 @@ function interpret(lines, globalLines, currentFunction) {
contexts.pop();
} else {
- error("Attempted to leave primary context", index, globalLines, currentFunction, lines);
+ error("Attempted to leave primary context", index, globalLines, currentFunction, lines, file);
}
index++; globalLines++;
@@ -157,16 +262,35 @@ function interpret(lines, globalLines, currentFunction) {
continue;
}
- if (line.match(/^\$([a-zA-Z0-9-_]+) *= *(.*)$/gm)) {
+ if (line.trim() === "" || line.trim().startsWith("--") || line.trim().startsWith("#!")) {
+ index++;
+ globalLines++;
+ if (_debug) console.log("-------------------");
+ continue;
+ } else if (line.match(/^\$([a-zA-Z0-9-_]+) *= *(.*)$/gm)) {
let name = /\$([a-zA-Z0-9-_]+) *= *(.*)/gm.exec(line)[1];
variables[name] = /\$([a-zA-Z0-9-_]+) *= *(.*)/gm.exec(line)[2];
- } else if (line.match(/^@([a-zA-Z0-9-_]+)( (.*)|)$/gm)) {
+ } 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 {
+ functions[name] = "@@\n@@" + index + "\n";
+ }
+ } else if (line.match(/^([a-zA-Z0-9-_]+)( (.*)|)$/gm)) {
let execute = true;
- let func = /@([a-zA-Z0-9-_]+)( (.*)|)/gm.exec(line)[1];
- let parameters = /@([a-zA-Z0-9-_]+)( (.*)|)/gm.exec(line)[3];
+ let func = /([a-zA-Z0-9-_]+)( (.*)|)/gm.exec(line)[1];
+ let parameters = /([a-zA-Z0-9-_]+)( (.*)|)/gm.exec(line)[3];
if (!Object.keys(functions).includes(func)) {
- error("Unresolved reference (@" + func + ")", index, globalLines, currentFunction, lines);
+ error("Unresolved reference (function " + func + ")", index, globalLines, currentFunction, lines, file);
}
if (parameters) {
@@ -175,7 +299,7 @@ function interpret(lines, globalLines, currentFunction) {
let name = vars[1];
if (!Object.keys(variables).includes(name)) {
- error("Unresolved reference ($" + name + ")", index, globalLines, currentFunction, lines);
+ error("Unresolved reference ($" + name + ")", index, globalLines, currentFunction, lines, file);
execute = false;
break;
}
@@ -187,11 +311,17 @@ function interpret(lines, globalLines, currentFunction) {
}
if (execute) {
- if (typeof functions[func] === "function") {
- functions[func](parameters, variables, functions, contexts, index, globalLines, currentFunction, lines);
+ if (typeof functions[func] === "object") {
+ if (functions[func]["parameter"] && !parameters) {
+ error("Missing parameter for function " + func, index, globalLines, currentFunction, lines, file);
+ } else if (!functions[func]["parameter"] && parameters) {
+ error("Function " + func + " does not admit a parameter", index, globalLines, currentFunction, lines, file);
+ }
+
+ functions[func]["runtime"](parameters, variables, functions, contexts, index, globalLines, currentFunction, lines, file);
} else {
let lines = functions[func].split("\n");
- let initialIndex = lines[1].substring(2);
+ let initialIndex = parseInt(lines[1].substring(2));
if (parameters && lines[0].startsWith("@@$")) {
let parameter = lines[0].substring(3);
@@ -199,38 +329,62 @@ function interpret(lines, globalLines, currentFunction) {
lines.shift();
lines.shift();
- interpret(lines, initialIndex, func);
+ interpret(lines, initialIndex, func, file);
} else if (parameters) {
- error("Function @" + func + " does not admit a parameter", index, globalLines, currentFunction, lines);
+ error("Function " + func + " does not admit a parameter", index, globalLines, currentFunction, lines, file);
+ } else if (lines[0].startsWith("@@$")) {
+ error("Missing parameter for function " + func, index, globalLines, currentFunction, lines, file);
} else {
lines.shift();
lines.shift();
- interpret(lines, initialIndex, func);
+ interpret(lines, initialIndex, func, file);
}
}
}
- } 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
- });
+ } else if (line.startsWith("#")) {
+ process.chdir(path.dirname(file));
- if (parameter) {
- functions[name] = "@@$" + parameter + "\n@@" + index + "\n";
+ if (currentFunction) {
+ error("Attempted to import from a function context", index, globalLines, currentFunction, lines, file);
+ index++;
+ globalLines++;
+ continue;
+ }
+
+ let importFile = line.substring(1);
+
+ if (!fs.existsSync(importFile)) {
+ error("Imported file " + importFile + " not found", index, globalLines, currentFunction, lines, file);
+ index++; globalLines++; continue;
+ }
+
+ try {
+ let _text = fs.readFileSync(importFile).toString();
+ } catch (e) {
+ error("Imported file " + importFile + " is unreadable", index, globalLines, currentFunction, lines, file);
+ index++;
+ globalLines++;
+ continue;
+ }
+
+ let ext = path.extname(importFile);
+
+ if (ext === ".wjs") {
+ eval(fs.readFileSync(importFile).toString());
+ } else if (ext === ".wing") {
+ interpret(fs.readFileSync(importFile).toString().replaceAll("\r\n", "\n").split("\n"), undefined, null, importFile);
} else {
- functions[name] = "@@\n@@" + index + "\n";
+ error("Imported file " + importFile + " is neither of Wing JS Binding file (.wjs) or Wing Source file (.wing)", index, globalLines, currentFunction, lines, file);
}
} else {
- error("Syntax error", index, globalLines, currentFunction, lines);
+ error("Syntax error", index, globalLines, currentFunction, lines, file);
}
index++; globalLines++;
if (_debug) console.log("-------------------");
} catch (e) {
- error("Internal system error", index, globalLines, currentFunction, lines);
+ error("Internal system error", index, globalLines, currentFunction, lines, file);
+ index++; globalLines++;
if (_debug) console.error(e);
if (_debug) console.log("-------------------");
}
diff --git a/test.wing b/test.wing
index 8c00f95..1dfa946 100755
--- a/test.wing
+++ b/test.wing
@@ -2,27 +2,22 @@
-- This is a test program
$test = 1
-function @hello
- if $test == 1 do
- @print hi
- else do
- @print no
- end
+function hello
+ print hi
end
-function @goodbye $thing
+function goodbye $thing
if defined $thing do
- @print thing is defined: $thing
+ print thing is defined: $thing
else do
- @print thing is not defined
+ print thing is not defined
end
end
-@hello
-@goodbye hello world
+hello
+goodbye hello world
-if $test == 1 do
- @print this one doesn't exist: $thing
-end
+print hello $test, this one is also escaped: \$test
-@print hello $test, this one is also escaped: \$test \ No newline at end of file
+#./demo.wing
+#./test.wjs \ No newline at end of file
diff --git a/test.wjs b/test.wjs
new file mode 100644
index 0000000..635625a
--- /dev/null
+++ b/test.wjs
@@ -0,0 +1 @@
+console.log("Hello world!"); \ No newline at end of file