diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index bad1c53a..ceff1040 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -1664,6 +1664,8 @@ public class CarpetExpression *

Removes tag from entity.

*

modify(e, 'talk')

*

Make noises.

+ *

modify(e, 'ai', boolean)

+ *

If called with false value, it will disable AI in the mob. true will enable it again.

*

modify(e, 'home', null), modify(e, 'home', block, distance?), modify(e, 'home', x, y, z, distance?)

*

Sets AI to stay around the home position, within distance blocks from it. distance * defaults to 16 blocks. null removes it. May not work fully with mobs that have this AI built in, like diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 135d8bc0..8bd840c9 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -839,8 +839,7 @@ public class Expression implements Cloneable *

To effectively write programs that have more than one line, a programmer needs way to specify a sequence of * commands that execute one after another. In scarpet this can be achieved with ;. Its an operator, * and by separating statements with semicolons. And since whitespaces and $ signs are all treats as - * whitespaces, how you layout your code doesn't matter, as long as it is readable to everyone involved. The - * usefulness of preceding all the lines of the script with $ is explained in the preamble

+ * whitespaces, how you layout your code doesn't matter, as long as it is readable to everyone involved.

*
      * expr;
      * expr;
@@ -848,22 +847,22 @@ public class Expression implements Cloneable
      * expr
      * 
*

Notice that the last expression is not followed by a semicolon. Since instruction separation is functional - * in scarpet, and not barely an instruction delimiter, - * terminating the code with a dangling operator wouldn't be valid.

+ * in scarpet, and not barely an instruction delimiter, terminating the code with a dangling operator + * wouldn't be valid. Having said that, since many programming languages don't care about the number of op terminators + * programmers use, carpet preprocessor will remove all unnecessary semicolons from scripts when compiled.

*

In general expr; expr; expr; expr is equivalent to - * (((expr ; expr) ; expr) ; expr). In case the programmer forgets that it should be warned with a - * helpful error at compile time.

+ * (((expr ; expr) ; expr) ; expr).

*

Result of the evaluated expression is the same as the result of the second expression, but first expression is * also evaluated for sideeffects

*
      * expr1 ; expr2 => expr2  // with expr1 as a sideeffect
      * 
+ *

Global variables

*

All defined functions are compiled, stored persistently, and available globally - * accessible to all other scripts. Functions can only be undefined via call to undef('fun'), which * would erase global entry for function fun. Since all variables have local scope inside each function, * one way to share large objects is via global variables *

- *

Global variables

*

Any variable that is used with a name that starts with 'global_' will be stored and accessible globally, * not, inside current scope. It will also persist across scripts, so if a procedure needs to use its own construct, it needs to * define it, or initialize it explicitly, or undefine it via undef

@@ -907,6 +906,23 @@ public class Expression implements Cloneable * *

Ability to combine more statements into one expression, with functions, passing parameters, and global and outer * scoping allow to organize even larger scripts

+ *

call(function, args.....)

+ *

calls a user defined function with specified arguments. It is equivalent to calling function(args...) + * directly except you can use it with function name instead. This means you can pass functions to other user defined + * functions as arguments and call them with call internally. And since function definitions return the + * defined function name, they can be defined in place

+ *

Little technical note: the use of _ in expression passed to built in functions is much more efficient due to + * not creating new call stacks for each invoked function, but anonymous functions is the only mechanism available + * for programmers with their own lambda arguments

+ *
+     * my_map(list, function) -> map(list, call(function, _));
+     * my_map(l(1,2,3), _(x) -> x*x);    // => [1,4,9]
+     *
+     * profile_expr(my_map(l(1,2,3), _(x) -> x*x));   // => ~32000
+     * sq(x) -> x*x; profile_expr(my_map(l(1,2,3),'sq'));   // => ~38000
+     * profile_expr(map(l(1,2,3), _*_));   // => ~80000
+     *
+     * 
*

Control flow

*

return(expr?)

*

Sometimes its convenient to break the organized control flow, or it is not practical to pass @@ -2648,6 +2664,14 @@ public class Expression implements Cloneable * title('aBc') => 'Abc' * * + *

replace(string, regex, repl?); replace_first(string, regex, repl?)

+ *

Replaces all, or first occurence of a regular expression in the string with repl expression, or + * nothing, if not specified

+ *
+     * replace('abbccddebfg','b+','z')  // => azccddezfg
+     * replace_first('abbccddebfg','b+','z')  // => azccddebfg
+     * 
+ * *

length(expr)

*

Returns length of the expression, the length of the string, * the length of the integer part of the number, or length of the list