variable number of arguments for user defined functions.
This commit is contained in:
1 parent
7de132eb56
commit
e8b2060fb3
15 files changed
+168
-68
No files matched your search
+35
-17
@@ -146,7 +146,7 @@ around built-in function `outer`. It adds the specified value to the function ca
|
|||||||
like capturing lambdas in Java, but unlike java captured variables don't need to be final. Scarpet will just
|
like capturing lambdas in Java, but unlike java captured variables don't need to be final. Scarpet will just
|
||||||
attach their new values at the time of the function definition, even if they change later. Most value will be
|
attach their new values at the time of the function definition, even if they change later. Most value will be
|
||||||
copied, but mutable values, like maps or lists, allow to keep the 'state' with the function, allowing them to
|
copied, but mutable values, like maps or lists, allow to keep the 'state' with the function, allowing them to
|
||||||
have memory and act like objects so to speak. . Check `outer(var)` for details.
|
have memory and act like objects so to speak. Check `outer(var)` for details.
|
||||||
|
|
||||||
## Code delivery, line indicators
|
## Code delivery, line indicators
|
||||||
|
|
||||||
@@ -767,22 +767,21 @@ from other threads, just because the only possibility of a deadlock in this case
|
|||||||
bad code, not the internal world access behaviour. Some things tough like player or entity manipulation, can be
|
bad code, not the internal world access behaviour. Some things tough like player or entity manipulation, can be
|
||||||
effectively parallelized.
|
effectively parallelized.
|
||||||
|
|
||||||
### `task(function, ?args...., ?executor)`
|
### `task(function, ... args)`, `task_thread(executor, function, ... args)`
|
||||||
|
|
||||||
Creates and runs a parallel task, returning the handle to the task object. Task will return the return value of the
|
Creates and runs a parallel task, returning the handle to the task object. Task will return the return value of the
|
||||||
function when its completed, or will return `null` immediately if task is still in progress, so grabbing a value of
|
function when its completed, or will return `null` immediately if task is still in progress, so grabbing a value of
|
||||||
a task object is non-blocking. Function can be either function value, or function lambda, or a name of an existing
|
a task object is non-blocking. Function can be either function value, or function lambda, or a name of an existing
|
||||||
defined function. In case function needs arguments to be called with, they should be supplied after the function
|
defined function. In case function needs arguments to be called with, they should be supplied after the function
|
||||||
name, or value. Optional `executor` identifier is to place the task in a specific queue identified by this value.
|
name, or value. `executor` identifier in `task_thread`, places the task in a specific queue identified by this value.
|
||||||
The default thread value is the `null` thread. There is no limits on number of parallel tasks for any executor,
|
The default thread value is the `null` thread. There are no limits on number of parallel tasks for any executor,
|
||||||
so using different queues is solely for synchronization purposes. Also, since `task` function knows how many extra
|
so using different queues is solely for synchronization purposes.
|
||||||
arguments it requires, the use of tailing optional parameter for the custom executor thread pool is not ambiguous.
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
task( _() -> print('Hello Other World') ) => Runs print command on a separate thread
|
task( _() -> print('Hello Other World') ) => Runs print command on a separate thread
|
||||||
foo(a, b) -> print(a+b); task('foo',2,2) => Uses existing function definition to start a task
|
foo(a, b) -> print(a+b); task('foo',2,2) => Uses existing function definition to start a task
|
||||||
task('foo',3,5,'temp'); => runs function foo with a different thread executor, identified as 'temp'
|
task_thread('temp', 'foo',3,5); => runs function foo with a different thread executor, identified as 'temp'
|
||||||
a = 3; task( _(outer(a), b) -> foo(a,b), 5, 'temp')
|
a = 3; task_thread('temp', _(outer(a), b) -> foo(a,b), 5)
|
||||||
=> Another example of running the same thing passing arguments using closure over anonymous function as well as passing a parameter.
|
=> Another example of running the same thing passing arguments using closure over anonymous function as well as passing a parameter.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -1274,10 +1273,11 @@ call creates new scope for variables inside `expr`, so all non-global variables
|
|||||||
scope. All parameters are passed by value to the new scope, including lists and other containers, however their
|
scope. All parameters are passed by value to the new scope, including lists and other containers, however their
|
||||||
copy will be shallow.
|
copy will be shallow.
|
||||||
|
|
||||||
The function returns its name as a string, which means it can be used to call it later with the `call` function
|
The function returns itself as a first class object, which means it can be used to call it later with the `call` function
|
||||||
|
|
||||||
Using `_` as the function name creates anonymous function, so each time `_` function is defined, it will be given
|
Using `_` as the function name creates anonymous function, so each time `_` function is defined, it will be given
|
||||||
a unique name, which you can pass somewhere else to get this function `call`ed.
|
a unique name, which you can pass somewhere else to get this function `call`ed. Anonymous functions can only be called
|
||||||
|
by their value and `call` method.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
a(lst) -> lst+=1; list = l(1,2,3); a(list); a(list); list // => [1,2,3]
|
a(lst) -> lst+=1; list = l(1,2,3); a(list); a(list); list // => [1,2,3]
|
||||||
@@ -1294,7 +1294,7 @@ arguments to a tuple which is used by map constructor as a key-value pair:
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
This means that it is not possible to define literally a set of inline function, however a set of functions can still
|
This means that it is not possible to define literally a set of inline function, however a set of functions can still
|
||||||
be created by adding elements to an empty set, and building it this way.
|
be created by adding elements to an empty set, and building it this way. That's a tradeoff for having a cool map initializer.
|
||||||
|
|
||||||
### `outer(arg)`
|
### `outer(arg)`
|
||||||
|
|
||||||
@@ -1319,6 +1319,23 @@ a(lst) -> lst+=1; list = l(1,2,3); list=a(list); list=a(list); list // => [1,2,
|
|||||||
Ability to combine more statements into one expression, with functions, passing parameters, and global and outer
|
Ability to combine more statements into one expression, with functions, passing parameters, and global and outer
|
||||||
scoping allow to organize even larger scripts
|
scoping allow to organize even larger scripts
|
||||||
|
|
||||||
|
### `Operator ...`
|
||||||
|
|
||||||
|
Defines a function argument to represent a variable length argument list of whatever arguments are left
|
||||||
|
from the argument call list, also known as a varargs. There can be only one defined vararg argument in a function signature.
|
||||||
|
Technically, it doesn't matter where is it, but it looks best at the butt side of it.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
foo(a, b, c) -> ... # fixed argument function, call foo(1, 2, 3)
|
||||||
|
foo(a, b, ... c) -> ... # c is now representing the variable argument part
|
||||||
|
foo(1, 2) # a:1, b:2, c:[]
|
||||||
|
foo(1, 2, 3) # a:1, b:2, c:[3]
|
||||||
|
foo(1, 2, 3, 4) # a:1, b:2, c:[3, 4]
|
||||||
|
foo(... x) -> ... # all arguments for foo are included in the list
|
||||||
|
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
### `import(module_name, symbols ...)`
|
### `import(module_name, symbols ...)`
|
||||||
|
|
||||||
Imports symbols from other apps and libraries into the current one: global variables or functions, allowing to use
|
Imports symbols from other apps and libraries into the current one: global variables or functions, allowing to use
|
||||||
@@ -2155,13 +2172,13 @@ structures and features. List of available options and names that you can use de
|
|||||||
with minecraft 1.16.1 and below or 1.16.2 and above since in 1.16.2 Mojang has added JSON support for worldgen features
|
with minecraft 1.16.1 and below or 1.16.2 and above since in 1.16.2 Mojang has added JSON support for worldgen features
|
||||||
meaning that since 1.16.2 - they have official names that can be used by datapacks and scarpet
|
meaning that since 1.16.2 - they have official names that can be used by datapacks and scarpet
|
||||||
|
|
||||||
### Previous Structure Names, including variants (MC 1.16.1 and below)
|
### Previous Structure Names, including variants (as of MC 1.16.3)
|
||||||
* `'monument'`: Ocean Monument. Generates at fixed Y coordinate, surrounds itself with water.
|
* `'monument'`: Ocean Monument. Generates at fixed Y coordinate, surrounds itself with water.
|
||||||
* `'fortress'`: Nether Fortress. Altitude varies, but its bounded by the code.
|
* `'fortress'`: Nether Fortress. Altitude varies, but its bounded by the code.
|
||||||
* `'mansion'`: Woodland Mansion
|
* `'mansion'`: Woodland Mansion
|
||||||
* `'jungle_temple'`: Jungle Temple
|
* `'jungle_temple'`: Jungle Temple
|
||||||
* `'desert_temple'`: Desert Temple. Generates at fixed Y altitude.
|
* `'desert_temple'`: Desert Temple. Generates at fixed Y altitude.
|
||||||
* `'end_city'`: End City with Shulkers
|
* `'endcity'`: End City with Shulkers (in 1.16.1- as `'end_city`)
|
||||||
* `'igloo'`: Igloo
|
* `'igloo'`: Igloo
|
||||||
* `'shipwreck'`: Shipwreck
|
* `'shipwreck'`: Shipwreck
|
||||||
* `'shipwreck2'`: Shipwreck, beached
|
* `'shipwreck2'`: Shipwreck, beached
|
||||||
@@ -2185,7 +2202,7 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
|||||||
* `'bastion_remnant_treasure'`: Treasure room version of a piglin bastion (1.16)
|
* `'bastion_remnant_treasure'`: Treasure room version of a piglin bastion (1.16)
|
||||||
* `'bastion_remnant_bridge'` : Bridge version of a piglin bastion (1.16)
|
* `'bastion_remnant_bridge'` : Bridge version of a piglin bastion (1.16)
|
||||||
|
|
||||||
### Feature Names (mc1.16.1-)
|
### Feature Names (as of mc1.16.1)
|
||||||
|
|
||||||
* `'oak'`
|
* `'oak'`
|
||||||
* `'oak_beehive'`: oak with a hive (1.15+).
|
* `'oak_beehive'`: oak with a hive (1.15+).
|
||||||
@@ -2249,13 +2266,13 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
|||||||
* `'twisting_vines'` (1.16)
|
* `'twisting_vines'` (1.16)
|
||||||
* `'basalt_pillar'` (1.16)
|
* `'basalt_pillar'` (1.16)
|
||||||
|
|
||||||
### Standard Structures (1.16.2+)
|
### Standard Structures (as of 1.16.2+)
|
||||||
|
|
||||||
`'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'endcity'`, `'fortress'`, `'igloo'`,
|
`'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'endcity'`, `'fortress'`, `'igloo'`,
|
||||||
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'monument'`, `'nether_fossil'`, `'ocean_ruin'`,
|
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'monument'`, `'nether_fossil'`, `'ocean_ruin'`,
|
||||||
`'pillager_outpost'`, `'ruined_portal'`, `'shipwreck'`, `'stronghold'`, `'swamp_hut'`, `'village'`
|
`'pillager_outpost'`, `'ruined_portal'`, `'shipwreck'`, `'stronghold'`, `'swamp_hut'`, `'village'`
|
||||||
|
|
||||||
### Structure Variants (1.16.2+)
|
### Structure Variants (as of 1.16.2+)
|
||||||
|
|
||||||
`'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'end_city'`, `'fortress'`, `'igloo'`,
|
`'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'end_city'`, `'fortress'`, `'igloo'`,
|
||||||
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'mineshaft_mesa'`, `'monument'`, `'nether_fossil'`,
|
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'mineshaft_mesa'`, `'monument'`, `'nether_fossil'`,
|
||||||
@@ -2264,7 +2281,7 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
|||||||
`'ruined_portal_swamp'`, `'shipwreck'`, `'shipwreck_beached'`, `'stronghold'`, `'swamp_hut'`,
|
`'ruined_portal_swamp'`, `'shipwreck'`, `'shipwreck_beached'`, `'stronghold'`, `'swamp_hut'`,
|
||||||
`'village_desert'`, `'village_plains'`, `'village_savanna'`, `'village_snovy'`, `'village_taiga'`
|
`'village_desert'`, `'village_plains'`, `'village_savanna'`, `'village_snovy'`, `'village_taiga'`
|
||||||
|
|
||||||
### World Generation Features (1.16.2+)
|
### World Generation Features (as of 1.16.2+)
|
||||||
|
|
||||||
`'acacia'`, `'bamboo'`, `'bamboo_light'`, `'bamboo_vegetation'`, `'basalt_blobs'`, `'basalt_pillar'`,
|
`'acacia'`, `'bamboo'`, `'bamboo_light'`, `'bamboo_vegetation'`, `'basalt_blobs'`, `'basalt_pillar'`,
|
||||||
`'birch'`, `'birch_bees_0002'`, `'birch_bees_002'`, `'birch_bees_005'`, `'birch_other'`, `'birch_tall'`,
|
`'birch'`, `'birch_bees_0002'`, `'birch_bees_002'`, `'birch_bees_005'`, `'birch_other'`, `'birch_tall'`,
|
||||||
@@ -3397,6 +3414,7 @@ __on_player_right_clicks_block(player, item_tuple, hand, block, face, hitvec) /
|
|||||||
__on_player_interacts_with_block(player, hand, block, face, hitvec) //right click on a block resulted in activation of said block
|
__on_player_interacts_with_block(player, hand, block, face, hitvec) //right click on a block resulted in activation of said block
|
||||||
__on_player_places_block(player, item_tuple, hand, block) // player have just placed the block.
|
__on_player_places_block(player, item_tuple, hand, block) // player have just placed the block.
|
||||||
__on_player_interacts_with_entity(player, entity, hand)
|
__on_player_interacts_with_entity(player, entity, hand)
|
||||||
|
__on_player_collides_with_entity(player, entity)
|
||||||
__on_player_chooses_recipe(player, recipe, full_stack)
|
__on_player_chooses_recipe(player, recipe, full_stack)
|
||||||
__on_player_switches_slot(player, from, to)
|
__on_player_switches_slot(player, from, to)
|
||||||
__on_player_swaps_hands(player)
|
__on_player_swaps_hands(player)
|
||||||
|
|||||||
@@ -63,10 +63,11 @@ call creates new scope for variables inside `expr`, so all non-global variables
|
|||||||
scope. All parameters are passed by value to the new scope, including lists and other containers, however their
|
scope. All parameters are passed by value to the new scope, including lists and other containers, however their
|
||||||
copy will be shallow.
|
copy will be shallow.
|
||||||
|
|
||||||
The function returns its name as a string, which means it can be used to call it later with the `call` function
|
The function returns itself as a first class object, which means it can be used to call it later with the `call` function
|
||||||
|
|
||||||
Using `_` as the function name creates anonymous function, so each time `_` function is defined, it will be given
|
Using `_` as the function name creates anonymous function, so each time `_` function is defined, it will be given
|
||||||
a unique name, which you can pass somewhere else to get this function `call`ed.
|
a unique name, which you can pass somewhere else to get this function `call`ed. Anonymous functions can only be called
|
||||||
|
by their value and `call` method.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
a(lst) -> lst+=1; list = l(1,2,3); a(list); a(list); list // => [1,2,3]
|
a(lst) -> lst+=1; list = l(1,2,3); a(list); a(list); list // => [1,2,3]
|
||||||
@@ -83,7 +84,7 @@ arguments to a tuple which is used by map constructor as a key-value pair:
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
This means that it is not possible to define literally a set of inline function, however a set of functions can still
|
This means that it is not possible to define literally a set of inline function, however a set of functions can still
|
||||||
be created by adding elements to an empty set, and building it this way.
|
be created by adding elements to an empty set, and building it this way. That's a tradeoff for having a cool map initializer.
|
||||||
|
|
||||||
### `outer(arg)`
|
### `outer(arg)`
|
||||||
|
|
||||||
@@ -108,6 +109,23 @@ a(lst) -> lst+=1; list = l(1,2,3); list=a(list); list=a(list); list // => [1,2,
|
|||||||
Ability to combine more statements into one expression, with functions, passing parameters, and global and outer
|
Ability to combine more statements into one expression, with functions, passing parameters, and global and outer
|
||||||
scoping allow to organize even larger scripts
|
scoping allow to organize even larger scripts
|
||||||
|
|
||||||
|
### `Operator ...`
|
||||||
|
|
||||||
|
Defines a function argument to represent a variable length argument list of whatever arguments are left
|
||||||
|
from the argument call list, also known as a varargs. There can be only one defined vararg argument in a function signature.
|
||||||
|
Technically, it doesn't matter where is it, but it looks best at the butt side of it.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
foo(a, b, c) -> ... # fixed argument function, call foo(1, 2, 3)
|
||||||
|
foo(a, b, ... c) -> ... # c is now representing the variable argument part
|
||||||
|
foo(1, 2) # a:1, b:2, c:[]
|
||||||
|
foo(1, 2, 3) # a:1, b:2, c:[3]
|
||||||
|
foo(1, 2, 3, 4) # a:1, b:2, c:[3, 4]
|
||||||
|
foo(... x) -> ... # all arguments for foo are included in the list
|
||||||
|
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
### `import(module_name, symbols ...)`
|
### `import(module_name, symbols ...)`
|
||||||
|
|
||||||
Imports symbols from other apps and libraries into the current one: global variables or functions, allowing to use
|
Imports symbols from other apps and libraries into the current one: global variables or functions, allowing to use
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ around built-in function `outer`. It adds the specified value to the function ca
|
|||||||
like capturing lambdas in Java, but unlike java captured variables don't need to be final. Scarpet will just
|
like capturing lambdas in Java, but unlike java captured variables don't need to be final. Scarpet will just
|
||||||
attach their new values at the time of the function definition, even if they change later. Most value will be
|
attach their new values at the time of the function definition, even if they change later. Most value will be
|
||||||
copied, but mutable values, like maps or lists, allow to keep the 'state' with the function, allowing them to
|
copied, but mutable values, like maps or lists, allow to keep the 'state' with the function, allowing them to
|
||||||
have memory and act like objects so to speak. . Check `outer(var)` for details.
|
have memory and act like objects so to speak. Check `outer(var)` for details.
|
||||||
|
|
||||||
## Code delivery, line indicators
|
## Code delivery, line indicators
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ task_completed
|
|||||||
task_count
|
task_count
|
||||||
task_dock
|
task_dock
|
||||||
task_join
|
task_join
|
||||||
|
task_thread
|
||||||
task_value
|
task_value
|
||||||
throw
|
throw
|
||||||
time
|
time
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<Keywords name="Numbers, suffix1"></Keywords>
|
<Keywords name="Numbers, suffix1"></Keywords>
|
||||||
<Keywords name="Numbers, suffix2"></Keywords>
|
<Keywords name="Numbers, suffix2"></Keywords>
|
||||||
<Keywords name="Numbers, range"></Keywords>
|
<Keywords name="Numbers, range"></Keywords>
|
||||||
<Keywords name="Operators1">; + - * / % ^ && || > >= < <= == != = += -> <> ! ~ , :</Keywords>
|
<Keywords name="Operators1">; + - * / % ^ && || > >= < <= == != = += -> <> ! ~ , : ...</Keywords>
|
||||||
<Keywords name="Operators2"></Keywords>
|
<Keywords name="Operators2"></Keywords>
|
||||||
<Keywords name="Folders in code1, open">(</Keywords>
|
<Keywords name="Folders in code1, open">(</Keywords>
|
||||||
<Keywords name="Folders in code1, middle"></Keywords>
|
<Keywords name="Folders in code1, middle"></Keywords>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
print return exit throw try
|
print return exit throw try
|
||||||
|
|
||||||
task task_count task_value task_join task_completed synchronize task_dock
|
task task_thread task_count task_value task_join task_completed synchronize task_dock
|
||||||
|
|
||||||
system_variable_get system_variable_set
|
system_variable_get system_variable_set
|
||||||
|
|
||||||
|
|||||||
@@ -309,7 +309,12 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
if (CarpetServer.scriptServer.stopAll)
|
if (CarpetServer.scriptServer.stopAll)
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
if (argv.size() != fun.getArguments().size())
|
try { // cause we can't throw checked exceptions in lambda. Left if be until need to handle these more gracefully
|
||||||
|
fun.assertArgsOk(argv.size(), (b) -> {
|
||||||
|
throw new InternalExpressionException("");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (InternalExpressionException ignored)
|
||||||
{
|
{
|
||||||
throw new InvalidCallbackException();
|
throw new InvalidCallbackException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ public class Expression
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public FunctionValue addContextFunction(Context context, String name, Expression expr, Tokenizer.Token token, List<String> arguments, List<String> outers, LazyValue code)
|
public FunctionValue addContextFunction(Context context, String name, Expression expr, Tokenizer.Token token, List<String> arguments, String varArgs, List<String> outers, LazyValue code)
|
||||||
{
|
{
|
||||||
if (functions.containsKey(name))
|
if (functions.containsKey(name))
|
||||||
throw new ExpressionException(context, expr, token, "Function "+name+" would mask a built-in function");
|
throw new ExpressionException(context, expr, token, "Function "+name+" would mask a built-in function");
|
||||||
@@ -358,7 +358,7 @@ public class Expression
|
|||||||
}
|
}
|
||||||
if (contextValues.isEmpty()) contextValues = null;
|
if (contextValues.isEmpty()) contextValues = null;
|
||||||
|
|
||||||
FunctionValue result = new FunctionValue(expr, token, name, code, arguments, contextValues);
|
FunctionValue result = new FunctionValue(expr, token, name, code, arguments, varArgs, contextValues);
|
||||||
// do not store lambda definitions
|
// do not store lambda definitions
|
||||||
if (!name.equals("_")) context.host.addUserDefinedFunction(context, module, name, result);
|
if (!name.equals("_")) context.host.addUserDefinedFunction(context, module, name, result);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -691,7 +691,7 @@ public class Auxiliary {
|
|||||||
throw new InternalExpressionException("'schedule' should have at least 2 arguments, delay and call name");
|
throw new InternalExpressionException("'schedule' should have at least 2 arguments, delay and call name");
|
||||||
long delay = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
long delay = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
||||||
|
|
||||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, true);
|
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true);
|
||||||
|
|
||||||
CarpetServer.scriptServer.events.scheduleCall(
|
CarpetServer.scriptServer.events.scheduleCall(
|
||||||
(CarpetContext) c,
|
(CarpetContext) c,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package carpet.script.argument;
|
package carpet.script.argument;
|
||||||
|
|
||||||
import carpet.script.CarpetContext;
|
|
||||||
import carpet.script.Context;
|
import carpet.script.Context;
|
||||||
import carpet.script.LazyValue;
|
import carpet.script.LazyValue;
|
||||||
import carpet.script.bundled.Module;
|
import carpet.script.bundled.Module;
|
||||||
@@ -22,7 +21,7 @@ public class FunctionArgument extends Argument
|
|||||||
this.function = function;
|
this.function = function;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
public static FunctionArgument findIn(Context c, Module module, List<LazyValue> params, int offset, boolean prematureEvaluation, boolean strict)
|
public static FunctionArgument findIn(Context c, Module module, List<LazyValue> params, int offset, boolean prematureEvaluation)
|
||||||
{
|
{
|
||||||
Value functionValue = params.get(offset).evalValue(c);
|
Value functionValue = params.get(offset).evalValue(c);
|
||||||
if (!(functionValue instanceof FunctionValue))
|
if (!(functionValue instanceof FunctionValue))
|
||||||
@@ -33,20 +32,22 @@ public class FunctionArgument extends Argument
|
|||||||
FunctionValue fun = (FunctionValue)functionValue;
|
FunctionValue fun = (FunctionValue)functionValue;
|
||||||
int argsize = fun.getArguments().size();
|
int argsize = fun.getArguments().size();
|
||||||
int extraargs = params.size() - argsize - offset - 1;
|
int extraargs = params.size() - argsize - offset - 1;
|
||||||
if (extraargs < 0 || (extraargs > 0 && strict))
|
if (extraargs < 0)
|
||||||
|
throw new InternalExpressionException("Function "+fun.getPrettyString()+" requires at least "+fun.getArguments().size()+" arguments");
|
||||||
|
if (extraargs > 0 && fun.getVarArgs()==null)
|
||||||
throw new InternalExpressionException("Function "+fun.getPrettyString()+" requires "+fun.getArguments().size()+" arguments");
|
throw new InternalExpressionException("Function "+fun.getPrettyString()+" requires "+fun.getArguments().size()+" arguments");
|
||||||
List<LazyValue> lvargs = new ArrayList<>();
|
List<LazyValue> lvargs = new ArrayList<>();
|
||||||
if (prematureEvaluation)
|
if (prematureEvaluation)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < argsize; i++)
|
for (int i = offset+1, mx = params.size(); i < mx; i++)
|
||||||
{
|
{
|
||||||
Value arg = params.get(offset + 1 + i).evalValue(c);
|
Value arg = params.get(i).evalValue(c);
|
||||||
lvargs.add((cc, tt) -> arg);
|
lvargs.add((cc, tt) -> arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < argsize; i++) lvargs.add(params.get(offset + 1 + i));
|
for (int i = offset+1, mx = params.size(); i < mx; i++) lvargs.add(params.get(i));
|
||||||
}
|
}
|
||||||
return new FunctionArgument(fun, offset+1+argsize, lvargs);
|
return new FunctionArgument(fun, offset+1+argsize, lvargs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import carpet.script.exception.InternalExpressionException;
|
|||||||
import carpet.script.exception.ReturnStatement;
|
import carpet.script.exception.ReturnStatement;
|
||||||
import carpet.script.value.FunctionSignatureValue;
|
import carpet.script.value.FunctionSignatureValue;
|
||||||
import carpet.script.value.FunctionValue;
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.GlobalValue;
|
import carpet.script.value.FunctionAnnotationValue;
|
||||||
import carpet.script.value.ListValue;
|
import carpet.script.value.ListValue;
|
||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
@@ -43,7 +43,7 @@ public class Functions {
|
|||||||
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
|
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
|
||||||
if (t != Context.SIGNATURE) // just call the function
|
if (t != Context.SIGNATURE) // just call the function
|
||||||
{
|
{
|
||||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
|
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false);
|
||||||
FunctionValue fun = functionArgument.function;
|
FunctionValue fun = functionArgument.function;
|
||||||
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), functionArgument.args).evalValue(c);
|
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), functionArgument.args).evalValue(c);
|
||||||
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
|
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
|
||||||
@@ -52,6 +52,7 @@ public class Functions {
|
|||||||
String name = lv.get(0).evalValue(c).getString();
|
String name = lv.get(0).evalValue(c).getString();
|
||||||
List<String> args = new ArrayList<>();
|
List<String> args = new ArrayList<>();
|
||||||
List<String> globals = new ArrayList<>();
|
List<String> globals = new ArrayList<>();
|
||||||
|
String varArgs = null;
|
||||||
for (int i = 1; i < lv.size(); i++)
|
for (int i = 1; i < lv.size(); i++)
|
||||||
{
|
{
|
||||||
Value v = lv.get(i).evalValue(c, Context.LOCALIZATION);
|
Value v = lv.get(i).evalValue(c, Context.LOCALIZATION);
|
||||||
@@ -59,27 +60,44 @@ public class Functions {
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Only variables can be used in function signature, not " + v.getString());
|
throw new InternalExpressionException("Only variables can be used in function signature, not " + v.getString());
|
||||||
}
|
}
|
||||||
if (v instanceof GlobalValue)
|
if (v instanceof FunctionAnnotationValue)
|
||||||
{
|
{
|
||||||
globals.add(v.boundVariable);
|
if (((FunctionAnnotationValue) v).type == 0)
|
||||||
|
{
|
||||||
|
globals.add(v.boundVariable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (varArgs != null)
|
||||||
|
throw new InternalExpressionException("Variable argument identifier is already defined as "+varArgs+", trying to overwrite with "+v.boundVariable);
|
||||||
|
varArgs = v.boundVariable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
args.add(v.boundVariable);
|
args.add(v.boundVariable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value retval = new FunctionSignatureValue(name, args, globals);
|
Value retval = new FunctionSignatureValue(name, args, varArgs, globals);
|
||||||
return (cc, tt) -> retval;
|
return (cc, tt) -> retval;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addLazyFunction("outer", 1, (c, t, lv) -> {
|
expression.addLazyFunction("outer", 1, (c, t, lv) ->
|
||||||
|
{
|
||||||
if (t != Context.LOCALIZATION)
|
if (t != Context.LOCALIZATION)
|
||||||
throw new InternalExpressionException("Outer scoping of variables is only possible in function signatures");
|
throw new InternalExpressionException("Outer scoping of variables is only possible in function signatures");
|
||||||
return (cc, tt) -> new GlobalValue(lv.get(0).evalValue(c));
|
return (cc, tt) -> new FunctionAnnotationValue(lv.get(0).evalValue(c), 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
expression.addLazyUnaryOperator("...", Operators.precedence.get("def->..."), false, (c, t, lv) ->
|
||||||
|
{
|
||||||
|
if (t != Context.LOCALIZATION)
|
||||||
|
throw new InternalExpressionException("Outer scoping of variables is only possible in function signatures");
|
||||||
|
return (cc, tt) -> new FunctionAnnotationValue(lv.evalValue(c), 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
//assigns const procedure to the lhs, returning its previous value
|
//assigns const procedure to the lhs, returning its previous value
|
||||||
expression.addLazyBinaryOperatorWithDelegation("->", Operators.precedence.get("def->"), false, (c, type, e, t, lv1, lv2) ->
|
expression.addLazyBinaryOperatorWithDelegation("->", Operators.precedence.get("def->..."), false, (c, type, e, t, lv1, lv2) ->
|
||||||
{
|
{
|
||||||
if (type == Context.MAPDEF)
|
if (type == Context.MAPDEF)
|
||||||
{
|
{
|
||||||
@@ -90,7 +108,7 @@ public class Functions {
|
|||||||
if (!(v1 instanceof FunctionSignatureValue))
|
if (!(v1 instanceof FunctionSignatureValue))
|
||||||
throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
|
throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
|
||||||
FunctionSignatureValue sign = (FunctionSignatureValue) v1;
|
FunctionSignatureValue sign = (FunctionSignatureValue) v1;
|
||||||
Value result = expression.addContextFunction(c, sign.getName(), e, t, sign.getArgs(), sign.getGlobals(), lv2);
|
Value result = expression.addContextFunction(c, sign.getName(), e, t, sign.getArgs(), sign.getVarArgs(), sign.getGlobals(), lv2);
|
||||||
return (cc, tt) -> result;
|
return (cc, tt) -> result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class Operators {
|
|||||||
put("and&&", 5);
|
put("and&&", 5);
|
||||||
put("or||", 4);
|
put("or||", 4);
|
||||||
put("assign=<>", 3);
|
put("assign=<>", 3);
|
||||||
put("def->", 2);
|
put("def->...", 2);
|
||||||
put("nextop;", 1);
|
put("nextop;", 1);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class Threading
|
|||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.size() == 0)
|
||||||
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
||||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, true, true);
|
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, true);
|
||||||
ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.args);
|
ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.args);
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
return (cc, tt) -> thread;
|
return (cc, tt) -> thread;
|
||||||
@@ -26,7 +26,7 @@ public class Threading
|
|||||||
if (lv.size() < 2)
|
if (lv.size() < 2)
|
||||||
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
||||||
Value queue = lv.get(0).evalValue(c);
|
Value queue = lv.get(0).evalValue(c);
|
||||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, true);
|
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true);
|
||||||
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.args);
|
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.args);
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
return (cc, tt) -> thread;
|
return (cc, tt) -> thread;
|
||||||
|
|||||||
+6
-2
@@ -3,13 +3,17 @@ package carpet.script.value;
|
|||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
public class GlobalValue extends Value
|
public class FunctionAnnotationValue extends Value
|
||||||
{
|
{
|
||||||
public GlobalValue(Value variable)
|
// 0 global
|
||||||
|
// 1 vararg
|
||||||
|
public int type;
|
||||||
|
public FunctionAnnotationValue(Value variable, int type)
|
||||||
{
|
{
|
||||||
if (variable.boundVariable == null)
|
if (variable.boundVariable == null)
|
||||||
throw new InternalExpressionException("You can only borrow variables from the outer scope");
|
throw new InternalExpressionException("You can only borrow variables from the outer scope");
|
||||||
this.boundVariable = variable.boundVariable;
|
this.boundVariable = variable.boundVariable;
|
||||||
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -7,11 +7,13 @@ public class FunctionSignatureValue extends FrameworkValue
|
|||||||
private String identifier;
|
private String identifier;
|
||||||
private List<String> arguments;
|
private List<String> arguments;
|
||||||
private List<String> globals;
|
private List<String> globals;
|
||||||
|
private String varArgs;
|
||||||
|
|
||||||
public FunctionSignatureValue(String name, List<String> args, List<String> globals)
|
public FunctionSignatureValue(String name, List<String> args, String varArgs, List<String> globals)
|
||||||
{
|
{
|
||||||
this.identifier = name;
|
this.identifier = name;
|
||||||
this.arguments = args;
|
this.arguments = args;
|
||||||
|
this.varArgs = varArgs;
|
||||||
this.globals = globals;
|
this.globals = globals;
|
||||||
}
|
}
|
||||||
public String getName()
|
public String getName()
|
||||||
@@ -25,6 +27,5 @@ public class FunctionSignatureValue extends FrameworkValue
|
|||||||
public List<String> getGlobals() {return globals;}
|
public List<String> getGlobals() {return globals;}
|
||||||
|
|
||||||
|
|
||||||
|
public String getVarArgs() { return varArgs;}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,6 @@ import carpet.script.Tokenizer;
|
|||||||
import carpet.script.bundled.Module;
|
import carpet.script.bundled.Module;
|
||||||
import carpet.script.exception.BreakStatement;
|
import carpet.script.exception.BreakStatement;
|
||||||
import carpet.script.exception.ContinueStatement;
|
import carpet.script.exception.ContinueStatement;
|
||||||
import carpet.script.exception.ExitStatement;
|
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.exception.ReturnStatement;
|
import carpet.script.exception.ReturnStatement;
|
||||||
@@ -20,6 +19,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class FunctionValue extends Value implements Fluff.ILazyFunction
|
public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||||
@@ -30,27 +30,30 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
private LazyValue body;
|
private LazyValue body;
|
||||||
private Map<String, LazyValue> outerState;
|
private Map<String, LazyValue> outerState;
|
||||||
private List<String> args;
|
private List<String> args;
|
||||||
|
private String varArgs;
|
||||||
private static long variantCounter = 1;
|
private static long variantCounter = 1;
|
||||||
private long variant;
|
private long variant;
|
||||||
|
|
||||||
private FunctionValue(Expression expression, Tokenizer.Token token, String name, LazyValue body, List<String> args)
|
private FunctionValue(Expression expression, Tokenizer.Token token, String name, LazyValue body, List<String> args, String varArgs)
|
||||||
{
|
{
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
this.varArgs = varArgs;
|
||||||
this.outerState = null;
|
this.outerState = null;
|
||||||
variant = 0L;
|
variant = 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionValue(Expression expression, Tokenizer.Token token, String name, LazyValue body, List<String> args, Map<String, LazyValue> outerState)
|
public FunctionValue(Expression expression, Tokenizer.Token token, String name, LazyValue body, List<String> args, String varArgs, Map<String, LazyValue> outerState)
|
||||||
{
|
{
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
this.varArgs = varArgs;
|
||||||
this.outerState = outerState;
|
this.outerState = outerState;
|
||||||
variant = variantCounter++;
|
variant = variantCounter++;
|
||||||
}
|
}
|
||||||
@@ -84,7 +87,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
@Override
|
@Override
|
||||||
protected Value clone()
|
protected Value clone()
|
||||||
{
|
{
|
||||||
FunctionValue ret = new FunctionValue(expression, token, name, body, args);
|
FunctionValue ret = new FunctionValue(expression, token, name, body, args, varArgs);
|
||||||
ret.outerState = this.outerState;
|
ret.outerState = this.outerState;
|
||||||
ret.variant = this.variant;
|
ret.variant = this.variant;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -146,7 +149,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
@Override
|
@Override
|
||||||
public boolean numParamsVaries()
|
public boolean numParamsVaries()
|
||||||
{
|
{
|
||||||
return false;
|
return varArgs != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LazyValue callInContext(Expression callingExpression, Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
public LazyValue callInContext(Expression callingExpression, Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||||
@@ -175,23 +178,44 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
@Override
|
@Override
|
||||||
public LazyValue lazyEval(Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
public LazyValue lazyEval(Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||||
{
|
{
|
||||||
if (args.size() != lazyParams.size()) // something that might be subject to change in the future
|
assertArgsOk(lazyParams.size(), (fixedArgs) ->{
|
||||||
// in case we add variable arguments
|
if (fixedArgs) // wrong number of args for fixed args
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, e, t,
|
throw new ExpressionException(c, e, t,
|
||||||
"Incorrect number of arguments for function "+name+
|
"Incorrect number of arguments for function "+name+
|
||||||
". Should be "+args.size()+", not "+lazyParams.size()+" like "+args
|
". Should be "+args.size()+", not "+lazyParams.size()+" like "+args
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else // too few args for varargs
|
||||||
|
{
|
||||||
|
List<String> argList = new ArrayList<>(args);
|
||||||
|
argList.add("... "+varArgs);
|
||||||
|
throw new ExpressionException(c, e, t,
|
||||||
|
"Incorrect number of arguments for function "+name+
|
||||||
|
". Should be at least "+args.size()+", not "+lazyParams.size()+" like "+argList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
Context newFrame = c.recreate();
|
Context newFrame = c.recreate();
|
||||||
|
|
||||||
if (outerState != null) outerState.forEach(newFrame::setVariable);
|
if (outerState != null) outerState.forEach(newFrame::setVariable);
|
||||||
for (int i=0; i<args.size(); i++)
|
for (int i=0; i<args.size(); i++)
|
||||||
{
|
{
|
||||||
String arg = args.get(i);
|
String arg = args.get(i);
|
||||||
Value val = lazyParams.get(i).evalValue(c).reboundedTo(arg);
|
Value val = lazyParams.get(i).evalValue(c).reboundedTo(arg); // todo check if we need to copy that
|
||||||
newFrame.setVariable(arg, (cc, tt) -> val);
|
newFrame.setVariable(arg, (cc, tt) -> val);
|
||||||
}
|
}
|
||||||
|
if (varArgs != null)
|
||||||
|
{
|
||||||
|
List<Value> extraParams = new ArrayList<>();
|
||||||
|
for (int i = args.size(), mx = lazyParams.size(); i < mx; i++)
|
||||||
|
{
|
||||||
|
extraParams.add(lazyParams.get(i).evalValue(c).reboundedTo(null)); // copy by value I guess
|
||||||
|
}
|
||||||
|
Value rest = ListValue.wrap(extraParams).bindTo(varArgs); // didn't we just copied that?
|
||||||
|
newFrame.setVariable(varArgs, (cc, tt) -> rest);
|
||||||
|
|
||||||
|
}
|
||||||
Value retVal;
|
Value retVal;
|
||||||
boolean rethrow = false;
|
boolean rethrow = false;
|
||||||
try
|
try
|
||||||
@@ -211,10 +235,6 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
retVal = throwStatement.retval;
|
retVal = throwStatement.retval;
|
||||||
rethrow = true;
|
rethrow = true;
|
||||||
}
|
}
|
||||||
//catch (ArithmeticException | ExitStatement | ExpressionException | InternalExpressionException exc )
|
|
||||||
//{
|
|
||||||
// throw exc; // rethrow so could be contextualized if needed
|
|
||||||
//}
|
|
||||||
if (rethrow)
|
if (rethrow)
|
||||||
{
|
{
|
||||||
throw new ThrowStatement(retVal);
|
throw new ThrowStatement(retVal);
|
||||||
@@ -235,6 +255,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
{
|
{
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
public String getVarArgs() {return varArgs; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(boolean force)
|
public Tag toTag(boolean force)
|
||||||
@@ -242,4 +263,17 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
if (!force) throw new NBTSerializableValue.IncompatibleTypeException(this);
|
if (!force) throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||||
return StringTag.of(getString());
|
return StringTag.of(getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void assertArgsOk(int size, Consumer<Boolean> feedback)
|
||||||
|
{
|
||||||
|
if (varArgs == null && args.size() != size) // wrong number of args for fixed args
|
||||||
|
{
|
||||||
|
feedback.accept(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (varArgs != null && args.size() > size) // too few args for varargs
|
||||||
|
{
|
||||||
|
feedback.accept(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user