<commit_before>/* 
 * File:   JsVars.h
 * Author: ghernan
 * 
 * Javascript variables and values implementation code
 *
 * Created on November 21, 2016, 7:24 PM
 */

#pragma once

#include <string>

#include "jsLexer.h"
#include "utils.h"
#include "RefCountObj.h"
#include <map>
#include <set>
#include <sstream>
#include <vector>

class CScriptToken;
struct IScope;

/**
 * Enumeration of basic Javascript value types.
 */
enum JSValueTypes
{
    VT_UNDEFINED,
    VT_NULL,
    VT_NUMBER,
    VT_BOOL,
    VT_OBJECT,  //All below are objects
    VT_STRING,
    VT_ARRAY,
    VT_ACTOR,
    VT_ACTOR_REF,
    VT_FUNCTION,//All below are functions
    VT_ACTOR_CLASS,
    VT_INPUT_EP,
    VT_OUTPUT_EP,
    VT_INPUT_EP_REF,
    VT_OUTPUT_EP_REF,
};
std::string getTypeName(JSValueTypes vType);

/**
 * The possible mutability states of a JSValue.
 */
enum JSMutability
{
    MT_MUTABLE,
    MT_FROZEN,
    MT_DEEPFROZEN   //Deep frozen means that it is frozen and contains no references
                    //which may lead to a mutable object.
};

/**
 * Root class for all Javascript types.
 * Defines several operations which must be implemented by the derived types.
 * The defined operations fall in these categories:
 *  - Conversion to basic types.
 *  - Standard operations
 *  - Type checking
 *  - JSON generation
 */
class JSValue : public RefCountObj
{
public:
    virtual JSValueTypes getType()const = 0;
    
    virtual JSMutability    getMutability()const=0;
    virtual Ref<JSValue>    freeze()=0;
    virtual Ref<JSValue>    unFreeze(bool forceClone=false)=0;

    virtual std::string toString()const = 0;
    virtual bool toBoolean()const = 0;
    virtual double toDouble()const = 0;

    virtual Ref<JSValue> readField(Ref<JSValue> key)const = 0;
    virtual Ref<JSValue> writeField(Ref<JSValue> key, Ref<JSValue> value) = 0;
    virtual Ref<JSValue> deleteField(Ref<JSValue> key) = 0;
    virtual std::string getJSON(int indent) = 0;
    
    Ref<JSValue> readFieldStr(const std::string& strKey)const;
    Ref<JSValue> writeFieldStr(const std::string& strKey, Ref<JSValue> value);

    virtual std::string getTypeName()const
    {
        return ::getTypeName(this->getType());
    }

    bool isFunction()const
    {
        return getType() >= VT_FUNCTION;
    }

    bool isArray()const
    {
        return getType() == VT_ARRAY;
    }

    bool isObject()const
    {
        return getType() >= VT_OBJECT;
    }

    bool isUndefined()const
    {
        return getType() == VT_UNDEFINED;
    }

    bool isNull()const
    {
        return getType() <= VT_NULL;
    }

    bool isPrimitive()const
    {
        const JSValueTypes t = this->getType();

        return t == VT_STRING || (t > VT_NULL && t < VT_OBJECT);
    }
    
    bool isMutable()const
    {
        return getMutability() == MT_MUTABLE;
    }
};

// JSValue helper functions
//////////////////////////////////////////

class JSBool;
class JSObject;

Ref<JSValue> undefined();
Ref<JSValue> jsNull();
Ref<JSBool> jsTrue();
Ref<JSBool> jsFalse();
Ref<JSValue> jsBool(bool value);
Ref<JSValue> jsInt(int value);
Ref<JSValue> jsDouble(double value);
Ref<JSValue> jsString(const std::string& value);

Ref<JSValue> createConstant(CScriptToken token);

Ref<JSObject> getObject(Ref<IScope> pScope, const std::string& name);

Ref<JSValue> null2undef (Ref<JSValue> value);
bool nullCheck (Ref<JSValue> value);

template <class DestType, class SrcType> 
Ref<DestType> castTo (Ref<SrcType> value)
{
    if (nullCheck(value))
        return Ref<DestType>();
    else
        return Ref<DestType>( static_cast<DestType*> ( value.getPointer() ) );
}

double jsValuesCompare (Ref<JSValue> a, Ref<JSValue> b);

int toInt32 (Ref<JSValue> a);
unsigned long long toUint64 (Ref<JSValue> a);
size_t toSizeT (Ref<JSValue> a);
bool isInteger (Ref<JSValue> a);
bool isUint (Ref<JSValue> a);


//////////////////////////////////////////

/**
 * Helper class to implement 'JSValue' derived classes.
 * Provides a default implementation for every virtual method.
 */
template <JSValueTypes V_TYPE>
class JSValueBase : public JSValue
{
public:
    
