Login

Subversion Repositories NedoOS

Rev

Rev 499 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

#include "interpreter.h"
#include "global_mem.h"
#include <stdio.h>
#include <stdlib.h>
//#include <time.h>
#include <string>
#include <sstream>

#ifdef FOR_DEBUGGER
#include "mainwindow.h"
//#include <QString>
//#include <QMessageBox>

uint8_t datastackindex = 0; //╤А╨░╤Б╤В╤С╤В ╨▓╨▓╨╡╤А╤Е
uint8_t callstackindex = 0; //╤А╨░╤Б╤В╤С╤В ╨▓╨▓╨╡╤А╤Е

data64bit datastack[STACKSIZE];
uint64_t callstack[STACKSIZE];
data64bit locals[LOCALSSIZE];

    uint64_t *pc;
    uint64_t *prog;
#endif //FOR_DEBUGGER
    void myprintstr(uint64_t *prog, uint64_t addr){
        char s[100];
        char *ps=s;
        uint64_t *tmppc=prog+addr;
        while(*tmppc)
            *ps++=static_cast<char>(*tmppc++);
        *ps=0;
        myprint(reinterpret_cast<char *>(s));
    }

#ifdef FOR_DEBUGGER
    void pushpar(uint64_t progpar){
        PUSH(progpar);
    }

    int interpret() {
#else //FOR_DEBUGGER
    int interpret(uint64_t *prog, uint64_t progpar) {
        uint64_t *pc = prog;
uint8_t datastackindex = 0; //╤А╨░╤Б╤В╤С╤В ╨▓╨▓╨╡╤А╤Е
uint8_t callstackindex = 0; //╤А╨░╤Б╤В╤С╤В ╨▓╨▓╨╡╤А╤Е

data64bit datastack[STACKSIZE];
uint64_t callstack[STACKSIZE];
data64bit locals[LOCALSSIZE];
        PUSH(progpar);
#endif //FOR_DEBUGGER

    const void *labels[] = {
        &&op_nop, /* !!! ╨Э╨Х ╨У╨Х╨Э╨Х╨а╨Ш╨в╨б╨п !!! */
        &&op_add, /* OK */
        &&op_sub, /* OK */
        &&op_mul, /* OK */
        &&op_div, /* OK */
        &&op_divsigned, /* OK */
        &&op_if0goto, /* OK */
        &&op_goto, /* OK */
        &&op_dup, /* OK */
        &&op_drop, /* !!! ╨Э╨Х ╨У╨Х╨Э╨Х╨а╨Ш╨в╨б╨п !!! */
        &&op_swap, /* OK */
        &&op_readvar, /* OK */
        &&op_writevar, /* OK */
        &&op_const, /* OK */
        &&op_ret, /* OK */
        &&op_call, /* OK */
        &&op_and, /* OK */
        &&op_or, /* OK */
        &&op_xor, /* OK */
        &&op_eq, /* OK */
        &&op_moreeq, /* OK */
        &&op_moreeqsigned, /* OK */
        &&op_inv, /* OK */
        &&op_rst, /* OK */
        &&op_shr, /* OK */
        &&op_shrsigned, /* OK */
        &&op_shl, /* OK */
        &&op_mod, /* !!! ╨Э╨Х ╨У╨Х╨Э╨Х╨а╨Ш╨в╨б╨п !!! */
        &&op_done, /* OK */
        &&op_addfloat, /* OK */
        &&op_subfloat, /* OK */
        &&op_mulfloat, /* OK */
        &&op_divfloat, /* OK */
        &&op_negfloat, /* OK */
        &&op_floattoint, /* OK */
        &&op_inttofloat, /* OK */
        &&op_eqfloat,
        &&op_moreeqfloat, /* OK */
        &&op_readconstvar,
        &&op_writeconstvar,
        &&op_incconstvar,
        &&op_decconstvar
    };
    MAINDISPATCH;/*!*/
op_nop: {
        DISPATCH;
    }
op_add: {
        uint64_t par2 = POP.u;
        TOS.u = (TOS.u+par2);
        DISPATCH;
    }
op_sub: {
        uint64_t par2 = POP.u;
        TOS.u = (TOS.u-par2);
        DISPATCH;
    }
op_mul: {
        uint64_t par2 = POP.u;
        TOS.u = (TOS.u*par2);
        DISPATCH;
    }
op_div: {
        uint64_t par2 = POP.u;
        if (par2)
            TOS.u = (TOS.u/par2);
        DISPATCH;
    }
op_divsigned: {/*!*/
        int64_t par2 = POP.i;
        if (par2)
            TOS.i = TOS.i/par2;
        DISPATCH;
    }
op_mod: {
        uint64_t par2 = POP.u;
        if (par2)
            TOS.u = (TOS.u-((TOS.u/par2)*par2));
        DISPATCH;
    }
op_and: {
        uint64_t par2 = POP.u;
        TOS.u = (TOS.u&par2);
        DISPATCH;
    }
op_or: {
        uint64_t par2 = POP.u;
        TOS.u = (TOS.u|par2);
        DISPATCH;
    }
op_xor: {
        uint64_t par2 = POP.u;
        TOS.u = (TOS.u^par2);
        DISPATCH;
    }
op_inv: {
        TOS.u = ~TOS.u;
        DISPATCH;
    }
op_shr: {
        uint64_t par2 = POP.u;
        TOS.u = (TOS.u>>par2);
        DISPATCH;
    }
op_shrsigned: {
        uint64_t par2 = POP.u;
        TOS.i = (TOS.i>>par2);
        DISPATCH;
    }
op_shl: {
        uint64_t par2 = POP.u;
        TOS.u = (TOS.u<<par2);
        DISPATCH;
    }
op_eq: {
        uint64_t par2 = POP.u;
        TOS.i = (TOS.u==par2)?-1:0;
        DISPATCH;
    }
op_moreeq: {
        uint64_t par2 = POP.u;
        TOS.i = (TOS.u>=par2)?-1:0;
        DISPATCH;
    }
op_moreeqsigned: {
        int64_t par2 = POP.i;
        TOS.i = (TOS.i>=par2)?-1:0;
        DISPATCH;
    }
op_const: {
        PUSH(GETPAR);
        DISPATCH;
    }
op_dup: {
        uint64_t par1 = TOS.u;
        PUSH(par1);
        DISPATCH;
    }
op_drop: {
        POP;
        DISPATCH;
    }
op_swap: {
        uint64_t par2 = POP.u;
        uint64_t par1 = TOS.u;
        TOS.u = par2;
        PUSH(par1);
        DISPATCH;
    }
//pointers:
//0x00000000 - global data segment (VAL)
//0x40000000 - code segment (prog)
//0x80000000 - local data segment (locals)
op_readvar: {
        if (TOS.u < static_cast<uint64_t>(N)) {
            TOS.u = VAL(TOS.u);
        }else if ((TOS.u < 0x80000000)/*&&((TOS.u&0x3fffffff) < progsize)*/) {
            TOS.u = prog[TOS.u&0x3fffffff];
        }else if ((TOS.u&0x3fffffff) < LOCALSSIZE) {
            TOS.u = locals[TOS.u&0x3fffffff].u;
        }
        DISPATCH;
    }
op_writevar: {
        uint64_t vardata = POP.u;
        uint64_t varaddr = POP.u;
        if (varaddr < static_cast<uint64_t>(N)) {
            POKEVAL(varaddr, vardata);
        }else if ((varaddr < 0x80000000)/*&&((varaddr&0x3fffffff) < progsize)*/) {
            prog[varaddr&0x3fffffff] = vardata; //╨┐╨╛ ╨╕╨┤╨╡╨╡ ╨╜╨╡ ╨╜╤Г╨╢╨╜╨╛
        }else if ((varaddr&0x3fffffff) < LOCALSSIZE) {
            locals[varaddr&0x3fffffff].u = vardata;
        }
        DISPATCH;
    }
op_goto: {
        pc = prog+((*pc)&0x3fffffff); //╨╜╨╡╨╗╤М╨╖╤П GETPAR - ╨┤╨╡╨╗╨░╨╡╤В pc++
        DISPATCH;
    }
op_if0goto: {
        if (!POP.u) {
            pc = prog+((*pc)&0x3fffffff); //╨╜╨╡╨╗╤М╨╖╤П GETPAR - ╨┤╨╡╨╗╨░╨╡╤В pc++
        }else {
            pc++;
        }
        DISPATCH;
    }
op_call: {
        uint64_t callpc = GETPAR;
        PUSHCALLSTACK(reinterpret_cast<uint64_t>(pc));
        pc = prog+(callpc&0x3fffffff);
        DISPATCH;
    }
op_ret: {
        pc = reinterpret_cast<uint64_t*>(POPCALLSTACK);
        DISPATCH;
    }
op_addfloat: {
        double par2 = POP.d;
        TOS.d = TOS.d+par2;
        DISPATCH;
    }
op_subfloat: {
        double par2 = POP.d;
        TOS.d = TOS.d - par2;
        DISPATCH;
    }
op_mulfloat: {
        double par2 = POP.d;
        TOS.d = TOS.d * par2;
        DISPATCH;
    }
op_divfloat: {
        double par2 = POP.d;
        TOS.d = TOS.d / par2;
        DISPATCH;
    }
op_negfloat: {
        TOS.d = -TOS.d;
        DISPATCH;
    }
op_floattoint: {
        TOS.i = static_cast<int64_t>(rint(TOS.d));
        DISPATCH;
    }
op_inttofloat: {
        TOS.d = TOS.i;
        DISPATCH;
    }
op_eqfloat: {
        uint64_t par2 = POP.u; //.u - ╤З╤В╨╛╨▒╤Л ╨╜╨╡ ╨┐╨╛╨╗╤Г╤З╨░╤В╤М warning ╨╛ ╤Б╤А╨░╨▓╨╜╨╡╨╜╨╕╨╕ 2╤Е double
        TOS.i = (TOS.u==par2)?-1:0;
        DISPATCH;
    }
op_moreeqfloat: {
        double par2 = POP.d;
        TOS.i = (TOS.d>=par2)?-1:0;
        DISPATCH;
    }
op_done: {
        return static_cast<int>(stcSMData[0].current_value.i);
    }
op_readconstvar:{
        uint64_t addr=GETPAR;
        if (addr < static_cast<uint64_t>(N)) {
            PUSH(VAL(addr));
        }else if ((addr < 0x80000000)/*&&((TOS.u&0x3fffffff) < progsize)*/) {
            PUSH(prog[addr]);
        }else if ((addr&0x3fffffff) < LOCALSSIZE) {
            PUSH(locals[addr].u);
        }
        DISPATCH;
    }
op_writeconstvar:{
    uint64_t vardata = POP.u;
    uint64_t varaddr = GETPAR;
    if (varaddr < static_cast<uint64_t>(N)) {
        POKEVAL(varaddr, vardata);
    }else if ((varaddr < 0x80000000)/*&&((varaddr&0x3fffffff) < progsize)*/) {
        prog[varaddr&0x3fffffff] = vardata; //╨┐╨╛ ╨╕╨┤╨╡╨╡ ╨╜╨╡ ╨╜╤Г╨╢╨╜╨╛
    }else if ((varaddr&0x3fffffff) < LOCALSSIZE) {
        locals[varaddr&0x3fffffff].u = vardata;
    }
    DISPATCH;
}
op_incconstvar:{
    uint64_t addr = GETPAR;
    if (addr < static_cast<uint64_t>(N)) {
        POKEVAL(addr, VAL(addr)+1);
    }else if ((addr < 0x80000000)/*&&((varaddr&0x3fffffff) < progsize)*/) {
        prog[addr&0x3fffffff]++; //╨┐╨╛ ╨╕╨┤╨╡╨╡ ╨╜╨╡ ╨╜╤Г╨╢╨╜╨╛
    }else if ((addr&0x3fffffff) < LOCALSSIZE) {
        locals[addr&0x3fffffff].u++;
    }
    DISPATCH;
}
op_decconstvar:{
    uint64_t addr = GETPAR;
    if (addr < static_cast<uint64_t>(N)) {
        POKEVAL(addr, VAL(addr)-1);
    }else if ((addr < 0x80000000)/*&&((varaddr&0x3fffffff) < progsize)*/) {
        prog[addr&0x3fffffff]--; //╨┐╨╛ ╨╕╨┤╨╡╨╡ ╨╜╨╡ ╨╜╤Г╨╢╨╜╨╛
    }else if ((addr&0x3fffffff) < LOCALSSIZE) {
        locals[addr&0x3fffffff].u--;
    }
    DISPATCH;
}
op_rst: {
    uint64_t op = GETPAR;
    double par1;
    uint64_t upar1;
    switch (op) {
//case RST_NOP: //fn_nop:
//        break;
case RST_SIN: //fn_sin:{
        TOS.d=sin(TOS.d);
        break;
case RST_COS: //fn_cos:{
        TOS.d=cos(TOS.d);
        break;
case RST_ATAN: //fn_atan:{
        TOS.d=atan(TOS.d);
        break;
case RST_ATAN2: //fn_atan2:{
        par1 = POP.d;
        TOS.d = atan2(TOS.d,par1);
        break;
case RST_EXP: //fn_exp:{
        TOS.d=exp(TOS.d);
        break;
case RST_LOG: //fn_log:{
        TOS.d=log(TOS.d);
        break;
case RST_SQRT: //fn_sqrt:{
        TOS.d=sqrt(TOS.d);
        break;
case RST_ABS: //fn_abs:{
        TOS.d=abs(TOS.d);
        break;
case RST_ACOS: //fn_acos:{
        TOS.d=acos(TOS.d);
        break;
case RST_ACOSH: //fn_acosh:{
        TOS.d=acosh(TOS.d);
        break;
case RST_ASIN: //fn_asin:{
        TOS.d=asin(TOS.d);
        break;
case RST_ASINH: //fn_asinh:{
        TOS.d=asinh(TOS.d);
        break;
case RST_ATANH: //fn_atanh:{
        TOS.d=atanh(TOS.d);
        break;
case RST_CBRT: //fn_cbrt:{
        TOS.d=cbrt(TOS.d);
        break;
case RST_CEIL: //fn_ceil:{
        TOS.d=ceil(TOS.d);
        break;
case RST_COSH: //fn_cosh:{
        TOS.d=cosh(TOS.d);
        break;
case RST_HYPOT: //fn_hypot:{
        par1 = POP.d;
        TOS.d=hypot(TOS.d,par1);
        break;
case RST_ISFINITE: //fn_isfinite:{
        TOS.i=(isfinite(TOS.d)?-1:0);
        break;
case RST_ISINF: //fn_isinf:{
        TOS.i=(isinf(TOS.d)?-1:0);
        break;
case RST_ISNAN: //fn_isnan:{
        TOS.i=(isnan(TOS.d)?-1:0);
        break;
case RST_J0: //fn_j0:{
        //TOS.d=j0(TOS.d);
        break;
case RST_J1: //fn_j1:{
        //TOS.d=j1(TOS.d);
        break;
case RST_JN: //fn_jn:{
        par1 = POP.d;
        //TOS.d=jn(static_cast<int>(TOS.i),par1);
        break;
case RST_LOG10: //fn_log10:{
        TOS.d=log10(TOS.d);
        break;
case RST_LOG1P: //fn_log1p:{
        TOS.d=log1p(TOS.d);
        break;
case RST_LOGB: //fn_logb:{
        TOS.d=logb(TOS.d);
        break;
case RST_MAX: //fn_max:{
        par1 = POP.d;
        TOS.d=(TOS.d>par1?TOS.d:par1);
        break;
case RST_MIN: //fn_min:{
        par1 = POP.d;
        TOS.d=(TOS.d<par1?TOS.d:par1);
        break;
case RST_RINT: //fn_rint:{
        TOS.d=rint(TOS.d);
        break;
case RST_SINH: //fn_sinh:{
        TOS.d=sinh(TOS.d);
        break;
case RST_TAN: //fn_tan:{
        TOS.d=tan(TOS.d);
        break;
case RST_TANH: //fn_tanh:{
        TOS.d=tanh(TOS.d);
        break;
case RST_Y0: //fn_y0:{
        //TOS.d=y0(TOS.d);
        break;
case RST_Y1: //fn_y1:{
        //TOS.d=y1(TOS.d);
        break;
case RST_YN: //fn_yn:{
        par1 = POP.d;
        //TOS.d=yn(static_cast<int>(TOS.i),par1);
        break;
case RST_POW: //fn_pow:{
        par1 = POP.d;
        TOS.d=pow(TOS.d,par1);
        break;
case RST_PRINT: //fn_print:{
        upar1 = POP.u;
        myprintstr(prog, upar1);
        break;
default: ;
}
        DISPATCH;
    }
}

#ifndef FOR_DEBUGGER
uint64_t *loadscript(int state_index, char *waspath) {
    uint64_t *prog;
    FILE *fileProg;

    stringstream strToInt;
    string stateIndex;
    string path = waspath;

    strToInt << state_index; // ╨┐╨╡╤А╨╡╨▓╨╛╨┤ ╨╕╨╖ ╤З╨╕╤Б╨╗╨░ ╨▓ ╤Б╤В╤А╨╛╨║╤Г
    strToInt >> stateIndex; //

    path += stateIndex;
    path += ".bin";

    int size;
    fileProg = fopen(path.c_str(), "r");
    if (fileProg) {
        fseek(fileProg,0,SEEK_END);
        size = ftell(fileProg);
        fseek(fileProg,0,SEEK_SET);
        prog = reinterpret_cast<uint64_t*>(malloc(size));
        fread(prog, 1, size, fileProg);
        fclose(fileProg);

    } else {
        prog = reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t)));
        prog[0] = CMD_DONE;
    }
    return prog;
}
#endif //FOR_DEBUGGER