mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Added math evaluation, the ability for commands to span multiple lines
within braces, and put support for comments back in (oops). To use math evaluation, put a math expression inside $(). If you have spaces in your expression, you'll need to enclose the entire thing in quotes so it doesn't get split up into multiple tokens.
This commit is contained in:
parent
aa00b7742c
commit
f4180e7ad8
6 changed files with 556 additions and 3 deletions
74
include/QF/exp.h
Normal file
74
include/QF/exp.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
|
||||
EXP equation evaluation routines
|
||||
Copyright (C) 2000, 2001 Brian Koropoff
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, US
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __exp_h
|
||||
#define __exp_h
|
||||
|
||||
typedef enum {TOKEN_GENERIC, TOKEN_NUM, TOKEN_OP, TOKEN_OPAREN, TOKEN_CPAREN}
|
||||
token_type;
|
||||
typedef enum {EXP_E_NORMAL = 0, EXP_E_PARSE, EXP_E_INVOP, EXP_E_PAREN,
|
||||
EXP_E_INVPARAM, EXP_E_SYNTAX} exp_error_t;
|
||||
typedef float (*opfunc) (float op1, float op2);
|
||||
|
||||
typedef struct token_generic_s
|
||||
{
|
||||
token_type type;
|
||||
union token_u *prev, *next;
|
||||
} token_generic;
|
||||
|
||||
typedef struct token_num_s
|
||||
{
|
||||
token_type type;
|
||||
union token_u *prev, *next;
|
||||
float value;
|
||||
} token_num;
|
||||
|
||||
typedef struct token_op_s
|
||||
{
|
||||
token_type type;
|
||||
union token_u *prev, *next;
|
||||
opfunc func;
|
||||
} token_op;
|
||||
|
||||
typedef union token_u
|
||||
{
|
||||
token_generic generic;
|
||||
token_num num;
|
||||
token_op op;
|
||||
} token;
|
||||
|
||||
typedef struct optable_s
|
||||
{
|
||||
char *str;
|
||||
opfunc func;
|
||||
} optable_t;
|
||||
|
||||
extern exp_error_t EXP_ERROR;
|
||||
|
||||
token *EXP_ParseString (char *str);
|
||||
void EXP_SimplifyTokens (token *chain);
|
||||
void EXP_RemoveToken (token *tok);
|
||||
void EXP_DestroyTokens (token *chain);
|
||||
float EXP_Evaluate (char *str);
|
||||
void EXP_InsertTokenAfter (token *spot, token *new);
|
||||
exp_error_t EXP_Validate (token *chain);
|
||||
void EXP_PrintTokens (token *chain);
|
||||
#endif // __exp_h
|
37
include/QF/ops.h
Normal file
37
include/QF/ops.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
|
||||
EXP equation evaluation routines
|
||||
Copyright (C) 2000, 2001 Brian Koropoff
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, US
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __ops_h
|
||||
#define __ops_h
|
||||
|
||||
float OP_Add (float op1, float op2);
|
||||
float OP_Sub (float op1, float op2);
|
||||
float OP_Mult (float op1, float op2);
|
||||
float OP_Div (float op1, float op2);
|
||||
float OP_Exp (float op1, float op2);
|
||||
float OP_Eq (float op1, float op2);
|
||||
float OP_Or (float op1, float op2);
|
||||
float OP_And (float op1, float op2);
|
||||
float OP_GreaterThan (float op1, float op2);
|
||||
float OP_LessThan (float op1, float op2);
|
||||
float OP_GreaterThanEqual (float op1, float op2);
|
||||
float OP_LessThanEqual (float op1, float op2);
|
||||
#endif // __ops_h
|
|
@ -29,6 +29,6 @@ libQFutil_la_SOURCES= \
|
|||
checksum.c cmd.c crc.c cvar.c fendian.c getopt.c getopt1.c hash.c \
|
||||
info.c link.c mathlib.c mdfour.c msg.c pcx.c plugin.c qargs.c \
|
||||
qendian.c qfplist.c quakefs.c quakeio.c sizebuf.c string.c sys.c \
|
||||
tga.c va.c ver_check.c wad.c zone.c dstring.c $(fnmatch)
|
||||
tga.c va.c ver_check.c wad.c zone.c dstring.c exp.c ops.c $(fnmatch)
|
||||
|
||||
EXTRA_DIST= $(asm_src) $(fnmatch_src)
|
||||
|
|
|
@ -50,6 +50,8 @@ static const char rcsid[] =
|
|||
#include "QF/zone.h"
|
||||
#include "compat.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/exp.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
typedef struct cmdalias_s {
|
||||
struct cmdalias_s *next;
|
||||
|
@ -202,7 +204,7 @@ Cbuf_InsertText (const char *text)
|
|||
void
|
||||
extract_line (dstring_t *buffer, dstring_t *line)
|
||||
{
|
||||
int i, squotes = 0, dquotes = 0, braces = 0;
|
||||
int i, squotes = 0, dquotes = 0, braces = 0, n;
|
||||
|
||||
for (i = 0; buffer->str[i]; i++) {
|
||||
if (buffer->str[i] == '\'' && !escaped(buffer->str,i) && !dquotes && !braces)
|
||||
|
@ -215,6 +217,10 @@ extract_line (dstring_t *buffer, dstring_t *line)
|
|||
braces++;
|
||||
if (buffer->str[i] == '}' && !escaped(buffer->str,i) && !squotes && !dquotes)
|
||||
braces--;
|
||||
if (buffer->str[i] == '/' && buffer->str[i+1] == '/' && !squotes && !dquotes) { // Filter out comments until newline
|
||||
for (n = 0;buffer->str[i+n] != '\n' && buffer->str[i+n] != '\r';n++);
|
||||
dstring_snip(buffer, i, n);
|
||||
}
|
||||
if (buffer->str[i] == '\n' || buffer->str[i] == '\r') {
|
||||
if (braces)
|
||||
dstring_snip(buffer, i, 1);
|
||||
|
@ -746,6 +752,48 @@ Cmd_ProcessVariables (dstring_t *dstr)
|
|||
dstring_delete (varname);
|
||||
}
|
||||
|
||||
int
|
||||
Cmd_ProcessMath (dstring_t *dstr)
|
||||
{
|
||||
dstring_t *statement;
|
||||
int i, n, paren;
|
||||
float value;
|
||||
char *temp;
|
||||
|
||||
statement = dstring_newstr ();
|
||||
|
||||
for (i = 0; i < strlen(dstr->str); i++) {
|
||||
if (dstr->str[i] == '$' && dstr->str[i+1] == '(' && !escaped(dstr->str,i)) {
|
||||
paren = 1;
|
||||
for (n = 2;;n++) {
|
||||
if (dstr->str[i+n] == '(')
|
||||
paren++;
|
||||
else if (dstr->str[i+n] == ')') {
|
||||
paren--;
|
||||
if (!paren)
|
||||
break;
|
||||
}
|
||||
else if (!dstr->str[i+n])
|
||||
return -1; // Open parentheses, give up
|
||||
}
|
||||
/* Copy text between braces into a buffer */
|
||||
dstring_clearstr (statement);
|
||||
dstring_insert (statement, dstr->str+i+2, n-2, 0);
|
||||
value = EXP_Evaluate (statement->str);
|
||||
if (EXP_ERROR == EXP_E_NORMAL) {
|
||||
temp = va("%f", value);
|
||||
dstring_snip (dstr, i, n+1); // Nuke the statement
|
||||
dstring_insertstr (dstr, temp, i); // Stick in the value
|
||||
i += strlen(temp) - 1;
|
||||
}
|
||||
else
|
||||
return -2; // Math evaluation error
|
||||
}
|
||||
}
|
||||
dstring_delete (statement);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Cmd_ProcessEscapes
|
||||
|
||||
|
@ -824,7 +872,7 @@ Cmd_ProcessPercents (dstring_t *dstr)
|
|||
void
|
||||
Cmd_TokenizeString (const char *text, qboolean filter)
|
||||
{
|
||||
int i = 0, n, len = 0, quotes, braces, space;
|
||||
int i = 0, n, len = 0, quotes, braces, space, res;
|
||||
const char *str = text;
|
||||
|
||||
cmd_argc = 0;
|
||||
|
@ -883,6 +931,17 @@ Cmd_TokenizeString (const char *text, qboolean filter)
|
|||
if (!braces) {
|
||||
Cmd_ProcessTags(cmd_argv[cmd_argc-1]);
|
||||
Cmd_ProcessVariables(cmd_argv[cmd_argc-1]);
|
||||
res = Cmd_ProcessMath(cmd_argv[cmd_argc-1]);
|
||||
if (res == -1) {
|
||||
Sys_Printf("Parse error: Unmatched parenthesis in following line:\n--> %s\n", text);
|
||||
cmd_argc = 0;
|
||||
return;
|
||||
}
|
||||
if (res == -2) {
|
||||
Sys_Printf("Math error: Invalid math expression on the following line:\n--> %s\n", text);
|
||||
cmd_argc = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Cmd_ProcessEscapes(cmd_argv[cmd_argc-1]);
|
||||
}
|
||||
|
|
304
libs/util/exp.c
Normal file
304
libs/util/exp.c
Normal file
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
|
||||
EXP equation evaluation routines
|
||||
Copyright (C) 2000, 2001 Brian Koropoff
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, US
|
||||
|
||||
*/
|
||||
|
||||
#include "QF/exp.h"
|
||||
#include "QF/ops.h"
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
exp_error_t EXP_ERROR;
|
||||
|
||||
optable_t optable[] =
|
||||
{
|
||||
{"**", OP_Exp},
|
||||
{"*", OP_Mult},
|
||||
{"/", OP_Div},
|
||||
{"+", OP_Add},
|
||||
{"-", OP_Sub},
|
||||
{"==", OP_Eq},
|
||||
{">=", OP_GreaterThanEqual},
|
||||
{">", OP_GreaterThan},
|
||||
{"<=", OP_LessThanEqual},
|
||||
{"<", OP_LessThan},
|
||||
{"||", OP_Or},
|
||||
{"&&", OP_And},
|
||||
{"", 0}
|
||||
};
|
||||
|
||||
token *EXP_NewToken (void)
|
||||
{
|
||||
token *new;
|
||||
|
||||
new = malloc(sizeof(token));
|
||||
|
||||
if (!new)
|
||||
return 0;
|
||||
new->generic.type = TOKEN_GENERIC;
|
||||
return new;
|
||||
}
|
||||
|
||||
token *EXP_ParseString (char *str)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
token *chain, *new, *cur;
|
||||
int i,n,m;
|
||||
|
||||
cur = chain = EXP_NewToken();
|
||||
chain->generic.type = TOKEN_OPAREN;
|
||||
chain->generic.prev = 0;
|
||||
chain->generic.next = 0;
|
||||
|
||||
for (i = 0; i < strlen(str); i++)
|
||||
{
|
||||
m = 0;
|
||||
while(str[i] == ' ')
|
||||
i++;
|
||||
if (isdigit(str[i]) || str[i] == '.')
|
||||
{
|
||||
while ((isdigit(str[i]) || str[i] == '.') && i < strlen(str) && m < 256)
|
||||
buf[m++] = str[i++];
|
||||
buf[m] = 0;
|
||||
new = EXP_NewToken();
|
||||
new->generic.type = TOKEN_NUM;
|
||||
new->num.value = atof(buf);
|
||||
new->generic.prev = cur;
|
||||
new->generic.next = 0;
|
||||
cur->generic.next = new;
|
||||
cur = new;
|
||||
i--;
|
||||
}
|
||||
else if (str[i] == '(')
|
||||
{
|
||||
new = EXP_NewToken();
|
||||
new->generic.type = TOKEN_OPAREN;
|
||||
new->generic.prev = cur;
|
||||
new->generic.next = 0;
|
||||
cur->generic.next = new;
|
||||
cur = new;
|
||||
}
|
||||
else if (str[i] == ')')
|
||||
{
|
||||
new = EXP_NewToken();
|
||||
new->generic.type = TOKEN_CPAREN;
|
||||
new->generic.prev = cur;
|
||||
new->generic.next = 0;
|
||||
cur->generic.next = new;
|
||||
cur = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(!(isdigit(str[i])) && str[i] != '.' && str[i] != '(' && str[i] != ')' && m < 256)
|
||||
buf[m++] = str[i++];
|
||||
buf[m] = 0;
|
||||
if (m)
|
||||
{
|
||||
for (n = 0; optable[n].func; n++)
|
||||
{
|
||||
if (!(strncmp(optable[n].str, buf, strlen(optable[n].str))))
|
||||
{
|
||||
i -= (m - strlen(optable[n].str) + 1);
|
||||
new = EXP_NewToken();
|
||||
new->generic.type = TOKEN_OP;
|
||||
new->op.func = optable[n].func;
|
||||
new->generic.prev = cur;
|
||||
new->generic.next = 0;
|
||||
cur->generic.next = new;
|
||||
cur = new;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!(optable[n].func))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
new = EXP_NewToken();
|
||||
new->generic.type = TOKEN_CPAREN;
|
||||
new->generic.prev = cur;
|
||||
new->generic.next = 0;
|
||||
cur->generic.next = new;
|
||||
return chain;
|
||||
}
|
||||
|
||||
void EXP_SimplifyTokens (token *chain)
|
||||
{
|
||||
int i;
|
||||
token *cur;
|
||||
token *temp;
|
||||
|
||||
/* First, get rid of parentheses */
|
||||
|
||||
for (cur = chain->generic.next; cur->generic.type != TOKEN_CPAREN; cur = cur->generic.next)
|
||||
{
|
||||
if (cur->generic.type == TOKEN_OPAREN)
|
||||
{
|
||||
EXP_SimplifyTokens(cur); /* Call ourself to simplify parentheses content */
|
||||
temp = cur;
|
||||
cur = cur->generic.next;
|
||||
EXP_RemoveToken(temp); /* Remove parentheses, leaving value behind */
|
||||
EXP_RemoveToken(cur->generic.next);
|
||||
}
|
||||
}
|
||||
|
||||
/* Next, evaluate all operators in order of operations */
|
||||
|
||||
for (i = 0; optable[i].func; i++)
|
||||
{
|
||||
for (cur = chain->generic.next; cur->generic.type != TOKEN_CPAREN; cur = cur->generic.next)
|
||||
{
|
||||
if (cur->generic.type == TOKEN_OP && cur->op.func == optable[i].func && cur->generic.next)
|
||||
if (cur->generic.prev->generic.type == TOKEN_NUM && cur->generic.next->generic.type == TOKEN_NUM)
|
||||
{
|
||||
cur->generic.prev->num.value = optable[i].func(cur->generic.prev->num.value, cur->generic.next->num.value);
|
||||
temp = cur;
|
||||
cur = cur->generic.prev;
|
||||
EXP_RemoveToken(temp->generic.next);
|
||||
EXP_RemoveToken(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EXP_RemoveToken (token *tok)
|
||||
{
|
||||
tok->generic.prev->generic.next = tok->generic.next;
|
||||
tok->generic.next->generic.prev = tok->generic.prev;
|
||||
free(tok);
|
||||
}
|
||||
|
||||
void EXP_DestroyTokens (token *chain)
|
||||
{
|
||||
token *temp;
|
||||
for (;chain; chain = temp)
|
||||
{
|
||||
temp = chain->generic.next;
|
||||
free(chain);
|
||||
}
|
||||
}
|
||||
|
||||
float EXP_Evaluate (char *str)
|
||||
{
|
||||
token *chain;
|
||||
float res;
|
||||
|
||||
if (!(chain = EXP_ParseString (str)))
|
||||
{
|
||||
EXP_ERROR = EXP_E_PARSE;
|
||||
return 0;
|
||||
}
|
||||
res = EXP_Validate (chain);
|
||||
|
||||
if (res)
|
||||
{
|
||||
EXP_ERROR = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXP_SimplifyTokens (chain);
|
||||
res = chain->generic.next->num.value;
|
||||
|
||||
EXP_DestroyTokens (chain);
|
||||
return res;
|
||||
}
|
||||
|
||||
void EXP_InsertTokenAfter (token *spot, token *new)
|
||||
{
|
||||
spot->generic.next->generic.prev = new;
|
||||
new->generic.next = spot->generic.next;
|
||||
new->generic.prev = spot;
|
||||
spot->generic.next = new;
|
||||
}
|
||||
|
||||
|
||||
exp_error_t EXP_Validate (token *chain)
|
||||
{
|
||||
token *cur, *new;
|
||||
int paren = 0;
|
||||
|
||||
for (cur = chain; cur->generic.next; cur = cur->generic.next)
|
||||
{
|
||||
if (cur->generic.type == TOKEN_OPAREN)
|
||||
paren++;
|
||||
if (cur->generic.type == TOKEN_CPAREN)
|
||||
paren--;
|
||||
/* Implied multiplication */
|
||||
if ((cur->generic.type == TOKEN_NUM && cur->generic.next->generic.type == TOKEN_OPAREN) || /* 5(1+1) */
|
||||
(cur->generic.type == TOKEN_CPAREN && cur->generic.next->generic.type == TOKEN_NUM) || /* (1+1)5 */
|
||||
(cur->generic.type == TOKEN_CPAREN && cur->generic.next->generic.type == TOKEN_OPAREN)) /* (1+1)(1+1) */
|
||||
{
|
||||
new = EXP_NewToken ();
|
||||
new->generic.type = TOKEN_OP;
|
||||
new->op.func = OP_Mult;
|
||||
EXP_InsertTokenAfter (cur, new);
|
||||
}
|
||||
|
||||
if ((cur->generic.type == TOKEN_OP || cur->generic.type == TOKEN_OPAREN) && cur->generic.next->generic.type == TOKEN_OP)
|
||||
{
|
||||
if (cur->generic.next->op.func == OP_Sub) /* Stupid hack for negation */
|
||||
{
|
||||
cur = cur->generic.next;
|
||||
cur->generic.type = TOKEN_NUM;
|
||||
cur->num.value = -1.0;
|
||||
new = EXP_NewToken();
|
||||
new->generic.type = TOKEN_OP;
|
||||
new->op.func = OP_Mult;
|
||||
EXP_InsertTokenAfter (cur, new);
|
||||
}
|
||||
else
|
||||
return EXP_E_SYNTAX; /* Operator misuse */
|
||||
}
|
||||
else if (cur->generic.type == TOKEN_NUM && cur->generic.next->generic.type == TOKEN_NUM)
|
||||
return EXP_E_SYNTAX; /* Double number error */
|
||||
else if (cur->generic.type == TOKEN_OPAREN && cur->generic.next->generic.type == TOKEN_CPAREN)
|
||||
return EXP_E_PAREN; /* Pointless parentheses */
|
||||
}
|
||||
|
||||
paren--;
|
||||
if (paren)
|
||||
return EXP_E_PAREN; /* Paren mismatch */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EXP_PrintTokens (token *chain)
|
||||
{
|
||||
int m;
|
||||
for (; chain; chain = chain->generic.next)
|
||||
switch (chain->generic.type)
|
||||
{
|
||||
case TOKEN_OPAREN:
|
||||
printf("(");
|
||||
break;
|
||||
case TOKEN_CPAREN:
|
||||
printf(")");
|
||||
break;
|
||||
case TOKEN_NUM:
|
||||
printf("%f", chain->num.value);
|
||||
break;
|
||||
case TOKEN_OP:
|
||||
for (m = 0; optable[m].func != chain->op.func; m++);
|
||||
printf("%s", optable[m].str);
|
||||
case TOKEN_GENERIC:
|
||||
break;
|
||||
}
|
||||
}
|
79
libs/util/ops.c
Normal file
79
libs/util/ops.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
|
||||
EXP equation evaluation routines
|
||||
Copyright (C) 2000, 2001 Brian Koropoff
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, US
|
||||
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
float OP_Add (float op1, float op2)
|
||||
{
|
||||
return op1 + op2;
|
||||
}
|
||||
|
||||
float OP_Sub (float op1, float op2)
|
||||
{
|
||||
return op1 - op2;
|
||||
}
|
||||
|
||||
float OP_Mult (float op1, float op2)
|
||||
{
|
||||
return op1 * op2;
|
||||
}
|
||||
|
||||
float OP_Div (float op1, float op2)
|
||||
{
|
||||
return op1 / op2;
|
||||
}
|
||||
|
||||
float OP_Exp (float op1, float op2)
|
||||
{
|
||||
return pow(op1, op2);
|
||||
}
|
||||
|
||||
float OP_Eq (float op1, float op2)
|
||||
{
|
||||
return op1 == op2;
|
||||
}
|
||||
|
||||
float OP_Or (float op1, float op2)
|
||||
{
|
||||
return op1 || op2;
|
||||
}
|
||||
|
||||
float OP_And (float op1, float op2)
|
||||
{
|
||||
return op1 && op2;
|
||||
}
|
||||
float OP_GreaterThan (float op1, float op2)
|
||||
{
|
||||
return op1 > op2;
|
||||
}
|
||||
|
||||
float OP_LessThan (float op1, float op2)
|
||||
{
|
||||
return op1 < op2;
|
||||
}
|
||||
float OP_GreaterThanEqual (float op1, float op2)
|
||||
{
|
||||
return op1 >= op2;
|
||||
}
|
||||
float OP_LessThanEqual (float op1, float op2)
|
||||
{
|
||||
return op2 <= op1;
|
||||
}
|
Loading…
Reference in a new issue