/* $Id: param.c,v 1.2 2009/01/04 15:42:14 kiesling Exp $ -*-c-*-*/

/*
  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 library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library 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
  Lesser 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 <errno.h>
#include "object.h"
#include "message.h"
#include "ctalk.h"
#include "rtinfo.h"
#ifdef __DJGPP__
#include "../classes/ctldjgpp"
#else
#include "../classes/ctalklib"
#endif

extern RT_INFO rtinfo;

PARAM *new_param (void) {
  PARAM *p;

  if ((p = (PARAM *)calloc (1, sizeof (PARAM))) == NULL)
    _error ("new_param: %s\n", strerror (errno));

  strcpy (p -> sig, "PARAM");
  return p;
}

/*
 *  When looking for a param name, find the method 
 *  that is currently executing by searching for the
 *  method by function in the receiver's class and 
 *  and its superclasses, then looking up the parameter
 *  name, and returning the corresponding argument.
 */

OBJECT *__ctalk_getParamByName (char *name) {

  OBJECT *rcvr_obj,
    *rcvr_class_obj;
  METHOD *this_method;
  int i;

  if (__ctalk_receiver_ptr == MAXARGS)
    return NULL;

  rcvr_obj = __ctalk_receivers[__ctalk_receiver_ptr + 1];

  if (!rcvr_obj || !IS_OBJECT (rcvr_obj))
    _error ("__ctalk_getParamByName: Unknown receiver.\n");

  if ((rcvr_class_obj = rcvr_obj->__o_class) == NULL)
    _error ("__ctalk_getParamByName: Unknown receiver class %s.\n",
	    rcvr_obj -> __o_classname);

  if (((this_method = 
       __ctalkGetInstanceMethodByFn (rcvr_obj, rtinfo.method_fn, TRUE))
      == NULL) &&
      ((this_method =
	__ctalkGetClassMethodByFn (rcvr_obj, rtinfo.method_fn, FALSE)) 
       == NULL))
    return NULL;

  for (i = 0; i < this_method -> n_params; i++)
    if (!strcmp (name, this_method -> params[i] -> name))
      return this_method -> args[i];

  return NULL;
}

