mirror of
https://github.com/zeroflag/fcl.git
synced 2025-01-12 20:01:25 +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(".", () -> show(stack.pop()));
|
||||||
addPrimitive("jvm-call-static", interOp::jvmCallStatic);
|
addPrimitive("jvm-call-static", interOp::jvmCallStatic);
|
||||||
addPrimitive("jvm-call-method", interOp::jvmCallMethod);
|
addPrimitive("jvm-call-method", interOp::jvmCallMethod);
|
||||||
|
addPrimitive("jvm-has-method", interOp::jvmHasMethod);
|
||||||
addPrimitive("jvm-static-var", interOp::jvmStaticVar);
|
addPrimitive("jvm-static-var", interOp::jvmStaticVar);
|
||||||
addPrimitive("jvm-null", () -> stack.push(null));
|
addPrimitive("jvm-null", () -> stack.push(null));
|
||||||
addPrimitive("asc*", this::sortAsc);
|
addPrimitive("asc*", this::sortAsc);
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.vectron.fcl.interop;
|
||||||
|
|
||||||
import com.vectron.fcl.FclStack;
|
import com.vectron.fcl.FclStack;
|
||||||
import com.vectron.fcl.exceptions.InterOpFailed;
|
import com.vectron.fcl.exceptions.InterOpFailed;
|
||||||
|
import com.vectron.fcl.types.Bool;
|
||||||
import com.vectron.fcl.types.JvmObj;
|
import com.vectron.fcl.types.JvmObj;
|
||||||
import com.vectron.fcl.types.Obj;
|
import com.vectron.fcl.types.Obj;
|
||||||
|
|
||||||
|
@ -31,6 +32,15 @@ public class JvmInterOp {
|
||||||
spec.invoke(stack);
|
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() {
|
public void jvmStaticVar() {
|
||||||
String spec = stack.pop().asStr().value();
|
String spec = stack.pop().asStr().value();
|
||||||
String[] parts = spec.split("/");
|
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) {
|
public static void processResult(Object result, FclStack stack) {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
if (result instanceof Number)
|
if (result instanceof Number)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
: hist ( c -- m )
|
: hist ( c -- m )
|
||||||
|
dup 'iterator' jvm-has-method not if
|
||||||
|
drop #[ ]# exit
|
||||||
|
then
|
||||||
<map> -> tbl {
|
<map> -> tbl {
|
||||||
-> elem
|
-> elem
|
||||||
tbl elem at -> count
|
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.Arrays.asList;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
@ -391,6 +392,12 @@ public class FclTest {
|
||||||
assertEquals(1.5430, evalPop("1 cosh").doubleValue(), 0.001);
|
assertEquals(1.5430, evalPop("1 cosh").doubleValue(), 0.001);
|
||||||
assertEquals(0.7616, evalPop("1 tanh").doubleValue(), 0.001);
|
assertEquals(0.7616, evalPop("1 tanh").doubleValue(), 0.001);
|
||||||
assertEquals(1, evalPop("1.3 'intValue' jvm-call-method").doubleValue(), 0.01);
|
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
|
@Test
|
||||||
|
@ -1122,6 +1129,7 @@ public class FclTest {
|
||||||
public void testHist() {
|
public void testHist() {
|
||||||
assertEquals("#[ 'a' 2 'b' 3 'c' 1 ]#", evalPop("'ababbc' hist").toString());
|
assertEquals("#[ 'a' 2 'b' 3 'c' 1 ]#", evalPop("'ababbc' hist").toString());
|
||||||
assertEquals("#[ ]#", evalPop("'' hist").toString());
|
assertEquals("#[ ]#", evalPop("'' hist").toString());
|
||||||
|
assertEquals("#[ ]#", evalPop("12 hist").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String transcript() {
|
private String transcript() {
|
||||||
|
|
Loading…
Reference in a new issue