<commit_before>#include "VM.h"
#include "Array.h"
#include "Map.h"
#include "String.h"
#include "Func.h"
#include "CFunc.h"
#include "Proto.h"
#include "Value.h"
#include "Object.h"
#include "Pepper.h"
#include "GC.h"
#include "NameValue.h"
#include "Stack.h"

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <setjmp.h>
#include <math.h>
#include <stdio.h>

#define STEP code=*pc++; ptrC=regs+OC(code); A=regs[OA(code)]; B=regs[OB(code)]; goto *dispatch[OP(code)];

#define INT(x) VAL_INT((signed char)x)

static Value arrayAdd(GC *gc, Value a, Value b) {
    assert(IS_ARRAY(a));
    ERR(!(IS_ARRAY(b) || IS_MAP(b) || IS_STRING(b)), E_WRONG_TYPE);
    Array *array = Array::alloc(gc);
    array->add(a);
    array->add(b);
    return VAL_OBJ(array);
}

static Value mapAdd(GC *gc, Value a, Value b) {
    assert(IS_MAP(a));
    ERR(!(IS_ARRAY(b) || IS_MAP(b) || IS_STRING(b)), E_WRONG_TYPE);
    Map *map = MAP(a)->copy(gc);
    map->add(b);
    return VAL_OBJ(map);
}

Value doAdd(GC *gc, Value a, Value b) {
    int ta = TAG(a);
    if (IS_NUM_TAG(ta) && IS_NUM(b)) {
        return VAL_NUM(GET_NUM(a) + GET_NUM(b));
    }
    if (IS_STRING(a)) {
        return String::concat(gc, a, b);
    }
    ERR(ta != T_OBJ, E_WRONG_TYPE);
    int type = O_TYPE(a);
    ERR(type != O_ARRAY && type != O_MAP, E_WRONG_TYPE);
    return type == O_ARRAY ? arrayAdd(gc, a, b) : mapAdd(gc, a, b);
}

Value doMod(Value a, Value b) {
    ERR(!IS_NUM(a) || !IS_NUM(b), E_WRONG_TYPE);
    double da = GET_NUM(a);
    double db = GET_NUM(b);
    return VAL_NUM(da - floor(da / db) * db);
}

Value doPow(Value a, Value b) {
    ERR(!IS_NUM(a) || !IS_NUM(b), E_WRONG_TYPE);
    return VAL_NUM(pow(GET_NUM(a), GET_NUM(b)));
}

static Value doSHL(Value v, int shift) {
    ERR(!IS_NUM(v), E_WRONG_TYPE);
    if (shift < 0) { shift = 0; }
    return VAL_NUM(shift >= 32 ? 0 : ((unsigned)GET_NUM(v) << shift));
}

static Value doSHR(Value v, int shift) {
    ERR(!IS_NUM(v), E_WRONG_TYPE);
    if (shift < 0) { shift = 0; }
    return VAL_NUM(shift >= 32 ? 0 : ((unsigned)GET_NUM(v) >> shift));
}

static Value getIndex(Value a, Value b) {
    return 
        IS_ARRAY(a)  ? ARRAY(a)->getV(b) :
        IS_STRING(a) ? String::get(a, b) :
        IS_MAP(a)    ? MAP(a)->rawGet(b) :
        ERROR(E_NOT_INDEXABLE);
}

Value VM::getField(Value a, Value b) {
    if (IS_STRING(a)) {
        return getField(stringMethods, b);
    } else {
        return getIndex(a, b);
    }
}

static void setIndex(Value c, Value a, Value b) {
    ERR(IS_STRING(c), E_STRING_WRITE);
    if (IS_ARRAY(c)) {
        ARRAY(c)->setV(a, b);
    } else if (IS_MAP(c)){
        MAP(c)->rawSet(a, b);
    } else {
        ERROR(E_NOT_INDEXABLE);
    }
}
<commit_msg>work on VM::getField for map;<commit_after>#include "VM.h"
#include "Array.h"
#include "Map.h"
#include "String.h"
#include "Func.h"
#include "CFunc.h"
#include "Proto.h"
#include "Value.h"
#include "Object.h"
#include "Pepper.h"
#include "GC.h"
#include "NameValue.h"
#include "Stack.h"

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <setjmp.h>
#include <math.h>
#include <stdio.h>

