Beispiel #1
0
HklrObject* hklr_search(HklString* key)
{
  assert(key != NULL);

  HklScope* scope = ((HklScope*) HKLR.scopes->tail->data);
  HklPair* pair = NULL;

  // check your scope first
  pair = hkl_hash_search(scope->locals, key);
  if (pair) return pair->value; 

  // now try upvals
  pair = hkl_hash_search(scope->upvals, key);
  if (pair) return pair->value;

  // Now try scopes above

  HklListNode* node = HKLR.scopes->tail;
  node = node->last;
  while(node != NULL)
  {
    scope = ((HklScope*) node->data);
    // check locals first then upvals
    pair = hkl_hash_search(scope->locals, key);
    if (!pair) pair = hkl_hash_search(scope->upvals, key);    

    // if you find the object 
    // make it an upval to my scope
    if (pair)
    {
      hklr_upval_insert(key, pair->value);
      return pair->value;
    }

    node = node->last;
  }

  // Finally try global scope
  pair = hkl_hash_search(HKLR.globals, key);
  if (pair)
  {
    hklr_upval_insert(key, pair->value);
    return pair->value;
  }

  // Didn't find it, make a nil object
  HklrObject* object = hklr_object_new(HKL_TYPE_NIL, HKL_FLAG_NONE);
  hklr_local_insert(key, object);
  return object;
}
Beispiel #2
0
HklObject* hklr_search(HklString* key)
{
  assert(key != NULL);

  HklScope* scope = HKLR.scopes;
  HklPair* pair = NULL;

  // check your scope first
  pair = hkl_hash_search(scope->locals, key);
  if (pair) return pair->value; 

  // now try upvals
  pair = hkl_hash_search(scope->upvals, key);
  if (pair) return pair->value;

  // Now try scopes above
  scope = scope->prev;
  while(scope != NULL)
  {
    // check locals first then upvals
    pair = hkl_hash_search(scope->locals, key);
    if (!pair) pair = hkl_hash_search(scope->upvals, key);    

    // if you find the object 
    // make it an upval to my scope
    if (pair)
    {
      hklr_upval_insert(key, pair->value);
      return pair->value;
    }
    scope = scope->prev;
  }

  // Finally try global scope
  pair = hkl_hash_search(HKLR.globals, key);
  if (pair)
  {
    hklr_upval_insert(key, pair->value);
    return pair->value;
  }

  return NULL;
}
Beispiel #3
0
HklValue* hklr_expression_eval(HklrExpression* expr)
{
  assert(expr != NULL);

  switch (expr->type)
  {
    case HKL_EXPR_NIL:
      return hkl_value_new(HKL_TYPE_NIL);
      break;

    case HKL_EXPR_MAYBE:
      return hkl_value_new(HKL_TYPE_INT, rand() % 2 == 1);
      break;

    case HKL_EXPR_INT:
      return hkl_value_new(HKL_TYPE_INT, expr->arg[0].integer);
      break;

    case HKL_EXPR_TYPE:
      return hkl_value_new(HKL_TYPE_TYPE, expr->arg[0].type);
      break;

    case HKL_EXPR_REAL:
      return hkl_value_new(HKL_TYPE_REAL, expr->arg[0].real);
      break;

    case HKL_EXPR_STRING: 
    {
      HklString* string = hkl_string_new_from_string(expr->arg[0].string);
      assert(string != NULL);
      return hkl_value_new(HKL_TYPE_STRING, string);
    }
    break;

    case HKL_EXPR_VAR:
    {
      HklrObject* object = hklr_search(expr->arg[0].string);

      // apply more list items to the object to fetch deeper ones

      HklList* list = expr->arg[1].list;

      if (list->size && object->type != HKL_TYPE_REF)
        assert(false);

      HklListNode* node = list->head;
      while (node && object->type == HKL_TYPE_REF)
      {
        HklVariable* var = node->data;

        if (object->type == HKL_TYPE_REF && object->as.object->type == HKL_TYPE_FUNCTION)
        {
          HKLR.reg_return = NULL;

          // Try a function call
          HklrFunction* function = object->as.object->as.function;
          assert(var->type == HKL_VAR_CALL);
          HklList* args = var->as.list;

          struct scope_carier carrier;
          carrier.locals = hkl_hash_new();
          carrier.upvals = hkl_hash_new();
          carrier.arg = args->head;

          // Create the closure variables
          hkl_tree_traverse(function->closure_list, make_closures, &carrier);

          // Make the args in the function signature local variables
          hkl_list_traverse(function->args_list, make_locals, &carrier);

          hklr_scope_push_full(true, carrier.locals, carrier.upvals);

          // execute the statements within
          hkl_list_traverse(function->stmt_list, hklr_statement_exec_list, NULL);

          // the post_object is the function return value
          if (HKLR.reg_return == NULL)
            HKLR.reg_return = hkl_value_new(HKL_TYPE_NIL);

          // if the return value is an object be sure to increase the ref count
          // Though, this count needs to be decced afterwards
          if (HKLR.reg_return->type == HKL_TYPE_REF)
            hklr_gc_inc(HKLR.reg_return->as.object);

          hklr_scope_pop();

          return HKLR.reg_return;
        }
        else if (object->type == HKL_TYPE_REF && object->as.object->type == HKL_TYPE_HASH)
        {
          HklPair* pair = hkl_hash_search(object->as.object->as.hash, var->as.string);

          // This key doesnt exist just create it
          if (pair == NULL)
          {
            HklrObject* post_object = hklr_object_new(HKL_TYPE_NIL, HKL_FLAG_NONE);
            hkl_hash_insert(object->as.object->as.hash, var->as.string, post_object);

            return hkl_value_new(HKL_TYPE_REF, post_object);
          }

          if (node->next == NULL)
            return hkl_value_new(HKL_TYPE_REF, pair->value);

          object = pair->value;
        }

        node = node->next;
      }

      return hkl_value_new(HKL_TYPE_REF, object);
    }
    break;

    case HKL_EXPR_GETS:
    {
      HklString* string = hkl_string_new_from_stream(stdin);
      assert(string != NULL);
      return hkl_value_new(HKL_TYPE_STRING, string);
    }
    break;

    case HKL_EXPR_ARRAY:
    {
      // allocate space ahead of time
      HklDeque* deque = hkl_deque_new();//_sized(list->size);
      hkl_list_traverse(expr->arg[0].list, hklr_array_add_list, deque);

      return hkl_value_new(HKL_TYPE_ARRAY, deque);
    }
    break;

    case HKL_EXPR_HASH:
    {
      HklHash* hash = hkl_hash_new();

      struct hash_index hash_index;

      hash_index.index = 0;
      hash_index.hash = hash;

      hkl_list_traverse(expr->arg[0].list, hklr_hash_add_list, &hash_index);

      return hkl_value_new(HKL_TYPE_HASH, hash);
    }
    break;

    case HKL_EXPR_FUNCTION:
    {
      return hkl_value_new(HKL_TYPE_FUNCTION, hklr_function_new(expr->arg[0].list, expr->arg[1].tree, expr->arg[2].list));
    }
    break;

    case HKL_EXPR_UNARY:
    {
      HklValue* value = hklr_expression_eval(expr->arg[1].expression);
      assert(value != NULL);

      switch (expr->arg[0].op)
      {
        case HKL_OP_UNARY_MINUS:
          switch (value->type)
          {
            case HKL_TYPE_INT:
              value->as.integer = -value->as.integer;
              return value;
              break;

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

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

        case HKL_OP_SIZE:
          return hklr_op_size(value);
          break; // HKL_OP_SIZE

        case HKL_OP_TYPEOF:
          return hklr_op_typeof(value);
          break; // HKL_OP_TYPE

        case HKL_OP_BITWISE_NOT:
          switch (value->type)
          {
            case HKL_TYPE_INT:
              value->as.integer = ~value->as.integer;
              return value;
              break;

            default:
              assert(false);
              break;
          }

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

    case HKL_EXPR_BINARY:
    {
      HklValue *left_value = hklr_expression_eval(expr->arg[0].expression);
      HklValue *right_value = hklr_expression_eval(expr->arg[2].expression);
      HklValue *result = NULL;

      assert(left_value != NULL);
      assert(right_value != NULL);

      switch (expr->arg[1].op)
      {
        case HKL_OP_PLUS:
          result = hklr_op_plus(left_value, right_value);
          break;
        case HKL_OP_MINUS:
          result = hklr_op_minus(left_value, right_value);
          break;
        case HKL_OP_LESS:
          result = hklr_op_less(left_value, right_value);
          break;  
        case HKL_OP_LESS_EQUAL:
          result = hklr_op_less_equal(left_value, right_value);
          break;   
        case HKL_OP_GREATER:
          result = hklr_op_greater(left_value, right_value);
          break;  
        case HKL_OP_GREATER_EQUAL:
          result = hklr_op_greater_equal(left_value, right_value);
          break;
        case HKL_OP_ASTERISK: 
          result = hklr_op_multiply(left_value, right_value); 
          break;
        case HKL_OP_DIVIDE:
          result = hklr_op_divide(left_value, right_value);
          break;
        case HKL_OP_MOD:
          result = hklr_op_mod(left_value, right_value);
          break;
        case HKL_OP_EQUAL:
          result = hklr_op_equal(left_value, right_value);
          break;
        case HKL_OP_COALESCE:
          result = hklr_op_coalesce(left_value, right_value);
          if (result == left_value) {
            result = hkl_value_new(left_value->type);
            result->as = left_value->as;
            left_value->type = HKL_TYPE_NIL;
          } else if (result == right_value) {
            result = hkl_value_new(right_value->type);
            result->as = right_value->as;
            right_value->type = HKL_TYPE_NIL;
          }
        break;

        case HKL_OP_BITWISE_AND:
          result = hklr_op_bitwise_and(left_value, right_value);
          break;
        case HKL_OP_BITWISE_OR:
          result = hklr_op_bitwise_or(left_value, right_value);
          break;

        case HKL_OP_BITWISE_XOR:
          result = hklr_op_bitwise_xor(left_value, right_value);
          break;

        case HKL_OP_AS:
        {
          assert(right_value->type == HKL_TYPE_TYPE);

          switch (right_value->as.type)
          {
            case HKL_TYPE_INT:
              result = hklr_as_integer(left_value);
            break;

            case HKL_TYPE_REAL:
              result = hklr_as_real(left_value);
            break;

            case HKL_TYPE_STRING:
              result = hklr_as_string(left_value);
            break;

            default:
              assert(false);
            break;
          }

        }
        break;

        default:
          assert(false);
          break;
      }

      hkl_value_free(left_value);
      hkl_value_free(right_value);

      return result;
    }
    break; // HKL_EXPR_BINARY

    default:
    assert(false);
      break;
  }

  assert(false);
  return NULL;
}