mirror of
https://github.com/sfall-team/sslc.git
synced 2026-07-27 16:52:49 -07:00
Rewrite "stringify" logic for consistency and take it into account when removing unused strings
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(¤tProgram->procedures, v);
|
||||
if (data->type & P_REFERENCE) {
|
||||
n->nodes[i].stringify = addString(¤tProgram->stringspace, data->stringData);
|
||||
if (data->type == T_STRING) {
|
||||
type |= P_STRINGIFY;
|
||||
Procedure *proc = ¤tProgram->procedures.procedures[v];
|
||||
// Add stringified procedure name (because program has separate namelist of string constants)
|
||||
if (!proc->stringifiedName) {
|
||||
proc->stringifiedName = addString(¤tProgram->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();
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user