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

/* ======================================================================== */
/* [using] */

Stmt *new_Stmt__using(Ctx *ctx, Token **ts, knh_int_t s, knh_int_t e, knh_int_t *cp)
{
    DEBUG_ASSERT(ts[s]->tt == TT_USING);
    DEBUG_ASSERT(s == *cp);
    Stmt *b = NULL;
    *cp += 1;
    if(!(*cp < e)) {
        MC_EPRINT(ctx, ts[s], MC_ERROR, "using statement: no entry");
        return new_Stmt__SyntaxError(ctx, ts, s, e, cp);
    }
    knh_bytes_t op = knh_Token_tobytes(ts[*cp]);
    if(ISB(op, "")) {
        b = new_Stmt(ctx, 0, STT_UIMPORT);
        *cp += 1;
        goto L_META;
    }
    if(ISB(op, "")) {
        b = new_Stmt(ctx, 0, STT_UVOCAB);
        *cp += 1;
        goto L_META;
    }
    if(ISB(op, "")) {
        b = new_Stmt(ctx, 0, STT_UINT);
        *cp += 1;
        goto L_META;
    }
    if(ISB(op, "")) {
        b = new_Stmt(ctx, 0, STT_ULONG);
        *cp += 1;
        goto L_META;
    }
    if(ISB(op, "")) {
        b = new_Stmt(ctx, 0, STT_UFLOAT);
        *cp += 1;
        goto L_META;
    }
    if(knh_Token_isCLASSTN(ts[*cp])) {
       if(knh_bytes_startsWith(op, STEXT("Int::"))) {
           b = new_Stmt(ctx, 0, STT_UINT);
            goto L_META;
       }
       if(knh_bytes_startsWith(op, STEXT("Float::"))) {
           b = new_Stmt(ctx, 0, STT_UFLOAT);
            goto L_META;
       }
       if(knh_bytes_startsWith(op, STEXT("String::"))) {
           b = new_Stmt(ctx, 0, STT_UVOCAB);
            goto L_META;
       }
       if(knh_bytes_startsWith(op, STEXT("Long::"))) {
           b = new_Stmt(ctx, 0, STT_ULONG);
            goto L_META;
       }
       KNH_GOTO(L_ERR);
    }
    if(knh_Token_isNSCLASSN(ts[*cp])) {
        if(knh_bytes_startsWith(op, STEXT("import"))) {
            b = new_Stmt(ctx, 0, STT_UIMPORT);
            goto L_META;
       }
    }
    else{
        KNH_GOTO(L_ERR);
    }
    
    L_META:;
    DEBUG_ASSERT(b != NULL);
    knh_Stmt_add_meta(ctx, b, ts, s);

    if(b->stt == STT_UIMPORT) {
        goto L_3;
    }
    /* CLASSQN */
    if(*cp < e && knh_Token_isCLASSTN(ts[*cp])) {
        knh_Stmt_terms_add(ctx, b, ts[*cp]);
        *cp += 1;
        goto L_3;
    }
    else {
        KNH_GOTO(L_ERR);
    }
    L_3:;
    /* CURN */
    if(*cp < e && knh_Token_isNSCLASSN(ts[*cp])) {
        knh_Stmt_terms_add(ctx, b, ts[*cp]);
        *cp += 1;
        goto L_4;
    }
    else {
        KNH_GOTO(L_ERR);
    }
    L_4:;
    /* ; */
    if(*cp < e && ts[*cp]->tt == TT_SEMICOLON) {
        *cp += 1;
        return b;
    }
    else {
        //MC_EPRINT(ctx, ts[*cp-1], MC_NOTICE, "; required");
        return b;
    }
    L_ERR:;
    knh_int_t ee = knh_tokens_epos(s, *cp, e);
    MC_EPRINT(ctx, ts[ee], MC_ERROR, "using statement: %s", knh_Token_tochar(ts[ee]));
    knh_Stmt_toSyntaxError(ctx, b, ts[ee]);
    *cp = knh_tokens_nextstmt(ts, *cp, e);
    return b; 
}

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


#ifdef __cplusplus
}
#endif
