Changeset 10238


Ignore:
Timestamp:
10/25/05 19:25:13 (16 years ago)
Author:
piso
Message:

JCALL, JCALL-RAW: refactoring.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/j/src/org/armedbear/lisp/Java.java

    r10217 r10238  
    33 *
    44 * Copyright (C) 2002-2005 Peter Graves, Andras Simon
    5  * $Id: Java.java,v 1.53 2005-10-24 21:13:53 piso Exp $
     5 * $Id: Java.java,v 1.54 2005-10-25 19:25:13 piso Exp $
    66 *
    77 * This program is free software; you can redistribute it and/or
     
    492492
    493493    // ### jcall method instance &rest args
     494    // Calls makeLispObject() to convert the result to an appropriate Lisp type.
    494495    private static final Primitive JCALL =
    495         new Primitive("jcall", PACKAGE_JAVA, true,
    496                       "method instance &rest args")
    497     {
    498         public LispObject execute(LispObject[] args) throws ConditionThrowable
    499         {
    500             return makeLispObject((JCALL_RAW.execute(args)).javaInstance());
     496        new Primitive(Symbol.JCALL, "method-ref instance &rest args")
     497    {
     498        public LispObject execute(LispObject[] args) throws ConditionThrowable
     499        {
     500            if (args.length < 2)
     501                signal(new WrongNumberOfArgumentsException(this));
     502            return makeLispObject(jcall(args));
    501503        }
    502504    };
    503505
    504506    // ### jcall-raw method instance &rest args
     507    // Does no type conversion. The result of the call is simply wrapped in a
     508    // JavaObject.
    505509    private static final Primitive JCALL_RAW =
    506         new Primitive("jcall-raw", PACKAGE_JAVA, true,
    507                       "method instance &rest args")
     510        new Primitive(Symbol.JCALL_RAW, "method-ref instance &rest args")
    508511    {
    509512        public LispObject execute(LispObject[] args) throws ConditionThrowable
     
    511514            if (args.length < 2)
    512515                signal(new WrongNumberOfArgumentsException(this));
    513             try {
    514                 Method method = (Method) JavaObject.getObject(args[0]);
    515                 Class[] argTypes = method.getParameterTypes();
    516                 final Object instance;
    517                 if (args[1] instanceof AbstractString)
    518                     instance = args[1].getStringValue();
     516            Object result = jcall(args);
     517            return (result != null) ? new JavaObject(result) : NIL;
     518        }
     519    };
     520
     521    private static Object jcall(LispObject[] args) throws ConditionThrowable
     522    {
     523        Debug.assertTrue(args.length >= 2); // Verified by callers.
     524        final LispObject methodArg = args[0];
     525        final LispObject instanceArg = args[1];
     526        final Object instance;
     527        if (instanceArg instanceof AbstractString)
     528            instance = instanceArg.getStringValue();
     529        else if (instanceArg instanceof JavaObject)
     530            instance = ((JavaObject)instanceArg).getObject();
     531        else {
     532            signalTypeError(instanceArg,
     533                            list3(Symbol.OR, Symbol.STRING, Symbol.JAVA_OBJECT));
     534            // Not reached.
     535            return null;
     536        }
     537        try {
     538            final Method method;
     539            if (methodArg instanceof AbstractString) {
     540                String methodName = methodArg.getStringValue();
     541                Class c = instance.getClass();
     542                // FIXME Use the actual args, not just the count!
     543                method = findMethod(c, methodName, args.length - 2);
     544            } else
     545                method = (Method) JavaObject.getObject(methodArg);
     546            Class[] argTypes = method.getParameterTypes();
     547            Object[] methodArgs = new Object[args.length - 2];
     548            for (int i = 2; i < args.length; i++) {
     549                LispObject arg = args[i];
     550                if (arg == NIL)
     551                    methodArgs[i-2] = null;
    519552                else
    520                     instance = JavaObject.getObject(args[1]);
    521                 Object[] methodArgs = new Object[args.length - 2];
    522                 for (int i = 2; i < args.length; i++) {
    523                     LispObject arg = args[i];
    524                     if (arg == NIL)
    525                         methodArgs[i-2] = null;
    526                     else
    527                         methodArgs[i-2] = arg.javaInstance(argTypes[i-2]);
    528                 }
    529                 Object result = method.invoke(instance, methodArgs);
    530                 return new JavaObject(result);
    531             }
    532             catch (ConditionThrowable t) {
    533                 throw t;
    534             }
    535             catch (Throwable t) {
    536                 Class tClass = t.getClass();
    537                 if (registeredExceptions.containsKey(tClass)) {
    538                     signal((Symbol)registeredExceptions.get(tClass),
    539                            new SimpleString(getMessage(t)));
    540                 }
    541                 signal(new LispError(getMessage(t)));
    542             }
    543             // Not reached.
    544             return NIL;
    545         }
    546     };
     553                    methodArgs[i-2] = arg.javaInstance(argTypes[i-2]);
     554            }
     555            return method.invoke(instance, methodArgs);
     556        }
     557        catch (ConditionThrowable t) {
     558            throw t;
     559        }
     560        catch (Throwable t) {
     561            Class tClass = t.getClass();
     562            if (registeredExceptions.containsKey(tClass)) {
     563                signal((Symbol)registeredExceptions.get(tClass),
     564                       new SimpleString(getMessage(t)));
     565            }
     566            signal(new LispError(getMessage(t)));
     567        }
     568        // Not reached.
     569        return null;
     570    }
     571
     572    // FIXME This just returns the first matching method that it finds. Allegro
     573    // signals a continuable error if there are multiple matching methods.
     574    private static Method findMethod(Class c, String methodName, int argCount)
     575    {
     576        Method[] methods = c.getMethods();
     577        for (int i = methods.length; i-- > 0;) {
     578            Method method = methods[i];
     579            if (method.getName().equals(methodName))
     580                if (method.getParameterTypes().length == argCount)
     581                    return method;
     582        }
     583        return null;
     584    }
    547585
    548586    // ### make-immediate-object object &optional type
     
    666704        if (obj instanceof Long)
    667705            return new Bignum(((Long)obj).longValue());
    668         if (obj instanceof Double || obj instanceof Float)
    669             return new DoubleFloat(((Number)obj).doubleValue());
     706        if (obj instanceof Float)
     707            return new SingleFloat(((Float)obj).floatValue());
     708        if (obj instanceof Double)
     709            return new DoubleFloat(((Double)obj).doubleValue());
    670710        if (obj instanceof String)
    671711            return new SimpleString((String)obj);
Note: See TracChangeset for help on using the changeset viewer.