⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lispobject.java

📁 类似于Windows上的Excel
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * MC2 -- j2me spreadsheet
 *
 * Copyright (c) 2004-2006 Michael Zemljanukha (mixaz@mail.ru)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

package com.wapindustrial.calc;
import java.util.*;
import java.io.*;

/**
 *
 * @author  mzemlyan
 */
public class LispObject {

    /** This function was added because Nokia 6600 had a bug in Character.isDigit()
     * and returned TRUE for isDigit(':')
     */
//#ifdef ISDIGIT	
//#    public static final boolean isDigit( char cc) {
//#        return cc >= '0' && cc <= '9';
//#    }
//#endif    
    /** max .mc2 file size when loading, kBytes */
    private static final int MAX_MC2FILE_SIZE = 15;

//    public LispObject() {}      // for zero atoms
    public static final LispObject NIL = new LispObject();
    
    /** Evaluates s-exp - this is a basic interface for Lisp objects
     * When evluating atoms return themselves, functors do some
     * calculations and return evaluated objects, often atoms.
     * Inherited classes are supposed to implement this method.
     * The default behaviour (implemented in LispObject) is to return the
     * object itself, so atoms are allowed to not implement it.
     * For current MC2 implementation only NameObject
     * and FunctorList has got it's own implementation of evaluateSExp()
     * @throws EvaluateException If cannot evaluate for some reason
     * @return evaluated LispObject
     */    
    public LispObject evaluateSExp() throws EvaluateException {
        // this for atoms & list, calculate functions for functors
        return this;
    }
    
//    /** Evaluates and resolves references if it's a Referrence
//     * @throws EvaluateException
//     * @return Atom and not a Reference
//     */    
//    public LispObject evaluateSExpRef() throws EvaluateException {
//        return evaluateSExp().getReferredValue();
//    }
    /** The same as evaluateSExp() but evaluates a QuotedList as well.
     * Used when code is stored in quoted list
     * @throws EvaluateException
     * @return for QuotedList it's result of evaluation of the last item in the list
     * @see evaluateSExp
     */    
    public LispObject interpret() throws EvaluateException {
        return evaluateSExp();
    }
    
    /** Shifts references in this sexp. 
     * The difference with shiftReferences() - shiftReferences changes references according given range,
     * which may be outside the cell. moveReferences moves the current cell.
     * @param di di to destination (rows)
     * @param dj dj to destination (columns
     * @return new object if something was shifted (any relative reference encountered)
     * @see shiftReferences
     */    
    public LispObject moveReferences( int di, int dj ) {
        return this;                // for immutable items
    }
    
    public LispObject shiftReferences(int I1, int J1, int dI, int dJ) {
        return this;
    }
    
//    /** To be overrided in Referrence calls. Returns referred value by a range, value of
//     * top-left cell in the range. Evaluates
//     * @returns Referrenced value, if it's a Reference too, recursivelly calculates it as well
//     */    
//    public LispObject getReferredValue() {
//        return this;
//    }
    /* =================================
     * Interfaces for type converting
     * Used in formula processing
     * Order makes sence as datatypes are converted to higher one in WS formula expressions
     */ 
    static final int TYPE_UNKNOWN = 0;
    /** represents empty cell as well (not sure if it was right decision) */
    static final int TYPE_NIL = 1;
    static final int TYPE_REFERENCE = 2;
    static final int TYPE_NAME = 3;
    static final int TYPE_FUNCTORLIST = 4;
    static final int TYPE_QUOTEDLIST = 5;
    static final int TYPE_BOOLEAN = 6;
    static final int TYPE_SHORT = 7;
    static final int TYPE_LONG = 8;
    static final int TYPE_FLOAT = 9;
    static final int TYPE_STRING = 10;
    static final int TYPE_ERROR = 11;
    static final int TYPE_DATE = 12;
    
