2007-10-03 22:00:00 +02:00
|
|
|
|
//=======================================================================
|
|
|
|
|
// Copyright XashXT Group 2007 <20>
|
|
|
|
|
// pr_main.c - QuakeC progs compiler
|
|
|
|
|
//=======================================================================
|
|
|
|
|
|
|
|
|
|
#include "qcclib.h"
|
|
|
|
|
|
|
|
|
|
byte *qccpool;
|
|
|
|
|
char v_copyright[1024];
|
|
|
|
|
uint MAX_REGS;
|
|
|
|
|
int MAX_ERRORS;
|
|
|
|
|
int MAX_STRINGS;
|
|
|
|
|
int MAX_GLOBALS;
|
|
|
|
|
int MAX_FIELDS;
|
|
|
|
|
int MAX_STATEMENTS;
|
|
|
|
|
int MAX_FUNCTIONS;
|
|
|
|
|
int MAX_CONSTANTS;
|
|
|
|
|
int numtemps;
|
|
|
|
|
bool compileactive = false;
|
2007-10-08 22:00:00 +02:00
|
|
|
|
char progsoutname[MAX_SYSPATH];
|
2007-10-03 22:00:00 +02:00
|
|
|
|
float *pr_globals;
|
|
|
|
|
uint numpr_globals;
|
|
|
|
|
char *strings;
|
|
|
|
|
int strofs;
|
|
|
|
|
dstatement_t *statements;
|
|
|
|
|
int numstatements;
|
|
|
|
|
int *statement_linenums;
|
2007-10-08 22:00:00 +02:00
|
|
|
|
char sourcedir[MAX_SYSPATH];
|
|
|
|
|
cachedsourcefile_t *sourcefile;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
dfunction_t *functions;
|
|
|
|
|
int numfunctions;
|
|
|
|
|
ddef_t *qcc_globals;
|
|
|
|
|
int numglobaldefs;
|
|
|
|
|
ddef_t *fields;
|
|
|
|
|
int numfielddefs;
|
|
|
|
|
hashtable_t compconstantstable;
|
|
|
|
|
hashtable_t globalstable;
|
|
|
|
|
hashtable_t localstable;
|
|
|
|
|
hashtable_t intconstdefstable;
|
|
|
|
|
hashtable_t floatconstdefstable;
|
|
|
|
|
hashtable_t stringconstdefstable;
|
|
|
|
|
bool pr_warning[WARN_MAX];
|
2007-10-05 22:00:00 +02:00
|
|
|
|
int target_version;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
bool bodylessfuncs;
|
|
|
|
|
type_t *qcc_typeinfo;
|
|
|
|
|
int numtypeinfos;
|
|
|
|
|
int maxtypeinfos;
|
|
|
|
|
|
2007-10-08 22:00:00 +02:00
|
|
|
|
void PR_SetDefaultProperties (void)
|
2007-10-03 22:00:00 +02:00
|
|
|
|
{
|
2007-10-04 22:00:00 +02:00
|
|
|
|
const_t *cnst;
|
2007-10-08 22:00:00 +02:00
|
|
|
|
int i, j;
|
2007-10-04 22:00:00 +02:00
|
|
|
|
char *name, *val;
|
|
|
|
|
|
2007-10-08 22:00:00 +02:00
|
|
|
|
Hash_InitTable(&compconstantstable, MAX_CONSTANTS);
|
|
|
|
|
|
|
|
|
|
ForcedCRC = 0;
|
|
|
|
|
// enable all warnings
|
|
|
|
|
memset(pr_warning, 0, sizeof(pr_warning));
|
|
|
|
|
|
|
|
|
|
// reset all optimizarions
|
|
|
|
|
for (i = 0; pr_optimisations[i].enabled; i++)
|
|
|
|
|
*pr_optimisations[i].enabled = false;
|
2007-10-05 22:00:00 +02:00
|
|
|
|
target_version = QPROGS_VERSION;
|
2007-10-08 22:00:00 +02:00
|
|
|
|
PR_DefineName("_QCLIB"); // compiler type
|
|
|
|
|
|
|
|
|
|
// play with default warnings.
|
|
|
|
|
pr_warning[WARN_NOTREFERENCEDCONST] = true;
|
|
|
|
|
pr_warning[WARN_MACROINSTRING] = true;
|
|
|
|
|
pr_warning[WARN_FIXEDRETURNVALUECONFLICT] = true;
|
|
|
|
|
pr_warning[WARN_EXTRAPRECACHE] = true;
|
|
|
|
|
pr_warning[WARN_DEADCODE] = true;
|
|
|
|
|
pr_warning[WARN_INEFFICIENTPLUSPLUS] = true;
|
|
|
|
|
pr_warning[WARN_EXTENSION_USED] = true;
|
|
|
|
|
pr_warning[WARN_IFSTRING_USED] = true;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
2007-10-04 22:00:00 +02:00
|
|
|
|
for (i = 1; i < fs_argc; i++)
|
2007-10-03 22:00:00 +02:00
|
|
|
|
{
|
2007-10-04 22:00:00 +02:00
|
|
|
|
if( !strnicmp(fs_argv[i], "/D", 2))
|
2007-10-03 22:00:00 +02:00
|
|
|
|
{
|
2007-10-05 22:00:00 +02:00
|
|
|
|
// #define
|
2007-10-04 22:00:00 +02:00
|
|
|
|
name = fs_argv[i+1];
|
2007-10-03 22:00:00 +02:00
|
|
|
|
val = strchr(name, '=');
|
2007-10-04 22:00:00 +02:00
|
|
|
|
if (val) { *val = '\0', val++; }
|
2007-10-03 22:00:00 +02:00
|
|
|
|
cnst = PR_DefineName(name);
|
|
|
|
|
if (val)
|
|
|
|
|
{
|
2007-10-04 22:00:00 +02:00
|
|
|
|
if(strlen(val) + 1 >= sizeof(cnst->value))
|
|
|
|
|
PR_ParseError(ERR_INTERNAL, "compiler constant value is too long\n");
|
2007-10-03 22:00:00 +02:00
|
|
|
|
strncpy(cnst->value, val, sizeof(cnst->value)-1);
|
2007-10-04 22:00:00 +02:00
|
|
|
|
PR_Message("value %s\n", val );
|
2007-10-03 22:00:00 +02:00
|
|
|
|
cnst->value[sizeof(cnst->value)-1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-10-08 22:00:00 +02:00
|
|
|
|
else if ( !strnicmp(fs_argv[i], "/V", 2))
|
|
|
|
|
{
|
|
|
|
|
// target version
|
|
|
|
|
if (fs_argv[i][2] == '6') target_version = QPROGS_VERSION;
|
|
|
|
|
else if (fs_argv[i][2] == '7') target_version = FPROGS_VERSION;
|
|
|
|
|
else if (fs_argv[i][2] == '8') target_version = VPROGS_VERSION;
|
|
|
|
|
else PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised version parametr (%s)", fs_argv[i]);
|
|
|
|
|
}
|
2007-10-04 22:00:00 +02:00
|
|
|
|
else if( !strnicmp(fs_argv[i], "/O", 2))
|
2007-10-03 22:00:00 +02:00
|
|
|
|
{
|
2007-10-08 22:00:00 +02:00
|
|
|
|
int currentlevel = 0; // optimization level
|
2007-10-04 22:00:00 +02:00
|
|
|
|
if(fs_argv[i][2] == 'd') currentlevel = MASK_DEBUG; // disable optimizations
|
|
|
|
|
else if (fs_argv[i][2] == '0') currentlevel = MASK_LEVEL_O;
|
|
|
|
|
else if (fs_argv[i][2] == '1') currentlevel = MASK_LEVEL_1;
|
|
|
|
|
else if (fs_argv[i][2] == '2') currentlevel = MASK_LEVEL_2;
|
|
|
|
|
else if (fs_argv[i][2] == '3') currentlevel = MASK_LEVEL_3;
|
|
|
|
|
else if (fs_argv[i][2] == '4') currentlevel = MASK_LEVEL_4;
|
|
|
|
|
|
2007-10-08 22:00:00 +02:00
|
|
|
|
if(currentlevel)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; pr_optimisations[j].enabled; j++)
|
|
|
|
|
{
|
|
|
|
|
if(pr_optimisations[j].levelmask & currentlevel)
|
|
|
|
|
*pr_optimisations[j].enabled = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2007-10-03 22:00:00 +02:00
|
|
|
|
{
|
2007-10-08 22:00:00 +02:00
|
|
|
|
char *abbrev = fs_argv[i]+2; // custom optimisation
|
|
|
|
|
for (j = 0; pr_optimisations[j].enabled; j++)
|
2007-10-03 22:00:00 +02:00
|
|
|
|
{
|
2007-10-08 22:00:00 +02:00
|
|
|
|
if(!strcmp(pr_optimisations[j].shortname, abbrev))
|
|
|
|
|
{
|
|
|
|
|
*pr_optimisations[j].enabled = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2007-10-03 22:00:00 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
===================
|
|
|
|
|
PR_Init
|
|
|
|
|
|
|
|
|
|
initialize compiler and hash tables
|
|
|
|
|
===================
|
|
|
|
|
*/
|
2007-10-04 22:00:00 +02:00
|
|
|
|
void PR_Init( const char *name )
|
2007-10-03 22:00:00 +02:00
|
|
|
|
{
|
2007-10-04 22:00:00 +02:00
|
|
|
|
static char parmname[12][MAX_PARMS];
|
|
|
|
|
static temp_t ret_temp;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
strncat(v_copyright, "This file was created with Xash3D QuakeC compiler,\n", sizeof(v_copyright));
|
|
|
|
|
strncat(v_copyright, "who based on original code of ForeThought's QuakeC compiler.\n", sizeof(v_copyright));
|
|
|
|
|
strncat(v_copyright, "Thanks to ID Software at all.", sizeof(v_copyright));
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
// tune limits
|
|
|
|
|
MAX_REGS = 65536;
|
|
|
|
|
MAX_ERRORS = 10; // per one file
|
|
|
|
|
MAX_STRINGS = 1000000;
|
|
|
|
|
MAX_GLOBALS = 32768;
|
|
|
|
|
MAX_FIELDS = 2048;
|
|
|
|
|
MAX_STATEMENTS = 0x80000;
|
|
|
|
|
MAX_FUNCTIONS = 16384;
|
|
|
|
|
maxtypeinfos = 16384;
|
|
|
|
|
MAX_CONSTANTS = 2048;
|
|
|
|
|
|
|
|
|
|
PR_SetDefaultProperties();
|
|
|
|
|
|
|
|
|
|
numtemps = 0;
|
2007-10-04 22:00:00 +02:00
|
|
|
|
functemps = NULL;
|
|
|
|
|
sourcefile = NULL;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
strings = (void *)Qalloc(sizeof(char) * MAX_STRINGS);
|
|
|
|
|
strofs = 1;
|
|
|
|
|
|
|
|
|
|
statements = (void *)Qalloc(sizeof(dstatement_t) * MAX_STATEMENTS);
|
2007-10-04 22:00:00 +02:00
|
|
|
|
numstatements = 1;
|
|
|
|
|
|
2007-10-03 22:00:00 +02:00
|
|
|
|
statement_linenums = (void *)Qalloc(sizeof(int) * MAX_STATEMENTS);
|
|
|
|
|
|
|
|
|
|
functions = (void *)Qalloc(sizeof(dfunction_t) * MAX_FUNCTIONS);
|
2007-10-04 22:00:00 +02:00
|
|
|
|
numfunctions = 1;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
pr_bracelevel = 0;
|
|
|
|
|
|
|
|
|
|
pr_globals = (void *)Qalloc(sizeof(float) * MAX_REGS);
|
2007-10-04 22:00:00 +02:00
|
|
|
|
numpr_globals = 0;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
2007-10-04 22:00:00 +02:00
|
|
|
|
Hash_InitTable(&globalstable, MAX_REGS);
|
|
|
|
|
Hash_InitTable(&localstable, MAX_REGS);
|
|
|
|
|
Hash_InitTable(&floatconstdefstable, MAX_REGS+1);
|
|
|
|
|
Hash_InitTable(&intconstdefstable, MAX_REGS+1);
|
|
|
|
|
Hash_InitTable(&stringconstdefstable, MAX_REGS);
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
qcc_globals = (void *)Qalloc(sizeof(ddef_t) * MAX_GLOBALS);
|
2007-10-04 22:00:00 +02:00
|
|
|
|
numglobaldefs = 1;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
fields = (void *)Qalloc(sizeof(ddef_t) * MAX_FIELDS);
|
2007-10-04 22:00:00 +02:00
|
|
|
|
numfielddefs = 1;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
2007-10-04 22:00:00 +02:00
|
|
|
|
qcc_typeinfo = (void *)Qalloc(sizeof(type_t) * maxtypeinfos);
|
2007-10-03 22:00:00 +02:00
|
|
|
|
numtypeinfos = 0;
|
2007-10-04 22:00:00 +02:00
|
|
|
|
bodylessfuncs = 0;
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
memset(&pr, 0, sizeof(pr));
|
2007-10-04 22:00:00 +02:00
|
|
|
|
memset(&ret_temp, 0, sizeof(ret_temp));
|
|
|
|
|
memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
2007-10-04 22:00:00 +02:00
|
|
|
|
if (opt_locals_marshalling) MsgWarn("Locals marshalling might be buggy. Use with caution\n");
|
2007-10-08 22:00:00 +02:00
|
|
|
|
strncpy( sourcefilename, name, sizeof(sourcefilename));
|
2007-10-04 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
// default parms
|
|
|
|
|
def_ret.ofs = OFS_RETURN;
|
|
|
|
|
def_ret.name = "return";
|
|
|
|
|
def_ret.temp = &ret_temp;
|
|
|
|
|
def_ret.constant = false;
|
|
|
|
|
def_ret.type = NULL;
|
|
|
|
|
ret_temp.ofs = def_ret.ofs;
|
|
|
|
|
ret_temp.scope = NULL;
|
|
|
|
|
ret_temp.size = 3;
|
|
|
|
|
ret_temp.next = NULL;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_PARMS; i++)
|
2007-10-03 22:00:00 +02:00
|
|
|
|
{
|
2007-10-04 22:00:00 +02:00
|
|
|
|
def_parms[i].temp = NULL;
|
|
|
|
|
def_parms[i].type = NULL;
|
|
|
|
|
def_parms[i].ofs = OFS_PARM0 + 3*i;
|
|
|
|
|
def_parms[i].name = parmname[i];
|
|
|
|
|
sprintf(parmname[i], "parm%i", i);
|
2007-10-03 22:00:00 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PrepareDATProgs ( const char *dir, const char *name, byte params )
|
|
|
|
|
{
|
|
|
|
|
qccpool = Mem_AllocPool( "QCC Compiler" );
|
|
|
|
|
|
2007-10-04 22:00:00 +02:00
|
|
|
|
FS_InitRootDir( (char *)dir );
|
|
|
|
|
PR_Init( name );
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
2007-10-08 22:00:00 +02:00
|
|
|
|
autoprototype = true;
|
|
|
|
|
|
2007-10-03 22:00:00 +02:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CompileDATProgs ( void )
|
|
|
|
|
{
|
|
|
|
|
PR_BeginCompilation();
|
2007-10-08 22:00:00 +02:00
|
|
|
|
while(PR_ContinueCompilation());
|
|
|
|
|
PR_FinishCompilation();
|
2007-10-03 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
Mem_FreePool( &qccpool );
|
2007-10-08 22:00:00 +02:00
|
|
|
|
|
2007-10-03 22:00:00 +02:00
|
|
|
|
return true;
|
|
|
|
|
}
|