Rewrite "stringify" logic for consistency and take it into account when removing unused strings

This commit is contained in:
phobos2077
2023-06-09 15:13:52 +02:00
parent bf164be1fc
commit fcea09ea73
5 changed files with 38 additions and 25 deletions
+7 -11
View File
@@ -95,28 +95,24 @@ static void writenamelist(FILE *f, char *namelist) {
}
static void writeProcAddress(NodeList *n, int i, FILE *f) {
int isRef = 0;
switch(n->nodes[i].token) {
case T_SYMBOL:
writeInt(n->nodes[i].value.intData, f);
/*if (n->nodes[i].flags & P_REFERENCE)
isRef = 1; */
if (!(n->nodes[i].value.type & P_PROCEDURE)) {
// We're trying to call on a variable. We can't know value type at compile. But engine handler expects it to be int.
// So we must assume string value type and insert proc lookup opcode.
if (n->nodes[i].value.type & P_LOCAL) {
writeOp(O_FETCH, f);
if (!isRef)
writeOp(O_LOOKUP_STRING_PROC, f);
writeOp(O_LOOKUP_STRING_PROC, f);
}
else if (n->nodes[i].value.type & P_GLOBAL) {
writeOp(O_FETCH_GLOBAL, f);
if (!isRef)
writeOp(O_LOOKUP_STRING_PROC, f);
writeOp(O_LOOKUP_STRING_PROC, f);
}
else if (n->nodes[i].value.type & P_EXTERN) {
writeOp(O_FETCH_EXTERNAL, f);
if (!isRef)
writeOp(O_LOOKUP_STRING_PROC, f);
writeOp(O_LOOKUP_STRING_PROC, f);
}
}
break;
@@ -259,8 +255,8 @@ int writeNode(NodeList *n, int i, FILE *f) {
break;
case T_SYMBOL:
if (n->nodes[i].value.type & P_PROCEDURE) {
if (n->nodes[i].stringify) { // special case when passing procedure as reference
writeString(n->nodes[i].stringify, f);
if (n->nodes[i].value.type & P_STRINGIFY) { // special case when passing procedure as reference
writeString(currentProgram->procedures.procedures[n->nodes[i].value.intData].stringifiedName, f);
} else
writeInt(n->nodes[i].value.intData, f);
}
+1
View File
@@ -759,6 +759,7 @@ top:
ret = lookupConstant(buf[which]);
if (ret == -1) {
lexData.type = T_SYMBOL;
lexData.stringData = buf[which];
ret = T_SYMBOL;
}
+18 -8
View File
@@ -961,7 +961,7 @@ static void UpdateProcedureReferences(Procedure* procs, int count) {
procs[i].uses = 2;
for (j = 0; j < procs[i].nodes.numNodes; j++) {
node = &procs[i].nodes.nodes[j];
if (node->token == T_SYMBOL && node->value.type == (P_PROCEDURE | P_LOCAL)) {
if (node->token == T_SYMBOL && node->value.type & (P_PROCEDURE | P_LOCAL)) {
if (!procs[node->value.intData].uses) {
matched = 1;
procs[node->value.intData].uses = 1;
@@ -971,7 +971,7 @@ static void UpdateProcedureReferences(Procedure* procs, int count) {
if (procs[i].type & P_CONDITIONAL) {
for (j = 0; j < procs[i].condition.numNodes; j++) {
node = &procs[i].condition.nodes[j];
if (node->token == T_SYMBOL && node->value.type == (P_PROCEDURE | P_LOCAL)) {
if (node->token == T_SYMBOL && node->value.type & (P_PROCEDURE | P_LOCAL)) {
if (!procs[node->value.intData].uses) {
matched = 1;
procs[node->value.intData].uses = 1;
@@ -1218,11 +1218,21 @@ static void CompressNamelist(Program *prog) {
FreeNamelistData(refs, offsets, transforms);
}
static int* GetStringReference(Node *node, Program *prog) {
if (node->token == T_CONSTANT && node->value.type == V_STRING) {
return &node->value.stringData;
}
else if (node->token == T_SYMBOL && node->value.type & P_STRINGIFY) {
return &prog->procedures.procedures[node->value.intData].stringifiedName;
}
return 0;
}
static void CompressStringspace(Program *prog) {
if (!prog->stringspace) return;
char* endptr;
int entries = 0, *refs, *offsets, *transforms, i, j, k;
int entries = 0, *refs, *offsets, *transforms, i, j, k, *stringData;
Procedure* proc;
Node* node;
@@ -1233,9 +1243,9 @@ static void CompressStringspace(Program *prog) {
proc = &prog->procedures.procedures[i];
for (k = 0; k < proc->nodes.numNodes; k++) {
node = &proc->nodes.nodes[k];
if (node->token == T_CONSTANT && node->value.type == V_STRING) {
if (stringData = GetStringReference(node, prog)) {
for (j = 0; j < entries; j++) {
if (node->value.stringData == offsets[j]) refs[j] = 1;
if (*stringData == offsets[j]) refs[j] = 1;
}
}
}
@@ -1251,11 +1261,11 @@ static void CompressStringspace(Program *prog) {
proc = &prog->procedures.procedures[i];
for (k = 0; k < proc->nodes.numNodes; k++) {
node = &proc->nodes.nodes[k];
if (node->token == T_CONSTANT && node->value.type == V_STRING) {
if (stringData = GetStringReference(node, prog)) {
for (j = 0; j < entries; j++) {
if (node->value.stringData == offsets[j]) {
if (*stringData == offsets[j]) {
assert(transforms[j] != 0x7fffffff);
node->value.stringData = transforms[j];
*stringData = transforms[j];
break;
}
}
+9 -4
View File
@@ -678,6 +678,7 @@ static Procedure *addProcedure(ProcedureList *procs, char **namelist, char *name
procs->procedures[i].start = -1;
procs->procedures[i].end = -1;
procs->procedures[i].defined = -1;
procs->procedures[i].stringifiedName = 0;
return procs->procedures + i;
}
@@ -936,7 +937,6 @@ void emitNode(Procedure *p, NodeList *n, LexData *data) {
n->nodes[i].token = data->token;
n->nodes[i].lineNum = lexGetLineno(currentInputStream);
n->nodes[i].column = lexGetColumn(currentInputStream);
n->nodes[i].stringify = 0;
switch (data->token) {
case T_CONSTANT:
@@ -975,8 +975,13 @@ void emitNode(Procedure *p, NodeList *n, LexData *data) {
else {
type |= P_PROCEDURE;
referenceProcedure(&currentProgram->procedures, v);
if (data->type & P_REFERENCE) {
n->nodes[i].stringify = addString(&currentProgram->stringspace, data->stringData);
if (data->type == T_STRING) {
type |= P_STRINGIFY;
Procedure *proc = &currentProgram->procedures.procedures[v];
// Add stringified procedure name (because program has separate namelist of string constants)
if (!proc->stringifiedName) {
proc->stringifiedName = addString(&currentProgram->stringspace, data->stringData);
}
}
}
}
@@ -1056,7 +1061,7 @@ static void factor(Procedure *p, NodeList *nodes) {
if (q) {
if (q->type&P_INLINE) parseSemanticError("Cannot use an inline procedure in an expression");
if (refSyntax) {
d.type |= P_REFERENCE; // this will make node stringify when writing code
d.type = T_STRING; // this will make node stringify when generating code
emitNode(p, nodes, &d);
} else if (isExpectingProcArg() && (expectToken('(') == -1)) {
ungetToken();
+3 -2
View File
@@ -57,14 +57,12 @@ typedef struct {
int numVariables;
} VariableList;
#define P_REFERENCE 0x08000000
typedef struct {
int token;
const char* file;
int lineNum;
Value value;
int column;
int stringify;
} Node;
typedef struct {
@@ -79,6 +77,7 @@ typedef struct {
#define P_CRITICAL 0x10
#define P_PURE 0x20
#define P_INLINE 0x40
typedef struct {
int name; /* offset into main program's namelist */
int type; /* timed, conditional, or system procedure */
@@ -102,6 +101,7 @@ typedef struct {
NodeList nodes;
int minArgs; // minimum number of arguments for call
int deftype; // set to 1 if this has been define (and not just declared)
int stringifiedName; // offset into program's string space, this used when procedure is referenced via stringify operator
} Procedure;
typedef struct {
@@ -158,6 +158,7 @@ extern char *getName(int offset, char *namelist);
#define P_LOCAL 0x40000000
#define P_PROCEDURE 0x20000000
#define P_EXTERN 0x10000000
#define P_STRINGIFY 0x08000000
#include "opcodes.h"