Пример #1
0
ast_t* eval_expression(env_t* env, ast_t* ast) {
  switch(ast->type) {
    /* valid */
    case at_call: return eval_call(env,ast);
    case at_identifier: return get_ast_by_id(env, ast->data.id);
    case at_expression: {
      ast_t* result = NULL;
      ast_t* left = eval_expression(env, ast->data.expression.left);
      ast_t* right = eval_expression(env, ast->data.expression.right);
      inc_ref(left);
      inc_ref(right);
      switch(ast->data.expression.op) {
        case op_add: result = eval_add(env, left, right); break;
        case op_mul: result = eval_mul(env, left, right); break;
        case op_div: result = eval_div(env, left, right); break;
        case op_sub: result = eval_sub(env, left, right); break;
        case op_mod: result = eval_mod(env, left, right); break;
        case op_and: result = eval_and(env, left, right); break;
        case op_or: result = eval_or(env, left, right); break;
        case op_gt: result = eval_gt(env, left, right); break;
        case op_ge: result = eval_ge(env, left, right); break;
        case op_lt: result = eval_lt(env, left, right); break;
        case op_le: result = eval_le(env, left, right); break;
        case op_eq: result = eval_eq(env, left, right); break;
        case op_neq: result = eval_neq(env, left, right); break;
        case op_cat: result = eval_cat(env, left, right); break;
        case op_deref: {
          ast_t* index = eval_expression(env, right);
          if (index->type != at_integer) {
            // TODO: error -> index must be an integer!
          } else {
            switch(left->type) {
              case at_list: result = left->data.list.elements[index->data.i];
            }
          }
        }
      }
      result->ref_count = 0;
      dec_ref(left);
      dec_ref(right);
      return result;
    }
    /* no need to evaluate */
    case at_integer:
    case at_bool:
    case at_double:
    case at_string:
    case at_function:
    case at_statements:
    case at_list:
      return ast;

    /* invalid */
    case at_assignment:
    case at_callargs:
    case at_conditional:
    case at_dowhile:
    case at_elif:
    case at_if:
    case at_params:
    case at_while:
    case at_builtin:
      error_expected(NULL,"expression",get_ast_type_name(ast->type));
  }
  return NULL; /* this should never happen */
}
Пример #2
0
	Value * visit(Mod const * e)   			{ return eval_mod(e->left->accept(*this), e->right->accept(*this)); }