Avoid using methods which are not available on TeaVM
This commit is contained in:
parent
d4b91c4d4f
commit
fef30042ce
@ -181,11 +181,11 @@ public class LineMap {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", "Line{", "}")
|
||||
.add("number=" + number)
|
||||
.add("startPosition=" + startPosition)
|
||||
.add("text='" + text + "'")
|
||||
.toString();
|
||||
return "Line{" +
|
||||
"number=" + number +
|
||||
", startPosition=" + startPosition +
|
||||
", text='" + text + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,9 @@ package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static it.cavallium.warppi.math.rules.dsl.frontend.TokenType.*;
|
||||
|
||||
@ -17,14 +12,19 @@ import static it.cavallium.warppi.math.rules.dsl.frontend.TokenType.*;
|
||||
* Converts the source string to a list of tokens.
|
||||
*/
|
||||
public class Lexer {
|
||||
private static final Map<String, TokenType> keywords = Stream.of(
|
||||
private static final Map<String, TokenType> KEYWORDS;
|
||||
static {
|
||||
TokenType[] keywordTokenTypes = {
|
||||
REDUCTION, EXPANSION, CALCULATION, EXISTENCE,
|
||||
ARCCOS, ARCSIN, ARCTAN, COS, SIN, TAN, ROOT, SQRT, LOG,
|
||||
UNDEFINED, PI, E
|
||||
).collect(Collectors.toMap(
|
||||
tokenType -> tokenType.name().toLowerCase(),
|
||||
Function.identity()
|
||||
));
|
||||
};
|
||||
Map<String, TokenType> map = new HashMap<>();
|
||||
for (TokenType type : keywordTokenTypes) {
|
||||
map.put(type.name().toLowerCase(), type);
|
||||
}
|
||||
KEYWORDS = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
private final String source;
|
||||
private final Consumer<? super DslError> errorReporter;
|
||||
@ -160,7 +160,7 @@ public class Lexer {
|
||||
|
||||
private void keywordOrIdentifier() {
|
||||
matchWhile(Character::isJavaIdentifierPart);
|
||||
TokenType type = keywords.getOrDefault(currentLexeme(), IDENTIFIER);
|
||||
TokenType type = KEYWORDS.getOrDefault(currentLexeme(), IDENTIFIER);
|
||||
emitToken(type);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
import it.cavallium.warppi.math.rules.dsl.Pattern;
|
||||
import it.cavallium.warppi.math.rules.dsl.PatternRule;
|
||||
import it.cavallium.warppi.math.rules.dsl.patterns.*;
|
||||
import it.cavallium.warppi.util.MapFactory;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
@ -19,11 +20,11 @@ import static it.cavallium.warppi.math.rules.dsl.frontend.TokenType.*;
|
||||
* Converts a list of tokens to a list of <code>PatternRule</code>s.
|
||||
*/
|
||||
public class Parser {
|
||||
private static final Map<TokenType, RuleType> ruleTypes = Map.ofEntries(
|
||||
Map.entry(REDUCTION, RuleType.REDUCTION),
|
||||
Map.entry(EXPANSION, RuleType.EXPANSION),
|
||||
Map.entry(CALCULATION, RuleType.CALCULATION),
|
||||
Map.entry(EXISTENCE, RuleType.EXISTENCE)
|
||||
private static final Map<TokenType, RuleType> RULE_TYPES = MapFactory.fromEntries(
|
||||
MapFactory.entry(REDUCTION, RuleType.REDUCTION),
|
||||
MapFactory.entry(EXPANSION, RuleType.EXPANSION),
|
||||
MapFactory.entry(CALCULATION, RuleType.CALCULATION),
|
||||
MapFactory.entry(EXISTENCE, RuleType.EXISTENCE)
|
||||
);
|
||||
|
||||
private final List<Token> tokens;
|
||||
@ -57,7 +58,7 @@ public class Parser {
|
||||
rules.add(rule());
|
||||
} catch (final SyntaxException e) {
|
||||
errorReporter.accept(e.getError());
|
||||
synchronizeTo(ruleTypes.keySet()); // Skip to the next rule to minimize "false" errors
|
||||
synchronizeTo(RULE_TYPES.keySet()); // Skip to the next rule to minimize "false" errors
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
@ -82,12 +83,12 @@ public class Parser {
|
||||
// rule type = REDUCTION | EXPANSION | CALCULATION | EXISTENCE ;
|
||||
private RuleType ruleType() throws SyntaxException {
|
||||
final Token curToken = pop();
|
||||
if (!ruleTypes.containsKey(curToken.type)) {
|
||||
if (!RULE_TYPES.containsKey(curToken.type)) {
|
||||
throw new SyntaxException(
|
||||
new UnexpectedToken(curToken, ruleTypes.keySet())
|
||||
new UnexpectedToken(curToken, RULE_TYPES.keySet())
|
||||
);
|
||||
}
|
||||
return ruleTypes.get(curToken.type);
|
||||
return RULE_TYPES.get(curToken.type);
|
||||
}
|
||||
|
||||
// pattern = equation ;
|
||||
@ -126,18 +127,18 @@ public class Parser {
|
||||
|
||||
// sum = product , { ( PLUS | MINUS | PLUS_MINUS ) product } ;
|
||||
private Pattern sum() throws SyntaxException {
|
||||
return matchLeftAssoc(this::product, Map.ofEntries(
|
||||
Map.entry(PLUS, SumPattern::new),
|
||||
Map.entry(MINUS, SubtractionPattern::new),
|
||||
Map.entry(PLUS_MINUS, SumSubtractionPattern::new)
|
||||
return matchLeftAssoc(this::product, MapFactory.fromEntries(
|
||||
MapFactory.entry(PLUS, SumPattern::new),
|
||||
MapFactory.entry(MINUS, SubtractionPattern::new),
|
||||
MapFactory.entry(PLUS_MINUS, SumSubtractionPattern::new)
|
||||
));
|
||||
}
|
||||
|
||||
// product = unary , { ( TIMES | DIVIDE ) unary } ;
|
||||
private Pattern product() throws SyntaxException {
|
||||
return matchLeftAssoc(this::unary, Map.ofEntries(
|
||||
Map.entry(TIMES, MultiplicationPattern::new),
|
||||
Map.entry(DIVIDE, DivisionPattern::new)
|
||||
return matchLeftAssoc(this::unary, MapFactory.fromEntries(
|
||||
MapFactory.entry(TIMES, MultiplicationPattern::new),
|
||||
MapFactory.entry(DIVIDE, DivisionPattern::new)
|
||||
));
|
||||
}
|
||||
|
||||
@ -170,18 +171,18 @@ public class Parser {
|
||||
// function = ( ARCCOS | ARCSIN | ARCTAN | COS | SIN | SQRT | TAN ) , LEFT_PAREN , sum , RIGHT_PAREN
|
||||
// | ( LOG | ROOT ) LEFT_PAREN , sum , COMMA , sum , RIGHT_PAREN ;
|
||||
private Pattern tryFunction() throws SyntaxException {
|
||||
final Map<TokenType, Function<Pattern, Pattern>> oneArg = Map.ofEntries(
|
||||
Map.entry(ARCCOS, ArcCosinePattern::new),
|
||||
Map.entry(ARCSIN, ArcSinePattern::new),
|
||||
Map.entry(ARCTAN, ArcTangentPattern::new),
|
||||
Map.entry(COS, CosinePattern::new),
|
||||
Map.entry(SIN, SinePattern::new),
|
||||
Map.entry(SQRT, arg -> new RootPattern(new NumberPattern(new BigDecimal(2)), arg)),
|
||||
Map.entry(TAN, TangentPattern::new)
|
||||
final Map<TokenType, Function<Pattern, Pattern>> oneArg = MapFactory.fromEntries(
|
||||
MapFactory.entry(ARCCOS, ArcCosinePattern::new),
|
||||
MapFactory.entry(ARCSIN, ArcSinePattern::new),
|
||||
MapFactory.entry(ARCTAN, ArcTangentPattern::new),
|
||||
MapFactory.entry(COS, CosinePattern::new),
|
||||
MapFactory.entry(SIN, SinePattern::new),
|
||||
MapFactory.entry(SQRT, arg -> new RootPattern(new NumberPattern(new BigDecimal(2)), arg)),
|
||||
MapFactory.entry(TAN, TangentPattern::new)
|
||||
);
|
||||
final Map<TokenType, BiFunction<Pattern, Pattern, Pattern>> twoArg = Map.ofEntries(
|
||||
Map.entry(LOG, LogarithmPattern::new),
|
||||
Map.entry(ROOT, RootPattern::new)
|
||||
final Map<TokenType, BiFunction<Pattern, Pattern, Pattern>> twoArg = MapFactory.fromEntries(
|
||||
MapFactory.entry(LOG, LogarithmPattern::new),
|
||||
MapFactory.entry(ROOT, RootPattern::new)
|
||||
);
|
||||
|
||||
final TokenType curType = peek().type;
|
||||
|
@ -2,6 +2,8 @@ package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@ -19,7 +21,7 @@ public class UnexpectedToken implements DslError {
|
||||
|
||||
public UnexpectedToken(final Token unexpected, final TokenType... suggested) {
|
||||
this.unexpected = unexpected;
|
||||
this.suggested = Set.of(suggested);
|
||||
this.suggested = new HashSet<>(Arrays.asList(suggested)); // TeaVM doesn't support Set.of
|
||||
}
|
||||
|
||||
@Override
|
||||
|
52
core/src/main/java/it/cavallium/warppi/util/MapFactory.java
Normal file
52
core/src/main/java/it/cavallium/warppi/util/MapFactory.java
Normal file
@ -0,0 +1,52 @@
|
||||
package it.cavallium.warppi.util;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Reimplements map creation methods which are not available on TeaVM.
|
||||
*/
|
||||
public class MapFactory {
|
||||
private MapFactory() {}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable map containing keys and values extracted from the given entries.
|
||||
* <p>
|
||||
* This method is equivalent to {@link Map#ofEntries(Map.Entry...)}.
|
||||
*
|
||||
* @param entries <code>Map.Entry</code>s containing the keys and values from which the map is populated
|
||||
* @param <K> the <code>Map</code>'s key type
|
||||
* @param <V> the <code>Map</code>'s value type
|
||||
* @return a Map containing the specified mappings
|
||||
* @see MapFactory#entry(K, V)
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <K, V> Map<K, V> fromEntries(Map.Entry<? extends K, ? extends V>... entries) {
|
||||
HashMap<K, V> map = new HashMap<>();
|
||||
for (Map.Entry<? extends K, ? extends V> entry : entries) {
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable <code>Map.Entry</code> containing the given key and value.
|
||||
* These entries are suitable for populating Map instances using the {@link MapFactory#fromEntries(Map.Entry...)}
|
||||
* or {@link Map#ofEntries(Map.Entry...)} methods.
|
||||
* <p>
|
||||
* This method can be used as a replacement for {@link Map#entry(K, V)}, if the latter is not available (for example,
|
||||
* when compiling for TeaVM). However, unlike <code>Map.entry</code>, <code>null</code> keys and values are allowed,
|
||||
* and the returned <code>Entry</code> is serializable.
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
* @param <K> the key's type
|
||||
* @param <V> the value's type
|
||||
* @return an <code>Entry</code> containing the specified key and value
|
||||
*/
|
||||
public static <K, V> Map.Entry<K, V> entry(K key, V value) {
|
||||
return new AbstractMap.SimpleImmutableEntry<>(key, value);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user