Skip to content

Commit

Permalink
Moved classes around a bit. Removed BF parser
Browse files Browse the repository at this point in the history
  • Loading branch information
LatvianModder committed Dec 16, 2023
1 parent 72d303e commit a2501e1
Show file tree
Hide file tree
Showing 40 changed files with 1,969 additions and 2,158 deletions.
2 changes: 1 addition & 1 deletion src/main/java/dev/latvian/apps/ichor/Callable.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
public interface Callable {
Object call(Context cx, Scope scope, Object[] args, boolean hasNew);

default Object[] convertArgs(Context cx, Scope scope, Object[] arguments) {
default Object[] evalArgs(Context cx, Scope scope, Object[] arguments) {
if (arguments.length == 0) {
return Empty.OBJECTS;
}
Expand Down
11 changes: 7 additions & 4 deletions src/main/java/dev/latvian/apps/ichor/CallableTypeAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ default <T> T adapt(Context cx, Scope scope, Class<T> type) {
}

@Override
default Object invoke(Object proxy, Method method, Object[] args) {
var cx = getEvalContext();
var scope = getEvalScope();

default Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getDeclaringClass() == Object.class) {
return switch (method.getName()) {
case "toString" -> toString();
Expand All @@ -31,6 +28,12 @@ default Object invoke(Object proxy, Method method, Object[] args) {
};
}

if (method.isDefault()) {
return InvocationHandler.invokeDefault(proxy, method, args);
}

var cx = getEvalContext();
var scope = getEvalScope();
return cx.as(scope, call(cx, scope, args == null ? Empty.OBJECTS : args, false), method.getReturnType());
}
}
157 changes: 153 additions & 4 deletions src/main/java/dev/latvian/apps/ichor/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,71 @@
import dev.latvian.apps.ichor.error.CastError;
import dev.latvian.apps.ichor.error.InternalScriptError;
import dev.latvian.apps.ichor.java.AnnotatedElementPrototype;
import dev.latvian.apps.ichor.java.BooleanPrototype;
import dev.latvian.apps.ichor.java.JavaClassPrototype;
import dev.latvian.apps.ichor.prototype.Prototype;
import dev.latvian.apps.ichor.prototype.PrototypeSupplier;
import dev.latvian.apps.ichor.type.ArrayJS;
import dev.latvian.apps.ichor.type.CollectionJS;
import dev.latvian.apps.ichor.type.IterableJS;
import dev.latvian.apps.ichor.type.ListJS;
import dev.latvian.apps.ichor.type.MapJS;
import dev.latvian.apps.ichor.type.MathJS;
import dev.latvian.apps.ichor.type.NumberJS;
import dev.latvian.apps.ichor.type.ObjectJS;
import dev.latvian.apps.ichor.type.RegExpJS;
import dev.latvian.apps.ichor.type.SetJS;
import dev.latvian.apps.ichor.type.StringJS;
import dev.latvian.apps.ichor.util.IchorUtils;
import dev.latvian.apps.ichor.util.JavaArray;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.regex.Pattern;

public abstract class Context {
public class Context {
private final Map<Class<?>, Prototype<?>> classPrototypes;
private int maxScopeDepth;
private long interpretingTimeout;
private long tokenStreamTimeout;
private Remapper remapper;
private ClassLoader classLoader;
private Executor timeoutExecutor, timeoutExecutorAfter;
private Consumer<Scope> debuggerCallback;

public final Prototype<?> objectPrototype,
arrayPrototype,
classPrototype,
stringPrototype,
numberPrototype,
booleanPrototype,
jsObjectPrototype,
jsArrayPrototype,
jsMathPrototype,
jsMapPrototype,
jsSetPrototype,
regExpPrototype,
listPrototype,
collectionPrototype,
iterablePrototype;

public final List<Prototype<?>> safePrototypes;

public Context() {
classPrototypes = new IdentityHashMap<>();
Expand All @@ -31,13 +77,42 @@ public Context() {
tokenStreamTimeout = 5000L;
remapper = null;
classLoader = null;
timeoutExecutor = null;
timeoutExecutorAfter = null;

objectPrototype = new Prototype<>(this, Object.class);
arrayPrototype = new Prototype<>(this, Object[].class);
classPrototype = new Prototype<>(this, Class.class);
stringPrototype = new StringJS(this);
numberPrototype = new NumberJS(this);
booleanPrototype = new BooleanPrototype(this);
jsObjectPrototype = new ObjectJS(this);
jsArrayPrototype = new ArrayJS(this);
jsMathPrototype = new MathJS(this);
jsMapPrototype = new MapJS(this);
jsSetPrototype = new SetJS(this);
regExpPrototype = new RegExpJS(this);
listPrototype = new ListJS(this);
collectionPrototype = new CollectionJS(this);
iterablePrototype = new IterableJS(this);

safePrototypes = new ArrayList<>();
safePrototypes.add(stringPrototype);
safePrototypes.add(numberPrototype);
safePrototypes.add(booleanPrototype);
safePrototypes.add(jsObjectPrototype);
safePrototypes.add(jsArrayPrototype);
safePrototypes.add(jsMathPrototype);
safePrototypes.add(jsMapPrototype);
safePrototypes.add(jsSetPrototype);
safePrototypes.add(regExpPrototype);

registerPrototype(new JavaClassPrototype(this));
registerPrototype(new AnnotatedElementPrototype(this));
}

public List<Prototype<?>> getSafePrototypes() {
return Collections.emptyList();
return safePrototypes;
}

public void registerPrototype(Prototype<?> prototype) {
Expand Down Expand Up @@ -86,6 +161,38 @@ public void setClassLoader(ClassLoader cl) {
classLoader = cl;
}

@Nullable
public Executor getTimeoutExecutor() {
if (timeoutExecutor == null) {
timeoutExecutor = CompletableFuture.completedFuture(null).defaultExecutor();
}

return timeoutExecutor;
}

public void setTimeoutExecutor(Executor executor) {
timeoutExecutor = executor;
}

@Nullable
public Executor getTimeoutExecutorAfter() {
return timeoutExecutorAfter;
}

public void setTimeoutExecutorAfter(Executor executor) {
timeoutExecutorAfter = executor;
}

public void setDebuggerCallback(Consumer<Scope> callback) {
debuggerCallback = callback;
}

public void onDebugger(Scope scope) {
if (debuggerCallback != null) {
debuggerCallback.accept(scope);
}
}

public Object eval(Scope scope, Object o) {
if (o == Special.UNDEFINED || o instanceof Callable) {
return o;
Expand Down Expand Up @@ -295,7 +402,7 @@ public List asList(Scope scope, Object o) {
public Object as(Scope scope, Object o, @Nullable Class<?> toType) {
if (Special.isInvalid(o)) {
return null;
} else if (toType == null || toType == Void.TYPE || toType == Object.class || toType == o.getClass() || toType.isInstance(o)) {
} else if (toType == null || toType == Void.TYPE || toType == Object.class || toType.isInstance(o)) {
return o;
} else if (toType == String.class || toType == CharSequence.class) {
return asString(scope, o, false);
Expand Down Expand Up @@ -345,10 +452,52 @@ protected Object customAs(Scope scope, Object o, Class<?> toType) {
}

public Prototype<?> getPrototype(Scope scope, Object o) {
if (o == null) {
return Special.NULL.prototype;
} else if (o instanceof PrototypeSupplier s) {
return s.getPrototype(this, scope);
} else if (o instanceof Boolean) {
return booleanPrototype;
} else if (o instanceof Number) {
return numberPrototype;
} else if (o instanceof CharSequence) {
return stringPrototype;
} else if (o instanceof Class) {
return classPrototype;
} else if (o instanceof Pattern) {
return regExpPrototype;
} else if (o.getClass().isArray()) {
return arrayPrototype;
}

return getClassPrototype(o.getClass());
}

public Prototype<?> getClassPrototype(Class<?> c) {
if (c == Boolean.class) {
return booleanPrototype;
} else if (c == Number.class) {
return numberPrototype;
} else if (c == String.class) {
return stringPrototype;
} else if (c == Class.class) {
return classPrototype;
} else if (c == Map.class || c == HashMap.class || c == LinkedHashMap.class || c == IdentityHashMap.class || c == EnumMap.class) {
return jsMapPrototype;
} else if (c == Set.class || c == HashSet.class || c == LinkedHashSet.class || c == EnumSet.class) {
return jsSetPrototype;
} else if (c == List.class || c == ArrayList.class || c == LinkedList.class) {
return listPrototype;
} else if (c == Collection.class) {
return collectionPrototype;
} else if (c == Iterable.class) {
return iterablePrototype;
} else if (c == Pattern.class) {
return regExpPrototype;
} else if (c.isArray()) {
return arrayPrototype;
}

var p = classPrototypes.get(c);

if (p == null) {
Expand Down
Loading

0 comments on commit a2501e1

Please sign in to comment.