#define STEP code=*pc++; ptrC=regs+OC(code); A=regs[OA(code)]; B=regs[OB(code)]; goto *dispatch[OP(code)];

#define INT(x) VAL_INT((signed char)x)

static Value arrayAdd(GC *gc, Value a, Value b) {
    assert(IS_ARRAY(a));
    ERR(!(IS_ARRAY(b) || IS_MAP(b) || IS_STRING(b)), E_WRONG_TYPE);
    Array *array = Array::alloc(gc);
    array->add(a);
    array->add(b);
    return VAL_OBJ(array);
}

static Value mapAdd(GC *gc, Value a, Value b) {
    assert(IS_MAP(a));
    ERR(!(IS_ARRAY(b) || IS_MAP(b) || IS_STRING(b)), E_WRONG_TYPE);
    Map *map = MAP(a)->copy(gc);
    map->add(b);
    return VAL_OBJ(map);
}

Value doAdd(GC *gc, Value a, Value b) {
    int ta = TAG(a);
    if (IS_NUM_TAG(ta) && IS_NUM(b)) {
        return VAL_NUM(GET_NUM(a) + GET_NUM(b));
    }
    if (IS_STRING(a)) {
        return String::concat(gc, a, b);
    }
    ERR(ta != T_OBJ, E_WRONG_TYPE);
    int type = O_TYPE(a);
    ERR(type != O_ARRAY && type != O_MAP, E_WRONG_TYPE);
    return type == O_ARRAY ? arrayAdd(gc, a, b) : mapAdd(gc, a, b);
}

Value doMod(Value a, Value b) {
    ERR(!IS_NUM(a) || !IS_NUM(b), E_WRONG_TYPE);
    double da = GET_NUM(a);
    double db = GET_NUM(b);
    return VAL_NUM(da - floor(da / db) * db);
}

Value doPow(Value a, Value b) {
    ERR(!IS_NUM(a) || !IS_NUM(b), E_WRONG_TYPE);
    return VAL_NUM(pow(GET_NUM(a), GET_NUM(b)));
}

static Value doSHL(Value v, int shift) {
    ERR(!IS_NUM(v), E_WRONG_TYPE);
    if (shift < 0) { shift = 0; }
    return VAL_NUM(shift >= 32 ? 0 : ((unsigned)GET_NUM(v) << shift));
}

static Value doSHR(Value v, int shift) {
    ERR(!IS_NUM(v), E_WRONG_TYPE);
    if (shift < 0) { shift = 0; }
    return VAL_NUM(shift >= 32 ? 0 : ((unsigned)GET_NUM(v) >> shift));
}

static Value getIndex(Value a, Value key) {
    return 
        IS_ARRAY(a)  ? ARRAY(a)->getV(key) :
        IS_STRING(a) ? String::get(a, key) :
        IS_MAP(a)    ? MAP(a)->rawGet(key) :
        ERROR(E_NOT_INDEXABLE);
}

Value VM::getField(Value a, Value key) {
    while (true) {
        if (IS_STRING(a)) {
            a = stringMethods;
        } else if (IS_MAP(a)) {
            Map *map = MAP(a);
            bool again = false;
            Value v = map->get(key, &again);
            if (again) {
                if (IS_FUNC(v) || IS_CFUNC(v)) {
                    return v;
                } else { 
                    a = v;
                }
            } else {
                return v;
            }
        } else {
            return getIndex(a, key);
        }
    }
}

static void setIndex(Value c, Value a, Value b) {
    ERR(IS_STRING(c), E_STRING_WRITE);
    if (IS_ARRAY(c)) {
        ARRAY(c)->setV(a, b);
    } else if (IS_MAP(c)){
        MAP(c)->rawSet(a, b);
    } else {
        ERROR(E_NOT_INDEXABLE);
    }
}

{'fraction_non_alphanumeric': 0.1835732430143946, 'fraction_numerical': 0.003386960203217612, 'mean_word_length': 2.8906455862977603, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 40, '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': '6380148', 'n_tokens_mistral': 2442, 'n_tokens_neox': 2379, 'n_words': 529}