mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
Fixed the GIB math evaluator to handle unary operators properly, made
indexing/clipping more like python, made some cosmetic changes to zoom.gib, and added the ability for GIB builtins to return values.
This commit is contained in:
parent
7bf21e20ed
commit
32f4e53aa5
7 changed files with 78 additions and 20 deletions
|
@ -1,4 +1,4 @@
|
||||||
// zoom.rc
|
// zoom.gib
|
||||||
//
|
//
|
||||||
// zoom script for GIB in QuakeForge 0.5
|
// zoom script for GIB in QuakeForge 0.5
|
||||||
//
|
//
|
||||||
|
@ -42,6 +42,7 @@ function "zoom.init" { // Initialize basic options
|
||||||
set in_amp ${zoom.amp}
|
set in_amp ${zoom.amp}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default initial values
|
||||||
zoom.init 1 90 1 90 1.15
|
zoom.init 1 90 1 90 1.15
|
||||||
|
|
||||||
function "zoom.adjust" { // Adjust fov and sensitivity to match zoom factor
|
function "zoom.adjust" { // Adjust fov and sensitivity to match zoom factor
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#define __ops_h
|
#define __ops_h
|
||||||
|
|
||||||
double OP_Not (double op1, double op2);
|
double OP_Not (double op1, double op2);
|
||||||
|
double OP_Negate (double op1, double op2);
|
||||||
double OP_Add (double op1, double op2);
|
double OP_Add (double op1, double op2);
|
||||||
double OP_Sub (double op1, double op2);
|
double OP_Sub (double op1, double op2);
|
||||||
double OP_Mult (double op1, double op2);
|
double OP_Mult (double op1, double op2);
|
||||||
|
|
|
@ -36,6 +36,7 @@ optable_t optable[] =
|
||||||
{"!", OP_Not, 1},
|
{"!", OP_Not, 1},
|
||||||
{"**", OP_Exp, 2},
|
{"**", OP_Exp, 2},
|
||||||
{"/", OP_Div, 2},
|
{"/", OP_Div, 2},
|
||||||
|
{"-", OP_Negate, 1},
|
||||||
{"*", OP_Mult, 2},
|
{"*", OP_Mult, 2},
|
||||||
{"+", OP_Add, 2},
|
{"+", OP_Add, 2},
|
||||||
{"-", OP_Sub, 2},
|
{"-", OP_Sub, 2},
|
||||||
|
@ -168,6 +169,16 @@ int EXP_DoFunction (token *chain)
|
||||||
return -2; // We shouldn't get here
|
return -2; // We shouldn't get here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EXP_DoUnary (token *chain)
|
||||||
|
{
|
||||||
|
if (chain->generic.next->generic.type == TOKEN_OP)
|
||||||
|
EXP_DoUnary (chain->generic.next);
|
||||||
|
if (chain->generic.next->generic.type != TOKEN_NUM)
|
||||||
|
return -1; // In theory, this should never happen
|
||||||
|
chain->generic.next->num.value = chain->op.op->func(chain->generic.next->num.value, 0);
|
||||||
|
EXP_RemoveToken (chain);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
token *EXP_ParseString (char *str)
|
token *EXP_ParseString (char *str)
|
||||||
{
|
{
|
||||||
|
@ -250,6 +261,8 @@ token *EXP_ParseString (char *str)
|
||||||
i -= (m - strlen(op->str) + 1);
|
i -= (m - strlen(op->str) + 1);
|
||||||
new = EXP_NewToken();
|
new = EXP_NewToken();
|
||||||
new->generic.type = TOKEN_OP;
|
new->generic.type = TOKEN_OP;
|
||||||
|
if (*(op->str) == '-') // HACK HACK HACK
|
||||||
|
op = optable + 6; // Always assume subtraction for -
|
||||||
new->op.op = op;
|
new->op.op = op;
|
||||||
new->generic.prev = cur;
|
new->generic.prev = cur;
|
||||||
new->generic.next = 0;
|
new->generic.next = 0;
|
||||||
|
@ -317,6 +330,10 @@ exp_error_t EXP_SimplifyTokens (token *chain)
|
||||||
for (cur = chain->generic.next; cur->generic.type != TOKEN_CPAREN; cur = cur->generic.next)
|
for (cur = chain->generic.next; cur->generic.type != TOKEN_CPAREN; cur = cur->generic.next)
|
||||||
{
|
{
|
||||||
if (cur->generic.type == TOKEN_OP && cur->op.op == optable + i && cur->generic.next) {
|
if (cur->generic.type == TOKEN_OP && cur->op.op == optable + i && cur->generic.next) {
|
||||||
|
// If a unary operator is in our way, it gets evaluated early
|
||||||
|
if (cur->generic.next->generic.type == TOKEN_OP)
|
||||||
|
if (EXP_DoUnary (cur->generic.next))
|
||||||
|
return EXP_E_SYNTAX;
|
||||||
if (optable[i].operands == 1 && cur->generic.next->generic.type == TOKEN_NUM) {
|
if (optable[i].operands == 1 && cur->generic.next->generic.type == TOKEN_NUM) {
|
||||||
cur->generic.next->num.value = optable[i].func(cur->generic.next->num.value, 0);
|
cur->generic.next->num.value = optable[i].func(cur->generic.next->num.value, 0);
|
||||||
temp = cur;
|
temp = cur;
|
||||||
|
@ -422,15 +439,7 @@ exp_error_t EXP_Validate (token *chain)
|
||||||
else if ((cur->generic.type == TOKEN_OP || cur->generic.type == TOKEN_OPAREN) && cur->generic.next->generic.type == TOKEN_OP)
|
else if ((cur->generic.type == TOKEN_OP || cur->generic.type == TOKEN_OPAREN) && cur->generic.next->generic.type == TOKEN_OP)
|
||||||
{
|
{
|
||||||
if (cur->generic.next->op.op->func == OP_Sub) /* Stupid hack for negation */
|
if (cur->generic.next->op.op->func == OP_Sub) /* Stupid hack for negation */
|
||||||
{
|
cur->generic.next->op.op = optable + 3;
|
||||||
cur = cur->generic.next;
|
|
||||||
cur->generic.type = TOKEN_NUM;
|
|
||||||
cur->num.value = -1.0;
|
|
||||||
new = EXP_NewToken();
|
|
||||||
new->generic.type = TOKEN_OP;
|
|
||||||
new->op.op = EXP_FindOpByStr ("*");
|
|
||||||
EXP_InsertTokenAfter (cur, new);
|
|
||||||
}
|
|
||||||
else if (cur->generic.next->op.op->operands == 2)
|
else if (cur->generic.next->op.op->operands == 2)
|
||||||
return EXP_E_SYNTAX; /* Operator misuse */
|
return EXP_E_SYNTAX; /* Operator misuse */
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,16 @@ GIB_Arg_Strip_Delim (unsigned int arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Return (const char *str)
|
||||||
|
{
|
||||||
|
if (GIB_DATA(cbuf_active)->type != GIB_BUFFER_PROXY)
|
||||||
|
return;
|
||||||
|
dstring_clearstr (GIB_DATA(cbuf_active->up)->ret.retval);
|
||||||
|
dstring_appendstr (GIB_DATA(cbuf_active->up)->ret.retval, str);
|
||||||
|
GIB_DATA(cbuf_active->up)->ret.available = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GIB Builtin functions
|
GIB Builtin functions
|
||||||
|
|
||||||
|
@ -178,6 +188,22 @@ GIB_Function_f (void)
|
||||||
GIB_Function_Define (GIB_Argv(1), GIB_Argv(2));
|
GIB_Function_Define (GIB_Argv(1), GIB_Argv(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_FunctionDotGet_f (void)
|
||||||
|
{
|
||||||
|
if (GIB_Argc () != 2)
|
||||||
|
Cbuf_Error ("syntax",
|
||||||
|
"function.get: invalid syntax\n"
|
||||||
|
"usage: function.get function_name");
|
||||||
|
else {
|
||||||
|
gib_function_t *f;
|
||||||
|
if ((f = GIB_Function_Find (GIB_Argv (1))))
|
||||||
|
GIB_Return (f->program->str);
|
||||||
|
else
|
||||||
|
GIB_Return ("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GIB_Local_f (void)
|
GIB_Local_f (void)
|
||||||
{
|
{
|
||||||
|
@ -335,6 +361,7 @@ void
|
||||||
GIB_Builtin_Init (void)
|
GIB_Builtin_Init (void)
|
||||||
{
|
{
|
||||||
GIB_Builtin_Add ("function", GIB_Function_f, GIB_BUILTIN_NORMAL);
|
GIB_Builtin_Add ("function", GIB_Function_f, GIB_BUILTIN_NORMAL);
|
||||||
|
GIB_Builtin_Add ("function.get", GIB_FunctionDotGet_f, GIB_BUILTIN_NORMAL);
|
||||||
GIB_Builtin_Add ("export", GIB_Export_f, GIB_BUILTIN_NORMAL);
|
GIB_Builtin_Add ("export", GIB_Export_f, GIB_BUILTIN_NORMAL);
|
||||||
GIB_Builtin_Add ("local", GIB_Local_f, GIB_BUILTIN_NORMAL);
|
GIB_Builtin_Add ("local", GIB_Local_f, GIB_BUILTIN_NORMAL);
|
||||||
GIB_Builtin_Add ("global", GIB_Global_f, GIB_BUILTIN_NORMAL);
|
GIB_Builtin_Add ("global", GIB_Global_f, GIB_BUILTIN_NORMAL);
|
||||||
|
|
|
@ -213,6 +213,11 @@ GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
||||||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (dstr->str[i] == '`') {
|
||||||
|
if ((c = GIB_Parse_Match_Backtick (dstr->str, &i))) {
|
||||||
|
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if (dstr->str[i] == '\n' || dstr->str[i] == ';')
|
} else if (dstr->str[i] == '\n' || dstr->str[i] == ';')
|
||||||
break;
|
break;
|
||||||
else if (dstr->str[i] == '/' && dstr->str[i+1] == '/') {
|
else if (dstr->str[i] == '/' && dstr->str[i+1] == '/') {
|
||||||
|
|
|
@ -64,7 +64,13 @@ GIB_Process_Index (dstring_t *index, unsigned int pos, int *i1, int *i2)
|
||||||
}
|
}
|
||||||
v1 = atoi (index->str+pos+1);
|
v1 = atoi (index->str+pos+1);
|
||||||
if ((p = strchr (index->str+pos, ':'))) {
|
if ((p = strchr (index->str+pos, ':'))) {
|
||||||
v2 = atoi (p+1);
|
if (*(p+1) == ']')
|
||||||
|
v2 = -1;
|
||||||
|
else {
|
||||||
|
v2 = atoi (p+1);
|
||||||
|
if (v2 < 0)
|
||||||
|
v2--;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
v2 = v1;
|
v2 = v1;
|
||||||
dstring_snip (index, pos, i - pos + 1);
|
dstring_snip (index, pos, i - pos + 1);
|
||||||
|
@ -140,9 +146,14 @@ GIB_Process_Variables_All (struct dstring_s *token)
|
||||||
token->str[i+n] == '_' ||
|
token->str[i+n] == '_' ||
|
||||||
token->str[i+n] == '[' ||
|
token->str[i+n] == '[' ||
|
||||||
token->str[i+n] == ':'; n++) {
|
token->str[i+n] == ':'; n++) {
|
||||||
if (token->str[i+n] == '[')
|
if (token->str[i+n] == '[') {
|
||||||
while (token->str[i+n] && token->str[i+n] != ']')
|
while (token->str[i+n] && token->str[i+n] != ']')
|
||||||
n++;
|
n++;
|
||||||
|
if (!token->str[i+n]) {
|
||||||
|
Cbuf_Error ("parse", "Could not find match for [");
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dstring_insert (var, 0, token->str+i, n); // extract it
|
dstring_insert (var, 0, token->str+i, n); // extract it
|
||||||
}
|
}
|
||||||
|
@ -172,15 +183,14 @@ GIB_Process_Variables_All (struct dstring_s *token)
|
||||||
i2 = 0;
|
i2 = 0;
|
||||||
} else if (i2 >= strlen (var->str))
|
} else if (i2 >= strlen (var->str))
|
||||||
i2 = strlen(var->str)-1;
|
i2 = strlen(var->str)-1;
|
||||||
if (i2 < i1) {
|
if (i2 < i1)
|
||||||
i1 ^= i2;
|
dstring_clearstr (var);
|
||||||
i2 ^= i1;
|
else {
|
||||||
i1 ^= i2;
|
if (i2 < strlen(var->str)-1) // Snip everthing after index 2
|
||||||
|
dstring_snip (var, i2+1, strlen(var->str)-i2-1);
|
||||||
|
if (i1 > 0) // Snip everything before index 1
|
||||||
|
dstring_snip (var, 0, i1);
|
||||||
}
|
}
|
||||||
if (i2 < strlen(var->str)-1) // Snip everthing after index 2
|
|
||||||
dstring_snip (var, i2+1, strlen(var->str)-i2-1);
|
|
||||||
if (i1 > 0) // Snip everything before index 1
|
|
||||||
dstring_snip (var, 0, i1);
|
|
||||||
}
|
}
|
||||||
dstring_replace (token, i, n, var->str, strlen(var->str));
|
dstring_replace (token, i, n, var->str, strlen(var->str));
|
||||||
i += strlen (var->str) - 1;
|
i += strlen (var->str) - 1;
|
||||||
|
|
|
@ -26,6 +26,11 @@ double OP_Not (double op1, double op2)
|
||||||
return !op1;
|
return !op1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double OP_Negate (double op1, double op2)
|
||||||
|
{
|
||||||
|
return -op1;
|
||||||
|
}
|
||||||
|
|
||||||
double OP_Add (double op1, double op2)
|
double OP_Add (double op1, double op2)
|
||||||
{
|
{
|
||||||
return op1 + op2;
|
return op1 + op2;
|
||||||
|
|
Loading…
Reference in a new issue