mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00
344 lines
7 KiB
C++
344 lines
7 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2008 the OpenMoHAA team
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
// parsetree.cpp: Abstract Syntax Layer for Lexer/Parser
|
|
|
|
#include "parsetree.h"
|
|
#include "../fgame/gamecvars.h"
|
|
#include "../qcommon/mem_tempalloc.h"
|
|
|
|
MEM_TempAlloc parsetree_allocator;
|
|
yyparsedata parsedata;
|
|
sval_u node_none = {0};
|
|
|
|
char *str_replace(char *orig, const char *rep, const char *with)
|
|
{
|
|
char *result; // the return string
|
|
char *ins; // the next insert point
|
|
char *tmp; // varies
|
|
size_t len_rep; // length of rep
|
|
size_t len_with; // length of with
|
|
size_t len_front; // distance between rep and end of last rep
|
|
int count; // number of replacements
|
|
|
|
if (!orig) {
|
|
return NULL;
|
|
}
|
|
if (!rep) {
|
|
rep = "";
|
|
}
|
|
len_rep = strlen(rep);
|
|
if (!with) {
|
|
with = "";
|
|
}
|
|
len_with = strlen(with);
|
|
|
|
ins = orig;
|
|
for (count = 0; (tmp = strstr(ins, rep)) != nullptr; ++count) {
|
|
ins = tmp + len_rep;
|
|
}
|
|
|
|
// first time through the loop, all the variable are set correctly
|
|
// from here on,
|
|
// tmp points to the end of the result string
|
|
// ins points to the next occurrence of rep in orig
|
|
// orig points to the remainder of orig after "end of rep"
|
|
tmp = result = (char *)parsetree_allocator.Alloc(strlen(orig) + (len_with - len_rep) * count + 1);
|
|
|
|
if (!result) {
|
|
return NULL;
|
|
}
|
|
|
|
while (count--) {
|
|
ins = strstr(orig, rep);
|
|
len_front = ins - orig;
|
|
tmp = strncpy(tmp, orig, len_front) + len_front;
|
|
tmp = strcpy(tmp, with) + len_with;
|
|
orig += len_front + len_rep; // move to next "end of rep"
|
|
}
|
|
strcpy(tmp, orig);
|
|
return result;
|
|
}
|
|
|
|
void parsetree_freeall()
|
|
{
|
|
parsetree_allocator.FreeAll();
|
|
|
|
if (g_showopcodes->integer) {
|
|
gi.DPrintf("%d bytes freed\n", parsedata.total_length);
|
|
}
|
|
}
|
|
|
|
void parsetree_init()
|
|
{
|
|
parsedata.total_length = 0;
|
|
}
|
|
|
|
size_t parsetree_length()
|
|
{
|
|
return parsedata.total_length;
|
|
}
|
|
|
|
#if 0
|
|
char* parsetree_string(const char* string)
|
|
{
|
|
//char *pszString = ( char * )parsetree_allocator.Alloc( strlen( string ) + 1 );
|
|
//strcpy( pszString, string );
|
|
|
|
char* buffer = str_replace((char*)string, "\\\"", "\"");
|
|
|
|
if (buffer)
|
|
{
|
|
char* ptr = buffer;
|
|
|
|
if (ptr[0] == '"')
|
|
{
|
|
ptr++;
|
|
}
|
|
|
|
int len = strlen(buffer);
|
|
|
|
if (buffer[len - 1] == '"')
|
|
{
|
|
buffer[len - 1] = 0;
|
|
}
|
|
|
|
buffer = ptr;
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
#endif
|
|
|
|
extern size_t yyleng;
|
|
extern size_t prev_yyleng;
|
|
|
|
char *parsetree_malloc(size_t s)
|
|
{
|
|
parsedata.total_length += s;
|
|
return (char *)parsetree_allocator.Alloc(s);
|
|
}
|
|
|
|
sval_u append_lists(sval_u val1, sval_u val2)
|
|
{
|
|
val1.node[1].node[1] = val2.node[0];
|
|
val1.node[1] = val2.node[1];
|
|
|
|
return val1;
|
|
}
|
|
|
|
sval_u append_node(sval_u val1, sval_u val2)
|
|
{
|
|
sval_u *node;
|
|
|
|
node = (sval_u *)parsetree_malloc(sizeof(sval_t[2]));
|
|
|
|
node[1].node = NULL;
|
|
node[0] = val2;
|
|
|
|
val1.node[1].node[1].node = node;
|
|
val1.node[1].node = node;
|
|
|
|
return val1;
|
|
}
|
|
|
|
sval_u prepend_node(sval_u val1, sval_u val2)
|
|
{
|
|
sval_u *node;
|
|
|
|
node = (sval_u *)parsetree_malloc(sizeof(sval_t[2]));
|
|
|
|
node[0] = val1;
|
|
node[1] = val2;
|
|
|
|
val2.node = node;
|
|
|
|
return val2;
|
|
}
|
|
|
|
sval_u linked_list_end(sval_u val)
|
|
{
|
|
sval_u *node;
|
|
sval_u end;
|
|
|
|
node = (sval_u *)parsetree_malloc(sizeof(sval_t[2]));
|
|
|
|
node[0] = val;
|
|
node[1].node = NULL;
|
|
|
|
end.node = (sval_u *)parsetree_malloc(sizeof(sval_t[2]));
|
|
|
|
end.node[0].node = node;
|
|
end.node[1].node = node;
|
|
|
|
return end;
|
|
}
|
|
|
|
sval_u node1_(int val1)
|
|
{
|
|
sval_u val;
|
|
|
|
val.intValue = val1;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node1b(int val1)
|
|
{
|
|
sval_u val;
|
|
|
|
val.byteValue = val1;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node_pos(unsigned int pos)
|
|
{
|
|
sval_u val;
|
|
|
|
val.sourcePosValue = pos;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node_string(char *text)
|
|
{
|
|
sval_u val;
|
|
|
|
val.stringValue = text;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node0(int type)
|
|
{
|
|
sval_u val;
|
|
|
|
if (type == ENUM_NOP) {
|
|
// memory optimization
|
|
val.node = &node_none;
|
|
} else {
|
|
val.node = (sval_u *)parsetree_malloc(sizeof(sval_u));
|
|
|
|
val.node[0].node = NULL;
|
|
val.node[0].type = type;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node1(int type, sval_u val1)
|
|
{
|
|
sval_u val;
|
|
|
|
val.node = (sval_u *)parsetree_malloc(sizeof(sval_u[2]));
|
|
|
|
val.node[0].type = type;
|
|
val.node[1] = val1;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node2(int type, sval_u val1, sval_u val2)
|
|
{
|
|
sval_u val;
|
|
|
|
assert(type != ENUM_NOP);
|
|
|
|
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[3]));
|
|
|
|
val.node[0].type = type;
|
|
val.node[1] = val1;
|
|
val.node[2] = val2;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node3(int type, sval_u val1, sval_u val2, sval_u val3)
|
|
{
|
|
sval_u val;
|
|
|
|
assert(type != ENUM_NOP);
|
|
|
|
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[4]));
|
|
|
|
val.node[0].type = type;
|
|
val.node[1] = val1;
|
|
val.node[2] = val2;
|
|
val.node[3] = val3;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node4(int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4)
|
|
{
|
|
sval_u val;
|
|
|
|
assert(type != ENUM_NOP);
|
|
|
|
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[5]));
|
|
|
|
val.node[0].type = type;
|
|
val.node[1] = val1;
|
|
val.node[2] = val2;
|
|
val.node[3] = val3;
|
|
val.node[4] = val4;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node5(int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_u val5)
|
|
{
|
|
sval_u val;
|
|
|
|
assert(type != ENUM_NOP);
|
|
|
|
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[6]));
|
|
|
|
val.node[0].type = type;
|
|
val.node[1] = val1;
|
|
val.node[2] = val2;
|
|
val.node[3] = val3;
|
|
val.node[4] = val4;
|
|
val.node[5] = val5;
|
|
|
|
return val;
|
|
}
|
|
|
|
sval_u node6(int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_u val5, sval_u val6)
|
|
{
|
|
sval_u val;
|
|
|
|
assert(type != ENUM_NOP);
|
|
|
|
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[7]));
|
|
|
|
val.node[0].type = type;
|
|
val.node[1] = val1;
|
|
val.node[2] = val2;
|
|
val.node[3] = val3;
|
|
val.node[4] = val4;
|
|
val.node[5] = val5;
|
|
val.node[6] = val6;
|
|
|
|
return val;
|
|
}
|