Ejemplo n.º 1
0
SCM SCM_apply (unsigned long number, va_list arguments) {
  SCM args[31];
  SCM last_arg;
  SCM fun = va_arg(arguments,SCM);
  unsigned long i;
  for ( i=0 ; i<number-1 ; i++  ) {
    args[i] = va_arg(arguments,SCM);
  }
  last_arg = args[--i];
  while ( SCM_PairP(last_arg) ) {
    args[i++] = SCM_Car(last_arg);
    last_arg = SCM_Cdr(last_arg);
  }
  if ( ! SCM_NullP(last_arg) ) {
    SCM_error(SCM_ERR_APPLY_ARG);
  }
  switch ( i ) {
  case 0: return SCM_invoke(fun,0);
  case 1: return SCM_invoke(fun,1,args[0]);
  case 2: return SCM_invoke(fun,2,args[0],args[1]);
  case 3: return SCM_invoke(fun,3,args[0],args[1],args[2]);
  case 4: return SCM_invoke(fun,4,args[0],args[1],args[2],args[3]);
  case 5: return SCM_invoke(fun,5,args[0],args[1],args[2],args[3],
                            args[4]);
  case 6: return SCM_invoke(fun,6,args[0],args[1],args[2],args[3],
                            args[4],args[5]);
  case 7: return SCM_invoke(fun,7,args[0],args[1],args[2],args[3],
                            args[4],args[5],args[6]);
  case 8: return SCM_invoke(fun,8,args[0],args[1],args[2],args[3],
                            args[4],args[5],args[6],args[7]);
  case 9: return SCM_invoke(fun,9,args[0],args[1],args[2],args[3],
                             args[4],args[5],args[6],args[7],args[8]);
  case 10: return SCM_invoke(fun,10,args[0],args[1],args[2],args[3],
                             args[4],args[5],args[6],args[7],args[8],args[9]);
  case 11: return SCM_invoke(fun,11,args[0],args[1],args[2],args[3],
                             args[4],args[5],args[6],args[7],args[8],args[9],
                             args[10]);
  case 12: return SCM_invoke(fun,12,args[0],args[1],args[2],args[3],
                             args[4],args[5],args[6],args[7],args[8],args[9],
                             args[10],args[11]);
  case 13: return SCM_invoke(fun,13,args[0],args[1],args[2],args[3],
                             args[4],args[5],args[6],args[7],args[8],args[9],
                             args[10],args[11],args[12]);
  case 14: return SCM_invoke(fun,14,args[0],args[1],args[2],args[3],
                             args[4],args[5],args[6],args[7],args[8],args[9],
                             args[10],args[11],args[12],args[13]);
  /* If this were less cumbersome, I will add cases up to 31. */
  default: return SCM_error(SCM_ERR_APPLY_SIZE);
  }
}
Ejemplo n.º 2
0
SCM SCM_allocate_continuation (struct SCM_jmp_buf *address) {
  SCMref continuation = (SCMref) malloc(sizeof(struct SCM_unwrapped_escape));
  if (continuation == (SCMref) NULL) SCM_error(SCM_ERR_CANT_ALLOC);
  continuation->escape.header.tag = SCM_ESCAPE_TAG;
  continuation->escape.stack_address = address;
  return SCM_Wrap(continuation);
}
Ejemplo n.º 3
0
SCM SCM_cons (SCM x, SCM y) {
  SCMref cell = (SCMref) malloc(sizeof(struct SCM_unwrapped_pair));
  if (cell == (SCMref) NULL) SCM_error(SCM_ERR_CANT_ALLOC);
  cell->pair.header.tag = SCM_PAIR_TAG;
  cell->pair.car = x;
  cell->pair.cdr = y;
  return SCM_Wrap(cell);
}
Ejemplo n.º 4
0
SCM SCM_close (SCM (*Cfunction)(void), long arity, unsigned long size, ...) {
  SCMref result = (SCMref) malloc(sizeof(struct SCM_unwrapped_closure) 
                                  + (size-1)*sizeof(SCM) );
  unsigned long i;
  va_list args;
  if (result == (SCMref) NULL) SCM_error(SCM_ERR_CANT_ALLOC);
  result->closure.header.tag = SCM_CLOSURE_TAG;
  result->closure.behavior = Cfunction;
  result->closure.arity = arity;
  va_start(args,size);
  for ( i=0 ; i<size ; i++ ) {
    result->closure.environment[i] = va_arg(args,SCM);
  }
  va_end(args);
  return SCM_Wrap(result);
}
Ejemplo n.º 5
0
object *
copy_object (object *obj)
{
    object *ret = NULL;
    if (NULL == obj)
        return NULL;
    else if (SCM_VOID == obj->type)
        ret = SCM_void ();
    else if (SCM_ERROR == obj->type)
        ret = SCM_error (((error_object *) obj)->error,
                         ((error_object *) obj)->msg);
    else if (SCM_ATOM == obj->type)
        ret = SCM_atom (((atom_object *) obj)->name);
    else if (SCM_BOOL == obj->type)
        ret = SCM_bool (((bool_object *) obj)->value);
    else if (SCM_VARIABLE == obj->type)
        ret = SCM_variable (((variable_object *) obj)->name,
                            copy_object (((variable_object *) obj)->value));
    else if (SCM_NUMBER == obj->type)
        ret = SCM_number_from_double (((number_object *) obj)->num);
    else if (SCM_STRING == obj->type)
        ret = SCM_string (((string_object *) obj)->str);
    else if (SCM_PAIR == obj->type)
        ret = SCM_cons (copy_object (car (obj)), copy_object (cdr (obj)));
    else if (SCM_FUNC == obj->type)
        ret = SCM_func (((func_object *) obj)->fn);
    else if (SCM_LAMBDA == obj->type)
        ret = SCM_lambda (copy_object (((lambda_object *) obj)->args),
                          copy_object (((lambda_object *) obj)->sexp));
    else
    {
        print_fatal (ETYPE);
        exit (1);
    }

    return ret;
}
Ejemplo n.º 6
0
SCM SCM_allocate_box (SCM v) {
  SCM cell = (SCM) malloc(sizeof(struct SCM_box));
  if (cell == (SCM) NULL) SCM_error(SCM_ERR_CANT_ALLOC);
  cell->box.content = v;
  return (cell);
}
Ejemplo n.º 7
0
SCM SCM_set_cdr (SCM x, SCM y) {
  if ( SCM_PairP(x) ) {
    SCM_Unwrap(x)->pair.cdr = y;
    return x;
  } else return SCM_error(SCM_ERR_SET_CDR);
}
Ejemplo n.º 8
0
SCM SCM_cdr (SCM x) { 
  if ( SCM_PairP(x) ) { 
    return SCM_Cdr(x);
  } else return SCM_error(SCM_ERR_CDR);
}
Ejemplo n.º 9
0
SCM SCM_car (SCM x) {
  if ( SCM_PairP(x) ) { 
    return SCM_Car(x);
  } else return SCM_error(SCM_ERR_CAR);
}
Ejemplo n.º 10
0
SCM SCM_invoke(SCM function, unsigned long number, ...) {
  if ( SCM_FixnumP(function) ) {
    return SCM_error(SCM_ERR_CANNOT_APPLY); /* Cannot apply a number! */
  } else {
    switch SCM_2tag(function) {
    case SCM_SUBR_TAG: {
      SCM (*behavior)(void) = (SCM_Unwrap(function)->subr).behavior;
      long arity = (SCM_Unwrap(function)->subr).arity;
      SCM result;
      if ( arity >= 0 ) {         /* Fixed arity subr */
        if ( arity != number ) {
          return SCM_error(SCM_ERR_WRONG_ARITY); /* Wrong arity! */
        } else {
          if ( arity == 0) {
            result = behavior();
          } else {
            va_list args;
            va_start(args,number);
            { SCM a0 ;
              a0 = va_arg(args,SCM);
              if ( arity == 1 ) {
                result = ((SCM (*)(SCM)) *behavior)(a0);
              } else {
                SCM a1 ;
                a1 = va_arg(args,SCM);
                if ( arity == 2 ) {
                  result = ((SCM (*)(SCM,SCM)) *behavior)(a0,a1);
                } else {
                  SCM a2 ;
                  a2 = va_arg(args,SCM);
                  if ( arity == 3 ) {
                    result = ((SCM (*)(SCM,SCM,SCM)) *behavior)(a0,a1,a2);
                  } else {
                    /* No fixed arity subr with more than 3 variables */
                    return SCM_error(SCM_ERR_INTERNAL); 
                  }
                }
              }
            }
            va_end(args);
          }
          return result;
        }
      } else {                  /* Nary subr */
        long min_arity = SCM_MinimalArity(arity) ;
        if ( number < min_arity ) {
          return SCM_error(SCM_ERR_MISSING_ARGS); /* Too less arguments! */
        } else {
          va_list args;
          SCM result;
          va_start(args,number);
          result = ((SCM (*)(unsigned long,va_list)) *behavior)(number,args);
          va_end(args);
          return result;
        }
      }
    }
    case SCM_CLOSURE_TAG: {
      SCM (*behavior)(void) = (SCM_Unwrap(function)->closure).behavior ;
      long arity = (SCM_Unwrap(function)->closure).arity ;
      SCM result;
      va_list args;
      va_start(args,number);
      if ( arity >= 0 ) {
        if ( arity != number ) { /* Wrong arity! */
          return SCM_error(SCM_ERR_WRONG_ARITY);
        } else {
          result = ((SCM (*)(SCM,unsigned long,va_list)) *behavior)(function,number,args);
        }
      } else {
        long min_arity = SCM_MinimalArity(arity) ;
        if ( number < min_arity ) { 
          return SCM_error(SCM_ERR_MISSING_ARGS);     /* Too less arguments! */
        } else {
          result = ((SCM (*)(SCM,unsigned long,va_list)) *behavior)(function,number,args);
        }
      }
      va_end(args);
      return result;
    }
    case SCM_ESCAPE_TAG: {
      if ( number == 1) {
        va_list args;
        va_start(args,number);
        jumpvalue = va_arg(args,SCM);
        va_end(args);
        { struct SCM_jmp_buf *address = 
            SCM_Unwrap(function)->escape.stack_address;
          if ( SCM_EqP(address->back_pointer,function) 
              && ( (void *) &address SCM_STACK_HIGHER (void *) address ) ) {
            longjmp(address->jb,1);
          } else {    /* surely out of dynamic extent! */
            return SCM_error(SCM_ERR_OUT_OF_EXTENT); 
          }
        }
      } else {
        return SCM_error(SCM_ERR_MISSING_ARGS);     /* Too less arguments! */
      }
    }
    default: {
      return SCM_error(SCM_ERR_CANNOT_APPLY);       /* Cannot apply! */
    } 
    }
  }
}