/*
 * The contents of this file are subject to the Netscape Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/NPL/

 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.

 * The Original Code is Rhino code, released
 * May 6, 1999.

 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1997-1999 Netscape Communications Corporation. All
 * Rights Reserved.

 * Contributor(s): 

 * Alternatively, the contents of this file may be used under the
 * terms of the GNU Public License (the "GPL"), in which case the
 * provisions of the GPL are applicable instead of those above.
 * If you wish to allow use of your version of this file only
 * under the terms of the GPL and not to allow others to use your
 * version of this file under the NPL, indicate your decision by
 * deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL.  If you do not delete
 * the provisions above, a recipient may use your version of this
 * file under either the NPL or the GPL.
 */

#ifndef _JS_I_R_FACTORY_H_
#define _JS_I_R_FACTORY_H_

#include "js-types.h"
#include "js-zonenew.h"
#include "js-node.h"
#include "js-tokenstream.h"

/* Classes */
class JSIRFactory: public JSZoneNew {
    protected:
        JSTokenStream   *ts;
        JSScriptable    *scope;

    protected:
        JSNode  *createConvert(JSContext *cx, jsType_t toType, JSNode *expr);
        JSNode  *createSetName(JSContext *cx, int nodeOp, JSNode *left,
                        JSNode *right, jsType_t convert, jsBool_t postfix);
        JSNode  *createSetProp(JSContext *cx, int nodeType, int nodeOp,
                        JSNode *obj, JSNode *id, JSNode *expr,
                        jsType_t convert, jsBool_t postfix);
        void    reportError(JSContext *cx, jsString_t msgResource);

    public:
        static jsBool_t
                        hasSideEffects(JSNode *exprTree);

        JSIRFactory(JSTokenStream *ts, JSScriptable *scope);

        JSNode  *createScript(JSContext *cx, JSNode *body,
                        jsString_t sourceName, int baseLineno, int endLineno,
                        jsString_t source, int sourceLength);
        JSNode  *createLeaf(JSContext *cx, int nodeType);
        JSNode  *createLeaf(JSContext *cx, int nodeType, jsString_t id);
        JSNode  *createLeaf(JSContext *cx, int nodeType, int nodeOp);
        JSNode  *createSwitch(JSContext *cx, int lineno);
        JSNode  *createVariables(JSContext *cx, int lineno);
        JSNode  *createExprStatement(JSContext *cx, JSNode *expr, int lineno);
        JSNode  *createName(JSContext *cx, jsString_t name);
        JSNode  *createString(JSContext *cx, jsString_t string);
        JSNode  *createNumber(JSContext *cx, double number);
        JSNode  *createCatch(JSContext *cx, jsString_t varName,
                        JSNode *catchCond, JSNode *stmts, int lineno);
        JSNode  *createThrow(JSContext *cx, JSNode *expr, int lineno);
        JSNode  *createReturn(JSContext *cx, JSNode *expr, int lineno);
        JSNode  *createLabel(JSContext *cx, jsString_t label, int lineno);
        JSNode  *createBreak(JSContext *cx, jsString_t label, int lineno);
        JSNode  *createContinue(JSContext *cx, jsString_t label, int lineno);
        JSNode  *createBlock(JSContext *cx, int lineno);
        JSNode  *createFunctionNode(JSContext *cx, jsString_t name,
                        JSNode *args, JSNode *statements);
        JSNode  *createFunction(JSContext *cx, jsString_t name, JSNode *args,
                        JSNode *statements, jsString_t sourceName,
                        int baseLineno, int endLineno, jsString_t source,
                        int sourceLength, jsBool_t isExpr);
        void    setFunctionExpressionStatement(JSContext *cx, JSNode *o);
        void    addChildToBack(JSNode *parent, JSNode *child);
        JSNode  *createWhile(JSContext *cx, JSNode *cond, JSNode *body,
                        int lineno);
        JSNode  *createDoWhile(JSContext *cx, JSNode *body, JSNode *cond,
                        int lineno);
        JSNode  *createFor(JSContext *cx, JSNode *init, JSNode *test,
                        JSNode *incr, JSNode *body, int lineno);
        JSNode  *createForIn(JSContext *cx, JSNode *lhs, JSNode *obj,
                        JSNode *body, int lineno);
        JSNode  *createTryCatchFinally(JSContext *cx, JSNode *tryblock,
                        JSNode *catchblocks, JSNode *finallyblock, int lineno);
        JSNode  *createWith(JSContext *cx, JSNode *obj, JSNode *body,
                        int lineno);
        JSNode  *createArrayLiteral(JSContext *cx, JSNode *obj);
        JSNode  *createObjectLiteral(JSContext *cx, JSNode *obj);
        JSNode  *createRegExp(JSContext *cx, jsString_t string,
                        jsString_t flags);
        JSNode  *createIf(JSContext *cx, JSNode *cond, JSNode *ifTrue,
                        JSNode *ifFalse, int lineno);
        JSNode  *createTernary(JSContext *cx, JSNode *cond, JSNode *ifTrue,
                        JSNode *ifFalse);
        JSNode  *createUnary(JSContext *cx, int nodeType, JSNode *child);
        JSNode  *createUnary(JSContext *cx, int nodeType, int nodeOp,
                        JSNode *child);
        JSNode  *createBinary(JSContext *cx, int nodeType, JSNode *left,
                        JSNode *right);
        JSNode  *createBinary(JSContext *cx, int nodeType, int nodeOp,
                        JSNode *left, JSNode *right);
        JSNode  *createAssignment(JSContext *cx, int nodeOp, JSNode *left,
                                JSNode *right, jsType_t convert,
                                jsBool_t postfix);
        JSNode  *createNewTemp(JSContext *cx, JSNode *n);
        JSNode  *createUseTemp(JSContext *cx, JSNode *newTemp);
        JSNode  *createNewLocal(JSContext *cx, JSNode *n);
        JSNode  *createUseLocal(JSContext *cx, JSNode *newLocal);
#ifdef REUSE_LOCAL
        JSNode  *createDelTemp(JSContext *cx, JSNode *n, JSNode *newTemp);
#endif
} ;

#endif /* _JS_I_R_FACTORY_H_ */
