/* --COPYRIGHT--,EPL
 *  Copyright (c) 2008 Texas Instruments and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *      Texas Instruments - initial implementation
 *
 * --/COPYRIGHT--*/
package xdc.services.intern.xsr;

import java.util.Vector;
import java.util.LinkedHashMap;
import java.util.Iterator;
import java.util.HashMap;
import java.util.Collection;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Undefined;

/*
 *  ======== Proto ========
 */
public abstract class Proto extends XScriptO
    implements Function
{
    interface ObjRef {};
    public interface Pred{};
    interface Sealable {};

    interface Aggregate {
        Object create(Value prnt, String name, boolean ronly, Object initval,
                      boolean check);
    }

    interface Embedded extends Aggregate {}

    public interface Typedef {
        Proto getBase();
        Function getEncFxn();
        void init( String name, Object base, Object encFxn );
    }

    abstract Object assign( Object oldval, Object newval );
    abstract boolean assignable( Proto proto );

    String toText( Object val )
    {
        if (val == null) {
            return "null";
        }
        else if (val instanceof Undefined) {
            return "undefined";
        }
        else {
            return val.toString();
        }
    }

    static Object unwrap( Object o )
    {
        return (o instanceof NativeJavaObject ? ((NativeJavaObject)o).unwrap() : o);
    }

    int depth() { return 0; }

    // interface Function

    public Object call( Context cx, Scriptable scope, Scriptable thisObj, Object[] args )
    {
        Err.exit("unsupported operation");
        return Context.getUndefinedValue();
    }

    public Scriptable construct( Context cx, Scriptable scope, Object[] args )
    {
        Err.exit("unsupported operation");
        return null;
    }

    // Proto.Adr
    /* This type represents configuration parameters of pointer types */
    static public class Adr extends Proto
        implements ObjRef, Pred
    {
        String sig;
        boolean anyT;
        boolean fxnT;

        public Adr( String sig, String code )
        {
            this.sig = sig;
            this.anyT = code.equals("Pv");
            this.fxnT = code.startsWith("PF");
        }

        Object assign( Object oldval, Object newval )
        {
            newval = Proto.unwrap(newval);
            if (newval == null || newval instanceof Undefined
                || newval == Value.DEFAULT || newval == Value.NOGEN) {
                return newval;
            }

//            System.out.println("Proto.Adr.assign: (" + this.sig + ")"
//                + this
//                + " = (" + newval.getClass().getName() + ")"
//                + newval);
            if (this.anyT) {

                if (newval instanceof AnyType) {
                    return newval;
                }
                if (newval instanceof CharSequence || newval instanceof Number
                    || newval instanceof Boolean ) {
                    return newval;
                }
            }

            if (newval instanceof Value.Obj && this.sig.equals(
                    ((Value.Obj) newval).proto.name.replace('.', '_') + "*")) {
                return newval;
            }

            if (newval instanceof Extern) {
                /* An Extern of the correct type can be assigned to a pointer
                 * config parameter.
                 */
                Extern ext = (Extern)newval;
                if (ext.sig == null) {
                    /* This Extern is created by calling the operator $externPtr
                     * and the signature was set to 'null'. Now we know the
                     * signature of the pointer we are assigning too, so we
                     * should adjust the type. We use the pointer's type when
                     * 'newval' is a string starting with '&'.
                     */
                    Extern typed = new Extern(ext.getName(), this.sig,
                                              ext.isFxnT(), ext.isRaw());
                    return ext.isFxnT() == this.isFxnT() ? typed : Value.ERROR;
                }
                else {
                    return this.sig.equals(ext.sig) ? newval : Value.ERROR;
                }
            }

            if (newval instanceof Ptr) {
                return newval;
            }

            /* This is the case where the assigned value is a string with the
             * name of a global variable preceeded by '&'. That syntax works 
             * only for types that do not accept values of multiple types
             * (this.anyT flags such types). If a config parameter of type Ptr
             * is assigned "&label", it cannot mean a symbol 'label', because 
             * then we wouldn't be able to assign the string "&label" to that
             * parameter, which is a valid value for Ptr. We have to use
             * $externPtr when we mean "the symbol 'label'". Therefore, the
             * IF statement that checks if anyT is true comes first, and it
             * will catch any string, and treat it as a string. If anyT is
             * false, the IF block below will convert a string that starts
             * with '&' to an Extern.
             * The type Fxn cannot accept strings, and anyT is always false
             * for that type, so both syntaxes above can only mean "the symbol
             * 'label'", and we accept them both in the following IF block.
             *
             * The implementation of the logic described here is based on the
             * type we return from this function. In case of Ptr, we return a
             * string and for Fxn, we return an Extern instance. Then, in 
             * gen/Config.java, in ptrToStr(), an Extern is always treated as
             * a symbol, while a string is just copied and quoted.
             */
            if (newval instanceof CharSequence) {
                String s = newval.toString();
                if (s.startsWith("&") && s.length() > 1) {
                    if (s.matches(".*\\s.*")) {
                        return (Value.ERROR);
                    }
                    return new Extern(s.substring(1), this.sig, this.fxnT,
                                      true);
                }
            }

            if (newval instanceof Addr) {
                return ((Addr)newval).val == 0 ? null : newval;
            }
/*
            if (!this.anyT) {
                return Value.ERROR;
            }

            if (newval instanceof String || newval instanceof Number || newval instanceof Boolean ) {
                return newval;
            }

            if (newval instanceof Value || newval instanceof Enum || newval instanceof Extern) {
                return newval;
            }
*/
            /* allow "config Bits8 *FOO = 0x32;" */
            if (newval instanceof Number) {
                return newval;
            }

            return Value.ERROR;
        }

        boolean assignable( Proto proto )
        {
            // TODO: fix this
            return true;
        }

        public final String getSig() { return this.sig; }

        public final boolean isAnyT() { return this.anyT; }
        public final boolean isFxnT() { return this.fxnT; }

        String toText( Object val )
        {
            if (val instanceof Value.Obj) {
                return (String) ((Value.Obj) val).getDefaultValue(null);
            }
            else if (val instanceof Extern) {
                Extern e = (Extern) val;
                return e.name.startsWith("0x") ? e.name : "&" + e.name;
            }
            else if (val instanceof Number) {
                return Proto.Elm.numval((Number) val);
            }
            else {
                return super.toText(val);
            }
        }
    }

    // Proto.Arr

    static public class Arr extends Proto
        implements Aggregate, Embedded, Pred, Sealable
    {
        Proto base;
        boolean lflag;
        int dim;
        int curid = 0;

        public Arr( Object base )
        {
            this(base, true, -1);
        }

        public Arr( Object base, boolean lflag )
        {
            this(base, lflag, -1);
        }

        public Arr( Object base, boolean lflag, Number dim )
        {
            this(base, lflag, dim.intValue());
        }

        public Arr( Object base, boolean lflag, long dim )
        {
            this(base, lflag, (int)dim);
        }

        public Arr( Object base, boolean lflag, int dim )
        {
            this.base = (Proto)base;
            this.lflag = lflag;
            this.dim = dim;
        }

        Object assign( Object oldval, Object newval )
        {
            newval = Proto.unwrap(newval);

            if (newval instanceof Undefined) {
                newval = Value.DEFAULT;
            }

            Value.Arr varr = (Value.Arr)oldval;
            Object res;

            if (varr != null && varr.sealed(null)) {
                varr.error("sealed array");
            }

            if (newval instanceof Value.Arr) {
                if (!(this.assignable(((Value.Arr)newval).proto))) {
                    res = Value.ERROR;
                }
                else if (varr != null) {
                    varr.assignV(newval);
                    res = varr;
                }
                else {
                    res = newval;
                }
            }

            else if (newval instanceof Addr) {
                varr.bind("$addr", new Long(((Addr)newval).val));
                res = varr;
            }

            else if (newval instanceof Scriptable) {
                if (varr == null) {
                    res = this.create(null, null, false, newval, true);
                }
                else {
                    varr.assignS((Scriptable)newval);
                    res = varr;
                }
            }

            else {
                res = Value.ERROR;
            }

            return res;
        }

        boolean assignable( Proto proto )
        {
            if (!(proto instanceof Proto.Arr)) {
                return false;
            }

            Proto.Arr parr = (Proto.Arr)proto;
            return (this.base.assignable(parr.base));
        }

        public int depth() { return this.base.depth() + 1; }

        public final Proto getBase() { return this.base; }
        public final int getDim() { return this.dim; }
        public final boolean getLflag() { return this.lflag; }

        // interface Aggregate

        public Object create( Value prnt, String name, boolean ronly, Object initval, boolean check )
        {
            Value.Arr varr = new Value.Arr();
            varr.init(this, prnt, name == null ? "[]#" + curid++ : name, ronly, initval, check);
            return varr;
        }

        // OVERRIDE Function

        public Scriptable construct( Context cx, Scriptable scope, Object[] args )
        {
            return (Scriptable)this.create(null, null, false, args.length == 1 ? args[0] : Value.DEFAULT, true);
        }
    }

    // Proto.Elm

    static public class Elm extends Proto
    {
        Class cls;
        String cast = null;

        static public Elm newBool()
        {
            Elm e = new Elm();
            e.cls = Boolean.class;
            return e;
        }

        static public Elm newCNum( String cast )
        {
            Elm e = new Elm();
            e.cls = Number.class;
            e.cast = cast;
            return e;
        }

        static public Elm newNum()
        {
            Elm e = new Elm();
            e.cls = Number.class;
            return e;
        }

        static public Elm newObj()
        {
            Elm e = new Elm();
            e.cls = Object.class;
            return e;
        }

        static public Elm newStr()
        {
            Elm e = new Elm();
            e.cls = String.class;
            return e;
        }

        static public String numval( Number num )
        {
            long lg = num.longValue();
            double d = num.doubleValue();
            if (d != lg) {
                return num.toString();
            }
            else if (lg < 0) {
                return "(-0x" + Long.toHexString(-(lg+1)) + " - 1)";
            }
            else {
                return "0x" + Long.toHexString(lg);
            }
        }

        Object assign( Object oldval, Object newval )
        {
            newval = Proto.unwrap(newval);

            if (newval instanceof Enum) {
                newval = ((Enum)newval).ival;
            }

            if (this.cls.isInstance(newval) || newval instanceof Undefined) {
                // fall through
            }
            else if (newval == null || newval == Value.DEFAULT) {
                newval =
                    (cls == Number.class) ? (Object)(new Integer(0)) :
                    (cls == Boolean.class) ? (Object)(Boolean.FALSE) :
                    null;
            }
            else if (cls == Number.class && newval instanceof Boolean) {
                boolean b = ((Boolean)newval).booleanValue();
                newval = b ? new Integer(1) : new Integer(0);
            }
            else if (cls == Boolean.class && newval instanceof Number) {
                int i = ((Number)newval).intValue();
                newval = i != 0 ? Boolean.TRUE : Boolean.FALSE;
            }
            else if (cls == String.class && newval instanceof CharSequence) {
                newval = newval.toString();
            }
            else if (cls == String.class && newval instanceof Addr) {
                newval = ((Addr)newval).val == 0 ? null : newval;
            }
            else {
                return Value.ERROR;
            }

            return newval;
        }

        boolean assignable( Proto proto )
        {
            return (proto instanceof Proto.Elm 
                    && ((Proto.Elm)proto).cls == this.cls);
        }

        public final String getCast() { return this.cast; }

        String toText( Object val )
        {
            if (val instanceof Number) {
                return Proto.Elm.numval((Number) val);
            }
            else {
                return super.toText(val);
            }
        }
    }

    // Proto.Enm

    static public class Enm extends Proto
    {
        String name;
        HashMap valmap = new HashMap();

        public Enm( String name )
        {
            this.name = name;
        }

        Object assign( Object oldval, Object newval )
        {
            newval = Proto.unwrap(newval);

            if (newval instanceof Undefined) {
                return newval;
            }
            else if (newval instanceof Enum && ((Enum)newval).proto == this) {
                return newval;
            }
            else {
                return Value.ERROR;
            }
        }

        boolean assignable( Proto proto )
        {
            return this == proto;
        }
    }

    /**
     * This is a prototype object for JavaScript functions.
     */
    // Proto.Fxn
    static public class Fxn extends Proto
    {
        Proto.Obj owner;
        Proto ret;
        int minargc;
        boolean vflag;
        Member[] args;

        static OpTab optab = new OpTab(Proto.Fxn.class, new String[] {
            "addArg:$$arg"
        });

        public Fxn(Object owner, Object ret, int argc, int minargc,
                   boolean vflag)
        {
            this.owner = (Proto.Obj)owner;
            this.ret = (Proto)ret;
            this.minargc = minargc;
            this.vflag = vflag;
            this.args = new Member[argc];
            this.bindtab.putAll(Proto.Fxn.optab);
        }

        Object assign( Object oldval, Object newval )
        {
            return Value.ERROR;
        }

        boolean assignable( Proto proto )
        {
            return false;
        }

        public void addArg( int idx, String name, Proto proto, Object defval )
        {
            Member mbr = this.args[idx] = new Member();

            mbr.name = name;
            mbr.proto = proto;
            mbr.defval = defval;
        }
    }

    // Proto.Map

    static public class Map extends Proto
        implements Aggregate, Embedded, Sealable
    {
        Proto base;
        int curid = 0;

        public Map( Object base )
        {
            this.base = (Proto)base;
        }

        Object assign( Object oldval, Object newval )
        {
            newval = Proto.unwrap(newval);

            if (newval instanceof Undefined) {
                newval = Value.DEFAULT;
            }

            Value.Map vmap = (Value.Map)oldval;
            Object res;

            if (vmap != null && vmap.sealed(null)) {
                vmap.error("sealed map");
            }

            if (newval instanceof Value.Map) {
                if (!(this.assignable(((Value.Map)newval).proto))) {
                    res = Value.ERROR;
                }
                else if (vmap != null) {
                    vmap.assignV(newval);
                    res = vmap;
                }
                else {
                    res = newval;
                }
            }

            else if (newval instanceof Scriptable) {
                if (vmap == null) {
                    res = this.create(null, null, false, newval, true);
                }
                else {
                    vmap.assignS((Scriptable)newval);
                    res = vmap;
                }
            }

            else {
                res = Value.ERROR;
            }

            return res;
        }

        boolean assignable( Proto proto )
        {
            if (!(proto instanceof Proto.Map)) {
                return false;
            }

            Proto.Map pmap = (Proto.Map)proto;
            return (this.base.assignable(pmap.base));
        }

        // interface Aggregate

        // interface Aggregate

        public Object create( Value prnt, String name, boolean ronly, Object initval, boolean check )
        {
            Value.Map map = new Value.Map();
            map.init(this, prnt, name == null ? "{}#" + curid++ : name, ronly, initval, check);
            return map;
        }

        // OVERRIDE Function

        public Scriptable construct( Context cx, Scriptable scope, Object[] args )
        {
            return (Scriptable)this.create(null, null, false, args.length == 1 ? args[0] : Value.DEFAULT, true);
        }
    }

    // Proto.Obj

    static public class Obj extends Proto
        implements Aggregate, Function, ObjRef
    {
        static OpTab optab = new OpTab(Proto.Obj.class, new String[] {
            "addFld:$$fld",
            "addFldV:$$fldv",
            "addFxn:$$fxn",
            "init:$$init",
            "make:$$make",
            "patchFxn:$patch"
        });

        static int curkey = 0;

        String name;
        Proto.Obj sup;
        int key;
        int curid = 0;
        int fldcnt = 0;

        /* mbrlist holds a list of all properties, while fldlist does
         * not contain functions
         */
        LinkedHashMap<String,Member> mbrlist = new LinkedHashMap();
        LinkedHashMap<String,Member> fldlist = new LinkedHashMap();

        public Obj()
        {
            this.bindtab.putAll(Proto.Obj.optab);
        }

        public void addFld( String name, Proto proto, Object defval, String flags )
        {
            addFldV(name, proto, defval, flags, null, null);
        }

        public void addFldV( String name, Proto proto, Object defval, String flags, Object getter, Object setter )
        {
            Member mbr = (Member)this.mbrlist.get(name);

            if (mbr == null) {
                mbr = new Member();
                mbr.name = name;
                mbr.idx = this.fldcnt++;
                mbr.owner = this;
            }
            else {
                try {
                    mbr = (Member)mbr.clone();
                }
                catch (Exception e) { Err.exit(e); }
            }

            mbr.proto = proto;
            mbr.defval = defval;
            mbr.getter = (Function)getter;
            mbr.setter = (Function)setter;
            mbr.hflag = flags.indexOf('h') != -1;
            mbr.rflag = flags.indexOf('r') != -1;

            this.mbrlist.put(name, mbr);
            this.fldlist.put(name, mbr);
        }

        public void addFxn( String name, Proto.Fxn proto, Object ofxn )
        {
            if (!(ofxn instanceof Function)) {
                return;
            }

            Member mbr = new Member();

            mbr.name = name;
            mbr.proto = proto;
            mbr.owner = proto.owner == null ? this : proto.owner;
            mbr.defval = new Invoke(name, (Function)ofxn, this, proto);

            this.mbrlist.put(name, mbr);
        }

        public Collection<Member> allFlds()
        {
            return this.fldlist.values();
        }

        Object assign( Object oldval, Object newval )
        {
            newval = Proto.unwrap(newval);

            if (newval == null || newval instanceof Undefined) {
                return newval;
            }
            else if (newval instanceof Value.Obj) {
                return this.cast((Value.Obj)newval);
            }
            else if (newval == Value.DEFAULT) {     /// necessary???
                return Context.getUndefinedValue();
            }
            else if (newval instanceof Addr) {
                return ((Addr)newval).val == 0 ? null : newval;
            }
            else if (newval instanceof XScriptO || !(newval instanceof Scriptable)) {
                return Value.ERROR;
            }
            else {
                return this.create(null, null, false, (Scriptable)newval, true);
            }
        }

        boolean assignable( Proto proto )
        {
            if (!(proto instanceof Proto.Obj)) {
                return false;
            }

            for (Proto.Obj pobj = (Proto.Obj)proto; pobj != null; pobj = pobj.sup) {
                if (pobj == this) {
                    return true;
                }
            }

            return false;
        }

        Object cast( Value.Obj vobj )
        {
            for (Proto.Obj pobj = (Proto.Obj)vobj.orig.proto; pobj != null; pobj = pobj.sup) {
                if (pobj == this) {
                    return vobj.castTo(pobj);
                }
            }

            return Value.ERROR;
        }

        String compat( Scriptable sobj )   /// FIX: pre-filter for arrays, etc.
        {
            Object[] ids = sobj.getIds();
            for (int i = 0; i < ids.length; i++) {
                 if (!this.fldlist.containsKey(ids[i])) {
                    return ids[i].toString();
                }
            }
            return null;
        }

        Object[] getMbrIds( String pre )
        {
            Vector idvec = new Vector();

            for (Iterator it = this.fldlist.keySet().iterator(); it.hasNext(); ) {
                String key = (String)it.next();
                if (pre == null || !key.startsWith(pre)) {
                    idvec.add(key);
                }
            }

            return idvec.toArray();
        }

        public final String getName() { return this.name; }
        public final Proto.Obj getSuper() { return this.sup; }

        public Proto.Obj init( String name, Object sup ) { return this.init(name, sup, false); }
        public Proto.Obj init( String name, Object sup, boolean newflg )
        {
            this.name = name;
            this.sup = (Proto.Obj)sup;
            this.key = Proto.Obj.curkey++;

            this.setName(name);

            if (sup != null) {
                this.mbrlist.putAll(this.sup.mbrlist);
                this.fldlist.putAll(this.sup.fldlist);
                this.fldcnt = this.sup.fldcnt;
            }

            return this;
        }

        Object lookupBind( String name )
        {
            this.errflg = false;

            Object res = this.get(name, this);
            if (res == NOT_FOUND && this.sup != null) {
                res = this.sup.lookupBind(name);
            }

            this.errflg = true;
            return res;
        }

        public Member lookupFld( String name )
        {
            return (Member)this.fldlist.get(name);
        }

        public Member lookupMbr( String name, Proto.Obj proto )
        {
            Member mbr = (Member)this.mbrlist.get(name);
            return (mbr != null && mbr.owner.key <= proto.key) ? mbr : null;
        }

        public Object make()
        {
            return this.create(null, null, false, Value.DEFAULT, false);
        }

        public void patchFxn( String name, Function newFxn )
        {
            Member mbr = (Member)this.mbrlist.get(name);
            if (mbr == null || !(mbr.defval instanceof Invoke)) {
                return;
            }

            Invoke inv = (Invoke)mbr.defval;
            this.addFxn(name, (Proto.Fxn)mbr.proto, new Patch(inv.fxn, newFxn));
        }

        public String tname()
        {
            return this.name;
        }

        // OVERRIDE Scriptable

        /*
         *  ======== Proto.Obj.get ========
         */
        public Object get( String name, Scriptable start )
        {
            Member mbr = (Member)this.mbrlist.get(name);
            return (mbr != null) ? mbr.defval : super.get(name, start);
        }

        public Object getDefaultValue( java.lang.Class hint )
        {
            return this.name;
        }

        /*
         *  ======== Proto.Obj.has ========
         */
        public boolean has( String name, Scriptable start )
        {
            Member mbr = (Member)this.mbrlist.get(name);
            if (mbr != null) {
                return (true);
            }
            else {
                return (super.has(name, start));	
            }
        }

        public boolean hasInstance( Scriptable value )
        {
            return value instanceof Value.Obj ? this.assignable(((Value.Obj)value).orig.proto) : false;
        }

        // OVERRIDE Function

        public Object call( Context cx, Scriptable scope, Scriptable thisObj, Object[] args )
        {
            if (args.length == 0) {
                Err.exit("an object argument is required");
                return Context.getUndefinedValue();
            }

            Value.Obj vobj;

            if (args[0] instanceof Value.Obj) {
                vobj = (Value.Obj)args[0];
            }
            else {
                Err.exit("an object argument is required");
                return Context.getUndefinedValue();
            }

            if (vobj == null) {
                return null;
            }
            for (Proto.Obj pobj = (Proto.Obj)vobj.orig.proto; pobj != null; pobj = pobj.sup) {
                if (pobj == this) {
                    return vobj.castTo(pobj);
                }
            }

            return Context.getUndefinedValue();
        }

        // interface Aggregate

        public Object create( Value prnt, String name, boolean ronly,
                              Object initval, boolean check )
        {
            if (initval == null || initval instanceof Undefined) {
                return initval;
            }
            else {
                String ns = (name == null) ? (this.name + '#' + this.curid++)
                                           : name;
                Value.Obj vobj = new Value.Obj(ns, this);
                vobj.init(this, prnt, ns, ronly, initval, check);
                return vobj;
            }
        }
    }

    // Proto.Str

    static public class Str extends Proto
        implements Aggregate, Embedded, ObjRef, Pred, Sealable
    {
        static OpTab optab = new OpTab(Proto.Str.class, new String[] {
                "make:$$make",
            });

        Proto.Obj base;
        boolean metaonly;
        Vector newvec;

        public Str( Proto.Obj base )
        {
            this(base, true);
            this.setName(base.name);
        }

        public Str( Proto.Obj base, boolean metaonly )
        {
            this.base = base;
            this.metaonly = metaonly;
            this.newvec = new Vector();
            this.bindtab.putAll(Proto.Str.optab);
        }

        public final Proto getBase() {
            return this.base;
        }

        /* This function is invoked when a function is called and one of the
         * function's typed parameters is a structure type, or in case of a
         * typed assignment to a variable of a structure type.
         * In the first case, oldval is 'null'.
         */
        Object assign( Object oldval, Object newval )
        {
            newval = Proto.unwrap(newval);

            if (newval instanceof Undefined) {
                newval = Value.DEFAULT;
            }

            if (oldval == null) {
            	/* primitive types are not allowed */
                if (!(newval instanceof Scriptable)) {
                    return (Value.ERROR);
                }
                return this.create(null, null, false, newval, true);
            }

            Value.Obj vobj = (Value.Obj)oldval;
            Object res = vobj;

            if (vobj.sealed(null)) {
                vobj.error("sealed object");
            }

            if (newval == null) {
                vobj.error("illegal assignment of 'null'");
                res = Value.ERROR;
            }
            else if (newval instanceof Value.Obj) {
                Object oval = this.base.cast((Value.Obj)newval);
                if (oval == Value.ERROR) {
                    vobj.error("incompatible assignment");
                    res = Value.ERROR;
                }
                else {
                    vobj.assignV((Value.Obj)oval);
                }
            }
            else if (newval instanceof XScriptO && newval != Value.DEFAULT || !(newval instanceof Scriptable)) {
                vobj.error("incompatible assignment: " + newval);
                res = Value.ERROR;
            }
            else {
                vobj.assignS((Scriptable)newval);
            }

            return res;
        }

        boolean assignable( Proto proto )
        {
            return proto instanceof Proto.Str ? this.base.assignable(((Proto.Str)proto).base) : false;
        }

        public Object make( Object prnt, String name )
        {
            return this.create((Value)prnt, name, false, Value.DEFAULT, false);
        }

        public Object newInstance()
        {
            Value.Obj vobj = (Value.Obj)this.create(null, null, false, Value.DEFAULT, true);
            vobj.bind("$category", "Struct");

            return vobj;
        }

        // OVERRIDE scriptable

        public boolean hasInstance( Scriptable value )
        {
            return this.base.hasInstance(value);
        }

        // OVERRIDE function

        public Scriptable construct( Context cx, Scriptable scope, Object[] args )
        {
            Value.Obj vobj = (Value.Obj)this.create(null, null, false, args.length == 1 ? args[0] : Value.DEFAULT, true);
            vobj.bind("$category", "Struct");

            return vobj;
        }

        // interface Aggregate

        public Object create( Value prnt, String name, boolean ronly, Object initval, boolean check )
        {
            if (initval == null) {
                Err.exit("illegal assignment of 'null'");
                return Value.ERROR;
            }

            if (initval instanceof Undefined) {
                initval = Value.DEFAULT;
            }

            Value.Obj vobj = (Value.Obj)this.base.create(prnt, name, ronly, initval, check);

            if (!this.metaonly && name == null) {
                this.newvec.add(vobj);
            }

            return vobj;
        }
    }

    // Proto.Tag

    static public class Tag extends Proto
        implements Aggregate, Embedded, Pred, Sealable, Typedef
    {
        static OpTab optab = new OpTab(Proto.Tag.class, new String[] {
                "init:$$init",
            });

        String name;
        Proto base;
        Function encFxn;

        public Tag()
        {
            this.bindtab.putAll(Proto.Tag.optab);
        }

        Object assign( Object oldval, Object newval )
        {
            return this.base.assign(oldval, newval);
        }

        boolean assignable( Proto proto )
        {
            return this.base.assignable(proto);
        }

        public Object create( Value prnt, String name, boolean ronly, Object initval, boolean check )
        {
            return ((Aggregate)this.base).create(prnt, name, ronly, initval, check);
        }

        int depth() { return this.base.depth(); }

        public Proto getBase() { return this.base; }
        public Function getEncFxn() { return this.encFxn; }

        public void init( String name, Object base, Object encFxn )
        {
            this.name = name;
            this.base = (Proto)base;
            this.encFxn = encFxn == null || encFxn instanceof Undefined ? null : (Function)encFxn;
        }
    }

    // Proto.Tel

    static public class Tel extends Proto
        implements Pred, Typedef
    {
        static OpTab optab = new OpTab(Proto.Tel.class, new String[] {
                "init:$$init",
            });

        String name;
        Proto base;
        Function encFxn;

        public Tel()
        {
            this.bindtab.putAll(Proto.Tel.optab);
        }

        Object assign( Object oldval, Object newval )
        {
            return this.base.assign(oldval, newval);
        }

        boolean assignable( Proto proto )
        {
            return this.base.assignable(proto);
        }

        public Proto getBase() { return this.base; }
        public Function getEncFxn() { return this.encFxn; }

        public void init( String name, Object base, Object encFxn )
        {
            this.name = name;
            this.base = (Proto)base;
            this.encFxn = encFxn == null || encFxn instanceof Undefined ? null : (Function)encFxn;
        }

        // OVERRIDE scriptable

        public boolean hasInstance( Scriptable value )
        {
            return this.base.hasInstance(value);
        }
    }
}
