83ce53f3efca7b96c423f86f2f9c16c0223b648d — octaspire 7 days ago v0.458.0
Add builtins 'sqrt' and 'pow', add and update unit tests

* Add builtins 'sqrt' and 'pow'.

* Add new unit tests and update existing one because of
  the changed error message.

* Game Bounce: position of the star (exit) is changed
  per level basis.
M dev/include/octaspire/dern/octaspire_dern_config.h => dev/include/octaspire/dern/octaspire_dern_config.h +2 -2
@@ 18,8 18,8 @@ #define OCTASPIRE_DERN_CONFIG_H
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "0"
- #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "457"
- #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "1"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "458"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "0"
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_STR "Octaspire Dern version " \
      OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "." \

M dev/include/octaspire/dern/octaspire_dern_stdlib.h => dev/include/octaspire/dern/octaspire_dern_stdlib.h +10 -0
@@ 232,6 232,16 @@ octaspire_dern_value_t *arguments,
      octaspire_dern_value_t *environment);
  
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_pow(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment);
+ 
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_sqrt(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment);
+ 
  octaspire_dern_value_t *octaspire_dern_vm_builtin_plus_equals(
      octaspire_dern_vm_t *vm,
      octaspire_dern_value_t *arguments,

M dev/src/octaspire_dern_stdlib.c => dev/src/octaspire_dern_stdlib.c +135 -0
@@ 6113,6 6113,141 @@ sin(octaspire_dern_value_as_number_get_value(argVal)));
  }
  
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_sqrt(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment)
+ {
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+ 
+     octaspire_helpers_verify_true(
+         arguments->typeTag == OCTASPIRE_DERN_VALUE_TAG_VECTOR);
+ 
+     octaspire_helpers_verify_true(
+         environment->typeTag == OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT);
+ 
+     char   const * const dernFuncName = "sqrt";
+     size_t const numArgs = octaspire_dern_value_get_length(arguments);
+     size_t const numExpectedArgs = 1;
+ 
+     if (numArgs != numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     octaspire_dern_value_t * argVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 0);
+ 
+     octaspire_helpers_verify_not_null(argVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     if (!octaspire_dern_value_is_number(argVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(argVal->typeTag));
+     }
+ 
+     if (octaspire_dern_value_as_number_get_value(argVal) < 0)
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' have to be non-negative. "
+             "Value '%f' was given.",
+             dernFuncName,
+             octaspire_dern_value_as_number_get_value(argVal));
+     }
+ 
+     return octaspire_dern_vm_create_new_value_real(
+         vm,
+         sqrt(octaspire_dern_value_as_number_get_value(argVal)));
+ }
+ 
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_pow(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment)
+ {
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+ 
+     octaspire_helpers_verify_true(
+         arguments->typeTag == OCTASPIRE_DERN_VALUE_TAG_VECTOR);
+ 
+     octaspire_helpers_verify_true(
+         environment->typeTag == OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT);
+ 
+     char   const * const dernFuncName = "pow";
+     size_t const numArgs = octaspire_dern_value_get_length(arguments);
+     size_t const numExpectedArgs = 2;
+ 
+     if (numArgs != numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     octaspire_dern_value_t * firstArgVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 0);
+ 
+     octaspire_helpers_verify_not_null(firstArgVal);
+ 
+     octaspire_dern_value_t * secondArgVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 1);
+ 
+     octaspire_helpers_verify_not_null(secondArgVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     if (!octaspire_dern_value_is_number(firstArgVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(firstArgVal->typeTag));
+     }
+ 
+     if (!octaspire_dern_value_is_number(secondArgVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Second argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(secondArgVal->typeTag));
+     }
+ 
+     return octaspire_dern_vm_create_new_value_real(
+         vm,
+         pow(
+             octaspire_dern_value_as_number_get_value(firstArgVal),
+             octaspire_dern_value_as_number_get_value(secondArgVal)));
+ }
+ 
  octaspire_dern_value_t *octaspire_dern_vm_builtin_plus_equals(
      octaspire_dern_vm_t *vm,
      octaspire_dern_value_t *arguments,

M dev/src/octaspire_dern_vm.c => dev/src/octaspire_dern_vm.c +26 -0
@@ 889,6 889,32 @@ abort();
      }
  
