SkriptLang / Skript

Skript is a Spigot plugin which allows server admins to customize their server easily, but without the hassle of programming a plugin or asking/paying someone to program a plugin for them.
https://docs.skriptlang.org
GNU General Public License v3.0
1.07k stars 369 forks source link

Feature Request: dynamic function calling #1265

Open JustDylan23 opened 6 years ago

JustDylan23 commented 6 years ago

Target Minecraft versions: any Requirements: none Related issues: none

Proposed syntax: {_textvariable}(parameters)

Description: It would be really handy if you could call a function using text variables so you can call a function based on circumstances without having to have a load of conditions

Snow-Pyon commented 6 years ago

What you're asking here is dynamic function calls. This is something that could be a bit troublesome when it comes to errors but I see its benefits.

Some addons such as TuSKe have implemented this already so I don't see why it can't be implemented in Skript at some point.

Meanwhile, you can create a new function with a text argument, and call the corresponding function depending on the argument.

JustDylan23 commented 6 years ago

I'd like to propose a new sytax that would make it a lot easier to code: New syntax:

[functionName](inputs)

the goal of this is to allow you to have multiple variables that make up the name together. Imagine something like this:

[%{_index}%%{_text}%](inputs)

TheLimeGlass commented 6 years ago

I don't agree with having the proposed syntax {_function}(player, ...) as this is very confusing to read depending on the variable name and arguments.

A proposal to the syntax can be:

(call|run|execute) function[s] %strings% [with arguments[s] %~objects%]
return function[s] %strings% [(with|using) arguments[s] %~objects%]
Pikachu920 commented 6 years ago

so i've been working on this and i'd like to request input on how the arguments should be parsed. Obviously, since i can't check things at parse time I don't have the luxury of being smart based on that. Here is my current logic:

    /**
     * This method takes an object expression
     * and converts it into values ready to pass
     * into a function. If you have the function
     * <code>
     *     function test(n1: number, n2: number):
     * </code>
     * and then run {@code result of "test"({_l::*})}
     * where {@code {_l::*}} holds 1 and 2, {@code test}
     * will be called. However, if an {@link ch.njol.skript.lang.ExpressionList}
     * is one of the expressions in {@code expression}
     * and you have the function
     * <code>
     *     function test(n1: number, s: strings):
     * </code>
     * and then run {@code result of "test"({_l::*})}
     * where {@code {_l::*}} contains 1, "something" and "something else"
     * the function will not be run because the second argument
     * is not it's own {@link ch.njol.skript.lang.ExpressionList}.
     * In this case, the valid call would be
     * {@code result of "test"(1 and ("thing" and "other thing"))}
     *
     * @param expression Expression to formatted
     * @return The formatted expression values
     */

I may also abandon this (or at least shelve it for now) because function code is all over the place and not commented.

bensku commented 6 years ago

I recommend that you try to reuse the existing function validation code, but this time, runtime. Or is it not possible for some reason?

Pikachu920 commented 6 years ago

The issue with that is things like this: Say I have a function, function twoNumbers(numberOne: number, numberTwo: number):. If I try to access this like this:

set {_l::*} to 1 and 2
twoNumbers({_l::*})

it obviously won't work. However, if i access it "reflectively" then you would except that the following works:

set {_l::*} to 1 and 2
call "twoNumbers"({_l:*})

so its kind of hard to find a good mix between functionality and accessibility (in regards to avoiding the need to specifically format things, because if accessing a function reflectively you probably can't do that)

LiamSystems commented 3 years ago

Any news with this? Would help a ton on some skripts that need tons of functions ran so I don't need to do loops to check for each type to then run the function