euddraft icon indicating copy to clipboard operation
euddraft copied to clipboard

Suggestion: A Way to Insert Raw Python Code Within EPS

Open Dr-zzt opened this issue 7 years ago • 4 comments

Right now, the only way to include a raw python code within eps code is py_exec or py_eval. However, it is ugly and slow (because it uses exec), and it can be used only under certain circumstances. Can you introduce a way to include python code within eps, like asm in C++?

Dr-zzt avatar Jul 25 '18 03:07 Dr-zzt

I'll look at it.

Some considerations are about how the eps code and python code could cleanly interoperate. epScript does a lot of things in a background to resolve differences btw python and epScript. For example, while eps supports nested local scope, python don't well. eps supports local scope by suffixing names. For example, the code below

var a = 1;

function x() {
    var a = dwread()[[5]];
    a = A[5];
    A[a] = 7;
}

is translated as:

a = EUDCreateVariables(1)
_IGVA([a], lambda: [1])
@EUDFunc
def f_x():
    a_1 = EUDVariable()
    a_1 << (f_dwread()[5])
    a_1 << (A[5])
    _ARRW(A, a_1) << (7)

The local variable a in eps is translated as a_1 in python code. For inline python code to be useful, eps code should be able to access python variables. I'm wondering how these two features could be interpolated cleanly.

phu54321 avatar Aug 11 '18 20:08 phu54321

I'm thinking of a syntax like this:

function x() {
     py {
          a = [x * x for x in range(5)]
     }
     const aArr = EUDArray(py_a);
}

eps code could access a defined in python namespace by py_a. py_a is translated to a in python source code. Users should handle various pitfalls themselves. (For example you shouldn't redefine a or use plain a in eps code)

Will this suffice? What's your use case?

phu54321 avatar Aug 11 '18 20:08 phu54321

May I introduce my cases?

// Using Forward in EPS - extra CUnit space
const extra = Db(1700 * 336);
const extra_jump, extra_exit = Forward(), Forward();
function JumpUnitDb() {
    py_exec('DoActions([extra_jump << SetMemory(0x6509B0, Add, 0xEDAC])');
}
function ExitUnitDb() {
    py_exec('DoActions([extra_exit << SetMemory(0x6509B0, Subtract, 0xEDAC])');
}
function onPluginStart() {
    SetMemory(extra_jump + 20, SetTo, (extra - 0x59CCA8) / 4);
    SetMemory(extra_exit + 20, SetTo, (extra - 0x59CCA8) / 4);
}
// draw circle
import py_math;
function Circle(t) {
    const Period = 32;
    EUDSwitch(t);
    foreach(i : py_range(Period)) {
        EUDSwitchCase()(i);
        // can't use py_math (py_math module doesn't have f_cos)
        const x = py_eval('int(round(160 * math.cos(i / Period * 2*math.pi)))');
        const x = py_eval('int(round(160 * math.sin(i / Period * 2*math.pi)))');
        loc.AddLoc($L("effect"), x, y);
        const epd = epdread_epd(EPD(0x628438));
        CreateUnit(1, "effect", e1 + 1, P8);
        dwwrite_epd(epd + 0x110 / 4, 29);
        loc.AddLoc($L("effect"), -x, -y);
        break;
    }
    EUDEndSwitch();
}

armoha avatar Aug 12 '18 03:08 armoha

Right now I am travelling around, so I can't come up with my case very soon. Please refer to Armo's cases. My cases are not very different from his.

Dr-zzt avatar Aug 12 '18 06:08 Dr-zzt