/* $Id: collection.c,v 1.2 2009/01/04 15:49:30 kiesling Exp $ */

/*
  This file is part of Ctalk.
  Copyright © 2005-2009 Robert Kiesling, ctalk@ctalklang.org.
  Permission is granted to copy this software provided that this copyright
  notice is included in all source code modules.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation, 
  Inc., 51 Franklin St., Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "object.h"
#include "message.h"
#include "ctalk.h"
#include "objtoc.h"

int collection_rt_expr (METHOD *method, MESSAGE_STACK messages, int msg_ptr,
			OBJECT_CONTEXT o_context) {

  char *expr_buf;
  char output_buf[MAXMSG];
  int receiver_ptr,
    arglist_start,
    arglist_end;

  if (((receiver_ptr = prevlangmsg (messages, msg_ptr)) == ERROR) ||
      ((arglist_start = nextlangmsg (messages, msg_ptr)) == ERROR))
    _error ("collection_rt_expr: parser error.\n");

  arglist_end = 
    method_arglist_limit (messages, arglist_start, method -> n_args,
			  method -> varargs);

  expr_buf = collect_tokens (messages, receiver_ptr, arglist_end);

  strcpy (output_buf, fmt_eval_expr (expr_buf));
  free (expr_buf);

  switch (o_context)
    {
    case c_context:
    case c_argument_context:
      fileout
	(array_obj_2_c_wrapper (messages, msg_ptr, 
				messages[msg_ptr]->receiver_obj,
				method, output_buf), 
	 FALSE, msg_ptr);
      break;
    default:
      fileout (output_buf, FALSE, msg_ptr);
      break;
    }

  return SUCCESS;
}

int collection_needs_rt_eval (OBJECT *obj, METHOD *m) {

  if (!obj || !IS_OBJECT(obj)) 
    return FALSE;
  return (IS_COLLECTION_SUBCLASS_OBJ(obj) &&
	  !IS_PRIMITIVE_METHOD(m) && strcmp (m -> name, "new")
	  && (m -> n_params != 0));
}


COLLECTION_CONTEXT collection_context (MESSAGE_STACK messages, int rcvr_idx) {

  if (IS_SIMPLE_SUBSCRIPT (messages, rcvr_idx,
			   stack_start (messages), 
			   get_stack_top (messages)))
    return int_collection_context;

  if (IS_CHAR_PTR_FMT_ARG (messages, rcvr_idx,
			   stack_start (messages), 
			   get_stack_top (messages)))
    return char_ptr_collection_context;

  return ptr_collection_context;

}

