mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-24 04:41:25 +00:00
Factoring out duplicate code into a function: create_vector_members; creating vector members for vector function parameters
This commit is contained in:
parent
78d04a8352
commit
92d40e0925
2 changed files with 134 additions and 41 deletions
|
@ -20,6 +20,11 @@ void(string x) myprintit = {
|
||||||
print3("-> ", x, "\n");
|
print3("-> ", x, "\n");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void(vector par) vecpar = {
|
||||||
|
// vector-parameters need _x, _y, _z as well
|
||||||
|
print3("par_y should be 5... = ", ftos(par_y), "\n");
|
||||||
|
};
|
||||||
|
|
||||||
void() main = {
|
void() main = {
|
||||||
local entity pawn;
|
local entity pawn;
|
||||||
print3("should be 1: ", ftos(dot('1 1 0', '1 0 0')), "\n");
|
print3("should be 1: ", ftos(dot('1 1 0', '1 0 0')), "\n");
|
||||||
|
@ -27,4 +32,6 @@ void() main = {
|
||||||
pawn = spawn();
|
pawn = spawn();
|
||||||
pawn.printit = myprintit;
|
pawn.printit = myprintit;
|
||||||
pawn.printit("Hello");
|
pawn.printit("Hello");
|
||||||
|
|
||||||
|
vecpar('1 5 9');
|
||||||
};
|
};
|
||||||
|
|
168
parser.c
168
parser.c
|
@ -47,6 +47,7 @@ MEM_VEC_FUNCTIONS(parser_t, ast_function*, functions)
|
||||||
static void parser_pop_local(parser_t *parser);
|
static void parser_pop_local(parser_t *parser);
|
||||||
static bool parser_variable(parser_t *parser, ast_block *localblock);
|
static bool parser_variable(parser_t *parser, ast_block *localblock);
|
||||||
static ast_block* parser_parse_block(parser_t *parser);
|
static ast_block* parser_parse_block(parser_t *parser);
|
||||||
|
static bool parser_parse_block_into(parser_t *parser, ast_block *block);
|
||||||
static ast_expression* parser_parse_statement_or_block(parser_t *parser);
|
static ast_expression* parser_parse_statement_or_block(parser_t *parser);
|
||||||
static ast_expression* parser_expression_leave(parser_t *parser, bool stopatcomma);
|
static ast_expression* parser_expression_leave(parser_t *parser, bool stopatcomma);
|
||||||
static ast_expression* parser_expression(parser_t *parser, bool stopatcomma);
|
static ast_expression* parser_expression(parser_t *parser, bool stopatcomma);
|
||||||
|
@ -1704,10 +1705,9 @@ static void parser_pop_local(parser_t *parser)
|
||||||
mem_d(parser->locals[parser->locals_count].name);
|
mem_d(parser->locals[parser->locals_count].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ast_block* parser_parse_block(parser_t *parser)
|
static bool parser_parse_block_into(parser_t *parser, ast_block *block)
|
||||||
{
|
{
|
||||||
size_t oldblocklocal;
|
size_t oldblocklocal;
|
||||||
ast_block *block = NULL;
|
|
||||||
|
|
||||||
oldblocklocal = parser->blocklocal;
|
oldblocklocal = parser->blocklocal;
|
||||||
parser->blocklocal = parser->locals_count;
|
parser->blocklocal = parser->locals_count;
|
||||||
|
@ -1717,8 +1717,6 @@ static ast_block* parser_parse_block(parser_t *parser)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
block = ast_block_new(parser_ctx(parser));
|
|
||||||
|
|
||||||
while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
|
while (parser->tok != TOKEN_EOF && parser->tok < TOKEN_ERROR)
|
||||||
{
|
{
|
||||||
ast_expression *expr;
|
ast_expression *expr;
|
||||||
|
@ -1727,7 +1725,6 @@ static ast_block* parser_parse_block(parser_t *parser)
|
||||||
|
|
||||||
if (!parser_parse_statement(parser, block, &expr)) {
|
if (!parser_parse_statement(parser, block, &expr)) {
|
||||||
parseerror(parser, "parse error");
|
parseerror(parser, "parse error");
|
||||||
ast_block_delete(block);
|
|
||||||
block = NULL;
|
block = NULL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -1735,14 +1732,12 @@ static ast_block* parser_parse_block(parser_t *parser)
|
||||||
continue;
|
continue;
|
||||||
if (!ast_block_exprs_add(block, expr)) {
|
if (!ast_block_exprs_add(block, expr)) {
|
||||||
ast_delete(expr);
|
ast_delete(expr);
|
||||||
ast_block_delete(block);
|
|
||||||
block = NULL;
|
block = NULL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parser->tok != '}') {
|
if (parser->tok != '}') {
|
||||||
ast_block_delete(block);
|
|
||||||
block = NULL;
|
block = NULL;
|
||||||
} else {
|
} else {
|
||||||
(void)parser_next(parser);
|
(void)parser_next(parser);
|
||||||
|
@ -1752,7 +1747,19 @@ cleanup:
|
||||||
while (parser->locals_count > parser->blocklocal)
|
while (parser->locals_count > parser->blocklocal)
|
||||||
parser_pop_local(parser);
|
parser_pop_local(parser);
|
||||||
parser->blocklocal = oldblocklocal;
|
parser->blocklocal = oldblocklocal;
|
||||||
/* unroll the local vector */
|
return !!block;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ast_block* parser_parse_block(parser_t *parser)
|
||||||
|
{
|
||||||
|
ast_block *block;
|
||||||
|
block = ast_block_new(parser_ctx(parser));
|
||||||
|
if (!block)
|
||||||
|
return NULL;
|
||||||
|
if (!parser_parse_block_into(parser, block)) {
|
||||||
|
ast_block_delete(block);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1766,6 +1773,67 @@ static ast_expression* parser_parse_statement_or_block(parser_t *parser)
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool create_vector_members(parser_t *parser, ast_value *var,
|
||||||
|
varentry_t *vx, varentry_t *vy, varentry_t *vz)
|
||||||
|
{
|
||||||
|
size_t len = strlen(var->name);
|
||||||
|
vx->var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, 0);
|
||||||
|
if (!vx->var) {
|
||||||
|
parseerror(parser, "failed to create vector members (out of memory)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vy->var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, 1);
|
||||||
|
if (!vy->var) {
|
||||||
|
ast_delete(vx->var);
|
||||||
|
parseerror(parser, "failed to create vector members (out of memory)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vz->var = (ast_expression*)ast_member_new(ast_ctx(var), (ast_expression*)var, 2);
|
||||||
|
if (!vz->var) {
|
||||||
|
ast_delete(vy->var);
|
||||||
|
ast_delete(vx->var);
|
||||||
|
parseerror(parser, "failed to create vector members (out of memory)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !(vx->name = (char*)mem_a(len+3)) ) {
|
||||||
|
ast_delete(vz->var);
|
||||||
|
ast_delete(vy->var);
|
||||||
|
ast_delete(vx->var);
|
||||||
|
parseerror(parser, "failed to create vector members (out of memory)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( !(vy->name = (char*)mem_a(len+3)) ) {
|
||||||
|
mem_d(vx->name);
|
||||||
|
ast_delete(vz->var);
|
||||||
|
ast_delete(vy->var);
|
||||||
|
ast_delete(vx->var);
|
||||||
|
parseerror(parser, "failed to create vector members (out of memory)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( !(vz->name = (char*)mem_a(len+3)) ) {
|
||||||
|
mem_d(vy->name);
|
||||||
|
mem_d(vx->name);
|
||||||
|
ast_delete(vz->var);
|
||||||
|
ast_delete(vy->var);
|
||||||
|
ast_delete(vx->var);
|
||||||
|
parseerror(parser, "failed to create vector members (out of memory)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(vx->name, var->name, len);
|
||||||
|
memcpy(vy->name, var->name, len);
|
||||||
|
memcpy(vz->name, var->name, len);
|
||||||
|
vx->name[len] = vy->name[len] = vz->name[len] = '_';
|
||||||
|
vx->name[len+1] = 'x';
|
||||||
|
vy->name[len+1] = 'y';
|
||||||
|
vz->name[len+1] = 'z';
|
||||||
|
vx->name[len+2] = vy->name[len+2] = vz->name[len+2] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool parser_variable(parser_t *parser, ast_block *localblock)
|
static bool parser_variable(parser_t *parser, ast_block *localblock)
|
||||||
{
|
{
|
||||||
bool isfunc = false;
|
bool isfunc = false;
|
||||||
|
@ -1952,22 +2020,11 @@ static bool parser_variable(parser_t *parser, ast_block *localblock)
|
||||||
varent.var = (ast_expression*)var;
|
varent.var = (ast_expression*)var;
|
||||||
if (var->expression.vtype == TYPE_VECTOR)
|
if (var->expression.vtype == TYPE_VECTOR)
|
||||||
{
|
{
|
||||||
size_t len = strlen(varent.name);
|
|
||||||
varentry_t vx, vy, vz;
|
varentry_t vx, vy, vz;
|
||||||
vx.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 0);
|
if (!create_vector_members(parser, var, &vx, &vy, &vz)) {
|
||||||
vy.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 1);
|
ast_delete(var);
|
||||||
vz.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 2);
|
return false;
|
||||||
vx.name = (char*)mem_a(len+3);
|
}
|
||||||
vy.name = (char*)mem_a(len+3);
|
|
||||||
vz.name = (char*)mem_a(len+3);
|
|
||||||
memcpy(vx.name, varent.name, len);
|
|
||||||
memcpy(vy.name, varent.name, len);
|
|
||||||
memcpy(vz.name, varent.name, len);
|
|
||||||
vx.name[len] = vy.name[len] = vz.name[len] = '_';
|
|
||||||
vx.name[len+1] = 'x';
|
|
||||||
vy.name[len+1] = 'y';
|
|
||||||
vz.name[len+1] = 'z';
|
|
||||||
vx.name[len+2] = vy.name[len+2] = vz.name[len+2] = 0;
|
|
||||||
|
|
||||||
if (!localblock) {
|
if (!localblock) {
|
||||||
(void)!parser_t_globals_add(parser, varent);
|
(void)!parser_t_globals_add(parser, varent);
|
||||||
|
@ -2064,6 +2121,7 @@ nextvar:
|
||||||
} else if (parser->tok == '{') {
|
} else if (parser->tok == '{') {
|
||||||
/* function body */
|
/* function body */
|
||||||
ast_block *block;
|
ast_block *block;
|
||||||
|
size_t parami;
|
||||||
ast_function *old = parser->function;
|
ast_function *old = parser->function;
|
||||||
|
|
||||||
if (localblock) {
|
if (localblock) {
|
||||||
|
@ -2071,8 +2129,49 @@ nextvar:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block = ast_block_new(parser_ctx(parser));
|
||||||
|
if (!block) {
|
||||||
|
parseerror(parser, "failed to allocate block");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (parami = 0; parami < var->expression.params_count; ++parami) {
|
||||||
|
ast_value *param = var->expression.params[parami];
|
||||||
|
varentry_t vx, vy, vz;
|
||||||
|
|
||||||
|
if (param->expression.vtype != TYPE_VECTOR &&
|
||||||
|
(param->expression.vtype != TYPE_FIELD ||
|
||||||
|
param->expression.next->expression.vtype != TYPE_VECTOR))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!create_vector_members(parser, param, &vx, &vy, &vz)) {
|
||||||
|
ast_block_delete(block);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)!parser_t_locals_add(parser, vx);
|
||||||
|
(void)!parser_t_locals_add(parser, vy);
|
||||||
|
(void)!parser_t_locals_add(parser, vz);
|
||||||
|
if (!ast_block_collect(block, vx.var) ||
|
||||||
|
!ast_block_collect(block, vy.var) ||
|
||||||
|
!ast_block_collect(block, vz.var) )
|
||||||
|
{
|
||||||
|
parser_pop_local(parser);
|
||||||
|
parser_pop_local(parser);
|
||||||
|
parser_pop_local(parser);
|
||||||
|
ast_block_delete(block);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parser->function = func;
|
parser->function = func;
|
||||||
block = parser_parse_block(parser);
|
if (!parser_parse_block_into(parser, block)) {
|
||||||
|
ast_block_delete(block);
|
||||||
|
parser->function = old;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
parser->function = old;
|
parser->function = old;
|
||||||
|
|
||||||
if (!block)
|
if (!block)
|
||||||
|
@ -2239,24 +2338,11 @@ static bool parser_do(parser_t *parser)
|
||||||
if (var->expression.vtype == TYPE_VECTOR)
|
if (var->expression.vtype == TYPE_VECTOR)
|
||||||
{
|
{
|
||||||
/* create _x, _y and _z fields as well */
|
/* create _x, _y and _z fields as well */
|
||||||
size_t len;
|
|
||||||
varentry_t vx, vy, vz;
|
varentry_t vx, vy, vz;
|
||||||
|
if (!create_vector_members(parser, fld, &vx, &vy, &vz)) {
|
||||||
len = strlen(varent.name);
|
ast_delete(fld);
|
||||||
vx.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 0);
|
return false;
|
||||||
vy.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 1);
|
}
|
||||||
vz.var = (ast_expression*)ast_member_new(ast_ctx(fld), (ast_expression*)fld, 2);
|
|
||||||
vx.name = (char*)mem_a(len+3);
|
|
||||||
vy.name = (char*)mem_a(len+3);
|
|
||||||
vz.name = (char*)mem_a(len+3);
|
|
||||||
memcpy(vx.name, varent.name, len);
|
|
||||||
memcpy(vy.name, varent.name, len);
|
|
||||||
memcpy(vz.name, varent.name, len);
|
|
||||||
vx.name[len] = vy.name[len] = vz.name[len] = '_';
|
|
||||||
vx.name[len+1] = 'x';
|
|
||||||
vy.name[len+1] = 'y';
|
|
||||||
vz.name[len+1] = 'z';
|
|
||||||
vx.name[len+2] = vy.name[len+2] = vz.name[len+2] = 0;
|
|
||||||
(void)!parser_t_fields_add(parser, vx);
|
(void)!parser_t_fields_add(parser, vx);
|
||||||
(void)!parser_t_fields_add(parser, vy);
|
(void)!parser_t_fields_add(parser, vy);
|
||||||
(void)!parser_t_fields_add(parser, vz);
|
(void)!parser_t_fields_add(parser, vz);
|
||||||
|
|
Loading…
Reference in a new issue