Example #1
0
const SpObject *SpVM::call_function(const std::string &name, const SpFunction *func, const SpExpr *call_expr, SpEnv *env) {
   // now, evaluate the arguments in a new scope
   // this is because Spooner is lexically scoped, so any this function call
   // can only access its arguments
   std::unique_ptr<SpEnv> call_env(new SpEnv());

   // check if the correct number of arguments are provided
   if (call_expr->length() - 1 != func->num_arguments())
      RUNTIME_ERROR_F("Function call to '%s' requires %lu arguments, "
         "but %d given", name.c_str(), func->num_arguments(),
         call_expr->length() - 1);

   size_t arg_index = 0;
   for (auto it = call_expr->cbegin(); it != call_expr->cend(); ++it, arg_index++) {
      // if there is a pattern for this argument
      if (arg_index < func->pattern()->length()) {
         // need to handle the quote pattern specially
         if (func->pattern(arg_index)->type() == T_NAME) {
            const char *name = ((SpName *)func->pattern(arg_index))->value();
            if (!strcmp(name, "quote")) {
               // we need to quote this argument and not evaluate it
               call_env->bind_name(func->arguments(arg_index), new SpExprObject(*it));
            } else if (!strcmp(name, "_")) {
               // wildcards match anything
               call_env->bind_name(func->arguments(arg_index), eval(*it, env));
            } else { 
               // TODO: allow names in patterns
               RUNTIME_ERROR("Names cannot be used in patterns yet...");
            }
         } else {
            // check if this pattern matches
            const SpObject *arg_result = eval(*it, env);
            if (is_match_pattern(func->pattern(arg_index), arg_result)) {
               // good, we'll bind this argument
               call_env->bind_name(func->arguments(arg_index), arg_result);
            } else {
               RUNTIME_ERROR_F("Arguments in function call to '%s' do not match any patterns", name.c_str());
            }
         }
      } else {
         // no pattern means anything matches
         call_env->bind_name(func->arguments(arg_index), eval(*it, env));
      }
   }

   // call the function (either natively or in the VM) using the new environment 
   return func->is_native() ?
      call_native_function((SpNativeFunction *)func, call_env.get()) :
      call_function_with_env(func, call_env.get());
}
Example #2
0
const SpObject *SpNativeWith::native_eval(SpEnv *env, SpVM *vm) const {
   // first, bind the variables in a new scope
   std::unique_ptr<SpEnv> call_env(new SpEnv());

   // TODO(evilncrazy): allow multiple variable declarations
   const SpExpr *name_expr =
      static_cast<const SpExprObject *>(env->resolve_name("x"))->expr();

   call_env->bind_name(name_expr->head()->value(),
      env->resolve_name("val")->shallow_copy());

   // then, evaluate the quoted body
   return vm->eval(
      static_cast<const SpExprObject *>(env->resolve_name("body"))->expr(),
      call_env.get());
}
int child(char **command, char **env, char *line)
{
  int status;
  pid_t pid;
  pid = fork();

  if ( pid == -1)
  {
    perror("fork");
    return (1);
  }
  else if (pid == 0)
  {
 execvp(command[0], command);

    if ( str_cmp(command[0],"env") == 0)
    {
      call_env(command,env);
      free(line);
      free_command(command);
      exit(0);
    }
    else if( str_cmp (command[0], "$?") == 0)
    {
      printf("%d\n",status);
      exit(0);
    }
    else
    {
      printf("%s: command not found\n",command[0]);
      free(line);
      free_command(command);
      exit(0);
    }
    return (1);
    free(line);
    free_command(command);
  }
  else
  {
    wait(&status);
  }
  return status;
}
Example #4
0
void	own_command(t_env *env, char **sa, char *s)
{
	if (ft_memcmp(sa[0], "echo", 4) == 0)
		ft_echo(sa);
	else if (ft_memcmp(sa[0], "cd", 2) == 0)
		ft_cd(env, sa);
	else if (ft_memcmp(sa[0], "setenv", 6) == 0)
		ft_setenv(env, sa);
	else if (ft_memcmp(sa[0], "unsetenv", 8) == 0)
		ft_unsetenv(env, sa);
	else if (ft_memcmp(sa[0], "env", 3) == 0)
		call_env(*env, s);
	else if (ft_memcmp(sa[0], "help", 4) == 0)
		ft_help(env, sa);
	else if (ft_memcmp(sa[0], "easter", 6) == 0)
		easteregg(env, sa);
	else if (ft_memcmp(sa[0], "history", 7) == 0)
		list_history(env, sa);
	else
		ft_putstr(E_MESS05);
	FREE_(s);
}