Skip to content

Commit

Permalink
Add equals_epsilon and array_clear
Browse files Browse the repository at this point in the history
  • Loading branch information
LadyCailin committed Feb 1, 2024
1 parent a1e83c8 commit e922b1b
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 3 deletions.
64 changes: 64 additions & 0 deletions src/main/java/com/laytonsmith/core/functions/ArrayHandling.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import com.laytonsmith.core.Script;
import com.laytonsmith.core.compiler.FileOptions;
import com.laytonsmith.core.compiler.analysis.StaticAnalysis;
import com.laytonsmith.core.compiler.signature.FunctionSignatures;
import com.laytonsmith.core.compiler.signature.SignatureBuilder;
import com.laytonsmith.core.constructs.CArray;
import com.laytonsmith.core.constructs.CBoolean;
import com.laytonsmith.core.constructs.CClassType;
Expand Down Expand Up @@ -3845,4 +3847,66 @@ public String docs() {
+ " for easy chaining.";
}
}

@api
public static class array_clear extends AbstractFunction {

@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CRECastException.class};
}

@Override
public boolean isRestricted() {
return false;
}

@Override
public Boolean runAsync() {
return null;
}

@Override
public Mixed exec(Target t, Environment env, Mixed... args) throws ConfigRuntimeException {
ArgumentValidation.getArray(args[0], t).clear();
return CVoid.VOID;
}

@Override
public String getName() {
return "array_clear";
}

@Override
public Integer[] numArgs() {
return new Integer[]{1};
}

@Override
public String docs() {
return "void {array} Clears the array of all values. This keeps the array reference the same, but"
+ " empties it. Both normal and associative arrays are supported, but the internal type (normal"
+ " or associative) is not reset.";
}

@Override
public Version since() {
return MSVersion.V3_3_5;
}

@Override
public FunctionSignatures getSignatures() {
return new SignatureBuilder(CVoid.TYPE)
.param(CArray.TYPE, "array", "The array to clear.")
.build();
}

@Override
public ExampleScript[] examples() throws ConfigCompileException {
return new ExampleScript[]{
new ExampleScript("Basic usage", "@array = array(1, 2, 3);\narray_clear(@array);\nmsg(@array);"),
new ExampleScript("Associative arrays", "@array = array(one: 1, two: 2, three: 3);\narray_clear(@array);\nmsg(@array);"),
};
}
}
}
98 changes: 95 additions & 3 deletions src/main/java/com/laytonsmith/core/functions/BasicLogic.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.laytonsmith.core.constructs.CArray;
import com.laytonsmith.core.constructs.CBoolean;
import com.laytonsmith.core.constructs.CClassType;
import com.laytonsmith.core.constructs.CDouble;
import com.laytonsmith.core.constructs.CFunction;
import com.laytonsmith.core.constructs.CInt;
import com.laytonsmith.core.constructs.CNull;
Expand Down Expand Up @@ -149,7 +150,7 @@ public CBoolean exec(Target t, Environment env, Mixed... args) throws CancelComm
}
}
return CBoolean.TRUE;
} catch (ConfigRuntimeException e) {
} catch(ConfigRuntimeException e) {
return CBoolean.FALSE;
}
}
Expand Down Expand Up @@ -525,7 +526,7 @@ public CBoolean exec(Target t, Environment env, Mixed... args) throws ConfigRunt
}
}
return CBoolean.TRUE;
} catch (ConfigRuntimeException e) {
} catch(ConfigRuntimeException e) {
return CBoolean.FALSE;
}
}
Expand Down Expand Up @@ -2674,7 +2675,7 @@ public Version since() {

@Override
public ExampleScript[] examples() throws ConfigCompileException {
return new ExampleScript[] {
return new ExampleScript[]{
new ExampleScript("", "hash(1);"),
new ExampleScript("", "hash(2);"),
new ExampleScript("", "hash(3);"),
Expand All @@ -2685,4 +2686,95 @@ public ExampleScript[] examples() throws ConfigCompileException {

}

@api
public static class equals_epsilon extends AbstractFunction implements Optimizable {

@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CRECastException.class};
}

@Override
public boolean isRestricted() {
return false;
}

@Override
public Boolean runAsync() {
return null;
}

@Override
public Mixed exec(Target t, Environment env, Mixed... args) throws ConfigRuntimeException {
double d1 = ArgumentValidation.getDouble(args[0], t);
double d2 = ArgumentValidation.getDouble(args[1], t);
double epsilon = ArgumentValidation.getDouble(args[2], t);
return CBoolean.get(java.lang.Math.abs(d1 - d2) < epsilon);
}

@Override
public String getName() {
return "equals_epsilon";
}

@Override
public Integer[] numArgs() {
return new Integer[]{3};
}

@Override
public String docs() {
return "boolean {double d1, double d2, double epsilon}"
+ " When comparing the equality of floating point numbers, it is often impossible to directly"
+ " compare via == (equals) since two floating point numbers that might be actually semantically"
+ " equivalent, are represented slightly differently in the computer, thus making them not actually"
+ " equal, even though they are effectively equal. This function provides an epsilon argument to"
+ " verify if two numbers are within that degree of difference. A good rule of thumb is"
+ " to use 5-6 places of precision, but depending on your program's needs, more or less might be"
+ " required.";
}

@Override
public Version since() {
return MSVersion.V3_3_5;
}

@Override
public FunctionSignatures getSignatures() {
return new SignatureBuilder(CBoolean.TYPE)
.param(CDouble.TYPE, "d1", "The first double to compare.")
.param(CDouble.TYPE, "d2", "The second double to compare.")
.param(CDouble.TYPE, "epsilon",
"The degree of difference to use to determine equality, for instance 0.00001")
.build();
}

@Override
public ExampleScript[] examples() throws ConfigCompileException {
return new ExampleScript[]{
new ExampleScript("Demonstrates why equals doesn't always work", """
@d1 = 0.8;
@d2 = 0;
for(@i = 0, @i < 8, @i++) {
@d2 += 0.1;
}
msg(@d1);
msg(@d2);
msg(@d1 == @d2);"""),
new ExampleScript("Same example, this time with a precision.", """
@d1 = 0.8;
@d2 = 0;
for(@i = 0, @i < 8, @i++) {
@d2 += 0.1;
}
msg(@d1);
msg(@d2);
msg(equals_epsilon(@d1, @d2, 0.0001));"""),};
}

@Override
public Set<OptimizationOption> optimizationOptions() {
return EnumSet.of(OptimizationOption.NO_SIDE_EFFECTS, OptimizationOption.CONSTANT_OFFLINE);
}
}
}

0 comments on commit e922b1b

Please sign in to comment.