Blender  V3.3
Classes | Macros
expr_pylike_eval.c File Reference
#include <ctype.h>
#include <fenv.h>
#include <float.h>
#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_expr_pylike_eval.h"
#include "BLI_math_base.h"
#include "BLI_utildefines.h"

Go to the source code of this file.

Classes

struct  ExprOp
 
struct  ExprPyLike_Parsed
 
struct  BuiltinConstDef
 
struct  BuiltinOpDef
 
struct  KeywordTokenDef
 
struct  ExprParseState
 

Macros

#define FAIL_IF(condition)
 

Functions

Public API
void BLI_expr_pylike_free (ExprPyLike_Parsed *expr)
 
bool BLI_expr_pylike_is_valid (ExprPyLike_Parsed *expr)
 
bool BLI_expr_pylike_is_constant (ExprPyLike_Parsed *expr)
 
bool BLI_expr_pylike_is_using_param (ExprPyLike_Parsed *expr, int index)
 
Stack Machine Evaluation
eExprPyLike_EvalStatus BLI_expr_pylike_eval (ExprPyLike_Parsed *expr, const double *param_values, int param_values_len, double *r_result)
 
Recursive Descent Parser
static bool parse_expr (ExprParseState *state)
 
static int parse_function_args (ExprParseState *state)
 
static bool parse_unary (ExprParseState *state)
 
static bool parse_mul (ExprParseState *state)
 
static bool parse_add (ExprParseState *state)
 
static BinaryOpFunc parse_get_cmp_func (short token)
 
static bool parse_cmp_chain (ExprParseState *state, BinaryOpFunc cur_func)
 
static bool parse_cmp (ExprParseState *state)
 
static bool parse_not (ExprParseState *state)
 
static bool parse_and (ExprParseState *state)
 
static bool parse_or (ExprParseState *state)
 
Main Parsing Function
ExprPyLike_ParsedBLI_expr_pylike_parse (const char *expression, const char **param_names, int param_names_len)
 

Expression Parser State

#define MAKE_CHAR2(a, b)   (((a) << 8) | (b))
 
#define CHECK_ERROR(condition)
 
#define TOKEN_ID   MAKE_CHAR2('I', 'D')
 
#define TOKEN_NUMBER   MAKE_CHAR2('0', '0')
 
#define TOKEN_GE   MAKE_CHAR2('>', '=')
 
#define TOKEN_LE   MAKE_CHAR2('<', '=')
 
#define TOKEN_NE   MAKE_CHAR2('!', '=')
 
#define TOKEN_EQ   MAKE_CHAR2('=', '=')
 
#define TOKEN_AND   MAKE_CHAR2('A', 'N')
 
#define TOKEN_OR   MAKE_CHAR2('O', 'R')
 
#define TOKEN_NOT   MAKE_CHAR2('N', 'O')
 
#define TOKEN_IF   MAKE_CHAR2('I', 'F')
 
#define TOKEN_ELSE   MAKE_CHAR2('E', 'L')
 
typedef struct KeywordTokenDef KeywordTokenDef
 
typedef struct ExprParseState ExprParseState
 
static const char * token_eq_characters = "!=><"
 
static const char * token_characters = "~`!@#$%^&*+-=/\\?:;<>(){}[]|.,\"'"
 
static KeywordTokenDef keyword_list []
 
static ExprOpparse_alloc_ops (ExprParseState *state, int count)
 
static ExprOpparse_add_op (ExprParseState *state, eOpCode code, int stack_delta)
 
static int parse_add_jump (ExprParseState *state, eOpCode code)
 
static void parse_set_jump (ExprParseState *state, int jump)
 
static int opcode_arg_count (eOpCode code)
 
static bool parse_add_func (ExprParseState *state, eOpCode code, int args, void *funcptr)
 
static bool parse_next_token (ExprParseState *state)
 

Internal Types

enum  eOpCode {
  OPCODE_CONST , OPCODE_FUNC1 , OPCODE_FUNC2 , OPCODE_FUNC3 ,
  OPCODE_PARAMETER , OPCODE_MIN , OPCODE_MAX , OPCODE_JMP ,
  OPCODE_JMP_ELSE , OPCODE_JMP_OR , OPCODE_JMP_AND , OPCODE_CMP_CHAIN
}
 
typedef enum eOpCode eOpCode
 
typedef double(* UnaryOpFunc) (double)
 
