<commit_before>"use strict";

global.WEB = false;

const assert   = require("assert");

const lua      = require('../../src/lua.js');
const lauxlib  = require('../../src/lauxlib.js');
const ljstype  = require('../../src/ljstype.js');
const lopcodes = require('../../src/lopcodes.js');
const sprintf  = require('sprintf-js').sprintf;

const delimits = [" ", "\t", "\n", ",", ";"].map(e => e.charCodeAt(0));

const skip = function(pc) {
    for (;;) {
        if (pc.script[pc.offset] !== 0 && pc.offset < pc.script.length && delimits.indexOf(pc.script[pc.offset]) >= 0)
            pc.offset++;
        else if (pc.script[pc.offset] === '#'.charCodeAt(0)) {
            while (pc.script[pc.offset] !== '\n'.charCodeAt(0) && pc.script[pc.offset] !== 0 && pc.offset < pc.script.length)
                pc.offset++;
        } else break;
    }
};

const getnum = function(L, L1, pc) {
    let res = 0;
    let sig = 1;
    skip(pc);
    if (pc.script[pc.offset] === '.'.charCodeAt(0)) {
        res = lua.lua_tointeger(L1, -1);
        lua.lua_pop(L1, 1);
        pc.offset++;
        return res;
    } else if (pc.script[pc.offset] === '*'.charCodeAt(0)) {
        res = lua.lua_gettop(L1);
        pc.offset++;
        return res;
    }
    else if (pc.script[pc.offset] === '-'.charCodeAt(0)) {
        sig = -1;
        pc.offset++;
    }
    if (!ljstype.lisdigit(pc.script[pc.offset]))
        lauxlib.luaL_error(L, lua.to_luastring("number expected (%s)"), pc.script);
    while (ljstype.lisdigit(pc.script[pc.offset])) res = res*10 + pc.script[pc.offset++] - '0'.charCodeAt(0);
    return sig*res;
};

const getstring = function(L, buff, pc) {
    let i = 0;
    skip(pc);
    if (pc.script[pc.offset] === '"'.charCodeAt(0) || pc.script[pc.offset] === '\''.charCodeAt(0)) {  /* quoted string? */
        let quote = pc.script[pc.offset++];
        while (pc.script[pc.offset] !== quote) {
            if (pc.script[pc.offset] === 0 || pc.offset >= pc.script.length)
                lauxlib.luaL_error(L, lua.to_luastring("unfinished string in JS script", true));
            buff[i++] = pc.script[pc.offset++];
        }
        pc.offset++;
    } else {
        while (pc.script[pc.offset] !== 0 && pc.offset < pc.script.length && delimits.indexOf(pc.script[pc.offset]) < 0)
          buff[i++] = pc.script[pc.offset++];
    }
    buff.length = i;
    return buff;
};

const getindex = function(L, L1, pc) {
    skip(pc);
    switch (pc.script[pc.offset++]) {
        case 'R'.charCodeAt(0): return lua.LUA_REGISTRYINDEX;
        case 'G'.charCodeAt(0): return lauxlib.luaL_error(L, lua.to_luastring("deprecated index 'G'", true));
        case 'U'.charCodeAt(0): return lua.lua_upvalueindex(getnum(L, L1, pc));
        default: pc.offset--; return getnum(L, L1, pc);
    }
};

const codes = ["OK", "YIELD", "ERRRUN", "ERRSYNTAX", "ERRMEM", "ERRGCMM", "ERRERR"].map(e => lua.to_luastring(e));

const pushcode = function(L, code) {
    lua.lua_pushstring(L, codes[code]);
};

const printstack = function(L) {
    let n = lua.lua_gettop(L);
    for (let i = 1; i <= n; i++) {
        console.log("${i}: %{lua.to_jsstring(lauxlib.luaL_tolstring(L, i, null))}\n");
        lua.lua_pop(L, 1);
    }
    console.log("");
};

/*
** arithmetic operation encoding for 'arith' instruction
** LUA_OPIDIV  -> \
** LUA_OPSHL   -> <
** LUA_OPSHR   -> >
** LUA_OPUNM   -> _
** LUA_OPBNOT  -> !
*/
const ops = "+-*%^/\\&|~<>_!".split('').map(e => e.charCodeAt(0));

