From f754c176c40809b3430c5d598df8e5a2b35e85d7 Mon Sep 17 00:00:00 2001 From: DrMaxNix Date: Sat, 1 Oct 2022 16:19:59 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20argument=20validation=20helpers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/command/drw.js | 9 +++++- src/command/mov.js | 13 ++++++++ src/main.js | 6 +++- src/runner.js | 75 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/command/mov.js diff --git a/src/command/drw.js b/src/command/drw.js index 951a662..a67bce9 100644 --- a/src/command/drw.js +++ b/src/command/drw.js @@ -2,6 +2,13 @@ Juicescript.command_add({ name: "drw", alias: ["draw", "echo"], function: function(runner){ - /**/runner.io.stdout(runner.command.argument[0].value); + // VALIDATE ARGUMENTS // + // count + runner.argument_validate_count({min: 1, max: null}); + + // types + for(var q = 1; q <= runner.command.argument.length; q++){ + runner.argument_validate_type(q, Juicescript.argument_type.VALUE); + } } }); diff --git a/src/command/mov.js b/src/command/mov.js new file mode 100644 index 0000000..a968ab7 --- /dev/null +++ b/src/command/mov.js @@ -0,0 +1,13 @@ +Juicescript.command_add({ + name: "mov", + alias: ["move", "set"], + function: function(runner){ + // VALIDATE ARGUMENTS // + // count + runner.argument_validate_count(2); + + // types + runner.argument_validate_type(1, Juicescript.argument_type.VARIABLE); + runner.argument_validate_type(2, Juicescript.argument_type.VALUE); + } +}); diff --git a/src/main.js b/src/main.js index 98170c7..65fdd0b 100644 --- a/src/main.js +++ b/src/main.js @@ -34,7 +34,11 @@ class Juicescript { // ARGUMENT TYPES // static argument_type = new Juicescript_helper_enum( - "VARIABLE", "LITERAL", "OPERATOR", "IDENTIFIER" + // parsable types + "VARIABLE", "LITERAL", "OPERATOR", "IDENTIFIER", + + // meta types + "VALUE" ); diff --git a/src/runner.js b/src/runner.js index 52137dd..3ce1d75 100644 --- a/src/runner.js +++ b/src/runner.js @@ -121,6 +121,81 @@ class Juicescript_runner { return this.tree.scope[this.scope]; } + /* + COMMAND HELPER: Validate number of command arguments + */ + argument_validate_count(count){ + // CONVERT SIMPLE FORM TO MIN / MAX // + if(Number.isInteger(count)){ + count = {min: count, max: count}; + } + + + // CHECK // + // get actual argument count + let actual_count = this.command.argument.length; + + // maybe compare against list + if(Array.isArray(count)){ + if(!count.includes(actual_count)){ + this.error(this.command.name + ": invalid argument count (" + count.join(" or ") + " expected)"); + } + return; + } + + // build range string + let range_string; + if(count.min === count.max){ + range_string = count.min; + + } else if(count.max === null){ + range_string = "at least " + count.min; + + } else { + range_string = count.min + " to " + count.max; + } + + // too few arguments + if(actual_count < count.min){ + this.error(this.command.name + ": too few arguments (" + range_string + " expected)"); + } + + // too many arguments + if(count.max !== null && actual_count > count.max){ + this.error(this.command.name + ": too many arguments (" + range_string + " expected)"); + } + } + + /* + COMMAND HELPER: Validate type of command arguments + */ + argument_validate_type(number, type){ + // GET WANTED ARGUMENT'S ACTUAL TYPE // + // make sure this argument number exists + if(this.command.argument.length < number){ + throw "unable to validate type of argument " + number + ", command " + this.command.name; + } + + // load + let actual_type = this.command.argument[(number - 1)].type; + + + // COMPARE AGAINST META TYPES // + // value + if(type === Juicescript.argument_type.VALUE){ + if(![Juicescript.argument_type.VARIABLE, Juicescript.argument_type.LITERAL].includes(actual_type)){ + this.error(this.command.name + ", argument " + number + ": expected " + Juicescript.argument_type.name(type) + ", but got " + Juicescript.argument_type.name(actual_type)); + } + return; + } + + + // COMPARE AGAINST PARSABLE TYPES // + if(actual_type !== type){ + this.error(this.command.name + ", argument " + number + ": expected " + Juicescript.argument_type.name(type) + ", but got " + Juicescript.argument_type.name(actual_type)); + } + } + /* HELPER: Automagically keep track of problems and add additional info to stderr */