typedef double(* BinaryOpFunc) (double, double)
 
typedef double(* TernaryOpFunc) (double, double, double)
 
typedef struct ExprOp ExprOp
 

Built-In Operations

typedef struct BuiltinConstDef BuiltinConstDef
 
typedef struct BuiltinOpDef BuiltinOpDef
 
static BuiltinConstDef builtin_consts []
 
static BuiltinOpDef builtin_ops []
 
static double op_negate (double arg)
 
static double op_mul (double a, double b)
 
static double op_div (double a, double b)
 
static double op_add (double a, double b)
 
static double op_sub (double a, double b)
 
static double op_radians (double arg)
 
static double op_degrees (double arg)
 
static double op_log2 (double a, double b)
 
static double op_lerp (double a, double b, double x)
 
static double op_clamp (double arg)
 
static double op_clamp3 (double arg, double minv, double maxv)
 
static double op_smoothstep (double a, double b, double x)
 
static double op_not (double a)
 
static double op_eq (double a, double b)
 
static double op_ne (double a, double b)
 
static double op_lt (double a, double b)
 
static double op_le (double a, double b)
 
static double op_gt (double a, double b)
 
static double op_ge (double a, double b)
 

Detailed Description

Simple evaluator for a subset of Python expressions that can be computed using purely double precision floating point values.

Supported subset:

The implementation has no global state and can be used multi-threaded.

Definition in file expr_pylike_eval.c.

Macro Definition Documentation

◆ CHECK_ERROR

#define CHECK_ERROR (   condition)
Value:
if (!(condition)) { \
return false; \
} \
((void)0)
SyclQueue void void size_t num_bytes void

Definition at line 437 of file expr_pylike_eval.c.

◆ FAIL_IF

#define FAIL_IF (   condition)
Value:
if (condition) { \
} \
((void)0)
@ EXPR_PYLIKE_FATAL_ERROR

◆ MAKE_CHAR2

#define MAKE_CHAR2 (   a,
 
)    (((a) << 8) | (b))

Definition at line 435 of file expr_pylike_eval.c.

◆ TOKEN_AND

#define TOKEN_AND   MAKE_CHAR2('A', 'N')

Definition at line 451 of file expr_pylike_eval.c.

◆ TOKEN_ELSE

#define TOKEN_ELSE   MAKE_CHAR2('E', 'L')

Definition at line 455 of file expr_pylike_eval.c.

◆ TOKEN_EQ

#define TOKEN_EQ   MAKE_CHAR2('=', '=')

Definition at line 450 of file expr_pylike_eval.c.

◆ TOKEN_GE

#define TOKEN_GE   MAKE_CHAR2('>', '=')

Definition at line 447 of file expr_pylike_eval.c.

◆ TOKEN_ID

#define TOKEN_ID   MAKE_CHAR2('I', 'D')

Definition at line 445 of file expr_pylike_eval.c.

◆ TOKEN_IF

#define TOKEN_IF   MAKE_CHAR2('I', 'F')

Definition at line 454 of file expr_pylike_eval.c.

◆ TOKEN_LE

#define TOKEN_LE   MAKE_CHAR2('<', '=')

Definition at line 448 of file expr_pylike_eval.c.

◆ TOKEN_NE

#define TOKEN_NE   MAKE_CHAR2('!', '=')

Definition at line 449 of file expr_pylike_eval.c.

◆ TOKEN_NOT

#define TOKEN_NOT   MAKE_CHAR2('N', 'O')

Definition at line 453 of file expr_pylike_eval.c.

◆ TOKEN_NUMBER

#define TOKEN_NUMBER   MAKE_CHAR2('0', '0')

Definition at line 446 of file expr_pylike_eval.c.

◆ TOKEN_OR

#define TOKEN_OR   MAKE_CHAR2('O', 'R')

Definition at line 452 of file expr_pylike_eval.c.

Typedef Documentation

◆ BinaryOpFunc

typedef double(* BinaryOpFunc) (double, double)

Definition at line 80 of file expr_pylike_eval.c.

◆ BuiltinConstDef

◆ BuiltinOpDef

typedef struct BuiltinOpDef BuiltinOpDef

◆ eOpCode

typedef enum eOpCode eOpCode

◆ ExprOp

typedef struct ExprOp ExprOp

◆ ExprParseState

◆ KeywordTokenDef

◆ TernaryOpFunc

typedef double(* TernaryOpFunc) (double, double, double)

Definition at line 81 of file expr_pylike_eval.c.

◆ UnaryOpFunc

typedef double(* UnaryOpFunc) (double)

Definition at line 79 of file expr_pylike_eval.c.

Enumeration Type Documentation

◆ eOpCode

enum eOpCode
Enumerator
OPCODE_CONST 
OPCODE_FUNC1 
OPCODE_FUNC2 
OPCODE_FUNC3 
OPCODE_PARAMETER 
OPCODE_MIN 
OPCODE_MAX 
OPCODE_JMP 
OPCODE_JMP_ELSE 
OPCODE_JMP_OR 
OPCODE_JMP_AND 
OPCODE_CMP_CHAIN 

Definition at line 52 of file expr_pylike_eval.c.

Function Documentation

◆ BLI_expr_pylike_eval()

eExprPyLike_EvalStatus BLI_expr_pylike_eval ( struct ExprPyLike_Parsed expr,
const double param_values,
int  param_values_len,
double r_result 
)

◆ BLI_expr_pylike_free()

void BLI_expr_pylike_free ( struct ExprPyLike_Parsed expr)

Free the parsed data; NULL argument is ok.

Definition at line 111 of file expr_pylike_eval.c.

References MEM_freeN, and NULL.

Referenced by BKE_driver_invalidate_expression(), driver_compile_simple_expr(), and fcurve_free_driver().

◆ BLI_expr_pylike_is_constant()

bool BLI_expr_pylike_is_constant ( struct ExprPyLike_Parsed expr)

Check if the parsed expression always evaluates to the same value.

Definition at line 123 of file expr_pylike_eval.c.

References NULL, ExprOp::opcode, OPCODE_CONST, ExprPyLike_Parsed::ops, and ExprPyLike_Parsed::ops_count.

Referenced by expr_pylike_const_test(), and parse_for_eval().

◆ BLI_expr_pylike_is_using_param()

bool BLI_expr_pylike_is_using_param ( struct ExprPyLike_Parsed expr,
int  index 
)

Check if the parsed expression uses the parameter with the given index.

Definition at line 128 of file expr_pylike_eval.c.

References ExprOp::arg, ExprOp::ival, NULL, ExprOp::opcode, OPCODE_PARAMETER, ExprPyLike_Parsed::ops, and ExprPyLike_Parsed::ops_count.

Referenced by driver_check_simple_expr_depends_on_time(), and TEST().

◆ BLI_expr_pylike_is_valid()

bool BLI_expr_pylike_is_valid ( struct ExprPyLike_Parsed expr)

◆ BLI_expr_pylike_parse()

ExprPyLike_Parsed* BLI_expr_pylike_parse ( const char *  expression,
const char **  param_names,
int  param_names_len 
)

Compile the expression and return the result.

Parse the expression for evaluation later. Returns non-NULL even on failure; use is_valid to check.

Definition at line 1052 of file expr_pylike_eval.c.

References BLI_assert, ExprPyLike_Parsed::max_stack, MEM_callocN, MEM_freeN, MEM_mallocN, ExprPyLike_Parsed::ops, ExprPyLike_Parsed::ops_count, parse_expr(), parse_next_token(), and state.

Referenced by driver_compile_simple_expr_impl(), expr_pylike_const_test(), expr_pylike_parse_fail_test(), parse_for_eval(), and TEST().

◆ op_add()

static double op_add ( double  a,
double  b 
)
static

Definition at line 294 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_add().

◆ op_clamp()

static double op_clamp ( double  arg)
static

Definition at line 324 of file expr_pylike_eval.c.

References CLAMP.

◆ op_clamp3()

static double op_clamp3 ( double  arg,
double  minv,
double  maxv 
)
static

Definition at line 330 of file expr_pylike_eval.c.

References CLAMP.

◆ op_degrees()

static double op_degrees ( double  arg)
static

Definition at line 309 of file expr_pylike_eval.c.

References M_PI.

◆ op_div()

static double op_div ( double  a,
double  b 
)
static

Definition at line 289 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_mul().

◆ op_eq()

static double op_eq ( double  a,
double  b 
)
static

Definition at line 348 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_get_cmp_func().

◆ op_ge()

static double op_ge ( double  a,
double  b 
)
static

Definition at line 373 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_get_cmp_func().

◆ op_gt()

static double op_gt ( double  a,
double  b 
)
static

Definition at line 368 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_get_cmp_func().

◆ op_le()

static double op_le ( double  a,
double  b 
)
static

Definition at line 363 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_get_cmp_func().

◆ op_lerp()

static double op_lerp ( double  a,
double  b,
double  x 
)
static

Definition at line 319 of file expr_pylike_eval.c.

References Freestyle::a, usdtokens::b(), and x.

◆ op_log2()

static double op_log2 ( double  a,
double  b 
)
static

Definition at line 314 of file expr_pylike_eval.c.

References Freestyle::a, usdtokens::b(), and log().

◆ op_lt()

static double op_lt ( double  a,
double  b 
)
static

Definition at line 358 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_get_cmp_func().

◆ op_mul()

static double op_mul ( double  a,
double  b 
)
static

Definition at line 284 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_mul().

◆ op_ne()

static double op_ne ( double  a,
double  b 
)
static

Definition at line 353 of file expr_pylike_eval.c.

References Freestyle::a, and usdtokens::b().

Referenced by parse_get_cmp_func().

◆ op_negate()

static double op_negate ( double  arg)
static

Definition at line 279 of file expr_pylike_eval.c.

Referenced by parse_unary().

◆ op_not()

static double op_not ( double  a)
static

Definition at line 343 of file expr_pylike_eval.c.

References Freestyle::a.

Referenced by parse_not().

◆ op_radians()

static double op_radians ( double  arg)
static

Definition at line 304 of file expr_pylike_eval.c.

References M_PI.

◆ op_smoothstep()

static double op_smoothstep ( double  a,
double  b,
double  x 
)
static

Definition at line 336 of file expr_pylike_eval.c.

References Freestyle::a, usdtokens::b(), CLAMP, t, and x.

◆ op_sub()

static double op_sub ( double  a,
double  b 
)
static

◆ opcode_arg_count()

static int opcode_arg_count ( eOpCode  code)
static

Definition at line 538 of file expr_pylike_eval.c.

References BLI_assert_msg, OPCODE_FUNC1, OPCODE_FUNC2, and OPCODE_FUNC3.

Referenced by parse_unary().

◆ parse_add()

static bool parse_add ( ExprParseState state)
static

◆ parse_add_func()

static bool parse_add_func ( ExprParseState state,
eOpCode  code,
int  args,
void funcptr 
)
static

◆ parse_add_jump()

static int parse_add_jump ( ExprParseState state,
eOpCode  code 
)
static

Definition at line 524 of file expr_pylike_eval.c.

References parse_add_op(), and state.

Referenced by parse_and(), parse_expr(), and parse_or().

◆ parse_add_op()

static ExprOp* parse_add_op ( ExprParseState state,
eOpCode  code,
int  stack_delta 
)
static

◆ parse_alloc_ops()

static ExprOp* parse_alloc_ops ( ExprParseState state,
int  count 
)
static

Definition at line 496 of file expr_pylike_eval.c.

References count, MEM_reallocN, power_of_2_max_i(), and state.

Referenced by parse_add_op(), and parse_expr().

◆ parse_and()

static bool parse_and ( ExprParseState state)
static

◆ parse_cmp()

static bool parse_cmp ( ExprParseState state)
static

◆ parse_cmp_chain()

static bool parse_cmp_chain ( ExprParseState state,
BinaryOpFunc  cur_func 
)
static

◆ parse_expr()

static bool parse_expr ( ExprParseState state)
static

◆ parse_function_args()

static int parse_function_args ( ExprParseState state)
static

Definition at line 737 of file expr_pylike_eval.c.

References parse_expr(), parse_next_token(), and state.

Referenced by parse_unary().

◆ parse_get_cmp_func()

static BinaryOpFunc parse_get_cmp_func ( short  token)
static

Definition at line 898 of file expr_pylike_eval.c.

References NULL, op_eq(), op_ge(), op_gt(), op_le(), op_lt(), op_ne(), TOKEN_EQ, TOKEN_GE, TOKEN_LE, and TOKEN_NE.

Referenced by parse_cmp(), and parse_cmp_chain().

◆ parse_mul()

static bool parse_mul ( ExprParseState state)
static

◆ parse_next_token()

static bool parse_next_token ( ExprParseState state)
static

◆ parse_not()

static bool parse_not ( ExprParseState state)
static

◆ parse_or()

static bool parse_or ( ExprParseState state)
static

◆ parse_set_jump()

static void parse_set_jump ( ExprParseState state,
int  jump 
)
static

Definition at line 531 of file expr_pylike_eval.c.

References jump(), and state.

Referenced by parse_and(), parse_cmp_chain(), parse_expr(), and parse_or().

◆ parse_unary()

static bool parse_unary ( ExprParseState state)
static

Variable Documentation

◆ builtin_consts

BuiltinConstDef builtin_consts[]
static
Initial value:
= {
{"pi", M_PI}, {"True", 1.0}, {"False", 0.0}, {NULL, 0.0}}
#define M_PI
Definition: BLI_math_base.h:20

Definition at line 383 of file expr_pylike_eval.c.

Referenced by parse_unary().

◆ builtin_ops

BuiltinOpDef builtin_ops[]
static
Initial value:
= {
{"radians", OPCODE_FUNC1, op_radians},
{"degrees", OPCODE_FUNC1, op_degrees},
{"abs", OPCODE_FUNC1, fabs},
{"fabs", OPCODE_FUNC1, fabs},
{"floor", OPCODE_FUNC1, floor},
{"ceil", OPCODE_FUNC1, ceil},
{"trunc", OPCODE_FUNC1, trunc},
{"round", OPCODE_FUNC1, round},
{"int", OPCODE_FUNC1, trunc},
{"sin", OPCODE_FUNC1, sin},
{"cos", OPCODE_FUNC1, cos},
{"tan", OPCODE_FUNC1, tan},
{"asin", OPCODE_FUNC1, asin},
{"acos", OPCODE_FUNC1, acos},
{"atan", OPCODE_FUNC1, atan},
{"atan2", OPCODE_FUNC2, atan2},
{"exp", OPCODE_FUNC1, exp},
{"log", OPCODE_FUNC1, log},
{"log", OPCODE_FUNC2, op_log2},
{"sqrt", OPCODE_FUNC1, sqrt},
{"pow", OPCODE_FUNC2, pow},
{"fmod", OPCODE_FUNC2, fmod},
{"lerp", OPCODE_FUNC3, op_lerp},
{"clamp", OPCODE_FUNC1, op_clamp},
{"clamp", OPCODE_FUNC3, op_clamp3},
{"smoothstep", OPCODE_FUNC3, op_smoothstep},
}
sqrt(x)+1/max(0
static double op_clamp3(double arg, double minv, double maxv)
static double op_smoothstep(double a, double b, double x)
static double op_lerp(double a, double b, double x)
@ OPCODE_FUNC3
@ OPCODE_FUNC2
@ OPCODE_CONST
@ OPCODE_FUNC1
static double op_degrees(double arg)
static double op_log2(double a, double b)
static double op_clamp(double arg)
static double op_radians(double arg)
ccl_device_inline float2 fabs(const float2 &a)
Definition: math_float2.h:222
ccl_device_inline float3 exp(float3 v)
Definition: math_float3.h:392
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
ccl_device_inline float3 log(float3 v)
Definition: math_float3.h:397
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > asin(const Rall1d< T, V, S > &x)
Definition: rall1d.h:391
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
Definition: rall1d.h:375
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
Definition: rall1d.h:399
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
INLINE Rall1d< T, V, S > tan(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:327
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
Definition: rall1d.h:429
T floor(const T &a)

Definition at line 399 of file expr_pylike_eval.c.

Referenced by parse_unary().

◆ keyword_list

KeywordTokenDef keyword_list[]
static
Initial value:
= {
{"and", TOKEN_AND},
{"or", TOKEN_OR},
{"not", TOKEN_NOT},
{"if", TOKEN_IF},
{"else", TOKEN_ELSE},
}
#define TOKEN_ID
#define TOKEN_NOT
#define TOKEN_ELSE
#define TOKEN_OR
#define TOKEN_IF
#define TOKEN_AND

Definition at line 465 of file expr_pylike_eval.c.

Referenced by denoise_func(), merge_func(), and parse_next_token().

◆ token_characters

const char* token_characters = "~`!@#$%^&*+-=/\\?:;<>(){}[]|.,\"'"
static

Definition at line 458 of file expr_pylike_eval.c.

Referenced by parse_next_token().

◆ token_eq_characters

const char* token_eq_characters = "!=><"
static

Definition at line 457 of file expr_pylike_eval.c.

Referenced by parse_next_token().