Skip to content

Commit

Permalink
set add union and intersection + allow v1-3
Browse files Browse the repository at this point in the history
  • Loading branch information
5pilow committed Sep 5, 2023
1 parent 296fbff commit 8ec9f48
Show file tree
Hide file tree
Showing 20 changed files with 514 additions and 339 deletions.
7 changes: 7 additions & 0 deletions src/main/java/leekscript/common/SetType.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package leekscript.common;

import leekscript.compiler.JavaWriter;

public class SetType extends Type {

private Type type;
Expand Down Expand Up @@ -46,4 +48,9 @@ public boolean equals(Object object) {
}
return false;
}

@Override
public String getDefaultValue(JavaWriter writer, int version) {
return "new SetLeekValue(" + writer.getAIThis() + ")";
}
}
13 changes: 6 additions & 7 deletions src/main/java/leekscript/compiler/JavaWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@ public void writeGenericFunctions(MainLeekBlock block) {

for (var entry : genericFunctions.entrySet()) {


var signature = entry.getKey();
var versions = entry.getValue();
var first_version = versions.get(0);
Expand All @@ -321,7 +320,7 @@ public void writeGenericFunctions(MainLeekBlock block) {
addCode("if (");
for (int a = 0; a < other_version.arguments.length; ++a) {
if (a > 0) addCode(" && ");
addCode("a" + a + " instanceof " + other_version.arguments[a].getJavaName(block.getVersion()));
addCode("a" + a + " instanceof " + other_version.arguments[a].getJavaName(block.getVersion()) + " x" + a);
}
addLine(") {");
writeFunctionCall(block, other_version, true);
Expand All @@ -342,14 +341,14 @@ public void writeGenericFunctions(MainLeekBlock block) {
}

private void writeFunctionCall(MainLeekBlock block, CallableVersion version, boolean cast) {
var function_name = version.function.getName();
if ((version.return_type.isArray() || version.return_type.isArrayOrNull()) && block.getVersion() <= 3) {
function_name += "_v1_3";
}
if (version.function.isStatic()) {
var function_name = version.function.getName();
if ((version.return_type.isArray() || version.return_type.isArrayOrNull()) && block.getVersion() <= 3) {
function_name += "_v1_3";
}
addCode("return " + version.function.getStandardClass() + "Class." + function_name + "(");
} else {
addCode("return x0." + version.function.getName() + "(");
addCode("return x0." + function_name + "(");
}
ArrayList<String> args = new ArrayList<>();
args.add("this");
Expand Down
58 changes: 39 additions & 19 deletions src/main/java/leekscript/compiler/WordCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,7 @@ public Expression readExpression(boolean inList, boolean inSet, boolean inInterv
retour.addExpression(new LeekString(word, word.getWord()));

} else if (word.getType() == TokenType.BRACKET_LEFT) {

retour.addExpression(readArrayOrMapOrInterval(mTokens.eat()));

} else if (word.getType() == TokenType.BRACKET_RIGHT) {
Expand All @@ -1565,7 +1566,8 @@ public Expression readExpression(boolean inList, boolean inSet, boolean inInterv
retour.addExpression(readInterval(token, expression));
}

} else if (getVersion() >= 4 && word.getType() == TokenType.OPERATOR && word.getWord().equals("<")) {
} else if (word.getType() == TokenType.OPERATOR && word.getWord().equals("<")) {

retour.addExpression(readSet(mTokens.eat()));

} else if (getVersion() >= 2 && word.getType() == TokenType.ACCOLADE_LEFT) {
Expand Down Expand Up @@ -1708,9 +1710,6 @@ private Expression readSet(Token openingToken) throws LeekCompilerException {
}

private Expression readArrayOrMapOrInterval(Token openingBracket) throws LeekCompilerException {
if (version < 4) {
return readLegacyArray(openingBracket);
}

// Empty map `[:]`
if (mTokens.get().getWord().equals(":")) {
Expand All @@ -1720,18 +1719,32 @@ private Expression readArrayOrMapOrInterval(Token openingBracket) throws LeekCom
throw new LeekCompilerException(mTokens.get(), Error.PARENTHESIS_EXPECTED_AFTER_PARAMETERS);
}

var container = new LeekMap(openingBracket);
container.setClosingBracket(mTokens.get());
return container;
if (version >= 4) {
var container = new LeekMap(openingBracket);
container.setClosingBracket(mTokens.get());
return container;
} else {
var container = new LegacyLeekArray(openingBracket);
container.mIsKeyVal = true;
container.setClosingBracket(mTokens.get());
return container;
}
}

// Empty array `[]`
if (mTokens.get().getType() == TokenType.BRACKET_RIGHT) {
var container = new LeekArray(openingBracket);
container.setClosingBracket(mTokens.get());
return container;
if (version >= 4) {
var container = new LeekArray(openingBracket);
container.setClosingBracket(mTokens.get());
return container;
} else {
var container = new LegacyLeekArray(openingBracket);
container.setClosingBracket(mTokens.get());
return container;
}
}

// Empty interval [..]
if (mTokens.get().getType() == TokenType.DOT_DOT) {
mTokens.skip();
return readInterval(openingBracket, null);
Expand All @@ -1740,12 +1753,20 @@ private Expression readArrayOrMapOrInterval(Token openingBracket) throws LeekCom
var firstExpression = readExpression(true);
if (mTokens.get().getWord().equals(":")) {
mTokens.skip();
return readMap(openingBracket, firstExpression);
} else if (version >= 4 && mTokens.get().getType() == TokenType.DOT_DOT) {
if (version >= 4) {
return readMap(openingBracket, firstExpression);
} else {
return readLegacyArray(openingBracket, firstExpression, true);
}
} else if (mTokens.get().getType() == TokenType.DOT_DOT) {
mTokens.skip();
return readInterval(openingBracket, firstExpression);
} else {
return readArray(openingBracket, firstExpression);
if (version >= 4) {
return readArray(openingBracket, firstExpression);
} else {
return readLegacyArray(openingBracket, firstExpression, false);
}
}
}

Expand Down Expand Up @@ -1807,10 +1828,11 @@ private Expression readArray(Token openingBracket, Expression firstExpression) t
return container;
}

private Expression readLegacyArray(Token openingBracket) throws LeekCompilerException {
private Expression readLegacyArray(Token openingBracket, Expression firstExpression, boolean isKeyVal) throws LeekCompilerException {

var container = new LegacyLeekArray(openingBracket);

// Empty map `[:]`
// Empty array `[:]`
if (mTokens.get().getWord().equals(":")) {
container.mIsKeyVal = true;
container.type = Type.MAP;
Expand All @@ -1825,15 +1847,12 @@ private Expression readLegacyArray(Token openingBracket) throws LeekCompilerExce

// Empty array `[]`
if (mTokens.get().getType() == TokenType.BRACKET_RIGHT) {
container.addValue(firstExpression);
container.setClosingBracket(mTokens.get());
return container;
}

var firstExpression = readExpression(true);
boolean isKeyVal = mTokens.get().getWord().equals(":");

if (isKeyVal) {
mTokens.skip();
var secondExpression = readExpression(true);
container.addValue(this, firstExpression, secondExpression);
} else {
Expand Down Expand Up @@ -1874,6 +1893,7 @@ private Expression readLegacyArray(Token openingBracket) throws LeekCompilerExce
}

private Expression readInterval(Token openingBracket, Expression fromExpression) throws LeekCompilerException {

if (mTokens.get().getType() == TokenType.BRACKET_RIGHT || mTokens.get().getType() == TokenType.BRACKET_LEFT) {
return new LeekInterval(openingBracket, fromExpression, null, mTokens.get());
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/leekscript/compiler/bloc/MainLeekBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ public MainLeekBlock(IACompiler compiler, WordCompiler wordCompiler, AIFile ai)
addClass(new ClassDeclarationInstruction(new Token("Array"), 0, ai, true, this, Type.ARRAY));
if (ai.getVersion() >= 4) {
addClass(new ClassDeclarationInstruction(new Token("Map"), 0, ai, true, this, Type.MAP));
addClass(new ClassDeclarationInstruction(new Token("Interval"), 0, ai, true, this, Type.INTERVAL));
addClass(new ClassDeclarationInstruction(new Token("Set"), 0, ai, true, this, Type.SET));
}
addClass(new ClassDeclarationInstruction(new Token("Interval"), 0, ai, true, this, Type.INTERVAL));
addClass(new ClassDeclarationInstruction(new Token("Set"), 0, ai, true, this, Type.SET));
addClass(new ClassDeclarationInstruction(new Token("String"), 0, ai, true, this, Type.STRING));
var objectClass = new ClassDeclarationInstruction(new Token("Object"), 0, ai, true, this, Type.OBJECT);
objectClass.addMethod(wordCompiler, new Token("keys"), new ClassMethodBlock(objectClass, false, false, wordCompiler.getCurrentBlock(), this, new Token("keys"), Type.ARRAY), AccessLevel.PUBLIC);
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/leekscript/compiler/expression/LeekExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import leekscript.compiler.exceptions.LeekCompilerException;
import leekscript.compiler.expression.LeekVariable.VariableType;
import leekscript.runner.values.LeekValue;
import leekscript.runner.values.LeekValueType;
import leekscript.common.ArrayType;
import leekscript.common.ClassValueType;
import leekscript.common.CompoundType;
Expand Down Expand Up @@ -1161,17 +1162,17 @@ else if (mOperator == Operators.AS) {
/////////////
operations = (mExpression1 != null ? mExpression1.getOperations() : 0) + (mExpression2 != null ? mExpression2.getOperations() : 0);
if (mOperator == Operators.POWER) {
operations += LeekValue.POW_COST;
operations += LeekValueType.POW_COST;
} else if (mOperator == Operators.POWERASSIGN) {
operations += LeekValue.POW_COST;
operations += LeekValueType.POW_COST;
} else if (mOperator == Operators.MULTIPLIE) {
operations += LeekValue.MUL_COST;
operations += LeekValueType.MUL_COST;
} else if (mOperator == Operators.MULTIPLIEASSIGN) {
operations += LeekValue.MUL_COST; //+ 1;
operations += LeekValueType.MUL_COST; //+ 1;
} else if (mOperator == Operators.DIVIDE || mOperator == Operators.DIVIDEASSIGN || mOperator == Operators.INTEGER_DIVISION || mOperator == Operators.INTEGER_DIVISION_EQ) {
operations += LeekValue.DIV_COST;
operations += LeekValueType.DIV_COST;
} else if (mOperator == Operators.MODULUS || mOperator == Operators.MODULUSASSIGN) {
operations += LeekValue.MOD_COST;
operations += LeekValueType.MOD_COST;
} else if (mOperator == Operators.REFERENCE || mOperator == Operators.NEW) {
// 0
} else if (mOperator == Operators.AND || mOperator == Operators.OR) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public void compileL(MainLeekBlock mainblock, JavaWriter writer) {
writer.addCode(".execute(");
addComma = false;
} else if (mExpression instanceof LeekVariable && ((LeekVariable) mExpression).getVariableType() == VariableType.SYSTEM_FUNCTION) {
if ((unsafe && callable_versions.size() > 1) || mainblock.getVersion() <= 3) {
if (unsafe || mainblock.getVersion() <= 3) {
if (callable_versions != null) {
var key = writer.generateGenericFunction(callable_versions);
writer.addCode(system_function.getStandardClass() + "_" + key + "(");
Expand Down Expand Up @@ -682,6 +682,7 @@ public void verifyVersions(WordCompiler compiler, CallableVersion[] versions) th
else if (cast_type == CastType.UNSAFE_DOWNCAST) distance += 1000;
else if (cast_type == CastType.INCOMPATIBLE) distance += 10000;
}
if (distance > 1000) distance = 1000;
// System.out.println("version = " + version + " distance = " + distance);
if (distance == best_distance) {
best_versions.add(version);
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/leekscript/runner/AI.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import leekscript.runner.values.RealIntervalLeekValue;
import leekscript.runner.values.SetLeekValue;
import leekscript.runner.values.LeekValue;
import leekscript.runner.values.LeekValueType;
import leekscript.runner.values.ObjectLeekValue;
import leekscript.runner.values.Box;
import leekscript.common.AccessLevel;
Expand Down Expand Up @@ -523,6 +524,7 @@ public LeekError throwableToError(Throwable throwable) {
}
} else {
// Erreur inconnue
throwable.printStackTrace(System.out);
error.parameters = throwable == null ? null : new Object[] { throwable.toString() };
}
return error;
Expand Down Expand Up @@ -1399,6 +1401,8 @@ public String export(Object value) throws LeekRunException {
return ((ArrayLeekValue) value).string(this, new HashSet<Object>());
} else if (value instanceof MapLeekValue) {
return ((MapLeekValue) value).string(this, new HashSet<Object>());
} else if (value instanceof SetLeekValue set) {
return set.string(this, new HashSet<Object>());
} else if (value instanceof IntervalLeekValue interval) {
return interval.string(this, new HashSet<Object>());
} else if (value instanceof String) {
Expand Down Expand Up @@ -2890,7 +2894,7 @@ public boolean check(String functionName, int[] types, Object... arguments) thro
if (verifyParameters(types, arguments)) {
return true;
}
String ret = LeekValue.getParamString(arguments);
String ret = LeekValueType.getParamString(arguments);
addSystemLog(AILog.ERROR, Error.UNKNOWN_FUNCTION, new String[] { functionName + "(" + ret + ")" });
return false;
}
Expand Down
38 changes: 20 additions & 18 deletions src/main/java/leekscript/runner/LeekFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,53 +235,55 @@ public class LeekFunctions {
/**
* Set functions
*/
method("setPut", "Set", 3, Type.ANY, new Type[] { Type.SET, Type.ANY }).setMinVersion(4);
method("setRemove", "Set", 2, Type.ANY, new Type[] { Type.SET, Type.ANY }).setMinVersion(4);
method("setClear", "Set", 1, Type.SET, new Type[] { Type.SET }).setMinVersion(4);
method("setContains", "Set", 2, Type.BOOL, new Type[] { Type.SET, Type.ANY }).setMinVersion(4);
method("setSize", "Set", 1, Type.INT, new Type[] { Type.SET }).setMinVersion(4);
method("setIsEmpty", "Set", 2, Type.BOOL, new Type[] { Type.SET }).setMinVersion(4);
method("setIsSubsetOf", "Set", Type.BOOL, new Type[] { Type.SET, Type.SET }).setMinVersion(4);
method("setPut", "Set", 3, Type.ANY, new Type[] { Type.SET, Type.ANY });
method("setRemove", "Set", 2, Type.ANY, new Type[] { Type.SET, Type.ANY });
method("setClear", "Set", 1, Type.SET, new Type[] { Type.SET });
method("setContains", "Set", 2, Type.BOOL, new Type[] { Type.SET, Type.ANY });
method("setSize", "Set", 1, Type.INT, new Type[] { Type.SET });
method("setIsEmpty", "Set", 2, Type.BOOL, new Type[] { Type.SET });
method("setIsSubsetOf", "Set", Type.BOOL, new Type[] { Type.SET, Type.SET });
method("setUnion", "Set", Type.SET, new Type[] { Type.SET, Type.SET });
method("setIntersection", "Set", Type.SET, new Type[] { Type.SET, Type.SET });

/**
* Interval functions
*/
method("intervalMin", "Interval", 1, new CallableVersion[] {
new CallableVersion(Type.REAL, new Type[] { Type.REAL_INTERVAL}),
new CallableVersion(Type.INT, new Type[] { Type.INTEGER_INTERVAL }),
}).setMinVersion(4);
});
method("intervalMax", "Interval", 1, new CallableVersion[] {
new CallableVersion(Type.REAL, new Type[] { Type.REAL_INTERVAL}),
new CallableVersion(Type.INT, new Type[] { Type.INTEGER_INTERVAL }),
}).setMinVersion(4);
});
method("intervalSize", "Interval", 1, new CallableVersion[] {
new CallableVersion(Type.REAL, new Type[] { Type.REAL_INTERVAL}),
new CallableVersion(Type.INT, new Type[] { Type.INTEGER_INTERVAL }),
}).setMinVersion(4);
method("intervalIsEmpty", "Interval", 1, Type.BOOL, new Type[] { Type.INTERVAL }).setMinVersion(4);
method("intervalIsBounded", "Interval", 1, Type.BOOL, new Type[] { Type.INTERVAL }).setMinVersion(4);
method("intervalIsRightBounded", "Interval", 1, Type.BOOL, new Type[] { Type.INTERVAL }).setMinVersion(4);
method("intervalIsLeftBounded", "Interval", 1, Type.BOOL, new Type[] { Type.INTERVAL }).setMinVersion(4);
method("intervalAverage", "Interval", 3, Type.REAL, new Type[] { Type.INTERVAL }).setMinVersion(4);
});
method("intervalIsEmpty", "Interval", 1, Type.BOOL, new Type[] { Type.INTERVAL });
method("intervalIsBounded", "Interval", 1, Type.BOOL, new Type[] { Type.INTERVAL });
method("intervalIsRightBounded", "Interval", 1, Type.BOOL, new Type[] { Type.INTERVAL });
method("intervalIsLeftBounded", "Interval", 1, Type.BOOL, new Type[] { Type.INTERVAL });
method("intervalAverage", "Interval", 3, Type.REAL, new Type[] { Type.INTERVAL });
method("intervalIntersection", "Interval", 3, new CallableVersion[] {
new CallableVersion(Type.REAL_INTERVAL, new Type[] { Type.REAL_INTERVAL, Type.REAL_INTERVAL }),
new CallableVersion(Type.REAL_INTERVAL, new Type[] { Type.INTEGER_INTERVAL, Type.REAL_INTERVAL }),
new CallableVersion(Type.REAL_INTERVAL, new Type[] { Type.REAL_INTERVAL, Type.INTEGER_INTERVAL }),
new CallableVersion(Type.INTEGER_INTERVAL, new Type[] { Type.INTEGER_INTERVAL, Type.INTEGER_INTERVAL }),
}).setMinVersion(4);
});
method("intervalCombine", "Interval", 3, new CallableVersion[] {
new CallableVersion(Type.REAL_INTERVAL, new Type[] { Type.REAL_INTERVAL, Type.REAL_INTERVAL }),
new CallableVersion(Type.REAL_INTERVAL, new Type[] { Type.INTEGER_INTERVAL, Type.REAL_INTERVAL }),
new CallableVersion(Type.REAL_INTERVAL, new Type[] { Type.REAL_INTERVAL, Type.INTEGER_INTERVAL }),
new CallableVersion(Type.INTEGER_INTERVAL, new Type[] { Type.INTEGER_INTERVAL, Type.INTEGER_INTERVAL }),
}).setMinVersion(4);
});
method("intervalToArray", "Interval", new CallableVersion[] {
new CallableVersion(Type.ARRAY_REAL, new Type[] { Type.REAL_INTERVAL, Type.REAL }),
new CallableVersion(Type.ARRAY_REAL, new Type[] { Type.REAL_INTERVAL}),
new CallableVersion(Type.ARRAY_REAL, new Type[] { Type.INTEGER_INTERVAL, Type.REAL }),
new CallableVersion(Type.ARRAY_INT, new Type[] { Type.INTEGER_INTERVAL, Type.INT }),
new CallableVersion(Type.ARRAY_INT, new Type[] { Type.INTEGER_INTERVAL}),
}).setMinVersion(4);
});

/**
* JSON functions
Expand Down

0 comments on commit 8ec9f48

Please sign in to comment.