mahlendur/_work/Data/Scripts/Content/LeGo/Locals.d
Daniel Heße 892a40ff0f Initial commit with Subversion-codebase from 13/05/2022.
Cleaned up the mess, at this time, only viable data get synced (_work directory for Gothic-data, miranda for mdc-scripts.
Need to symlink files to a working directory.
2022-05-13 17:38:52 +02:00

465 lines
14 KiB
D

/***********************************\
LOCALS
\***********************************/
//========================================
// Arrayfunktionen
//========================================
func int MEM_ArrayLast(var int arr) {
var zCArray a; a = MEM_PtrToInst(arr);
return MEM_ReadInt(a.array + 4 * (a.numInArray-1));
};
func int MEM_ArrayOverwrite(var int arr, var int val, var int newVal) {
var zCArray a; a = MEM_PtrToInst(arr);
var int i; i = 0;
var int p; p = MEM_StackPos.position;
if(i < a.numInArray) {
if(MEM_ReadInt(a.array+4*i) == val) {
MEM_WriteInt(a.array+4*i, newVal);
return i;
};
i += 1;
MEM_StackPos.position = p;
};
return -1;
};
func int MEM_ArrayOverwriteFirst(var int arr, var int val, var int newVal) {
var zCArray a; a = MEM_PtrToInst(arr);
var int i; i = 0;
var int p; p = MEM_StackPos.position;
if(i < a.numInArray) {
if(MEM_ReadInt(a.array+4*i) == val) {
MEM_WriteInt(a.array+4*i, newVal);
return i;
};
i += 1;
MEM_StackPos.position = p;
};
MEM_ArrayInsert(arr, newVal);
return a.numInArray-1;
};
//========================================
// Locals
//========================================
func void Locals() {
// Okay. Auf gehts.
var zCPar_Symbol s;
const string locals_bufferStr = "";
const int locals_bufferInt = 0;
var string locals_retstr;
var zCPar_Symbol retinst;
var int arr, var int type;
var int sPtr;
// Array vorbereiten
const int locals_Arr = 0;
if(!locals_Arr) {
locals_Arr = MEM_ArrayCreate();
};
// Zuerst alle Symbole die ich für die Tokens brauche initialisieren. //{
const int arrayinsert = -1;
const int arraypop = -1;
const int copybytes = -1;
const int clear = -1;
const int alloc = -1;
const int free = -1;
const int readint = -1;
const int writeint = -1;
const int bufferstr = -1;
const int bufferstrPtr = -1;
const int bufferint = -1;
const int retstr = -1;
if(arrayinsert == -1) {
arrayinsert = MEM_GetFuncOffset(MEM_ArrayInsert);
arraypop = MEM_GetFuncOffset(MEM_ArrayPop);
copybytes = MEM_GetFuncOffset(MEM_CopyBytes);
clear = MEM_GetFuncOffset(MEM_Clear);
alloc = MEM_GetFuncOffset(MEM_Alloc);
free = MEM_GetFuncOffset(MEM_Free);
readint = MEM_GetFuncOffset(MEM_ReadInt);
writeint = MEM_GetFuncOffset(MEM_WriteInt);
bufferstr = s + 1;
bufferstrPtr = _@s(locals_bufferStr) + 8;
bufferint = s + 2;
retstr = s + 3;
};
//}
// Ein neuer StringBuilder. In ihm werden alle neuen Tokens gespeichert.
var int stream; stream = SB_New();
// Funktion bestimmen
var int p; p = MEM_GetCallerStackPos();
var int fid; fid = MEM_GetFuncIDByOffset(p);
var int cid; cid = fid;
var int mid;
if(cid == -1) {
MEM_Error("Locals: CallStackPos invalid");
return;
};
// Tokenarray zusammenschrauben
s = _^(MEM_ReadIntArray(currSymbolTableAddress, cid));
var string fname; fname = ConcatStrings(s.name, ".");
var int fret; fret = s.offset;
var int foff; foff = s.content;
MEM_Info(ConcatStrings("Locals: Install at ", s.name));
MEM_Info(ConcatStrings(" Offset is ", IntToString(p - foff)));
// Größe bestimmen
var int size; size = 0;
while(1); //{
cid += 1;
sPtr = MEM_ReadIntArray(currSymbolTableAddress, cid);
s = _^(sPtr);
if(!STR_StartsWith(s.name, fname)) {
break;
};
arr = s.bitfield & zCPar_Symbol_bitfield_ele;
type = s.bitfield & zCPar_Symbol_bitfield_type;
if(arr > 1) {
if(type == zPAR_TYPE_STRING) {
MEM_Error("Locals: Stringarrays are not implemented. Sorry!");
return;
}
else {
size += s_array + s_p_array;
};
}
else if(type == zPAR_TYPE_STRING) {
size += s_string + s_p_string;
}
else if(type == zPAR_TYPE_INSTANCE) {
size += s_inst + s_p_inst;
}
else {
size += s_int + s_p_int;
};
end; //}
mid = cid;
cid = fid;
size += s_header + s_assignblock * 2 + s_skipblock + s_misc + 10;
if(fret == 0) {}
else if(fret == (zPAR_TYPE_STRING>>12)) {
size += s_ret_string;
}
else if(fret == (zPAR_TYPE_INSTANCE>>12)) {
size += s_ret_inst;
}
else {
size += s_ret_int;
};
SB_InitBuffer(size);
SBw(1000); // Remember-int
stream = SB_GetStream();
// Optmimierungshook
SBc(zPAR_TOK_PUSHINT); SBw(stream);
SBc(zPAR_TOK_CALL); SBw(readint);
SBc(zPAR_TOK_JUMPF); SBw(false);
const int s_header = 3 * 5;
// Zuerst alle Symbole pushen
while(1); //{
cid += 1;
if(cid == mid) {
break;
};
sPtr = MEM_ReadIntArray(currSymbolTableAddress, cid);
s = _^(sPtr);
arr = s.bitfield & zCPar_Symbol_bitfield_ele;
type = s.bitfield & zCPar_Symbol_bitfield_type;
if(arr > 1) {
arr *= 4;
SBc(zPAR_TOK_PUSHINT); SBw(arr);
SBc(zPAR_TOK_CALL); SBw(alloc);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_OP_IS);
SBc(zPAR_TOK_PUSHINT); SBw(s.content);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_TOK_PUSHINT); SBw(arr);
SBc(ZPAR_TOK_CALL); SBw(copybytes);
SBc(zPAR_TOK_PUSHINT); SBw(locals_Arr);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_TOK_CALL); SBw(arrayinsert);
const int s_array = 10 * 5 + 1;
}
else if(type == zPAR_TYPE_STRING) {
SBc(zPAR_TOK_PUSHVAR); SBw(cid);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferstr);
SBc(zPAR_TOK_ASSIGNSTR);
SBc(zPAR_TOK_PUSHINT); SBw(12);
SBc(zPAR_TOK_CALL); SBw(alloc);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_OP_IS);
SBc(zPAR_TOK_PUSHINT); SBw(bufferstrPtr);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_TOK_PUSHINT); SBw(12);
SBc(zPAR_TOK_CALL); SBw(copybytes);
SBc(zPAR_TOK_PUSHINT); SBw(bufferstrPtr);
SBc(zPAR_TOK_PUSHINT); SBw(12);
SBc(zPAR_TOK_CALL); SBw(clear);
SBc(zPAR_TOK_PUSHINT); SBw(locals_Arr);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_TOK_CALL); SBw(arrayinsert);
const int s_string = 15 * 5 + 2;
}
else if(type == zPAR_TYPE_INSTANCE) {
SBc(zPAR_TOK_PUSHINT); SBw(locals_Arr);
SBc(zPAR_TOK_PUSHINT); SBw(_@(s.offset));
SBc(zPAR_TOK_CALL); SBw(readint);
SBc(zPAR_TOK_CALL); SBw(arrayinsert);
const int s_inst = 4 * 5;
}
else {
SBc(zPAR_TOK_PUSHINT); SBw(locals_Arr);
SBc(zPAR_TOK_PUSHVAR); SBw(cid);
SBc(zPAR_TOK_CALL); SBw(arrayinsert);
const int s_int = 3 * 5;
};
end; //}
MEM_WriteInt(stream + 4 + 11, (stream + SB_Length()) - currParserStackAddress);
SBc(zPAR_TOK_PUSHINT); SBw(stream);
SBc(zPAR_TOK_PUSHINT); SBw(stream);
SBc(zPAR_TOK_CALL); SBw(readint);
SBc(zPAR_TOK_PUSHINT); SBw(1);
SBc(zPAR_OP_PLUS);
SBc(zPAR_TOK_CALL); SBw(writeint);
const int s_assignblock = 5 * 5 + 1;
// Dann die Funktion callen
SBc(zPAR_TOK_CALL); SBw(foff+5);
SBc(zPAR_TOK_PUSHINT); SBw(stream);
SBc(zPAR_TOK_PUSHINT); SBw(1);
SBc(zPAR_TOK_PUSHINT); SBw(stream);
SBc(zPAR_TOK_CALL); SBw(readint);
SBc(zPAR_OP_MINUS);
SBc(zPAR_TOK_CALL); SBw(writeint);
SBc(zPAR_TOK_PUSHINT); SBw(stream);
SBc(zPAR_TOK_CALL); SBw(readint);
SBc(zPAR_OP_UN_NOT);
SBc(zPAR_TOK_JUMPF); SBw(stream + SB_Length() + 4 + 1 - currParserStackAddress);
SBc(zPAR_TOK_RET);
const int s_skipblock = 3 * 5 + 2;
// Den Rückgabewert behandeln:
if(fret == 0) {}
else if(fret == (zPAR_TYPE_STRING>>12)) {
SBc(zPAR_TOK_PUSHVAR); SBc(retstr);
SBc(zPAR_TOK_ASSIGNSTR);
SBc(zPAR_TOK_PUSHVAR); SBc(retstr);
const int s_ret_string = 2 * 5 + 1;
}
else if(fret == (zPAR_TYPE_INSTANCE>>12)) {
SBc(zPAR_TOK_PUSHINST); SBc(retinst);
SBc(zPAR_TOK_ASSIGNINST);
SBc(zPAR_TOK_PUSHINST); SBc(retinst);
const int s_ret_inst = 2 * 5 + 1;
}
else {
SBc(zPAR_OP_UN_PLUS);
const int s_ret_int = 1;
};
// Und wieder alles popen
while(1); //{
cid -= 1;
if(cid == fid) {
break;
};
sPtr = MEM_ReadIntArray(currSymbolTableAddress, cid);
s = _^(sPtr);
arr = s.bitfield & zCPar_Symbol_bitfield_ele;
type = s.bitfield & zCPar_Symbol_bitfield_type;
if(arr > 1) {
arr *= 4;
SBc(zPAR_TOK_PUSHINT); SBw(locals_Arr);
SBc(zPAR_TOK_CALL); SBw(arraypop);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_OP_IS);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_TOK_PUSHINT); SBw(s.content);
SBc(zPAR_TOK_PUSHINT); SBw(arr);
SBc(zPAR_TOK_CALL); SBw(copybytes);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_TOK_CALL); SBw(free);
const int s_p_array = 9 * 5 + 1;
}
else if(type == zPAR_TYPE_STRING) {
SBc(zPAR_TOK_PUSHINT); SBw(locals_Arr);
SBc(zPAR_TOK_CALL); SBw(arraypop);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_OP_IS);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_TOK_PUSHINT); SBw(bufferstrPtr);
SBc(zPAR_TOK_PUSHINT); SBw(12);
SBc(zPAR_TOK_CALL); SBw(copybytes);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferint);
SBc(zPAR_TOK_CALL); SBw(free);
SBc(zPAR_TOK_PUSHVAR); SBw(bufferstr);
SBc(zPAR_TOK_PUSHVAR); SBw(cid);
SBc(zPAR_TOK_ASSIGNSTR);
const int s_p_string = 11 * 5 + 2;
}
else if(type == zPAR_TYPE_INSTANCE) {
SBc(zPAR_TOK_PUSHINT); SBw(_@(s.offset));
SBc(zPAR_TOK_PUSHINT); SBw(locals_Arr);
SBc(zPAR_TOK_CALL); SBw(arraypop);
SBc(zPAR_TOK_CALL); SBw(writeint);
const int s_p_inst = 4 * 5;
}
else {
SBc(zPAR_TOK_PUSHINT); SBw(locals_Arr);
SBc(zPAR_TOK_CALL); SBw(arraypop);
SBc(zPAR_TOK_PUSHVAR); SBw(cid);
SBc(zPAR_OP_IS);
const int s_p_int = 3 * 5 + 1;
};
end; //}
SBc(zPAR_TOK_RET);
const int s_misc = 5 + 1 + 4; // call + ret + remember-int
// Jetzt muss die Funktion aber noch neu sortiert werden, damit alles glatt geht:
var int len; len = (p - 5) - foff;
foff += currParserStackAddress;
if(len) {
var int pre; pre = MEM_Alloc(len);
MEM_CopyBytes(foff, pre, len);
MEM_CopyBytes(pre, foff+5, len);
MEM_Free(pre);
};
if(SB_Length() > size) {
MEM_Error(STR_Unescape("LeGo::Locals\n\nLength of the StringBuilder exceeded calculated\nsize of locals stream.\n\nPlease report errorcode: loc403"));
};
SB_Release();
MEM_WriteInt(foff+0, zPAR_TOK_JUMP);
MEM_WriteInt(foff+1, (stream+4) - currParserStackAddress);
MEM_ArrayInsert(locals_Arr, stream);
MEM_CallByOffset(p);
stream = MEM_ArrayPop(locals_Arr);
MEM_WriteInt(stream, 0);
MEM_SetCallerStackPos(_@(zPAR_TOK_RET) - currParserStackAddress);
};
//========================================
// Hilfsfunktionen
//========================================
func int Token_GetSize(var int tok) {
if((tok >= zPAR_TOK_CALL && tok <= zPAR_TOK_PUSHINDEX)||(tok >= zPAR_TOK_JUMP && tok <= zPAR_TOK_SETINSTANCE)) {
return 5;
};
return 1;
};
func int Tokens_Copy(var int src, var int dest, var int len) {
MEM_Warn(ConcatStrings("Now movin tokens: ", inttostring(len)));
var int p; p = MEM_Alloc(len);
MEM_CopyBytes(src, p, len);
MEM_CopyBytes(p, dest, len);
MEM_Free(p);
var int dstC; dstC = dest;
var int dstF; dstF = dest+len;
var int srcF; srcF = src+len;
var int diff; diff = dest-src;
while(dstC < dstF);
var int tok; tok = MEM_ReadByte(dstC);
if(tok == zPAR_TOK_JUMPF || tok == zPAR_TOK_JUMP) {
MEM_Info("Move if for Bytes.");
MEM_Info(inttostring(diff));
var int trg; trg = MEM_ReadInt(dstC+1);
if(trg <= srcF && trg >= src) {
MEM_WriteInt(dstC+1, trg+diff);
};
};
dstC += Token_GetSize(tok);
end;
};
//========================================
// Final
//========================================
func int Final() {
// Alle benötigten Funktionsoffsets
const int setcallerpos = -1;
if(setcallerpos == -1) {
setcallerpos = MEM_GetFuncOffset(MEM_SetCallerStackPos);
};
var int p; p = MEM_GetCallerStackPos();
var int pa; pa = p + currParserStackAddress;
if(MEM_ReadByte(pa) != zPAR_TOK_JUMPF) {
MEM_Error("final() darf nur hinter einem if verwendet werden!");
return false;
};
var int ifp; ifp = MEM_ReadInt(pa + 1);
var int ifl; ifl = ifp - p - 5;
var int s; s = SB_New();
SBc(zPAR_TOK_PUSHINT); SBw(p);
SBc(zPAR_TOK_CALL); SBw(setcallerpos);
SBc(zPAR_TOK_JUMP); SBw(ifp);
var int ptr; ptr = SB_GetStream();
SB_Release();
MEM_WriteInt(pa-5, zPAR_TOK_CALL);
MEM_WriteInt(pa-4, ptr - currParserStackAddress);
Tokens_Copy(pa+5, pa, ifl);
MEM_WriteInt(pa+ifl, zPAR_TOK_RET | (zPAR_TOK_RET<<8) | (zPAR_TOK_RET<<16) | (zPAR_TOK_RET<<24));
MEM_SetCallerStackPos(p - 5);
};