// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme;

import bdc.util.FastStringBuffer;
import bdc.util.Fmt;
import java.util.List;

/**
    Encapsulates the knowledge of the Scheme printer
*/
public final class Writer
{
    /*
        write tries to be the inverse of what we can read.

        It special cases Booleans, Strings, char[],
        Characters, and List to match the reader.

        It also special cases Object[] for debugging.
    */

    public static String write (Object expression)
    {
        /*
            Writing Booleans used reader syntax
        */
        if (expression == Boolean.TRUE) {
            return "#t";
        }
        if (expression == Boolean.FALSE) {
            return "#f";
        }

        /*
            Writing strings puts quotes around them
        */
        if (expression instanceof String) {
            return Fmt.S("\"%s\"", expression);
        }
        if (expression instanceof char[]) {
            char[] chars = (char[])expression;
            FastStringBuffer fsb = new FastStringBuffer(chars.length+2);
            fsb.append('"');
            fsb.append(chars);
            fsb.append('"');
            return fsb.toString();
        }

        /*
            Writing Characters used reader syntax
        */
        if (expression instanceof Character) {
            char ch = ((Character)expression).charValue();
            if (ch == ' ') {
                return "#\\space";
            }
            if (ch == '\n') {
                return "#\\newline";
            }
            return Fmt.S("#\\%s", expression);
        }

        /*
            Write Lists used reader syntax (which the Reader doesn't yet do)
        */
        if (expression instanceof List) {
            FastStringBuffer result = new FastStringBuffer("#(");
            List l = (List)expression;
            for (int i=0, s=l.size(); i<s; i++) {
                if (i!=0) {
                    result.append(' ');
                }
                Object object = l.get(i);
                result.append(Writer.write(object));
            }
            result.append(')');
            return result.toString();
        }

        /*
            Object arrays can be printed out when debugging environments
        */
        if (expression instanceof Object[]) {
            FastStringBuffer result = new FastStringBuffer("{");
            Object objects[] = (Object[])expression;
            for (int i = 0; i < objects.length; i++) {
                result.append(Writer.write(objects[i]));
                if (i+1 < objects.length) {
                    result.append(' ');
                }
            }
            result.append('}');
            return result.toString();
        }

        return String.valueOf(expression);
    }
}
