mirror of
https://github.com/zeroflag/fcl.git
synced 2025-01-11 20:01:10 +01:00
jvm-has-method
This commit is contained in:
parent
da0a365bcf
commit
e93fd4d6bb
5 changed files with 36 additions and 0 deletions
|
@ -350,6 +350,7 @@ public class Fcl {
|
|||
addPrimitive(".", () -> show(stack.pop()));
|
||||
addPrimitive("jvm-call-static", interOp::jvmCallStatic);
|
||||
addPrimitive("jvm-call-method", interOp::jvmCallMethod);
|
||||
addPrimitive("jvm-has-method", interOp::jvmHasMethod);
|
||||
addPrimitive("jvm-static-var", interOp::jvmStaticVar);
|
||||
addPrimitive("jvm-null", () -> stack.push(null));
|
||||
addPrimitive("asc*", this::sortAsc);
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.vectron.fcl.interop;
|
|||
|
||||
import com.vectron.fcl.FclStack;
|
||||
import com.vectron.fcl.exceptions.InterOpFailed;
|
||||
import com.vectron.fcl.types.Bool;
|
||||
import com.vectron.fcl.types.JvmObj;
|
||||
import com.vectron.fcl.types.Obj;
|
||||
|
||||
|
@ -31,6 +32,15 @@ public class JvmInterOp {
|
|||
spec.invoke(stack);
|
||||
}
|
||||
|
||||
public void jvmHasMethod() {
|
||||
String methodName = stack.pop().asStr().value();
|
||||
Obj receiver = stack.pop();
|
||||
MethodSpec spec = MethodSpec.parseDynamic(
|
||||
methodName,
|
||||
receiver instanceof JvmObj ? ((JvmObj) receiver).value() : receiver);
|
||||
stack.push(spec.exists() ? Bool.TRUE : Bool.FALSE);
|
||||
}
|
||||
|
||||
public void jvmStaticVar() {
|
||||
String spec = stack.pop().asStr().value();
|
||||
String[] parts = spec.split("/");
|
||||
|
|
|
@ -71,6 +71,20 @@ class MethodSpec {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean exists() {
|
||||
List<Class<?>> types = new ArrayList<>();
|
||||
for (int i = 0; i < arity; i++) {
|
||||
Class<?> clazz = typeOf(typeSpec.charAt(i));
|
||||
types.add(clazz);
|
||||
}
|
||||
try {
|
||||
clazz.getMethod(methodName, types.toArray(new Class[0]));
|
||||
return true;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void processResult(Object result, FclStack stack) {
|
||||
if (result != null) {
|
||||
if (result instanceof Number)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
: hist ( c -- m )
|
||||
dup 'iterator' jvm-has-method not if
|
||||
drop #[ ]# exit
|
||||
then
|
||||
<map> -> tbl {
|
||||
-> elem
|
||||
tbl elem at -> count
|
||||
|
|
|
@ -26,6 +26,7 @@ import static com.vectron.fcl.types.Bool.TRUE;
|
|||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
@ -391,6 +392,12 @@ public class FclTest {
|
|||
assertEquals(1.5430, evalPop("1 cosh").doubleValue(), 0.001);
|
||||
assertEquals(0.7616, evalPop("1 tanh").doubleValue(), 0.001);
|
||||
assertEquals(1, evalPop("1.3 'intValue' jvm-call-method").doubleValue(), 0.01);
|
||||
assertFalse(evalPop("1.3 'nosuch' jvm-has-method").boolValue());
|
||||
assertTrue(evalPop("1.3 'round' jvm-has-method").boolValue());
|
||||
assertTrue(evalPop("[ 1 2 ] 'iterator' jvm-has-method").boolValue());
|
||||
assertTrue(evalPop("[ 1 2 ] 'append/O' jvm-has-method").boolValue());
|
||||
assertFalse(evalPop("[ 1 2 ] 'append/i' jvm-has-method").boolValue());
|
||||
assertFalse(evalPop("[ 1 2 ] 'append/OO' jvm-has-method").boolValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1122,6 +1129,7 @@ public class FclTest {
|
|||
public void testHist() {
|
||||
assertEquals("#[ 'a' 2 'b' 3 'c' 1 ]#", evalPop("'ababbc' hist").toString());
|
||||
assertEquals("#[ ]#", evalPop("'' hist").toString());
|
||||
assertEquals("#[ ]#", evalPop("12 hist").toString());
|
||||
}
|
||||
|
||||
private String transcript() {
|
||||
|
|
Loading…
Reference in a new issue