static char rcsid[] = "$Id: F-mem.c,v 1.15 2000/12/27 15:23:41 m-hirano Exp $";
/* 
 * $RWC_Release: Omni-1.6 $
 * $RWC_Copyright:
 *  Omni Compiler Software Version 1.5-1.6
 *  Copyright (C) 2002 PC Cluster Consortium
 *  
 *  This software is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version
 *  2.1 published by the Free Software Foundation.
 *  
 *  Omni Compiler Software Version 1.0-1.4
 *  Copyright (C) 1999, 2000, 2001.
 *   Tsukuba Research Center, Real World Computing Partnership, Japan.
 *  
 *  Please check the Copyright and License information in the files named
 *  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
 *  Software release kit.
 *  
 *  
 *  $
 */
#include "F-front.h"

#define XMALLOC(t,size)	((t)xmalloc(size))

ID
new_ident_desc(sp)
     SYMBOL sp;
{
    ID id;
    id = XMALLOC(ID,sizeof(*id));
    ID_SYM(id) = sp;
    return(id);
}

EXT_ID
new_external_id(sp)
     SYMBOL sp;
{
    EXT_ID id;
    id = XMALLOC(EXT_ID,sizeof(*id));
    EXT_SYM(id) = sp;
    return(id);
}

TYPE_DESC
new_type_desc()
{
    TYPE_DESC tp;
    tp = XMALLOC(TYPE_DESC,sizeof(*tp));
    return(tp);
}

/* construct expression */
expv
expv_cons(code,tp,left,right)
     enum expr_code code;
     TYPE_DESC tp;
     expv left,right;
{
    expv v;
    struct list_node *l,*r;

    v = XMALLOC(expv,sizeof(*v));
    l = XMALLOC(struct list_node *,sizeof(struct list_node));
    EXPV_CODE(v) = code;
    EXPV_TYPE(v) = tp;
    EXPV_LIST(v) = l;
    l->l_item = left;
    if(right){
	r = XMALLOC(struct list_node *,sizeof(struct list_node));
	r->l_item = right;
	l->l_next = r;
    }
    return(v);
}


/* FOR:
 * 	IDENT 
 * 	STRING_CONSTANT
 *	LABEL_CONSTANT
 */	
expv
expv_sym_term(code,tp,name)
     enum expr_code code;
     TYPE_DESC tp;
     SYMBOL name;
{
    expv v;

    v = XMALLOC(expv,sizeof(*v));
    EXPV_CODE(v) = code;
    EXPV_TYPE(v) = tp;
    EXPV_NAME(v) = name;
    return(v);
}

expv
expv_str_term(code,tp,str)
     enum expr_code code;
     TYPE_DESC tp;
     char *str;
{
    expv v;

    v = XMALLOC(expv,sizeof(*v));
    EXPV_CODE(v) = code;
    EXPV_TYPE(v) = tp;
    EXPV_STR(v) = strdup(str);
    return(v);
}


expv
expv_int_term(code, tp, i)
     enum expr_code code;
     TYPE_DESC tp;
     int i;
{
    expv v;

    v = XMALLOC(expv,sizeof(*v));
    EXPV_CODE(v) = code;
    EXPV_TYPE(v) = tp;
    EXPV_GEN(v) = (void *)((_omAddrInt_t)i);
    return(v);
}


expv
expv_any_term(code,p)
     enum expr_code code;
     void *p;
{
    expv v;

    v = XMALLOC(expv,sizeof(*v));
    EXPV_CODE(v) = code;
    EXPV_TYPE(v) = NULL;
    EXPV_GEN(v) = p;
    return(v);
}

expv
expv_float_term(code,tp,d)
     enum expr_code code;
     TYPE_DESC tp;
     double d;
{
    expv v;

    v = XMALLOC(expv,sizeof(*v));
    EXPV_CODE(v) = code;
    EXPV_TYPE(v) = tp;
    EXPV_FLOAT_VALUE(v) = d;
    return(v);
}

#ifdef ENABLE_QREAL
expv
expv_qreal_term(code,tp,strV)
     enum expr_code code;
     TYPE_DESC tp;
     expv strV;
{
    expv v;

    v = XMALLOC(expv,sizeof(*v));
    EXPV_CODE(v) = code;
    EXPV_TYPE(v) = tp;
    EXPV_QREAL_CONST(v) = strV;
    return(v);
}
#endif /* ENABLE_QREAL */

expv
expv_longlong_term(code,tp,h,l)
     enum expr_code code;
     TYPE_DESC tp;
     int h;
     int l;
{
    expv v;

    v = XMALLOC(expv,sizeof(*v));
    EXPV_CODE(v) = code;
    EXPV_TYPE(v) = tp;
    EXPV_LLINT_HIGH(v) = h;
    EXPV_LLINT_LOW(v) = l;
    return(v);
}

expv
expv_retype(tp,v)
     TYPE_DESC tp;
     expv v;
{
    expv vv;
    vv = XMALLOC(expv,sizeof(*v));
    bcopy(v,vv,sizeof(*v));
    EXPV_TYPE(vv) = tp;
    return(vv);
}


static void
listToArray(lp)
     list lp;
{
    if (LIST_ARRAY(lp) == NULL) {
	list lq;
	int i = 0;
	int n = 0;
	for (lq = lp; lq != NULL; lq = lq->l_next) {
	    n++;
	}
	LIST_N_ITEMS(lp) = n;
	if (LIST_N_ITEMS(lp) > 0) {
	    LIST_ARRAY(lp) = (struct list_node **)malloc(sizeof(struct list_node *) * LIST_N_ITEMS(lp));
	    for (lq = lp; i < LIST_N_ITEMS(lp); i++, lq = lq->l_next) {
		lp->l_array[i] = lq;
	    }
	}
    }
}

expr
expr_list_get_n(x, n)
     expr x;
     int n;
{
    list lp;
    int i;
    for (i = 0, lp = EXPR_LIST(x); (i < n && lp != NULL); i++, lp = LIST_NEXT(lp)) {};
    if (lp == NULL) {
	return NULL;
    }
    return LIST_ITEM(lp);
}

int
expr_list_set_n(x, n, val, doOverride)
     expr x;
     int n;
     expr val;
     int doOverride;
{
    list lp = EXPR_LIST(x);
    
    if (LIST_ARRAY(lp) == NULL) {
	listToArray(lp);
    }
    if (n >= LIST_N_ITEMS(lp)) {
	return FALSE;
    }
    lp = LIST_ARRAY(lp)[n];
    if (doOverride == FALSE) {
	if (LIST_ITEM(lp) != NULL) {
	    return FALSE;
	}
    }
    LIST_ITEM(lp) = val;

    return TRUE;
}

