Package Rakudo.Metamodel.Representations

Source Code of Rakudo.Metamodel.Representations.P6hash$Instance

package Rakudo.Metamodel.Representations;

import java.util.HashMap;
import Rakudo.Metamodel.Hints;
import Rakudo.Metamodel.RakudoObject;
import Rakudo.Metamodel.Representation;
import Rakudo.Metamodel.SharedTable;
import Rakudo.Runtime.ThreadContext;
import Rakudo.Serialization.SerializationContext;

/// <summary>
/// A representation that uses a hash of hash representation to store
/// the attributes. No real restriction on the sort of class it can be
/// used with. Also dead easy to implement. :-)
/// </summary>
public final class P6hash implements Representation
{
    /// <summary>
    /// This class represents our instances. It's inner workings are
    /// entirely private to this representation, which is the only
    /// thing that knows how it looks on the inside.
    /// XXX Once we do this production level, we really need to
    /// consider concurrency in accesses to the Dictionary. But
    /// this is OK for a prototype. -- jnthn
    /// </summary>
    private final class Instance extends RakudoObject
    {
        public HashMap<RakudoObject, HashMap<String, RakudoObject>> Storage;
        public Instance(SharedTable sTable)
        {
            this.setSTable(sTable);
        }
    }

    /// <summary>
    /// Creates a type object that references the given HOW and
    /// this REPR; note we just use the singleton instance for
    /// all of them, since the REPR stores nothing distinct.
    /// </summary>
    /// <param name="HOW"></param>
    /// <returns></returns>
    public RakudoObject type_object_for(ThreadContext tc, RakudoObject metaPackage)
    {
        SharedTable sTable = new SharedTable();
        sTable.HOW = metaPackage;
        sTable.REPR = this;
        sTable.WHAT = new Instance(sTable);
        return sTable.WHAT;
    }

    /// <summary>
    /// Allocates and returns a new object based upon the type object
    /// supplied.
    /// </summary>
    /// <param name="HOW"></param>
    /// <returns></returns>
    public RakudoObject instance_of(ThreadContext tc, RakudoObject WHAT)
    {
        Instance Object = new Instance(WHAT.getSTable());
        Object.Storage = new HashMap<RakudoObject, HashMap<String, RakudoObject>>();
        return Object;
    }

    /// <summary>
    /// Checks if the object is defined, which boils down to "is
    /// this a type object", which in trun means "did we allocate
    /// any storage".
    /// </summary>
    /// <param name="Object"></param>
    /// <returns></returns>
    public boolean defined(ThreadContext tc, RakudoObject Object)
    {
        return ((Instance)Object).Storage != null;
    }

    /// <summary>
    /// Gets the attribute with the given value.
    /// </summary>
    /// <param name="ClassHandle"></param>
    /// <param name="Name"></param>
    /// <returns></returns>
    public RakudoObject get_attribute(ThreadContext tc, RakudoObject Object, RakudoObject classHandle, String name)
    {
        // If no storage ever allocated, trivially no value. Otherwise,
        // return what we find.
        Instance I = (Instance)Object;
        if (I.Storage == null || !I.Storage.containsKey(classHandle))
            return null;
        HashMap<String, RakudoObject> classStore = I.Storage.get(classHandle);
        return classStore.containsKey(name) ? classStore.get(name) : null;
    }

    /// <summary>
    /// This representation doesn't use hints, so this just delegates
    /// straight off to the hint-less version.
    /// </summary>
    /// <param name="ClassHandle"></param>
    /// <param name="Name"></param>
    /// <param name="Hint"></param>
    /// <returns></returns>
    public RakudoObject get_attribute_with_hint(ThreadContext tc, RakudoObject Object, RakudoObject ClassHandle, String Name, int Hint)
    {
        return get_attribute(tc, Object, ClassHandle, Name);
    }

    /// <summary>
    /// Binds an attribute to the given value.
    /// </summary>
    /// <param name="Object"></param>
    /// <param name="ClassHandle"></param>
    /// <param name="Name"></param>
    /// <param name="Value"></param>
    public void bind_attribute(ThreadContext tc, RakudoObject Object, RakudoObject ClassHandle, String Name, RakudoObject Value)
    {
        // If no storage at all, allocate some.
        Instance I = (Instance)Object;
        if (I.Storage == null)
            I.Storage = new HashMap<RakudoObject, HashMap<String, RakudoObject>>();
        if (!I.Storage.containsKey(ClassHandle))
            I.Storage.put(ClassHandle, new HashMap<String, RakudoObject>());
       
        // Now stick in the name slot for the class storage, creating if it
        // needed.
        HashMap<String, RakudoObject> ClassStore = I.Storage.get(ClassHandle);
//      if (ClassStore.ContainsKey(Name)) // redundant on HashMap
//          ClassStore[Name] = Value;
//      else
            ClassStore.put(Name, Value);
    }

    /// <summary>
    /// This representation doesn't do hints, so this delegates straight
    /// off to the hint-less version.
    /// </summary>
    /// <param name="ClassHandle"></param>
    /// <param name="Name"></param>
    /// <param name="Hint"></param>
    /// <param name="Value"></param>
    public void bind_attribute_with_hint(ThreadContext tc, RakudoObject Object, RakudoObject ClassHandle, String Name, int Hint, RakudoObject Value)
    {
        bind_attribute(tc, Object, ClassHandle, Name, Value);
    }

    /// <summary>
    /// No hints for P6Hash.
    /// </summary>
    /// <param name="ClassHandle"></param>
    /// <param name="Name"></param>
    /// <returns></returns>
    public int hint_for(ThreadContext tc, RakudoObject ClassHandle, String Name)
    {
        return Hints.NO_HINT;
    }

    public void set_int(ThreadContext tc, RakudoObject Object, int Value)
    {
        throw new UnsupportedOperationException("This type of representation cannot box a native int");
    }

    public int get_int(ThreadContext tc, RakudoObject Object)
    {
        throw new UnsupportedOperationException("This type of representation cannot unbox to a native int");
    }

    public void set_num(ThreadContext tc, RakudoObject Object, double Value)
    {
        throw new UnsupportedOperationException("This type of representation cannot box a native num");
    }

    public double get_num(ThreadContext tc, RakudoObject Object)
    {
        throw new UnsupportedOperationException("This type of representation cannot unbox to a native num");
    }

    public void set_str(ThreadContext tc, RakudoObject Object, String Value)
    {
        throw new UnsupportedOperationException("This type of representation cannot box a native string");
    }

    public String get_str(ThreadContext tc, RakudoObject Object)
    {
        throw new UnsupportedOperationException("This type of representation cannot unbox to a native string");
    }
}
TOP

Related Classes of Rakudo.Metamodel.Representations.P6hash$Instance

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.