+     // pow
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+         self,
+         "pow",
+         octaspire_dern_vm_builtin_pow,
+         2,
+         "Calculate given value raised to the given exponent",
+         false,
+         env))
+     {
+         abort();
+     }
+ 
+     // sqrt
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+         self,
+         "sqrt",
+         octaspire_dern_vm_builtin_sqrt,
+         1,
+         "Calculate square root of the given value",
+         false,
+         env))
+     {
+         abort();
+     }
+ 
      // +=
      if (!octaspire_dern_vm_create_and_register_new_builtin(
          self,

M dev/test/test_dern_vm.c => dev/test/test_dern_vm.c +448 -1
@@ 1430,6 1430,432 @@ PASS();
  }
  
+ TEST octaspire_dern_vm_builtin_cos_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(cos {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         1.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_cos_1_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(cos {D+1})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.5403023058681398f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_cos_3_dot_14_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(cos {D+3.14})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         -0.9999987317275395f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_cos_minus_9_dot_876_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(cos {D-9.876})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         -0.8999148851836156f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sin_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sin {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sin_1_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sin {D+1})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.8414709848078965f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sin_3_dot_14_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sin {D+3.14})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.0015926529164868282f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sin_minus_9_dot_876_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sin {D-9.876})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.4360655907371733f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_1_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+1} {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         1.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_0_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+0} {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         1.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_2_3_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+2} {D+3})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         8.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_5_6_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+5} {D+6})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         15625.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_5_minus_2_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+5} {D-2})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.04f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sqrt_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sqrt {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sqrt_9_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sqrt {D+9})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         3.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sqrt_5432_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sqrt {D+5432})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         73.70210309075311f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sqrt_minus_1_failure_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sqrt {D-1})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_ERROR, evaluatedValue->typeTag);
+ 
+     ASSERT_STR_EQ(
+         "First argument to builtin 'sqrt' have to be non-negative. "
+         "Value '-1.000000' was given.\n"
+         "\tAt form: >>>>>>>>>>(sqrt {D-1})<<<<<<<<<<\n",
+         octaspire_string_get_c_string(evaluatedValue->value.error->message));
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
  TEST octaspire_dern_vm_builtin_distance_integers_0_failure_test(void)
  {
      octaspire_dern_vm_t *vm = octaspire_dern_vm_new(


@@ 11867,7 12293,7 @@ ASSERT_STR_EQ(
          "Unbound symbol 'pi'. Did you mean '/', '--', 'do', '<', 'uid', "
          "'cp@', 'if', 'min', '>', '+=', '++', '*', 'nil', '+', '-', '<=', "
-         "'fn', '==', '=', 'or', 'sin', '!=', '-=' or '>='?\n"
+         "'fn', '==', '=', 'or', 'sin', '!=', 'pow', '-=' or '>='?\n"
          "\tAt form: >>>>>>>>>>(eval (+ {D+1} {D+1}) pi)<<<<<<<<<<\n",
          octaspire_string_get_c_string(evaluatedValue->value.error->message));
  


@@ 16452,6 16878,27 @@ RUN_TEST(octaspire_dern_vm_builtin_min_strings_abc_abd_abe_test);
      RUN_TEST(octaspire_dern_vm_builtin_min_strings_abe_abd_abc_test);
  
+     RUN_TEST(octaspire_dern_vm_builtin_cos_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_cos_1_test);
+     RUN_TEST(octaspire_dern_vm_builtin_cos_3_dot_14_test);
+     RUN_TEST(octaspire_dern_vm_builtin_cos_minus_9_dot_876_test);
+ 
+     RUN_TEST(octaspire_dern_vm_builtin_sin_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sin_1_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sin_3_dot_14_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sin_minus_9_dot_876_test);
+ 
+     RUN_TEST(octaspire_dern_vm_builtin_pow_1_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_pow_0_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_pow_2_3_test);
+     RUN_TEST(octaspire_dern_vm_builtin_pow_5_6_test);
+     RUN_TEST(octaspire_dern_vm_builtin_pow_5_minus_2_test);
+ 
+     RUN_TEST(octaspire_dern_vm_builtin_sqrt_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sqrt_9_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sqrt_5432_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sqrt_minus_1_failure_test);
+ 
      RUN_TEST(octaspire_dern_vm_builtin_distance_integers_0_failure_test);
      RUN_TEST(octaspire_dern_vm_builtin_distance_integers_0_1_2_failure_test);
      RUN_TEST(octaspire_dern_vm_builtin_distance_integers_0_1_test);

M release/games/octaspire-bounce.dern => release/games/octaspire-bounce.dern +26 -6
@@ 209,6 209,7 @@ (define bounce-level-load as (fn (index)
    (bounce-space-create)
    (if (== index {D+0}) (do
+     (bounce-star-location-set {D+147} {D+110}) ; location of the exit
      ; pipe1
      (bounce-wall-add     {D-155} {D+100} {D-155} {D-115}) ; left wall
      (bounce-wall-add     {D-154} {D+10}  {D-150} {D+15})  ; lower left ramp wall


@@ 218,7 219,8 @@ (bounce-platform-add {D-138} {D+20}  {D+4}   (chipmunk-cpv {D+0}  {D+20}) (chipmunk-cpv {D+0} {D+30})) ; upper  platform
      (bounce-platform-add {D-145} {D-30}  {D+4}   (chipmunk-cpv {D+15} {D+0})  (chipmunk-cpv {D+6} {D+0}))  ; middle platform
      (bounce-platform-add {D-145} {D-90}  {D+8}   (chipmunk-cpv {D+0}  {D+30}) (chipmunk-cpv {D+0} {D+30})) ; bottom platform
-     (bounce-ball-add     {D-145} {D-40})
+     ;(bounce-ball-add     {D-145} {D-40})
+     (bounce-ball-add     {D+140} {D+40})
  
      ; pipe2
      (bounce-wall-add     {D-115} {D+155} {D-115} {D-100}) ; right wall


@@ 273,6 275,8 @@       (return)))
    (if (== index {D+1}) (do
+     (bounce-star-location-set {D+147} {D-105}) ; location of the exit
+ 
      (for i from {D+0} to {D+5}
        (bounce-slope-add (+ {D-155} (* i {D+50})) {D+100} (+ {D-125} (* i {D+50})) {D+97})) ; top row
  


@@ 327,7 331,14 @@ (bounce-level-load bounce-level-index))
    [game over] '() howto-no)
  
- (define bounce-star-angle as {D+0} [angle of the star])
+ (define bounce-star-angle      as {D+0} [angle of the star])
+ (define bounce-star-location-x as {D+0} [position of the star])
+ (define bounce-star-location-y as {D+0} [position of the star])
+ 
+ (define bounce-star-location-set as (fn (x y)
+   (= bounce-star-location-x x)
+   (= bounce-star-location-y y))
+   [set star location] '(x [x] y [y]) howto-no)
  
  (define bounce-render-game as (fn ()
    (define bounce-ball-pos as (chipmunk-cpBodyGetPosition bounce-ball) [position of the ball])


@@ 349,14 360,14 @@ (for i in bounce-slopes
      (bounce-slope-draw i))
    (sdl2-glColor4ub {X+99} {X+FF} {X+0} {X+FF})
-   (sdl2-gl-ortho-star-rotated {D+1470} {D+1145} {D+40} {D+5} bounce-star-angle)
+   (sdl2-gl-ortho-star-rotated (* {D+10} bounce-star-location-x) (* {D+10} bounce-star-location-y) {D+40} {D+5} bounce-star-angle)
    (sdl2-glColor4ub {X+FF} {X+FF} {X+FF} {X+FF}))
    [render game] '() howto-no)
  
  (define bounce-render-pass as (fn ()
    (bounce-render-game)
-   (define x as {D+1470} [x])
-   (define y as {D+1145} [y])
+   (define x as (* {D+10} bounce-star-location-x) [x])
+   (define y as (* {D+10} bounce-star-location-y) [y])
    (define delta as bounce-pass-star-delta [star movement])
    (define angle as (* {D+0.5} bounce-star-angle) [angle])
    (define num-stars as {D+8} [number of stars])


@@ 407,6 418,14 @@ (bounce-ball-apply-impulse (chipmunk-cpv {D+0} (min (/ bounce-key-down-duration {D+3}) {D+250}))))))
    [handle keydup-event] '(event [event]) howto-no)
  
+ (define bounce-is-player-on-star as (fn ()
+   (define ball-pos as (chipmunk-cpBodyGetPosition bounce-ball) [position of the ball])
+   (define ball-x   as (chipmunk-cpv-get-x ball-pos) [x component])
+   (define ball-y   as (chipmunk-cpv-get-y ball-pos) [y component])
+   (define distance as (sqrt (+ (pow (- ball-x bounce-star-location-x) {D+2}) (pow (- ball-y bounce-star-location-y) {D+2}))) [distance])
+   (<= distance {D+8}))
+   [does player touch the star] '() howto-no)
+ 
  (define bounce-update-game as (fn (dt)
    (+= bounce-star-angle {D+0.02})
    (if (< bounce-window-zoom {D+1}) (+= bounce-window-zoom {D+0.05}))


@@ 423,7 442,8 @@ (define ball-x   as (chipmunk-cpv-get-x ball-pos) [x component])
    (define ball-y   as (chipmunk-cpv-get-y ball-pos) [y component])
    (if (< ball-y {D-240}) (bounce-game-over))
-   (if (and (> ball-x {D+135}) (< ball-x {D+160}) (> ball-y {D+130}) (< ball-y {D+160})) (bounce-level-pass)))
+   ;(if (and (> ball-x {D+135}) (< ball-x {D+160}) (> ball-y {D+130}) (< ball-y {D+160})) (bounce-level-pass)))
+   (if (bounce-is-player-on-star) (bounce-level-pass)))
    [update game] '(dt [dt]) howto-no)
  
  (define bounce-update-pass as (fn (dt)

M release/octaspire-dern-amalgamated.c => release/octaspire-dern-amalgamated.c +621 -3
@@ 26214,8 26214,8 @@ #define OCTASPIRE_DERN_CONFIG_H
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "0"
- #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "457"
- #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "1"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "458"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "0"
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_STR "Octaspire Dern version " \
      OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "." \


@@ 28166,6 28166,16 @@ octaspire_dern_value_t *arguments,
      octaspire_dern_value_t *environment);
  
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_pow(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment);
+ 
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_sqrt(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment);
+ 
  octaspire_dern_value_t *octaspire_dern_vm_builtin_plus_equals(
      octaspire_dern_vm_t *vm,
      octaspire_dern_value_t *arguments,


@@ 39835,6 39845,141 @@ sin(octaspire_dern_value_as_number_get_value(argVal)));
  }
  
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_sqrt(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment)
+ {
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+ 
+     octaspire_helpers_verify_true(
+         arguments->typeTag == OCTASPIRE_DERN_VALUE_TAG_VECTOR);
+ 
+     octaspire_helpers_verify_true(
+         environment->typeTag == OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT);
+ 
+     char   const * const dernFuncName = "sqrt";
+     size_t const numArgs = octaspire_dern_value_get_length(arguments);
+     size_t const numExpectedArgs = 1;
+ 
+     if (numArgs != numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     octaspire_dern_value_t * argVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 0);
+ 
+     octaspire_helpers_verify_not_null(argVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     if (!octaspire_dern_value_is_number(argVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(argVal->typeTag));
+     }
+ 
+     if (octaspire_dern_value_as_number_get_value(argVal) < 0)
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' have to be non-negative. "
+             "Value '%f' was given.",
+             dernFuncName,
+             octaspire_dern_value_as_number_get_value(argVal));
+     }
+ 
+     return octaspire_dern_vm_create_new_value_real(
+         vm,
+         sqrt(octaspire_dern_value_as_number_get_value(argVal)));
+ }
+ 
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_pow(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment)
+ {
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+ 
+     octaspire_helpers_verify_true(
+         arguments->typeTag == OCTASPIRE_DERN_VALUE_TAG_VECTOR);
+ 
+     octaspire_helpers_verify_true(
+         environment->typeTag == OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT);
+ 
+     char   const * const dernFuncName = "pow";
+     size_t const numArgs = octaspire_dern_value_get_length(arguments);
+     size_t const numExpectedArgs = 2;
+ 
+     if (numArgs != numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     octaspire_dern_value_t * firstArgVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 0);
+ 
+     octaspire_helpers_verify_not_null(firstArgVal);
+ 
+     octaspire_dern_value_t * secondArgVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 1);
+ 
+     octaspire_helpers_verify_not_null(secondArgVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     if (!octaspire_dern_value_is_number(firstArgVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(firstArgVal->typeTag));
+     }
+ 
+     if (!octaspire_dern_value_is_number(secondArgVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Second argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(secondArgVal->typeTag));
+     }
+ 
+     return octaspire_dern_vm_create_new_value_real(
+         vm,
+         pow(
+             octaspire_dern_value_as_number_get_value(firstArgVal),
+             octaspire_dern_value_as_number_get_value(secondArgVal)));
+ }
+ 
  octaspire_dern_value_t *octaspire_dern_vm_builtin_plus_equals(
      octaspire_dern_vm_t *vm,
      octaspire_dern_value_t *arguments,


@@ 49195,6 49340,32 @@ abort();
      }
  
+     // pow
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+         self,
+         "pow",
+         octaspire_dern_vm_builtin_pow,
+         2,
+         "Calculate given value raised to the given exponent",
+         false,
+         env))
+     {
+         abort();
+     }
+ 
+     // sqrt
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+         self,
+         "sqrt",
+         octaspire_dern_vm_builtin_sqrt,
+         1,
+         "Calculate square root of the given value",
+         false,
+         env))
+     {
+         abort();
+     }
+ 
      // +=
      if (!octaspire_dern_vm_create_and_register_new_builtin(
          self,


@@ 59801,6 59972,432 @@ PASS();
  }
  
+ TEST octaspire_dern_vm_builtin_cos_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(cos {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         1.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_cos_1_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(cos {D+1})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.5403023058681398f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_cos_3_dot_14_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(cos {D+3.14})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         -0.9999987317275395f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_cos_minus_9_dot_876_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(cos {D-9.876})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         -0.8999148851836156f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sin_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sin {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sin_1_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sin {D+1})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.8414709848078965f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sin_3_dot_14_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sin {D+3.14})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.0015926529164868282f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sin_minus_9_dot_876_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sin {D-9.876})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.4360655907371733f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_1_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+1} {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         1.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_0_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+0} {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         1.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_2_3_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+2} {D+3})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         8.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_5_6_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+5} {D+6})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         15625.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_pow_5_minus_2_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(pow {D+5} {D-2})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.04f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sqrt_0_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sqrt {D+0})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         0.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sqrt_9_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sqrt {D+9})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         3.0f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sqrt_5432_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sqrt {D+5432})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_REAL, evaluatedValue->typeTag);
+ 
+     ASSERT_IN_RANGE(
+         73.70210309075311f,
+         evaluatedValue->value.real,
+         0.000001);
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
+ TEST octaspire_dern_vm_builtin_sqrt_minus_1_failure_test(void)
+ {
+     octaspire_dern_vm_t *vm = octaspire_dern_vm_new(
+         octaspireDernVmTestAllocator,
+         octaspireDernVmTestStdio);
+ 
+     octaspire_dern_value_t *evaluatedValue =
+         octaspire_dern_vm_read_from_c_string_and_eval_in_global_environment(
+             vm,
+             "(sqrt {D-1})");
+ 
+     ASSERT(evaluatedValue);
+     ASSERT_EQ(OCTASPIRE_DERN_VALUE_TAG_ERROR, evaluatedValue->typeTag);
+ 
+     ASSERT_STR_EQ(
+         "First argument to builtin 'sqrt' have to be non-negative. "
+         "Value '-1.000000' was given.\n"
+         "\tAt form: >>>>>>>>>>(sqrt {D-1})<<<<<<<<<<\n",
+         octaspire_string_get_c_string(evaluatedValue->value.error->message));
+ 
+     octaspire_dern_vm_release(vm);
+     vm = 0;
+ 
+     PASS();
+ }
+ 
  TEST octaspire_dern_vm_builtin_distance_integers_0_failure_test(void)
  {
      octaspire_dern_vm_t *vm = octaspire_dern_vm_new(


@@ 70238,7 70835,7 @@ ASSERT_STR_EQ(
          "Unbound symbol 'pi'. Did you mean '/', '--', 'do', '<', 'uid', "
          "'cp@', 'if', 'min', '>', '+=', '++', '*', 'nil', '+', '-', '<=', "
-         "'fn', '==', '=', 'or', 'sin', '!=', '-=' or '>='?\n"
+         "'fn', '==', '=', 'or', 'sin', '!=', 'pow', '-=' or '>='?\n"
          "\tAt form: >>>>>>>>>>(eval (+ {D+1} {D+1}) pi)<<<<<<<<<<\n",
          octaspire_string_get_c_string(evaluatedValue->value.error->message));
  


@@ 74823,6 75420,27 @@ RUN_TEST(octaspire_dern_vm_builtin_min_strings_abc_abd_abe_test);
      RUN_TEST(octaspire_dern_vm_builtin_min_strings_abe_abd_abc_test);
  
+     RUN_TEST(octaspire_dern_vm_builtin_cos_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_cos_1_test);
+     RUN_TEST(octaspire_dern_vm_builtin_cos_3_dot_14_test);
+     RUN_TEST(octaspire_dern_vm_builtin_cos_minus_9_dot_876_test);
+ 
+     RUN_TEST(octaspire_dern_vm_builtin_sin_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sin_1_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sin_3_dot_14_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sin_minus_9_dot_876_test);
+ 
+     RUN_TEST(octaspire_dern_vm_builtin_pow_1_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_pow_0_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_pow_2_3_test);
+     RUN_TEST(octaspire_dern_vm_builtin_pow_5_6_test);
+     RUN_TEST(octaspire_dern_vm_builtin_pow_5_minus_2_test);
+ 
+     RUN_TEST(octaspire_dern_vm_builtin_sqrt_0_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sqrt_9_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sqrt_5432_test);
+     RUN_TEST(octaspire_dern_vm_builtin_sqrt_minus_1_failure_test);
+ 
      RUN_TEST(octaspire_dern_vm_builtin_distance_integers_0_failure_test);
      RUN_TEST(octaspire_dern_vm_builtin_distance_integers_0_1_2_failure_test);
      RUN_TEST(octaspire_dern_vm_builtin_distance_integers_0_1_test);