// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme;

import bdc.util.URLUtil;
import bdc.scheme.compiler.Compiler;
import bdc.scheme.exception.ParseException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PushbackReader;
import java.net.URL;

/**
    Loader encapsulates the functionality of the Scheme file loader
*/
public final class Loader
{
    private Compiler compiler;

    /**
        Create a loader
    */
    Loader (Compiler compiler)
    {
        this.compiler = compiler;
    }

    /**
        Helper to load from a file
    */
    public Object load (URL url, String relative, Stack stack) throws SchemeException
    {
        try {
            if (!URLUtil.maybeURLExists(url)) {
                url = this.getClass().getClassLoader().getResource(relative);
            }
            return
                load(
                    new BufferedReader(
                        new InputStreamReader(url.openStream())),
                    url.toString(),
                    stack);
        }
        catch (IOException ioe) {
            throw new ParseException(url.toString(),
                                     0,
                                     ioe.toString());
        }
    }

    /**
        Loads from a InputStream and returns the result of evaluating the
        last object from the InputStream
    */
    public Object load (java.io.Reader in,
                        String filename,
                        Stack stack)
      throws SchemeException
    {
        PushbackReader input = new PushbackReader(in);
        Reader reader = new Reader(filename, input);
        Object expression = reader.read();
        Object result = Scheme.Unspecified;
        while (expression != Scheme.EOFObject) {
            result = compiler.eval(expression, stack);
            expression = reader.read();
        }
        return result;
    }
}
