Permalink
Browse files

Compiler Cleanup: Remove more global state, fix alarms

Some global state wasn't being updated because I cut a bunch of it out, deleted a redundant copy of some code, and lost a little information in the process. The alarms fix was really just updating the `namespace_enigma` global. Instead of doing that, I've removed the `namespace_enigma` global. Good fucking riddance.

There's still some more global state lying around, and ENIGMA is passing around JDI definition pointers willy-nilly, which it should NOT be doing. That's entirely my fault, but it still hurts the same.

In the future, we'll want to pull out the JDI definitions from the compiler. But the only occurrences of JDI-isms, now, are within `lang_CPP`, the syntax checker, and the code translation / "linking" module. The syntax checker and code translation unit are going to be replaced by a tree builder and pretty printer, respectively. When this occurs, I intend to abstract away the process of symbol definition (checking if a function exists, checking if it's variadic, etc). The linking module will only need minor tweaks. It's actually pretty brilliant for young me; I'm impressed.
  • Loading branch information...
JoshDreamland committed Jan 25, 2019
1 parent 066b36b commit 090d1a92fa377e0f9a851ebdaa3daa325b76a497
@@ -370,7 +370,7 @@ ImageData::ImageData(const Image &img):
ImageData::ImageData(int w, int h, const uint8_t *data, size_t size):
width(w), height(h), pixels(data, data + size) {}