    static final int TYPE_ROWCOLUMN = 13;
    static final int TYPE_CELL = 14;
    static final int TYPE_SHEET = 15;
    
    static final int TYPE_FUNCTION = 16;
    
    static final int TYPE_PROFILE = 17;         // user profile object, to be used on server side only
    
    public int typeNumber() {
        return TYPE_NIL;
    }

    /* ==============================================================
     * Portability functions (to fix platform bugs) 
     */
    public static final byte[] getBytesUTF8(String ss) {
    	if(ss==null)
    		throw new IllegalArgumentException();
        byte value[] = {};
//#ifndef UTF8            
//#                  value = ss.getBytes();
//#else
            try {
                value = ss.getBytes("UTF-8");
            }
            catch (UnsupportedEncodingException e) {
                debug("can't encode name to UTF-8: <"+ss+">");
            }
//#endif
        return value;
    }
    
    public static final String getStringUTF8( byte buf[], int offset, int len) {
    	if(buf==null)
    		throw new IllegalArgumentException();
//#ifndef UTF8            
//#        return new String(buf,offset,len);
//#else
        try {
            return new String(buf,offset,len,"UTF-8");
        }
        catch (UnsupportedEncodingException e) {
            debug("cannot decode name from UTF-8");
            throw new IllegalStateException();
        }
//#endif
    }
    
    public static final Hashtable createHashtable(int capacity) {
//#ifdef HASHTABLE_ZERO
//#    	if (capacity==0)
//#    		return new Hashtable();
//#endif    	
    	return new Hashtable(capacity);
    }
    
    /** converts object to given type
     * @param type
     * @throws EvaluateException
     * @return
     */    
    public LispObject convertToType( int type ) throws EvaluateException {
        if( this == NIL ) {
            LispObject rez = this;
            switch( type ) {
                case TYPE_SHORT:
                    rez = ShortAtom.ZERO;
                    break;
                case TYPE_LONG:
                    rez = LongAtom.ZERO;
                    break;
                case TYPE_FLOAT:
                    rez = FloatAtom.ZERO;
                    break;
//                default:    // to STRING
//                    return super.convertToType( type );
            }
            return rez;
        }
        if( type == TYPE_STRING )
            return new StringAtom( toString() );
        throw new EvaluateException( "cannot convert type "+typeNumber()+" to "+type, this );
    }
    
    /* ===================================== */
    
    /** 
     * To represent complex atom as list.
     * It calls getPart() up to listSize() times and uses FunctorListN form.
     * Subclasses may want to implement it to use smaller FunctorList, 
     * or for efficiency.
     * @return representation of complex atom as a functor list
     */
    FunctorList toList() {
    	int len = listSize();
    	if( len == 0 ) {
            // atoms cannot be represented as lists
        	return null;
    	}
    	LispObject args[] = new LispObject[len-1];
    	for( int i=1; i<len; i++) {
    		args[i-1] = getPart(i);
    	}
    	try {
    		return new FunctorListN((NameObjectBase)getPart(0),args);
    	}
    	catch(ClassCastException e) {
    		throw new IllegalArgumentException("wrong getPart(0) implementation");
    	}
    }
    
    /**
     * Returns member of a complicated atom (represented as a list)
     * @param item member number (in list representation). 
     * When item = 0 returns functor name
     * @return part of list
     * @throws IllegalArgumentException for illegal item number
     */
    LispObject getPart(int item) throws IllegalArgumentException {
        // atoms cannot be represented as lists
    	// this function is also called by implementations if part number is wrong
    	throw new IllegalArgumentException("Wrong call of getPart()");
    }
    
    /**
     * Sets item of list to new value
     * @param item item number
     * @param newvalue new value to set to
     * @return old value of the list item
     * @throws IllegalArgumentException if item number is illegal or if newvalue is wrong type, 
     * or item is readonly and can't be set
     */
    LispObject setPart(int item, LispObject newvalue) throws IllegalArgumentException {
    	throw new IllegalArgumentException("Wrong call of setPart()");
    }
    
