openmohaa/code/parser/parsetree.cpp

354 lines
7.2 KiB
C++
Raw Permalink Normal View History

2016-03-27 11:49:47 +02:00
/*
===========================================================================
2025-04-26 19:22:34 +02:00
Copyright (C) 2025 the OpenMoHAA team
2016-03-27 11:49:47 +02:00
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"
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
MEM_TempAlloc parsetree_allocator;
yyparsedata parsedata;
sval_u node_none = {0};
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
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;
2016-03-27 11:49:47 +02:00
}
void parsetree_freeall()
{
2023-07-05 21:23:39 +02:00
parsetree_allocator.FreeAll();
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
if (g_showopcodes->integer) {
gi.DPrintf("%d bytes freed\n", parsedata.total_length);
}
2016-03-27 11:49:47 +02:00
}
void parsetree_init()
{
2023-07-05 21:23:39 +02:00
parsedata.total_length = 0;
2016-03-27 11:49:47 +02:00
}
size_t parsetree_length()
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
return parsedata.total_length;
2016-03-27 11:49:47 +02:00
}
#if 0
char* parsetree_string(const char* string)
2016-03-27 11:49:47 +02:00
{
//char *pszString = ( char * )parsetree_allocator.Alloc( strlen( string ) + 1 );
//strcpy( pszString, string );
char* buffer = str_replace((char*)string, "\\\"", "\"");
2016-03-27 11:49:47 +02:00
if (buffer)
2016-03-27 11:49:47 +02:00
{
char* ptr = buffer;
2016-03-27 11:49:47 +02:00
if (ptr[0] == '"')
2016-03-27 11:49:47 +02:00
{
ptr++;
}
int len = strlen(buffer);
2016-03-27 11:49:47 +02:00
if (buffer[len - 1] == '"')
2016-03-27 11:49:47 +02:00
{
buffer[len - 1] = 0;
2016-03-27 11:49:47 +02:00
}
buffer = ptr;
}
return buffer;
}
#endif
extern size_t yyleng;
extern size_t prev_yyleng;
2023-07-05 21:23:39 +02:00
char *parsetree_malloc(size_t s)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
parsedata.total_length += s;
return (char *)parsetree_allocator.Alloc(s);
2016-03-27 11:49:47 +02:00
}
sval_u append_lists(sval_u val1, sval_u val2)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
val1.node[1].node[1] = val2.node[0];
val1.node[1] = val2.node[1];
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val1;
2016-03-27 11:49:47 +02:00
}
sval_u append_node(sval_u val1, sval_u val2)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u *node;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
node = (sval_u *)parsetree_malloc(sizeof(sval_t[2]));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
node[1].node = NULL;
node[0] = val2;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val1.node[1].node[1].node = node;
val1.node[1].node = node;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val1;
2016-03-27 11:49:47 +02:00
}
sval_u prepend_node(sval_u val1, sval_u val2)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u *node;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
node = (sval_u *)parsetree_malloc(sizeof(sval_t[2]));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
node[0] = val1;
node[1] = val2;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val2.node = node;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val2;
2016-03-27 11:49:47 +02:00
}
sval_u linked_list_end(sval_u val)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u *node;
sval_u end;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
node = (sval_u *)parsetree_malloc(sizeof(sval_t[2]));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
node[0] = val;
node[1].node = NULL;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
end.node = (sval_u *)parsetree_malloc(sizeof(sval_t[2]));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
end.node[0].node = node;
end.node[1].node = node;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return end;
2016-03-27 11:49:47 +02:00
}
sval_u node1_(int val1)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.intValue = val1;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node1b(int val1)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.byteValue = val1;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node_pos(unsigned int pos)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.sourcePosValue = pos;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
2023-07-05 21:23:39 +02:00
sval_u node_string(char *text)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.stringValue = text;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node0(int type)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-08-12 19:59:40 +02:00
if (type == ENUM_NOP) {
2023-07-05 21:23:39 +02:00
// memory optimization
val.node = &node_none;
} else {
val.node = (sval_u *)parsetree_malloc(sizeof(sval_u));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.node[0].node = NULL;
val.node[0].type = type;
}
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node1(int type, sval_u val1)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.node = (sval_u *)parsetree_malloc(sizeof(sval_u[2]));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.node[0].type = type;
val.node[1] = val1;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node2(int type, sval_u val1, sval_u val2)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-08-12 19:59:40 +02:00
assert(type != ENUM_NOP);
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[3]));
2023-07-05 21:23:39 +02:00
val.node[0].type = type;
val.node[1] = val1;
val.node[2] = val2;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node3(int type, sval_u val1, sval_u val2, sval_u val3)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-08-12 19:59:40 +02:00
assert(type != ENUM_NOP);
2023-07-05 21:23:39 +02:00
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[4]));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.node[0].type = type;
val.node[1] = val1;
val.node[2] = val2;
val.node[3] = val3;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node4(int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-08-12 19:59:40 +02:00
assert(type != ENUM_NOP);
2023-07-05 21:23:39 +02:00
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[5]));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.node[0].type = type;
val.node[1] = val1;
val.node[2] = val2;
val.node[3] = val3;
val.node[4] = val4;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node5(int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_u val5)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-08-12 19:59:40 +02:00
assert(type != ENUM_NOP);
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[6]));
2023-07-05 21:23:39 +02:00
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;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
sval_u node6(int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_u val5, sval_u val6)
2016-03-27 11:49:47 +02:00
{
2023-07-05 21:23:39 +02:00
sval_u val;
2016-03-27 11:49:47 +02:00
2023-08-12 19:59:40 +02:00
assert(type != ENUM_NOP);
2023-07-05 21:23:39 +02:00
val.node = (sval_u *)parsetree_malloc(sizeof(sval_t[7]));
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
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;
2016-03-27 11:49:47 +02:00
2023-07-05 21:23:39 +02:00
return val;
2016-03-27 11:49:47 +02:00
}
2024-04-09 23:22:45 +02:00
sval_u node_listener(sval_u val1, sval_u val2)
{
if (!str::icmp(val1.stringValue, "self")) {
return node2(ENUM_listener, node1_(method_self), val2);
} else {
return node2(ENUM_string, val1, val2);
}
}