Exemplo n.º 1
0
static void
_syx_parser_parse_method_message_pattern (SyxParser *self)
{
  SyxToken token = syx_lexer_get_last_token (self->lexer);
  syx_char selector[256] = {0};
  SyxParserScope scope;
  scope.start = self->_argument_names_top;
  scope.end = self->_argument_names_top;

  switch (token.type)
    {
    case SYX_TOKEN_NAME_CONST:
      /* Unary message pattern */
      SYX_METHOD_SELECTOR(self->method) = syx_symbol_new (token.value.string);
      syx_token_free (token);

      syx_lexer_next_token (self->lexer);
      break;
    case SYX_TOKEN_BINARY:
      /* Binary message pattern */
      SYX_METHOD_SELECTOR(self->method) = syx_symbol_new (token.value.string);
      syx_token_free (token);

      token = syx_lexer_next_token (self->lexer);
      if (token.type != SYX_TOKEN_NAME_CONST)
        syx_error ("Expected name constant for argument name\n");
      self->_argument_names[self->_argument_names_top++] = token.value.string;
      scope.end++;

      syx_lexer_next_token (self->lexer);
      break;
    case SYX_TOKEN_NAME_COLON:
      /* Keyword message pattern */
      while (token.type == SYX_TOKEN_NAME_COLON)
        {
          strcat (selector, token.value.string);
          syx_token_free (token);

          token = syx_lexer_next_token (self->lexer);
          if (token.type != SYX_TOKEN_NAME_CONST)
            syx_error ("Expected name constant for argument name\n");
          self->_argument_names[self->_argument_names_top++] = token.value.string;
          scope.end++;

          token = syx_lexer_next_token (self->lexer);
        }

      SYX_METHOD_SELECTOR(self->method) = syx_symbol_new (selector);
      break;
    default:
      syx_error ("Invalid message pattern\n");
    }

  self->_argument_scopes.stack[(syx_int32) self->_argument_scopes.top++] = scope;
  SYX_CODE_ARGUMENT_COUNT(self->method) = syx_small_integer_new (scope.end - scope.start);
}
Exemplo n.º 2
0
static void
_syx_parser_parse_method_message_pattern (SyxParser *self)
{
  SyxToken token = syx_lexer_get_last_token (self->lexer);
  syx_char selector[0xFF] = {0};
  SyxParserScope *scope = self->_argument_scopes + self->_argument_scopes_top;

  switch (token.type)
    {
    case SYX_TOKEN_NAME_CONST:
      /* Unary message pattern */
      SYX_METHOD_SELECTOR(self->method) = syx_symbol_new (token.value.string);
      syx_token_free (token);

      syx_lexer_next_token (self->lexer);
      break;
    case SYX_TOKEN_BINARY:
      /* Binary message pattern */
      SYX_METHOD_SELECTOR(self->method) = syx_symbol_new (token.value.string);
      syx_token_free (token);

      token = syx_lexer_next_token (self->lexer);
      if (token.type != SYX_TOKEN_NAME_CONST)
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected name constant for argument name\n"));
      scope->stack[scope->top++] = syx_strdup (token.value.string);
      syx_token_free (token);

      syx_lexer_next_token (self->lexer);
      break;
    case SYX_TOKEN_NAME_COLON:
      /* Keyword message pattern */
      while (token.type == SYX_TOKEN_NAME_COLON)
        {
          strcat (selector, token.value.string);
          syx_token_free (token);

          token = syx_lexer_next_token (self->lexer);
          if (token.type != SYX_TOKEN_NAME_CONST)
            syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected name constant for argument name\n"));
          scope->stack[scope->top++] = syx_strdup (token.value.string);
          syx_token_free (token);

          token = syx_lexer_next_token (self->lexer);
        }
      
      SYX_METHOD_SELECTOR(self->method) = syx_symbol_new (selector);
      break;
    default:
      syx_signal (SYX_ERROR_INTERP, syx_string_new ("Invalid message pattern\n"));
    }

  SYX_CODE_ARGUMENTS_COUNT(self->method) = syx_small_integer_new (scope->top);
}
Exemplo n.º 3
0
/*!
  Leaves the current frame and push an object into the returning context.

  Use the stack return frame use_stack_return is specified, otherwise use the parent frame.
  Then sets the returned object variable of the process to the specified object.
  Finally swap the context with the new one. Terminate the process if no valid return frame is found.

  \param return_object the object to be pushed into the returning context
  \param use_stack_return TRUE to use the stack return frame, FALSE to use the parent frame
  \return FALSE if no valid return frame is found
*/
syx_bool
syx_interp_leave_and_answer (SyxOop return_object, syx_bool use_stack_return)
{
  SyxInterpFrame *return_frame = (use_stack_return
                                  ? _syx_interp_state.frame->stack_return_frame
                                  : _syx_interp_state.frame->parent_frame);

#ifdef SYX_DEBUG_CONTEXT
  syx_debug ("CONTEXT - Leave frame %p for %p - Depth: %d - %s\n", _syx_interp_state.frame, return_frame, --_frame_depth,
             (_SYX_INTERP_IN_BLOCK
              ? NULL
              : SYX_OBJECT_STRING (SYX_METHOD_SELECTOR (_syx_interp_state.frame->method))));
#endif

  SYX_PROCESS_RETURNED_OBJECT(syx_processor_active_process) = return_object;

  _syx_interp_state.frame = return_frame;
  if (!return_frame)
    {
      syx_scheduler_remove_process (syx_processor_active_process);
      return FALSE;
    }

  _syx_interp_state_update (&_syx_interp_state, return_frame);
  syx_interp_stack_push (return_object);
  return TRUE;
}
Exemplo n.º 4
0
/*! Print to stdout the current execution state of the interpreter and the Process traceback */
void
syx_show_traceback (void)
{
  SyxInterpState *es;
  SyxInterpFrame *frame, *homeframe;
  syx_symbol traceformat;
  SyxOop classname;
  syx_symbol extraclass;
  SyxOop receiver;

  if (!syx_memory)
    {
      puts ("Can't print the memory state");
      return;
    }

  es = &_syx_interp_state;
  frame = es->frame;

  puts ("Memory state:");
  printf("Memory size: %d\n", _syx_memory_size);
  printf("Freed memory top: %d\n", _syx_freed_memory_top);
  if (!_syx_memory_gc_trans_running)
    puts ("No GC transaction");
  else
    printf("GC transaction top: %d\n", _syx_memory_gc_trans_top);

  if (!es)
    {
      puts ("Can't print the execution state");
      return;
    }

  puts ("\nExecution state:");
  printf("Process: %p (memory index: %ld)\n",
         SYX_OOP_CAST_POINTER (syx_processor_active_process),
         SYX_MEMORY_INDEX_OF (syx_processor_active_process));
  printf("Frame: %p\n", (syx_pointer) frame);

  if (!frame)
    return;

  printf("Receiver: %p (memory index: %ld)\n",
         SYX_OOP_CAST_POINTER (frame->receiver),
         SYX_MEMORY_INDEX_OF (frame->receiver));
  printf("Arguments: %p\n", (syx_pointer) es->arguments);
  printf("Temporaries: %p\n", (syx_pointer) es->temporaries);
  printf("Stack: %p\n", (syx_pointer) frame->stack);
  printf("Literals: %p\n", (syx_pointer) es->method_literals);
  printf("Bytecodes: %p (size: %d)\n", (syx_pointer) es->method_bytecodes, es->method_bytecodes_count);
  printf("Byteslice: %d\n", es->byteslice);
  printf("Instruction pointer: %p\n", (syx_pointer) frame->next_instruction);
  printf("Stack pointer: %p\n", (syx_pointer) frame->stack);
  printf("Message receiver: %p (memory index: %ld)\n",
         SYX_OOP_CAST_POINTER (es->message_receiver),
         SYX_MEMORY_INDEX_OF (es->message_receiver));
  printf("Message arguments: %p (size: %d)\n",
         (syx_pointer) es->message_arguments,
         es->message_arguments_count);

  if (SYX_IS_NIL (frame->detached_frame))
    printf("Process offset: %d\n", SYX_POINTERS_OFFSET (frame, SYX_OBJECT_DATA (SYX_PROCESS_STACK (_syx_interp_state.process))));

  puts ("\nTraceback:");
  while (frame)
    {
      if (frame->outer_frame)
        {
          homeframe = frame->outer_frame;
          while (homeframe->outer_frame)
            homeframe = homeframe->outer_frame;
          traceformat = "%s%s>>%s[]\n";
        }
      else
        {
          homeframe = frame;
          traceformat = "%s%s>>%s\n";
        }

      receiver = frame->receiver;
      classname = SYX_CLASS_NAME(syx_object_get_class(receiver));
      if (SYX_IS_NIL (classname))
        {
          classname = SYX_CLASS_NAME(SYX_METACLASS_INSTANCE_CLASS(syx_object_get_class(receiver)));
          extraclass = " class";
        }
      else
        extraclass = "";

      printf (traceformat,
              SYX_OBJECT_SYMBOL(classname),
              extraclass,
              SYX_OBJECT_SYMBOL(SYX_METHOD_SELECTOR(homeframe->method)));

      frame = frame->parent_frame;
    }
}
Exemplo n.º 5
0
syx_bool
syx_cold_parse_methods (SyxLexer *lexer)
{
  SyxToken token;
  SyxOop klass;
  SyxParser *parser;
  SyxLexer *method_lexer;
  /*syx_symbol category; */
  syx_string chunk;
  SyxLexer saved_lexer = *lexer;

  token = syx_lexer_next_token (lexer);
  if (token.type != SYX_TOKEN_NAME_CONST)
    {
      *lexer = saved_lexer;
      return FALSE;
    }

  klass = syx_globals_at (token.value.string);
  syx_token_free (token);

  if (SYX_IS_NIL (klass))
    return FALSE;

  token = syx_lexer_next_token (lexer);
  if (token.type == SYX_TOKEN_NAME_CONST && !strcmp (token.value.string, "class"))
    {
      klass = syx_object_get_class (klass);
      syx_token_free (token);
      token = syx_lexer_next_token (lexer);
    }

  if (! (token.type == SYX_TOKEN_NAME_COLON && !strcmp (token.value.string, "methodsFor:")))
    {
      *lexer = saved_lexer;
      return FALSE;
    }
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  if (token.type != SYX_TOKEN_STR_CONST)
    {
      *lexer = saved_lexer;
      return FALSE;
    }

  /*  category = syx_strdup (token.value.string); */
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  if (!_IS_EXL_MARK (token))
    {
      *lexer = saved_lexer;
      return FALSE;
    }
  syx_token_free (token);

  if (SYX_IS_NIL (SYX_CLASS_METHODS (klass)))
    {
      SYX_CLASS_METHODS(klass) = syx_dictionary_new (50);
    }

  while (TRUE)
    {
      chunk = syx_lexer_next_chunk (lexer);
      method_lexer = syx_lexer_new (chunk);
      if (!method_lexer)
        break;

      parser = syx_parser_new (method_lexer, syx_method_new (), klass);
      syx_parser_parse (parser, FALSE);

      syx_dictionary_at_symbol_put (SYX_CLASS_METHODS(klass),
                                    SYX_METHOD_SELECTOR(parser->method),
                                    parser->method);

      syx_parser_free (parser, TRUE);
    }
  
  return TRUE;
}