const runJS = function(L, L1, pc) {
    let buff = [];
    let status = 0;  
    assert(pc.script);
    if (!pc || pc.script.length === 0) return lauxlib.luaL_error(L, "attempt to runJS empty script");
    for (;;) {
        let inst = lua.to_jsstring(getstring(L, buff, pc));
        if (inst.length === 0) return 0;
        switch (inst) {
        case "absindex": {
            lua.lua_pushnumber(L1, lua.lua_absindex(L1, getindex(L, L1, pc)));
            break;
        }<commit_msg>tests/test-suite/ltests.js: Don't error on empty scripts (just null ones)<commit_after>"use strict";

global.WEB = false;

const assert   = require("assert");

const lua      = require('../../src/lua.js');
const lauxlib  = require('../../src/lauxlib.js');
const ljstype  = require('../../src/ljstype.js');
const lopcodes = require('../../src/lopcodes.js');
const sprintf  = require('sprintf-js').sprintf;

const delimits = [" ", "\t", "\n", ",", ";"].map(e => e.charCodeAt(0));

const skip = function(pc) {
    for (;;) {
        if (pc.script[pc.offset] !== 0 && pc.offset < pc.script.length && delimits.indexOf(pc.script[pc.offset]) >= 0)
            pc.offset++;
        else if (pc.script[pc.offset] === '#'.charCodeAt(0)) {
            while (pc.script[pc.offset] !== '\n'.charCodeAt(0) && pc.script[pc.offset] !== 0 && pc.offset < pc.script.length)
                pc.offset++;
        } else break;
    }
};

const getnum = function(L, L1, pc) {
    let res = 0;
    let sig = 1;
    skip(pc);
    if (pc.script[pc.offset] === '.'.charCodeAt(0)) {
        res = lua.lua_tointeger(L1, -1);
        lua.lua_pop(L1, 1);
        pc.offset++;
        return res;
    } else if (pc.script[pc.offset] === '*'.charCodeAt(0)) {
        res = lua.lua_gettop(L1);
        pc.offset++;
        return res;
    }
    else if (pc.script[pc.offset] === '-'.charCodeAt(0)) {
        sig = -1;
        pc.offset++;
    }
    if (!ljstype.lisdigit(pc.script[pc.offset]))
        lauxlib.luaL_error(L, lua.to_luastring("number expected (%s)"), pc.script);
    while (ljstype.lisdigit(pc.script[pc.offset])) res = res*10 + pc.script[pc.offset++] - '0'.charCodeAt(0);
    return sig*res;
};

const getstring = function(L, buff, pc) {
    let i = 0;
    skip(pc);
    if (pc.script[pc.offset] === '"'.charCodeAt(0) || pc.script[pc.offset] === '\''.charCodeAt(0)) {  /* quoted string? */
        let quote = pc.script[pc.offset++];
        while (pc.script[pc.offset] !== quote) {
            if (pc.script[pc.offset] === 0 || pc.offset >= pc.script.length)
                lauxlib.luaL_error(L, lua.to_luastring("unfinished string in JS script", true));
            buff[i++] = pc.script[pc.offset++];
        }
        pc.offset++;
    } else {
        while (pc.script[pc.offset] !== 0 && pc.offset < pc.script.length && delimits.indexOf(pc.script[pc.offset]) < 0)
          buff[i++] = pc.script[pc.offset++];
    }
    buff.length = i;
    return buff;
};

const getindex = function(L, L1, pc) {
    skip(pc);
    switch (pc.script[pc.offset++]) {
        case 'R'.charCodeAt(0): return lua.LUA_REGISTRYINDEX;
        case 'G'.charCodeAt(0): return lauxlib.luaL_error(L, lua.to_luastring("deprecated index 'G'", true));
        case 'U'.charCodeAt(0): return lua.lua_upvalueindex(getnum(L, L1, pc));
        default: pc.offset--; return getnum(L, L1, pc);
    }
};

const codes = ["OK", "YIELD", "ERRRUN", "ERRSYNTAX", "ERRMEM", "ERRGCMM", "ERRERR"].map(e => lua.to_luastring(e));

const pushcode = function(L, code) {
    lua.lua_pushstring(L, codes[code]);
};

const printstack = function(L) {
    let n = lua.lua_gettop(L);
    for (let i = 1; i <= n; i++) {
        console.log("${i}: %{lua.to_jsstring(lauxlib.luaL_tolstring(L, i, null))}\n");
        lua.lua_pop(L, 1);
    }
    console.log("");
};

/*
** arithmetic operation encoding for 'arith' instruction
** LUA_OPIDIV  -> \
** LUA_OPSHL   -> <
** LUA_OPSHR   -> >
** LUA_OPUNM   -> _
** LUA_OPBNOT  -> !
*/
const ops = "+-*%^/\\&|~<>_!".split('').map(e => e.charCodeAt(0));

const runJS = function(L, L1, pc) {
    let buff = [];
    let status = 0;
    if (!pc || !pc.script) return lauxlib.luaL_error(L, lua.to_luastring("attempt to runJS null script"));
    for (;;) {
        let inst = lua.to_jsstring(getstring(L, buff, pc));
        if (inst.length === 0) return 0;
        switch (inst) {
        case "absindex": {
            lua.lua_pushnumber(L1, lua.lua_absindex(L1, getindex(L, L1, pc)));
            break;
        }
{'fraction_non_alphanumeric': 0.20817562452687358, 'fraction_numerical': 0.011228867019934393, 'mean_word_length': 2.6015447523852795, 'pattern_counts': {'":': 2, '<': 17, '<?xml version=': 0, '>': 27, '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': '4009245', 'n_tokens_mistral': 3016, 'n_tokens_neox': 2938, 'n_words': 576}