This is the mail archive of the
kawa@sources.redhat.com
mailing list for the Kawa project.
pseudo-method patch
- From: Chris Dean <ctdean at sokitomi dot com>
- To: Kawa List <kawa at sources dot redhat dot com>
- Date: Tue, 10 Aug 2004 19:57:12 -0700
- Subject: pseudo-method patch
Here is a patch for three "pseudo" methods that can be used along with
a namespace alias. The new methods "instance?", "cast", and "class"
are similar to the "new" pseudo-method in that they are not actually
class methods, but special names that are available when using a
namespace alias.
This might be controversial, so let the comments fly.
You can use the method name `instance?' to check the type of objects:
(Int32:instance? x)
This is equivalent to the Java expression `x instanceof Integer'
or the Kawa `(instance? x <java.lang.Integer>)' form. Be aware
that this overrides normal Kawa name mangling and that methods
named `isInstance' should be called using `(MyClass:isInstance x)'.
You can use the method name `cast' to converts or coerces the
argument to a different type:
(Int32:cast x)
This is equivalent to the Java expression `((Integer) x)' or the
Kawa `(as <java.lang.Integer> x)' form.
You can use the method name `class' to get the class:
(Int32:class)
This is equivalent to the Java expression `java.lang.Integer' or
the Kawa `<java.lang.Integer>' and `(find-class
'java.lang.Integer)' forms.
Regards,
Chris Dean
Index: doc/kawa.texi
===================================================================
RCS file: /cvs/kawa/kawa/doc/kawa.texi,v
retrieving revision 1.150
diff -u -w -r1.150 kawa.texi
--- doc/kawa.texi 28 Jul 2004 22:36:49 -0000 1.150
+++ doc/kawa.texi 11 Aug 2004 02:48:42 -0000
@@ -3933,6 +3933,31 @@
@end example
This evaluates to the Java String @code{"255"}.
+You can use the method name @code{instance?} to check the type of objects:
+@example
+(Int32:instance? x)
+@end example
+This is equivalent to the Java expression @code{x instanceof Integer} or
+the Kawa @code{(instance? x <java.lang.Integer>)} form. Be aware that
+this overrides normal Kawa name mangling and that methods named
+@code{isInstance} should be called using @code{(MyClass:isInstance x)}.
+
+You can use the method name @code{cast} to converts or coerces the
+argument to a different type:
+@example
+(Int32:cast x)
+@end example
+This is equivalent to the Java expression @code{((Integer) x)} or
+the Kawa @code{(as <java.lang.Integer> x)} form.
+
+You can use the method name @code{class} to get the class:
+@example
+(Int32:class)
+@end example
+This is equivalent to the Java expression @code{java.lang.Integer} or
+the Kawa @code{<java.lang.Integer>} and @code{(find-class
+'java.lang.Integer)} forms.
+
As a shorthand, you can use the name of a Java class instead of a
namespace alias:
@example
Index: gnu/expr/ChangeLog
===================================================================
RCS file: /cvs/kawa/kawa/gnu/expr/ChangeLog,v
retrieving revision 1.324
diff -u -w -r1.324 ChangeLog
--- gnu/expr/ChangeLog 9 Aug 2004 05:26:57 -0000 1.324
+++ gnu/expr/ChangeLog 11 Aug 2004 02:48:43 -0000
@@ -1,3 +1,7 @@
+2004-08-10 Chris Dean <ctdean@sokitomi.com>
+
+ * InlineCalls.java: Add instance?, class, and cast pseudo-methods.
+
2004-08-06 Per Bothner <per@bothner.com>
Change tailcall function API to use matchX+apply.
Index: gnu/expr/InlineCalls.java
===================================================================
RCS file: /cvs/kawa/kawa/gnu/expr/InlineCalls.java,v
retrieving revision 1.21
diff -u -w -r1.21 InlineCalls.java
--- gnu/expr/InlineCalls.java 20 Jul 2004 23:30:18 -0000 1.21
+++ gnu/expr/InlineCalls.java 11 Aug 2004 02:48:43 -0000
@@ -15,16 +15,29 @@
/** Possibly convert a Symbol method call to invokeStatic or make. */
Expression rewriteToInvocation(Symbol sym, ApplyExp aexp)
{
- Expression[] args = aexp.args;
String uri = sym.getNamespaceURI();
if (uri == null || ! uri.startsWith("class:"))
return null;
String className = uri.substring(6);
String methodName = sym.getName();
- ClassType typeInvoke = ClassType.make("gnu.kawa.reflect.Invoke");
+ if (methodName.equals("instance?"))
+ return rewriteToInstance(aexp, className);
+ else if (methodName.equals("class"))
+ return rewriteToClass(aexp, className);
+ else if (methodName.equals("cast"))
+ return rewriteToCast(aexp, className);
+ else
+ return rewriteToInvoke(aexp, className, methodName);
+ }
+
+ private Expression rewriteToInvoke(ApplyExp aexp,
+ String className, String methodName)
+ {
+ Expression[] args = aexp.args;
String invFieldName;
Invoke invProc;
boolean isNew = methodName.equals("new");
+ boolean isInstance = methodName.equals("instance?");
if (isNew)
{
invFieldName = "make";
@@ -35,6 +48,7 @@
invFieldName = "invokeStatic";
invProc = gnu.kawa.reflect.Invoke.invokeStatic;
}
+ ClassType typeInvoke = ClassType.make(invProc.getClass().getName());
Field invField = typeInvoke.getDeclaredField(invFieldName);
Declaration invDecl = new Declaration("invoke", invField);
invDecl.noteValue(new QuoteExp(invProc));
@@ -44,12 +58,90 @@
xargs[0] = new QuoteExp(className);
if (! isNew)
xargs[1] = new QuoteExp(methodName);
- args = xargs;
- ApplyExp nexp = new ApplyExp(new ReferenceExp(invDecl), args);
+
+ return finishRewrite(aexp, invDecl, invProc, xargs);
+ }
+
+ private Expression rewriteToInstance(ApplyExp aexp, String className)
+ {
+ Expression[] args = aexp.args;
+ CanInline proc = kawa.standard.Scheme.instanceOf;
+ ClassType type = ClassType.make(proc.getClass().getName());
+ Declaration decl = new Declaration("instance?", type);
+
+ decl.noteValue(new QuoteExp(proc));
+ decl.setFlag(Declaration.IS_CONSTANT);
+
+ if (args.length != 1) {
+ String nm = className + ":" + "instance?";
+ throw new WrongArguments(nm, args.length,
+ WrongArguments.checkArgCount(nm, 1, 1,
+ args.length));
+ }
+
+ Expression[] xargs = new Expression[2];
+ xargs[0] = args[0];
+ xargs[1] = new QuoteExp(ClassType.make(className));
+
+ return finishRewrite(aexp, decl, proc, xargs);
+ }
+
+ private Expression rewriteToClass(ApplyExp aexp, String className)
+ {
+ Expression[] args = aexp.args;
+ CanInline proc = kawa.standard.Scheme.findClass;
+ ClassType type = ClassType.make(proc.getClass().getName());
+ Declaration decl = new Declaration("class", type);
+
+ decl.noteValue(new QuoteExp(proc));
+ decl.setFlag(Declaration.IS_CONSTANT);
+
+ if (args.length != 0) {
+ String nm = className + ":" + "class";
+ throw new WrongArguments(nm, args.length,
+ WrongArguments.checkArgCount(nm, 0, 0,
+ args.length));
+ }
+
+ Expression[] xargs = new Expression[1];
+ xargs[0] = new QuoteExp(ClassType.make(className));
+
+ return finishRewrite(aexp, decl, proc, xargs);
+ }
+
+ private Expression rewriteToCast(ApplyExp aexp, String className)
+ {
+ Expression[] args = aexp.args;
+ CanInline proc = gnu.kawa.functions.Convert.as;
+ ClassType type = ClassType.make(proc.getClass().getName());
+ Declaration decl = new Declaration("cast", type);
+
+ decl.noteValue(new QuoteExp(proc));
+ decl.setFlag(Declaration.IS_CONSTANT);
+
+ if (args.length != 1) {
+ String nm = className + ":" + "cast";
+ throw new WrongArguments(nm, args.length,
+ WrongArguments.checkArgCount(nm, 1, 1,
+ args.length));
+ }
+
+ Expression[] xargs = new Expression[2];
+ xargs[1] = args[0];
+ xargs[0] = new QuoteExp(ClassType.make(className));
+
+ return finishRewrite(aexp, decl, proc, xargs);
+ }
+
+ private Expression finishRewrite(ApplyExp aexp, Declaration decl,
+ CanInline proc, Expression[] args)
+ {
+ ApplyExp nexp = new ApplyExp(new ReferenceExp(decl), args);
nexp.setLine(aexp);
- return invProc.inline(nexp, this);
+ return proc.inline(nexp, this);
}
+
protected Expression walkApplyExp(ApplyExp exp)
{
super.walkApplyExp(exp);
Index: gnu/kawa/reflect/ChangeLog
===================================================================
RCS file: /cvs/kawa/kawa/gnu/kawa/reflect/ChangeLog,v
retrieving revision 1.74
diff -u -w -r1.74 ChangeLog
--- gnu/kawa/reflect/ChangeLog 9 Aug 2004 05:30:14 -0000 1.74
+++ gnu/kawa/reflect/ChangeLog 11 Aug 2004 02:48:43 -0000
@@ -1,3 +1,8 @@
+2004-08-10 Chris Dean <ctdean@sokitomi.com>
+
+ * ClassMethods.java (apply): Add instance?, class, and cast
+ pseudo-methods.
+
2004-08-08 Per Bothner <per@bothner.com>
* Invoke.java (applyN): Use new matchN method. Don't use applyV.
Index: gnu/kawa/reflect/ClassMethods.java
===================================================================
RCS file: /cvs/kawa/kawa/gnu/kawa/reflect/ClassMethods.java,v
retrieving revision 1.21
diff -u -w -r1.21 ClassMethods.java
--- gnu/kawa/reflect/ClassMethods.java 11 Feb 2004 20:26:40 -0000 1.21
+++ gnu/kawa/reflect/ClassMethods.java 11 Aug 2004 02:48:43 -0000
@@ -15,11 +15,22 @@
public static MethodProc apply (String className, String methodName)
{
+ if (methodName.equals("instance?"))
+ return MethodProcWrapper.makeSimple(kawa.standard.Scheme.instanceOf,
+ className, 1, 2);
+ else if (methodName.equals("class"))
+ return MethodProcWrapper.makeSimple(kawa.standard.Scheme.findClass,
+ className, 0, 1);
+ else if (methodName.equals("cast"))
+ return MethodProcWrapper.makeSimple(gnu.kawa.functions.Convert.as,
+ className, 0, 2);
+
String mname = methodName.equals("new") ? "<init>"
: Compilation.mangleName(methodName);
ClassType methodClass = ClassType.make(className);
MethodProc proc
= ClassMethods.apply(methodClass, mname, null, null, 0, 0);
+
if (proc == null)
{
StringBuffer sbuf = new StringBuffer();
Index: gnu/mapping/ChangeLog
===================================================================
RCS file: /cvs/kawa/kawa/gnu/mapping/ChangeLog,v
retrieving revision 1.120
diff -u -w -r1.120 ChangeLog
--- gnu/mapping/ChangeLog 9 Aug 2004 05:25:26 -0000 1.120
+++ gnu/mapping/ChangeLog 11 Aug 2004 02:48:43 -0000
@@ -1,3 +1,8 @@
+2004-08-10 Chris Dean <ctdean@sokitomi.com>
+
+ * MethodProcWrapper.java: New class that extends MethodProc.
+ * Makefile.am (java_sources): Added MethodProcWrapper.java.
+
2004-08-06 Per Bothner <per@bothner.com>
* Procedure.java: New API, especially for --full-tailcalls.
Index: gnu/mapping/Makefile.am
===================================================================
RCS file: /cvs/kawa/kawa/gnu/mapping/Makefile.am,v
retrieving revision 1.30
diff -u -w -r1.30 Makefile.am
--- gnu/mapping/Makefile.am 9 Aug 2004 05:25:26 -0000 1.30
+++ gnu/mapping/Makefile.am 11 Aug 2004 02:48:43 -0000
@@ -17,6 +17,7 @@
Location.java \
LogWriter.java \
MethodProc.java \
+ MethodProcWrapper.java \
NameMap.java \
Named.java \
OutPort.java \
Index: testsuite/ChangeLog
===================================================================
RCS file: /cvs/kawa/kawa/testsuite/ChangeLog,v
retrieving revision 1.146
diff -u -w -r1.146 ChangeLog
--- testsuite/ChangeLog 9 Aug 2004 05:40:32 -0000 1.146
+++ testsuite/ChangeLog 11 Aug 2004 02:48:43 -0000
@@ -1,3 +1,8 @@
+2004-08-10 Chris Dean <ctdean@sokitomi.com>
+
+ * obj-test.scm: Test cases for find-class, namespace:class and
+ namespace:instance.
+
2004-08-07 Per Bothner <per@bothner.com>
* misc-test.scm: Overload resolution test is now expected to pass.
Index: testsuite/obj-test.scm
===================================================================
RCS file: /cvs/kawa/kawa/testsuite/obj-test.scm,v
retrieving revision 1.45
diff -u -w -r1.45 obj-test.scm
--- testsuite/obj-test.scm 23 May 2004 20:03:46 -0000 1.45
+++ testsuite/obj-test.scm 11 Aug 2004 02:48:43 -0000
@@ -1,4 +1,4 @@
-(test-init "Objects" 91)
+(test-init "Objects" 95)
;; Force procedure to be applied without being inlined:
(define-syntax force-eval
@@ -279,6 +279,11 @@
(test (+ 1900 (date:get-year (date:new)))
invoke non-simple-date 'get-year)
+(test #t date:instance? simple-date)
+(test #f date:instance? "hello")
+(test <SimpleDateTest> find-class 'SimpleDateTest)
+(test <java.util.Date> date:class)
+
;; Test for Savannah bug #4289
(define pa-data (pa-new 10))
(pa-setter pa-data 5 99)