/****************************************************************************
 * KONOHA COPYRIGHT, LICENSE NOTICE, AND DISCRIMER  
 * 
 * Copyright (c) 2005-2008, Kimio Kuramitsu <kimio at ynu.ac.jp>
 *           (c) 2008-      Konoha Software Foundation  
 * All rights reserved.
 * 
 * You may choose one of the following two licenses when you use konoha. 
 * See www.konohaware.org/license.html for further information.
 * 
 * (1) GNU General Public License 2.0      (with    KONOHA_UNDER_GPL2)
 * (2) Konoha Software Foundation License 1.0
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *  
 ****************************************************************************/

/* ************************************************************************ */

#include"commons.h"

/* ************************************************************************ */

#ifdef __cplusplus 
extern "C" {
#endif

	
/* ======================================================================== */
/* [ERR] */
	
void knh_Stmt_toERR(Ctx *ctx, Stmt *stmt, String *msg)
{
	knh_Stmt_done(ctx, stmt);
	SP(stmt)->stt = STT_ERR;
	KNH_SETv(ctx, DP(stmt)->errMsg, msg);
}

/* ------------------------------------------------------------------------ */
	
void knh_StmtERR_cmpl(Ctx *ctx, Stmt *stmt, Compiler *cpr, NameSpace *ns, knh_type_t reqt, int level)
{
	if(IS_bString(DP(stmt)->errMsg)) {
		KNH_ASM_THROW__OBJ(ctx, cpr, (Object*)DP(stmt)->errMsg);
	}
	else {
		KNH_ASM_THROW__OBJ(ctx, cpr, (Object*)TS_SYNTAXERR);
	}
	knh_Compiler_setStopped(cpr, 1);
}

/* ======================================================================== */
/* [PRINT] */

static
knh_methodn_t knh_Stmt_getMT(Ctx *ctx, Stmt *stmt, size_t n)
{
	knh_methodn_t mn = METHODN__k;
	Stmt *o = DP(stmt)->stmts[n];
	if(IS_Stmt(o) && SP(o)->stt == STT_MT) {
		KNH_ASSERT(DP(o)->size > 1);
		mn = knh_Token_tomethodn(ctx, DP(o)->tokens[0]);
		KNH_SETv(ctx, DP(stmt)->terms[n], DP(o)->terms[1]);
	}
	return mn;
}

/* ------------------------------------------------------------------------ */

static
String *knh_Term_getNameNULL(Term *tm)
{
	Token *tk = (Token*)tm;
	if(!IS_Token(tk)) {
		return NULL;
	}
	else if(SP(tk)->tt == TT_NAME) {
		DEBUG3_ASSERT(IS_String(DP(tk)->data));
		return (String*)DP(tk)->data;
	}
	return NULL;
}

/* ------------------------------------------------------------------------ */
	
void knh_StmtPRINT_cmpl(Ctx *ctx, Stmt *stmt, Compiler *cpr, NameSpace *ns, knh_type_t reqt, int level)
{
	knh_flag_t flag = knh_StmtMETA_flagPRINT(ctx, stmt);
	if(DP(stmt)->size == 0) {
		Object *o = (Object*)TS_EMPTY;
		KNH_ASM_PRINT__OBJ(ctx, cpr, flag | KNH_FLAG_PF_EOL | KNH_FLAG_PF_EMPTY, o, METHODN__s, o);
	}
	else {
		int i;
		knh_flag_t mask = 0;
		for(i = 0; i < DP(stmt)->size; i++) {
			knh_methodn_t mn = knh_Stmt_getMT(ctx, stmt, i);
			String *name = knh_Term_getNameNULL(DP(stmt)->terms[i]);
			if(i == 0) {
				mask |= KNH_FLAG_PF_BOL;
			}
			if(i == DP(stmt)->size - 1) {
				mask |= KNH_FLAG_PF_EOL;
			}
			
			if(name == NULL) {
				knh_Stmt_terms_typing(ctx, stmt, i, cpr, ns, CLASS_Any);
				name = (String*)knh_Term_constValue(ctx, DP(stmt)->terms[i], CLASS_Any);
				if(IS_bString(name)) {
					KNH_ASM_PRINT__OBJ(ctx, cpr, flag | mask | KNH_FLAG_PF_EMPTY, (Object*)name, mn, (Object*)TS_EMPTY);
					mask = 0;
					mask |= KNH_FLAG_PF_NOCOMMA;
				}
				else {
					knh_Stmt_terms_cmpl(ctx, stmt, i, cpr, ns, CLASS_Any, 0);
					KNH_ASM_PRINT(ctx, cpr, flag | mask, (Object*)KNH_NULL, mn, DP(stmt)->terms[i]);
					mask = 0;
				}
			}
			else {
				//DEBUG3("name='%s', refc=%d", knh_String_tochar(name), (int)name->h.refc);
				knh_Stmt_terms_cmpl(ctx, stmt, i, cpr, ns, CLASS_Any, 0);
				KNH_ASSERT(name->h.refc > 0);
				//DEBUG3("name='%s', refc=%d", knh_String_tochar(name), (int)name->h.refc);
				KNH_ASM_PRINT(ctx, cpr, flag | mask | KNH_FLAG_PF_NAME, (Object*)name, mn, DP(stmt)->terms[i]);
				mask = 0;
			}
		}
	}
}

/* ------------------------------------------------------------------------ */

void knh_StmtASSERT_decl(Ctx *ctx, Stmt *stmt, Compiler *cpr, NameSpace *ns, knh_type_t reqt, int level)
{
	//DEBUG_STMT(ctx, stmt);
	//Compiler *mc = (Compiler*)v;
	/* ['assert', 'expr'] */

	//knh_Stmt_dispatch(ctx, stmt, knh_stmtvisit_asm, v, level, step);
	//knh_Stmt_done(ctx, stmt);
}


/* ------------------------------------------------------------------------ */

#ifdef __cplusplus
}
#endif
