Example #1
0
HklValue* hklr_op_bitwise_xor(HklValue* left_value, HklValue* right_value)
{
  HklValue* result = NULL;
  bool left_updated = false, right_updated = false;

  // Dereference left and right sides
  if (left_value->type == HKL_TYPE_REF)
  {
    left_updated = true;
    left_value = hklr_object_dereference(left_value->as.object);
  }

  if (right_value->type == HKL_TYPE_REF)
  {
    right_updated = true;
    right_value = hklr_object_dereference(right_value->as.object);
  }

  switch (left_value->type)
  {
    case HKL_TYPE_INT:
      switch(right_value->type)
      {
        case HKL_TYPE_INT:
          result = hkl_value_new(HKL_TYPE_INT,
            left_value->as.integer ^ right_value->as.integer);
          break;

        case HKL_TYPE_REAL:
        case HKL_TYPE_STRING:
        default:
          assert(false);
          break;
      }
      break; // HKL_TYPE_INT
    default:
      assert(false);
      break;
  }

  if (left_updated)
  {
    hkl_value_free(left_value);
  }

  if (right_updated)
  {
    hkl_value_free(right_value);
  }

  return result;
}
Example #2
0
HklValue* hklr_op_typeof(HklValue* value)
{
  bool temporary = true;

  // Dereference
  if (value->type == HKL_TYPE_REF)
  {
    HklValue* temp = value;
    
    value = hklr_object_dereference(value->as.object);
    
    // Don't free the deque or hash since it can't be a temporary
    if (value->type == HKL_TYPE_ARRAY || value->type == HKL_TYPE_HASH || value->type == HKL_TYPE_FUNCTION)
    {
      temporary = false;
      // simply spoof the value
      temp->type = HKL_TYPE_NIL;
    }

    hkl_value_free(temp);
  }

  HklType type = value->type;

  // Spoof the value if it not temporary
  if (temporary == false)
    value->type = HKL_TYPE_NIL;

  hkl_value_free(value);

  value = hkl_value_new(HKL_TYPE_TYPE, type);
  value->type = HKL_TYPE_TYPE;
  return value;
}
Example #3
0
HklValue* hklr_op_size(HklValue* value)
{
  // Dereference
  if (value->type == HKL_TYPE_REF)
  {
    HklValue* temp = value;
    value = hklr_object_dereference(value->as.object);
    hkl_value_free(temp);
  }

  switch (value->type)
  {
    case HKL_TYPE_STRING:
    {
      HklString* string = value->as.string;
      value->type = HKL_TYPE_INT;
      value->as.integer = string->length;
      hkl_string_free(string);
    }
    break;

    default:
      assert(false);
      break;
  }

  return value;
}
Example #4
0
HklValue* hklr_op_multiply(HklValue* left_value, HklValue* right_value)
{
  HklValue* result = NULL;
  bool left_updated = false, right_updated = false;

  // Dereference left and right sides
  if (left_value->type == HKL_TYPE_REF)
  {
    left_updated = true;
    left_value = hklr_object_dereference(left_value->as.object);
  }

  if (right_value->type == HKL_TYPE_REF)
  {
    right_updated = true;
    right_value = hklr_object_dereference(right_value->as.object);
  }

  switch (left_value->type)
  {
    case HKL_TYPE_INT:
      switch(right_value->type)
      {
        case HKL_TYPE_INT:
          result = hkl_value_new(HKL_TYPE_INT,
            left_value->as.integer * right_value->as.integer);
          break;

        case HKL_TYPE_REAL:
          result = hkl_value_new(HKL_TYPE_REAL,
            left_value->as.integer * right_value->as.real);
          break;

        case HKL_TYPE_STRING:
          result = hkl_value_new(HKL_TYPE_STRING,
            hkl_string_new());
          int i;
          for (i=0; i < (int)left_value->as.integer; i ++)
          {
             hkl_string_cat(result->as.string, right_value->as.string);
          }
        break;

        default:
          assert(false);
          break;
      }
      break; // HKL_TYPE_INT

    case HKL_TYPE_REAL:
      switch(right_value->type)
      {
        case HKL_TYPE_INT:
          result = hkl_value_new(HKL_TYPE_REAL,
            left_value->as.real * right_value->as.integer);
          break;

        case HKL_TYPE_REAL:
          result = hkl_value_new(HKL_TYPE_REAL,
            left_value->as.real * right_value->as.real);
          break;
        default:
          assert(false);
          break;
      }
      break; // HKL_TYPE_REAL
    
    case HKL_TYPE_STRING:
      switch(right_value->type)
      {
        
        case HKL_TYPE_INT:
        {
          result = hkl_value_new(HKL_TYPE_STRING,
            hkl_string_new());
          int i;
          for (i=0; i < (int)right_value->as.integer; i ++)
          {
             hkl_string_cat(result->as.string, left_value->as.string);
          }
        }
        break;

        default:
          assert(false);
          break;
      }
      break; // HKL_TYPE_STRING

    default:
      assert(false);
      break;
  }

  if (left_updated)
  {
    hkl_value_free(left_value);
  }

  if (right_updated)
  {
    hkl_value_free(right_value);
  }

  return result;
}
void hklr_statement_assign(HklrExpression* lhs, HklrExpression* rhs)
{
  // Evaluate the left hand side and then discard the value object
  HklValue* vobj = hklr_expression_eval(lhs);
  HklrObject* object = vobj->as.object;
  hkl_value_free(vobj);

  HklValue* value = hklr_expression_eval(rhs);

  assert(object != NULL);
  assert(value != NULL);

  // dereference the objcet
  if (value->type == HKL_TYPE_REF)
  {
    HklValue* temp = value;
    value = hklr_object_dereference(value->as.object);
    hkl_value_free(temp);
  }

  // wipe out the original value

  // Composite objects will
  // create new objects to replace the variable
  // and decrease the ref count of the original
  switch (object->type)
  {
    case HKL_TYPE_STRING:
      hkl_string_free(object->as.string);
    break;

    default:
    break;
  }

  switch (value->type)
  {
    case HKL_TYPE_NIL:
      object->type = HKL_TYPE_NIL;
    break;

    case HKL_TYPE_INT:
      object->type = HKL_TYPE_INT;
      object->as.integer = value->as.integer;
    break;

    case HKL_TYPE_REAL:
      object->type = HKL_TYPE_REAL;
      object->as.real = value->as.real;
    break;

    case HKL_TYPE_STRING:
      object->type = HKL_TYPE_STRING;
      object->as.string = hkl_string_new_from_string(value->as.string);
    break;

    default:
    break;
  }

  hkl_value_free(value);
}
Example #6
0
HklValue* hklr_op_size(HklValue* value)
{

  bool temporary = true;

  // Dereference
  if (value->type == HKL_TYPE_REF)
  {
    HklValue* temp = value;
    
    value = hklr_object_dereference(value->as.object);
    
    // Don't free the deque or hash since it can't be a temporary
    if (value->type == HKL_TYPE_ARRAY || value->type == HKL_TYPE_HASH || value->type == HKL_TYPE_FUNCTION)
    {
      temporary = false;
      // simply spoof the value
      temp->type = HKL_TYPE_NIL;
    }

    hkl_value_free(temp);
  }

  switch (value->type)
  {
    case HKL_TYPE_STRING:
    {
      HklString* string = value->as.string;
      value->type = HKL_TYPE_INT;
      value->as.integer = string->length;
      hkl_string_free(string);
    }
    break;

    case HKL_TYPE_ARRAY:
    {
      HklDeque* deque = value->as.deque;
      value->type = HKL_TYPE_INT;
      value->as.integer = deque->size;

      if (temporary)
      {
        // Free the deque
        hkl_value_free(hkl_value_new(HKL_TYPE_ARRAY, deque));
      }
    }
    break;

    case HKL_TYPE_HASH:
    {
      HklHash* hash = value->as.hash;
      value->type = HKL_TYPE_INT;
      value->as.integer = hash->length;

      if (temporary)
      {
        // Free the hash
        hkl_value_free(hkl_value_new(HKL_TYPE_HASH, hash));
      }
    }
    break;

    case HKL_TYPE_FUNCTION:
    {
      HklrFunction* function = value->as.function;
      value->type = HKL_TYPE_INT;
      value->as.integer = function->stmt_list->size;

      if (temporary)
      {
        // Free the function
        hklr_function_free(function);
      }
    }
    break;

    default:
      assert(false);
      break;
  }

  return value;
}