    /**
     * Used in Lisp representation
     * @param sb
     */
    public void toBuffer(StringBuffer sb) {
        FunctorList list = toList();
        if (list != null) {
            list.toBuffer(sb);
            return;
        }
        if (this == NIL)
            sb.append("nil");
        else {
            sb.append('<');
            sb.append(getClass().getName());
            sb.append('>');
        }
    }

    /**
     * Used to represent atoms (and lists) in worksheets formulas. The representation must be
     * supported by Operator.parseFormula(), this is related interfaces. To be overrided by
     * implementations.
     * 
     * @param sb
     *            Buffer to write to. To get a string use toFormulaString()
     */    
    public void toFormulaBuffer( StringBuffer sb ) {            // to be displayed in FW
        // adds nothing for NIL implementation
        if( this == NIL )
            return;
        // if not overriden, lisp representation will be used
        toBuffer( sb );
    }
    
    /**
     * Used to represent atoms as values in cells. Not actual for functors
     * @param sb
     *      buffer to append to
     * @param format
     *      cell format
     */
    public void toValueBuffer( StringBuffer sb, int format ) {
        // intended for atoms
        // adds noyhing for NIL implementation
        if( this == NIL )
            return;         // empty
        toBuffer( sb );
    }
    
    /** Gets string representation of a lisp object to be used in WS formulas.
     * This string must be parsed by Operator.parseFormula().
     * Just call toFormulaBuffer().
     * @return String representation of atom/list in WS formulas
     */    
    public String toFormulaString() {
        StringBuffer sb = new StringBuffer();
        toFormulaBuffer( sb );
        return sb.toString();
    }
    
    // intended for atoms
    public String toValueString( int format ) {
        StringBuffer sb = new StringBuffer();
        toValueBuffer( sb, format );
        return sb.toString();
    }
    
    public String toString() {
        StringBuffer sb = new StringBuffer();
        toBuffer( sb );
        return sb.toString();
    }
    
    protected void addIdent( StringBuffer sb, int ident ) {
        for( int i=0; i<ident; i++ )
            sb.append("    ");
    }
    
//#ifdef JAVA_COMPILER
    public void toJavaBuffer( StringBuffer sb, int ident, FunctorList parent ) {
        FunctorList list = toList();
        if( list != null ) {
           list.toJavaBuffer( sb, ident, null );
           return;
        }
        addIdent( sb, ident );
        sb.append( "NIL" );
    }
    
    /** used to print lisp objects as java code, to compile lisp -> native (JVM)
     * @return Java code constructing corresponding lisp code
     * by calling constructors (new LispObject())
     * Use LispObject.evaluateSExp() to run this code
     */    
    public String toJavaString() {
        StringBuffer sb = new StringBuffer();
        toJavaBuffer( sb, 0, null );
        return sb.toString();
    }
//#endif    

//#ifndef MINIMAL_SET                
    /**
     * Preprocesses lisp tree, evaluates preprocessor functors such as ($if)
     * [shouldn't it be done for (ref) or (qlist)?] 
     * @param functor functor to be evaluated
     * @return tree with replaced preprocessor functors
     * @throws EvaluateException when can't evaluate sexp of conditional
     */
    public LispObject preprocess(NameObjectBase functor) throws EvaluateException {
        return this;
    }
//#endif    

    // to display on sheet screen, actual for references ie.
    // actual for atoms since all other cannot be result of expression
    // will be extended to support formatters
//    public String toScreenString() {
//        return toString();
//    }
    
    // =========================================================
    // FunctorList factory
    // =========================================================
    public static final QuotedList EMPTY_LIST = new QuotedList(new LispObject[0]);
    
    // throws classcastexception if functor is not a nameobject
    public static FunctorList createFunctorList(LispObject args[]) throws ClassCastException {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -