Skip to content

More math fixes/workarounds and unit tests #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/Expression-Syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ fixed _value_ `0`, and no memory is changed when assigning another value to it.

### memcpy(dest, src, count)

Copies `count` values starting at `src` to `dest`.
Copies `count` values starting at `src` to `dest`. Returns a reference to `dest`.

Memory areas are allowed to overlap.

Expand Down
5 changes: 5 additions & 0 deletions projectm-eval/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ target_include_directories(projectM_eval
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/projectm-eval>
)

target_compile_definitions(projectM_eval
PUBLIC
PRJM_F_SIZE=${PROJECTM_EVAL_FLOAT_SIZE}
)

set_target_properties(projectM_eval PROPERTIES
EXPORT_NAME Eval
)
Expand Down
6 changes: 5 additions & 1 deletion projectm-eval/MemoryBuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ void prjm_eval_memory_free_block(projectm_eval_mem_buffer buffer, int block)
}
if (block < PRJM_EVAL_MEM_BLOCKS * PRJM_EVAL_MEM_ITEMSPERBLOCK)
{
// Set int following the block pointer to the starting index of the first index/block to be freed.
// ns-eel2 sets ctx->ram_needfree to the starting index (plus one) of the first index/block to be freed:
// ((INT_PTR *)blocks)[1]=1+d;
// But since NSEEL_VM_freeRAMIfCodeRequested() is never called, no memory is ever cleared.
}
}

Expand Down Expand Up @@ -112,6 +114,7 @@ PRJM_EVAL_F* prjm_eval_memory_copy(projectm_eval_mem_buffer buffer,
PRJM_EVAL_F* src,
PRJM_EVAL_F* len)
{
// Add 0.0001 to avoid using the wrong index due to tiny float rounding errors.
int offset_dest = (int) (*dest + 0.0001);
int offset_src = (int) (*src + 0.0001);
int count = (int) (*len + 0.0001);
Expand Down Expand Up @@ -181,6 +184,7 @@ PRJM_EVAL_F* prjm_eval_memory_set(projectm_eval_mem_buffer buffer,
PRJM_EVAL_F* value,
PRJM_EVAL_F* len)
{
// Add 0.0001 to avoid using the wrong index due to tiny float rounding errors.
int offset_dest = (int) (*dest + 0.0001);
int count = (int) (*len + 0.0001);

Expand Down
66 changes: 53 additions & 13 deletions projectm-eval/TreeFunctions.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,19 +158,19 @@ void prjm_eval_intrinsic_functions(prjm_eval_intrinsic_function_list_ptr list, i
}

/* This is Milkdrop's original rand() implementation. */
static unsigned int prjm_eval_genrand_int32(void)
static uint32_t prjm_eval_genrand_int32(void)
{
unsigned int y;
static unsigned int mag01[2] = { 0x0UL, MATRIX_A };
uint32_t y;
static uint32_t mag01[2] = { 0x0UL, MATRIX_A };
/* mag01[x] = x * MATRIX_A for x=0,1 */

static unsigned int mt[N]; /* the array for the state vector */
static int mti; /* mti==N+1 means mt[N] is not initialized */
static uint32_t mt[N]; /* the array for the state vector */
static int32_t mti; /* mti==N+1 means mt[N] is not initialized */


if (!mti)
{
unsigned int s = 0x4141f00d;
uint32_t s = 0x4141f00d; // Initial Mersenne Twister seed
mt[0] = s & 0xffffffffUL;
for (mti = 1; mti < N; mti++)
{
Expand All @@ -188,7 +188,7 @@ static unsigned int prjm_eval_genrand_int32(void)

if (mti >= N)
{ /* generate N words at one time */
int kk;
int32_t kk;

for (kk = 0; kk < N - M; kk++)
{
Expand Down Expand Up @@ -360,6 +360,7 @@ prjm_eval_function_decl(mem)
PRJM_EVAL_F* index_ptr = &ctx->value;
invoke_arg(0, &index_ptr);

// Add 0.0001 to avoid using the wrong index due to tiny float rounding errors.
PRJM_EVAL_F* mem_addr = prjm_eval_memory_allocate(ctx->memory_buffer, (int) (*index_ptr + 0.0001));
if (mem_addr)
{
Expand All @@ -377,9 +378,8 @@ prjm_eval_function_decl(freembuf)

invoke_arg(0, ret_val);

prjm_eval_memory_free(ctx->memory_buffer);

assign_ret_val(.0);
// Add 0.0001 to avoid using the wrong index due to tiny float rounding errors.
prjm_eval_memory_free_block(ctx->memory_buffer, (int) (**ret_val + 0.0001));
}

prjm_eval_function_decl(memcpy)
Expand Down Expand Up @@ -851,7 +851,15 @@ prjm_eval_function_decl(pow_op)
invoke_arg(0, ret_val);
invoke_arg(1, &val2_ptr);

assign_ret_val(pow(**ret_val, *val2_ptr));
if(fabs(**ret_val) < close_factor_low && *val2_ptr < 0)
{
assign_ret_val(.0);
return;
}

PRJM_EVAL_F result = pow(**ret_val, *val2_ptr);

assign_ret_val(isnan(result) ? .0 : result);
}


Expand Down Expand Up @@ -901,6 +909,12 @@ prjm_eval_function_decl(asin)

invoke_arg(0, &math_arg_ptr);

if (*math_arg_ptr < -1.0 || *math_arg_ptr > 1.0)
{
assign_ret_val(.0);
return;
}

assign_ret_val(asin(*math_arg_ptr));
}

Expand All @@ -913,6 +927,12 @@ prjm_eval_function_decl(acos)

invoke_arg(0, &math_arg_ptr);

if (*math_arg_ptr < -1.0 || *math_arg_ptr > 1.0)
{
assign_ret_val(.0);
return;
}

assign_ret_val(acos(*math_arg_ptr));
}

Expand Down Expand Up @@ -967,7 +987,15 @@ prjm_eval_function_decl(pow)
invoke_arg(0, &math_arg1_ptr);
invoke_arg(1, &math_arg2_ptr);

assign_ret_val(pow(*math_arg1_ptr, *math_arg2_ptr));
if (fabs(*math_arg1_ptr) < close_factor_low && *math_arg2_ptr < 0)
{
assign_ret_val(.0);
return;
}

PRJM_EVAL_F result = pow(*math_arg1_ptr, *math_arg2_ptr);

assign_ret_val(isnan(result) ? .0 : result);
}

prjm_eval_function_decl(exp)
Expand All @@ -991,6 +1019,12 @@ prjm_eval_function_decl(log)

invoke_arg(0, &math_arg_ptr);

if (*math_arg_ptr <= 0.0)
{
assign_ret_val(.0);
return;
}

assign_ret_val(log(*math_arg_ptr));
}

Expand All @@ -1003,6 +1037,12 @@ prjm_eval_function_decl(log10)

invoke_arg(0, &math_arg_ptr);

if (*math_arg_ptr <= 0.0)
{
assign_ret_val(.0);
return;
}

assign_ret_val(log10(*math_arg_ptr));
}

Expand Down Expand Up @@ -1171,5 +1211,5 @@ prjm_eval_function_decl(invsqrt)
type_conv.int_val = INVSQRT_MAGIC_NUMBER - (type_conv.int_val >> 1);
type_conv.PRJM_F_val = type_conv.PRJM_F_val * (three_halfs - (num2 * type_conv.PRJM_F_val * type_conv.PRJM_F_val));

assign_ret_val(type_conv.PRJM_F_val);
assign_ret_val(isnan(type_conv.PRJM_F_val) ? 0 : (type_conv.PRJM_F_val));
}
6 changes: 0 additions & 6 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,12 @@ add_executable(projectM_EvalLib_Test
TreeFunctionsTest.cpp
)


target_link_libraries(projectM_EvalLib_Test
PRIVATE
projectM::Eval
GTest::gtest_main
)

target_include_directories(projectM_EvalLib_Test
PRIVATE
${CMAKE_SOURCE_DIR}/SimpleCompiler
)

target_compile_definitions(projectM_EvalLib_Test
PRIVATE
PROJECTM_TEST_DATA_DIR="${CMAKE_CURRENT_LIST_DIR}/data"
Expand Down
Loading
Loading