/*
 * 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_ */