GameData::GameData(EnigmaStruct *es) {
GameData::GameData(EnigmaStruct *es): filename(es->filename ?: "") {
cout << "Translating EnigmaStruct" << endl;
cout << "- Indexing names" << endl;
ESLookup lookup(es);
@@ -406,11 +406,13 @@ GameData::GameData(EnigmaStruct *es) {
for (int i = 0; i < es->roomCount; ++i)
rooms.emplace_back(es->rooms[i], lookup);

cout << "- Transferring other stuff" << endl;
cout << "- Transferring " << es->constantCount << " constants" << endl;
for (int i = 0; i < es->constantCount; ++i)
constants.push_back({es->constants[i].name, es->constants[i].value});
constants.emplace_back(es->constants[i].name, es->constants[i].value);
cout << "- Transferring " << es->extensionCount << " extensions" << endl;
for (int i = 0; i < es->extensionCount; ++i)
extensions.push_back({es->extensions[i].name, es->extensions[i].path});
extensions.emplace_back(es->extensions[i].name, es->extensions[i].path);
cout << "- Transferring " << es->packageCount << " packages" << endl;
for (int i = 0; i < es->packageCount; ++i)
packages.push_back(es->packages[i]);

@@ -126,8 +126,14 @@ struct GameData {
std::vector<RoomData> rooms;

// TODO(Robert): Why do none of these have Proto equivalents?
struct Extension { std::string name, path; };
struct Constant { std::string name, value; };
struct Extension {
std::string name, path;
Extension(std::string n, std::string p): name(n), path(p) {}
};
struct Constant {
std::string name, value;
Constant(std::string n, std::string v): name(n), value(v) {}
};

// std::vector<Trigger> triggers;
std::vector<Constant> constants;
@@ -18,7 +18,7 @@

#include "makedir.h"
#include "OS_Switchboard.h" //Tell us where the hell we are
#include "backend/EnigmaStruct.h" //LateralGM interface structures
#include "backend/GameData.h"
#include "settings.h"

#include "general/darray.h"
@@ -68,8 +68,6 @@ using namespace std;

#include "languages/lang_CPP.h"

#include "compiler/jdi_utility.h"

#ifdef WRITE_UNIMPLEMENTED_TXT
std::map <string, char> unimplemented_function_list;
#endif
@@ -149,15 +147,11 @@ inline void write_exe_info(const std::string codegen_directory, const GameData &
<< "VALUE \"FileVersion\", \"" << gloss_version << "\\0\"\n"
<< "VALUE \"ProductName\", \"" << gameSet.product() << "\"\n"
<< "VALUE \"ProductVersion\", \"" << gloss_version << "\\0\"\n"
<< "VALUE \"LegalCopyright\", \"" << gameSet.copyright() << "\"\n";
if (!game.filename.empty()) {
wto << "VALUE \"OriginalFilename\", \"" << string_replace_all(game.filename,"\\","/") << "\"\n";
} else {
wto << "VALUE \"OriginalFilename\", \"\"\n";
}
wto << "END\nEND\nBLOCK \"VarFileInfo\"\nBEGIN\n";
wto << "VALUE \"Translation\", 0x409, 1252\n";
wto << "END\nEND";
<< "VALUE \"LegalCopyright\", \"" << gameSet.copyright() << "\"\n"
<< "VALUE \"OriginalFilename\", \"" << string_replace_all(game.filename,"\\","/") << "\"\n"
<< "END\nEND\nBLOCK \"VarFileInfo\"\nBEGIN\n"
<< "VALUE \"Translation\", 0x409, 1252\n"
<< "END\nEND";
wto.close();
}

@@ -235,18 +229,25 @@ int lang_CPP::compile(const GameData &game, const char* exe_filename, int mode)
// Re-establish ourself
// Read the global locals: locals that will be included with each instance
{
set<string> extnp, extlp;
set<string> exts_new_parse, exts_last_parse;
for (const auto &ext : game.extensions) {
extnp.insert(ext.path + ext.name);
exts_new_parse.insert(ext.path + "/" + ext.name);
}
for (const string &ext : requested_extensions_last_parse) {
extlp.insert(ext);
exts_last_parse.insert(ext);
}
edbg << "Loading shared locals from extensions list" << flushl;
if (extnp != extnp) {
if (exts_new_parse != exts_last_parse) {
user << "The IDE didn't tell ENIGMA what extensions "
"were selected before requesting a build.";
idpr("ENIGMA Misconfiguration",-1); return E_ERROR_LOAD_LOCALS;

cout << "Extensions I have loaded:" << endl;
for (const string &e : exts_last_parse) cout << "- " << e << endl;
cout << "Extensions I should have loaded:" << endl;
for (const string &e : exts_new_parse) cout << "- " << e << endl;

//idpr("ENIGMA Misconfiguration",-1); return E_ERROR_LOAD_LOCALS;
user << "...Continuing anyway..." << flushl;
}
}

@@ -270,54 +271,48 @@ int lang_CPP::compile(const GameData &game, const char* exe_filename, int mode)
edbg << "Copying resources:" << flushl;

edbg << "Copying sprite names [" << game.sprites.size() << "]" << flushl;
for (size_t i = 0; i < game.sprites.size(); i++) {
cout << "Name on this side: " << globals_scope.name << endl;
cout << "Name on this side2: " << ((jdi::definition_scope*)&globals_scope)->name << endl;
cout << "Pointer on this side: " << (&globals_scope) << endl;
cout << "Address on this side: " << ((jdi::definition_scope*)&globals_scope) << endl;

quickmember_variable(&globals_scope,jdi::builtin_type__int,game.sprites[i].name);
}
for (size_t i = 0; i < game.sprites.size(); i++)
current_language->quickmember_integer(&globals_scope, game.sprites[i].name);

edbg << "Copying sound names [" << game.sounds.size() << "]" << flushl;
for (size_t i = 0; i < game.sounds.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.sounds[i].name);
current_language->quickmember_integer(&globals_scope, game.sounds[i].name);

edbg << "Copying background names [" << game.backgrounds.size() << "]" << flushl;
for (size_t i = 0; i < game.backgrounds.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.backgrounds[i].name);
current_language->quickmember_integer(&globals_scope, game.backgrounds[i].name);

edbg << "Copying path names [" << game.paths.size() << "]" << flushl;
for (size_t i = 0; i < game.paths.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.paths[i].name);
current_language->quickmember_integer(&globals_scope, game.paths[i].name);

edbg << "Copying script names [" << game.scripts.size() << "]" << flushl;
for (size_t i = 0; i < game.scripts.size(); i++)
quickmember_script(&globals_scope,game.scripts[i].name);
current_language->quickmember_script(&globals_scope,game.scripts[i].name);

edbg << "Copying shader names [" << game.shaders.size() << "]" << flushl;
for (size_t i = 0; i < game.shaders.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.shaders[i].name);
current_language->quickmember_integer(&globals_scope, game.shaders[i].name);

edbg << "Copying font names [" << game.fonts.size() << "]" << flushl;
for (size_t i = 0; i < game.fonts.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.fonts[i].name);
current_language->quickmember_integer(&globals_scope, game.fonts[i].name);

edbg << "Copying timeline names [" << game.timelines.size() << "]" << flushl;
for (size_t i = 0; i < game.timelines.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.timelines[i].name);
current_language->quickmember_integer(&globals_scope, game.timelines[i].name);

edbg << "Copying object names [" << game.objects.size() << "]" << flushl;
for (size_t i = 0; i < game.objects.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.objects[i].name);
current_language->quickmember_integer(&globals_scope, game.objects[i].name);

edbg << "Copying room names [" << game.rooms.size() << "]" << flushl;
for (size_t i = 0; i < game.rooms.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.rooms[i].name);
current_language->quickmember_integer(&globals_scope, game.rooms[i].name);

edbg << "Copying constant names [" << game.constants.size() << "]" << flushl;
for (size_t i = 0; i < game.constants.size(); i++)
quickmember_variable(&globals_scope,jdi::builtin_type__int,game.constants[i].name);
current_language->quickmember_integer(&globals_scope, game.constants[i].name);


/// Next we do a simple parse of the code, scouting for some variable names and adding semicolons.
@@ -26,10 +26,6 @@

#include <JDI/src/Storage/definition.h>

extern jdi::definition *enigma_type__var;
extern jdi::definition *enigma_type__variant;
extern jdi::definition *enigma_type__varargs;

extern string tostring(int val);

inline string format_error(string code,string err,int pos)
@@ -34,7 +34,6 @@ using namespace std;
#include "syntax/syncheck.h"
#include "parser/parser.h"

#include "backend/EnigmaStruct.h" //LateralGM interface structures
#include "parser/object_storage.h"
#include "compiler/compile_common.h"

@@ -27,7 +27,7 @@ using namespace std;
#include "syntax/syncheck.h"
#include "parser/parser.h"

#include "backend/EnigmaStruct.h" //LateralGM interface structures
#include "backend/GameData.h"
#include "parser/object_storage.h"
#include "compiler/compile_common.h"

@@ -36,7 +36,7 @@ using namespace std;
#include "syntax/syncheck.h"
#include "parser/parser.h"

#include "backend/EnigmaStruct.h" //LateralGM interface structures
#include "backend/GameData.h"
#include "parser/object_storage.h"
#include "compiler/compile_common.h"

@@ -34,7 +34,7 @@ using namespace std;
#include "syntax/syncheck.h"
#include "parser/parser.h"

#include "backend/EnigmaStruct.h" //LateralGM interface structures
#include "backend/GameData.h"
#include "parser/object_storage.h"
#include "compiler/compile_common.h"

@@ -31,7 +31,7 @@ using namespace std;
#include "syntax/syncheck.h"
#include "parser/parser.h"

#include "backend/EnigmaStruct.h" //LateralGM interface structures
#include "backend/GameData.h"
#include "compiler/compile_common.h"

#include "event_reader/event_parser.h"
@@ -29,7 +29,6 @@
#include <cstdio>
#include <fstream>
#include "backend/GameData.h"
#include "compiler/reshandlers/refont.h"
#include <string>
using namespace std;
#include "compiler/compile_common.h"
@@ -21,36 +21,24 @@
* JustDefineIt. If not, see <http://www.gnu.org/licenses/>.
**/

#include "jdi_utility.h"
#include <Storage/definition.h>
#include <languages/lang_CPP.h>

using namespace jdip;

definition* enigma_type__var;
definition* enigma_type__variant;
definition* enigma_type__varargs;

int referencers_varargs_at(ref_stack &refs) {
if (refs.top().type != ref_stack::RT_FUNCTION)
return -1;
ref_stack::parameter_ct &params = ((ref_stack::node_func*)&refs.top())->params;
for (size_t i = 0; i < params.size(); ++i)
if (params[i].def == enigma_type__varargs)
return i;
return -1;
}

/*
* Visit a function overload and change minimum argument count and maximum
* argument count based on the number of arguments in the overload.
*/
static void visit_overload(definition_function* d, unsigned &min, unsigned &max) {
static void visit_overload(
definition_function* d, unsigned &min, unsigned &max, definition *varargs_t) {
bool variadic = false;
unsigned int local_min=0,local_max=0;

const ref_stack &refs = ((definition_function*)d)->referencers;
const ref_stack::parameter_ct& params = ((ref_stack::node_func*)&refs.top())->params;
for (size_t i = 0; i < params.size(); ++i)
if (params[i].variadic or params[i].def == enigma_type__varargs) variadic = true;
if (params[i].variadic or params[i].def == varargs_t) variadic = true;
else if (params[i].default_value) ++local_max; else ++local_min, ++local_max;
if (variadic) max = -1;
if (min > local_min) min = local_min;
@@ -61,27 +49,38 @@ static void visit_overload(definition_function* d, unsigned &min, unsigned &max)
* Iterate overloads of a function and change minimum argument count and maximum
* argument count based on the number of arguments in the overload.
*/
static void iterate_overloads(definition_function* d, unsigned &min, unsigned &max) {
static void iterate_overloads(
definition_function* d, unsigned &min, unsigned &max, definition *varargs_t) {
for (map<arg_key, definition_function*>::iterator iter = d->overloads.begin();
iter != ((definition_function*)d)->overloads.end(); iter++) {
visit_overload(iter->second, min, max);
visit_overload(iter->second, min, max, varargs_t);
}
}

void definition_parameter_bounds(definition *d, unsigned &min, unsigned &max) {
int lang_CPP::referencers_varargs_at(ref_stack &refs) {
if (refs.top().type != ref_stack::RT_FUNCTION)
return -1;
ref_stack::parameter_ct &params = ((ref_stack::node_func*)&refs.top())->params;
for (size_t i = 0; i < params.size(); ++i)
if (params[i].def == enigma_type__varargs)
return i;
return -1;
}

void lang_CPP::definition_parameter_bounds(definition *d, unsigned &min, unsigned &max) {
min = (unsigned) SIZE_MAX;
max = 0;

if (!(d->flags & DEF_FUNCTION)) {
if (d->flags & DEF_TEMPLATE) {
definition_template *dt = (definition_template*) d;
if (dt->def && (dt->def->flags & DEF_FUNCTION)) {
iterate_overloads((definition_function*) dt->def, min, max);
iterate_overloads((definition_function*) dt->def, min, max, enigma_type__varargs);
for (definition_template::specmap::iterator it = dt->specializations.begin();
it != dt->specializations.end(); ++it) {
definition_template *spec = it->second;
if (spec->def && spec->def->flags & DEF_FUNCTION)
iterate_overloads((definition_function*) spec->def, min, max);
iterate_overloads((definition_function*) spec->def, min, max, enigma_type__varargs);
}
return;
}
@@ -90,10 +89,10 @@ void definition_parameter_bounds(definition *d, unsigned &min, unsigned &max) {
return;
}

iterate_overloads((definition_function*) d, min, max);
iterate_overloads((definition_function*) d, min, max, enigma_type__varargs);
}

bool definition_is_function(definition *d) {
bool lang_CPP::definition_is_function(definition *d) {
if (d->flags & DEF_FUNCTION) return true;
if (d->flags & DEF_TEMPLATE) {
definition_template *dt = (definition_template*) d;
@@ -102,7 +101,7 @@ bool definition_is_function(definition *d) {
return false;
}

size_t definition_overload_count(jdi::definition *d) {
size_t lang_CPP::definition_overload_count(jdi::definition *d) {
if (!(d->flags & DEF_FUNCTION)) {
if (d->flags & DEF_TEMPLATE) {
definition_template *dt = (definition_template*) d;
@@ -136,10 +135,10 @@ bool lang_CPP::global_exists(string n) {
}


void quickmember_variable(jdi::definition_scope* scope, jdi::definition* type, string name) {
void lang_CPP::quickmember_variable(jdi::definition_scope* scope, jdi::definition* type, string name) {
scope->members[name] = new jdi::definition_typed(name,scope,type,0);
}
void quickmember_script(jdi::definition_scope* scope, string name) {
void lang_CPP::quickmember_script(jdi::definition_scope* scope, string name) {
jdi::ref_stack rfs;
jdi::ref_stack::parameter_ct params;
for (int i = 0; i < 16; ++i) {
Oops, something went wrong.

0 comments on commit 090d1a9

Please sign in to comment.