    virtual JSMutability getMutability()const
    {
        return MT_DEEPFROZEN;
    }<commit_msg>Reorganize 'JSValueTypes', so 'isObject' checks keep being valid.<commit_after>/* 
 * File:   JsVars.h
 * Author: ghernan
 * 
 * Javascript variables and values implementation code
 *
 * Created on November 21, 2016, 7:24 PM
 */

#pragma once

#include <string>

#include "jsLexer.h"
#include "utils.h"
#include "RefCountObj.h"
#include <map>
#include <set>
#include <sstream>
#include <vector>

class CScriptToken;
struct IScope;

/**
 * Enumeration of basic Javascript value types.
 */
enum JSValueTypes
{
    VT_UNDEFINED,
    VT_NULL,
    VT_NUMBER,
    VT_BOOL,
    VT_ACTOR_REF,
    VT_INPUT_EP_REF,
    VT_OUTPUT_EP_REF,
    VT_OBJECT,  //All below are objects
    VT_STRING,
    VT_ARRAY,
    VT_ACTOR,
    VT_FUNCTION,//All below are functions
    VT_ACTOR_CLASS,
    VT_INPUT_EP,
    VT_OUTPUT_EP,
};
std::string getTypeName(JSValueTypes vType);

/**
 * The possible mutability states of a JSValue.
 */
enum JSMutability
{
    MT_MUTABLE,
    MT_FROZEN,
    MT_DEEPFROZEN   //Deep frozen means that it is frozen and contains no references
                    //which may lead to a mutable object.
};

/**
 * Root class for all Javascript types.
 * Defines several operations which must be implemented by the derived types.
 * The defined operations fall in these categories:
 *  - Conversion to basic types.
 *  - Standard operations
 *  - Type checking
 *  - JSON generation
 */
class JSValue : public RefCountObj
{
public:
    virtual JSValueTypes getType()const = 0;
    
    virtual JSMutability    getMutability()const=0;
    virtual Ref<JSValue>    freeze()=0;
    virtual Ref<JSValue>    unFreeze(bool forceClone=false)=0;

    virtual std::string toString()const = 0;
    virtual bool toBoolean()const = 0;
    virtual double toDouble()const = 0;

    virtual Ref<JSValue> readField(Ref<JSValue> key)const = 0;
    virtual Ref<JSValue> writeField(Ref<JSValue> key, Ref<JSValue> value) = 0;
    virtual Ref<JSValue> deleteField(Ref<JSValue> key) = 0;
    virtual std::string getJSON(int indent) = 0;
    
    Ref<JSValue> readFieldStr(const std::string& strKey)const;
    Ref<JSValue> writeFieldStr(const std::string& strKey, Ref<JSValue> value);

    virtual std::string getTypeName()const
    {
        return ::getTypeName(this->getType());
    }

    bool isFunction()const
    {
        return getType() >= VT_FUNCTION;
    }

    bool isArray()const
    {
        return getType() == VT_ARRAY;
    }

    bool isObject()const
    {
        return getType() >= VT_OBJECT;
    }

    bool isUndefined()const
    {
        return getType() == VT_UNDEFINED;
    }

    bool isNull()const
    {
        return getType() <= VT_NULL;
    }

    bool isPrimitive()const
    {
        const JSValueTypes t = this->getType();

        return t == VT_STRING || (t > VT_NULL && t < VT_OBJECT);
    }
    
    bool isMutable()const
    {
        return getMutability() == MT_MUTABLE;
    }
};

// JSValue helper functions
//////////////////////////////////////////

class JSBool;
class JSObject;

Ref<JSValue> undefined();
Ref<JSValue> jsNull();
Ref<JSBool> jsTrue();
Ref<JSBool> jsFalse();
Ref<JSValue> jsBool(bool value);
Ref<JSValue> jsInt(int value);
Ref<JSValue> jsDouble(double value);
Ref<JSValue> jsString(const std::string& value);

Ref<JSValue> createConstant(CScriptToken token);

Ref<JSObject> getObject(Ref<IScope> pScope, const std::string& name);

Ref<JSValue> null2undef (Ref<JSValue> value);
bool nullCheck (Ref<JSValue> value);

template <class DestType, class SrcType> 
Ref<DestType> castTo (Ref<SrcType> value)
{
    if (nullCheck(value))
        return Ref<DestType>();
    else
        return Ref<DestType>( static_cast<DestType*> ( value.getPointer() ) );
}

double jsValuesCompare (Ref<JSValue> a, Ref<JSValue> b);

int toInt32 (Ref<JSValue> a);
unsigned long long toUint64 (Ref<JSValue> a);
size_t toSizeT (Ref<JSValue> a);
bool isInteger (Ref<JSValue> a);
bool isUint (Ref<JSValue> a);

Ref<JSValue>    deepFreeze(Ref<JSValue>);


//////////////////////////////////////////

/**
 * Helper class to implement 'JSValue' derived classes.
 * Provides a default implementation for every virtual method.
 */
template <JSValueTypes V_TYPE>
class JSValueBase : public JSValue
{
public:
    
    virtual JSMutability getMutability()const
    {
        return MT_DEEPFROZEN;
    }
{'fraction_non_alphanumeric': 0.13021016789949513, 'fraction_numerical': 0.005870611717740989, 'mean_word_length': 3.1369596891694997, 'pattern_counts': {'":': 0, '<': 99, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5656498', 'n_tokens_mistral': 2819, 'n_tokens_neox': 2751, 'n_words': 743}