Пример #1
0
/*!
  Do parse.

  \return TRUE if parsing was successful, otherwise FALSE
*/
syx_bool
syx_parser_parse (SyxParser *self, syx_bool skip_message_pattern)
{
  SyxToken token;
  SyxParserScope scope;

  token = syx_lexer_next_token (self->lexer);
  if (token.type == SYX_TOKEN_END)
    return TRUE;

  if (skip_message_pattern)
    {
      scope.start = self->_argument_names_top;
      scope.end = self->_argument_names_top;
      self->_argument_scopes.stack[(syx_int32) self->_argument_scopes.top++] = scope;
    }
  else
    _syx_parser_parse_message_pattern (self);

  if (!self->_in_block)
    _syx_parser_parse_primitive (self);

  _syx_parser_parse_temporaries (self);

  if (self->_in_block)
    syx_bytecode_push_constant (self->bytecode, SYX_BYTECODE_CONST_NIL);
  _syx_parser_parse_body (self);

  syx_bytecode_do_special (self->bytecode, SYX_BYTECODE_SELF_RETURN);

  SYX_CODE_BYTECODES(self->method) = syx_byte_array_new_ref (self->bytecode->code_top * sizeof (syx_uint16),
                                                             (syx_uint8 *)self->bytecode->code);
  SYX_CODE_LITERALS(self->method) = syx_array_new_ref (self->bytecode->literals_top,
                                                       self->bytecode->literals);
  
  if (self->_in_block)
    SYX_BLOCK_ARGUMENT_STACK_TOP(self->method) = syx_small_integer_new (self->_argument_scopes.stack[self->_argument_scopes.top-1].start);
  else
    {
      SYX_METHOD_ARGUMENT_STACK_SIZE(self->method) = syx_small_integer_new (self->_argument_names_top);
      SYX_METHOD_TEMPORARY_STACK_SIZE(self->method) = syx_small_integer_new (self->_temporary_names_top);
    }

  SYX_CODE_STACK_SIZE(self->method) = syx_small_integer_new (self->bytecode->stack_size + 1);
  SYX_CODE_TEXT(self->method) = syx_string_new (self->lexer->text +
                                                syx_find_first_non_whitespace (self->lexer->text));
  SYX_CODE_CLASS(self->method) = self->klass;

  return TRUE;
}
Пример #2
0
static syx_varsize
_syx_parser_parse_optimized_block (SyxParser *self, SyxBytecodeSpecial branch_type, syx_bool do_pop)
{
  syx_int8 scope_top;
  syx_uint16 jump;
  syx_bool block_state;
  SyxToken token;
  syx_int32 i;

  syx_bytecode_do_special (self->bytecode, branch_type);
  syx_bytecode_gen_code (self->bytecode, 0);
  jump = self->bytecode->code_top - 1;

  if (do_pop)
    syx_bytecode_pop_top (self->bytecode);
  
  block_state = self->_in_block;
  self->_in_block = TRUE;

  token = syx_lexer_get_last_token (self->lexer);
  if (token.type == SYX_TOKEN_BINARY && !strcmp (token.value.string, "["))
    {
      syx_token_free (token);
      syx_lexer_next_token (self->lexer);
      /* we need to restore the current scope after the optimized block has been parsed */
      scope_top = self->_temporary_scopes[self->_temporary_scopes_top].top;
      _syx_parser_parse_temporaries (self);
      _syx_parser_parse_body (self);
      for (i=scope_top; i < self->_temporary_scopes[self->_temporary_scopes_top].top; i++)
        syx_free (self->_temporary_scopes[self->_temporary_scopes_top].stack[i]);
      self->_temporary_scopes[self->_temporary_scopes_top].top = scope_top;
      token = syx_lexer_next_token (self->lexer);
    }
  else
    {
      /* a variable or such has been used, like ifTrue: trueBlock */
      _syx_parser_do_binary_continuation (self, _syx_parser_parse_term (self), FALSE);
      syx_bytecode_gen_message (self->bytecode, FALSE, 0, "value");
    }

  self->_in_block = block_state;
  self->bytecode->code[jump] = SYX_COMPAT_SWAP_16 (self->bytecode->code_top);
  return jump;
}
Пример #3
0
/*!
  Do parse.

  \return TRUE if parsing was successful, otherwise FALSE
*/
syx_bool
syx_parser_parse (SyxParser *self, syx_bool skip_message_pattern)
{
  SyxToken token;

  token = syx_lexer_next_token (self->lexer);
  if (token.type == SYX_TOKEN_END)
    return TRUE;

  self->_temporary_scopes[self->_temporary_scopes_top].top = 0;
  self->_argument_scopes[self->_argument_scopes_top].top = 0;

  if (!skip_message_pattern)
    _syx_parser_parse_message_pattern (self);

  if (!self->_in_block)
    _syx_parser_parse_primitive (self);

  _syx_parser_parse_temporaries (self);

  if (self->_in_block)
    syx_bytecode_push_constant (self->bytecode, SYX_BYTECODE_CONST_NIL);

  _syx_parser_parse_body (self);

  syx_bytecode_do_special (self->bytecode, SYX_BYTECODE_SELF_RETURN);

  SYX_CODE_BYTECODES(self->method) = syx_byte_array_new_ref (self->bytecode->code_top * sizeof (syx_uint16),
                                                             (syx_uint8 *)self->bytecode->code);
  SYX_CODE_LITERALS(self->method) = syx_array_new_ref (self->bytecode->literals_top,
                                                       self->bytecode->literals);
  
  SYX_CODE_STACK_SIZE(self->method) = syx_small_integer_new (self->bytecode->stack_size + 1);
  SYX_CODE_TEXT(self->method) = syx_string_new (self->lexer->text +
                                                syx_find_first_non_whitespace (self->lexer->text));
  SYX_CODE_CLASS(self->method) = self->klass;

  /* Free arguments and temporaries of this scope */
  _syx_parser_free_arguments (self);
  _syx_parser_free_temporaries (self);

  return TRUE;
}
Пример #4
0
static syx_varsize
_syx_parser_parse_optimized_block (SyxParser *self, SyxBytecodeSpecial branch_type, syx_bool do_pop)
{
  syx_uint16 jump;
  syx_bool block_state;
  SyxToken token;

  syx_bytecode_do_special (self->bytecode, branch_type);
  syx_bytecode_gen_code (self->bytecode, 0);
  jump = self->bytecode->code_top - 1;

  if (do_pop)
    syx_bytecode_pop_top (self->bytecode);
  
  block_state = self->_in_block;
  self->_in_block = TRUE;

  token = syx_lexer_get_last_token (self->lexer);
  if (token.type == SYX_TOKEN_BINARY && !strcmp (token.value.string, "["))
    {
      syx_token_free (token);
      syx_lexer_next_token (self->lexer);
      _syx_parser_parse_temporaries (self);
      _syx_parser_parse_body (self);
      self->_temporary_scopes.top--;
      token = syx_lexer_next_token (self->lexer);
    }
  else
    {
      _syx_parser_do_binary_continuation (self, _syx_parser_parse_term (self), FALSE);
      syx_bytecode_gen_message (self->bytecode, FALSE, 0, "value");
    }

  self->_in_block = block_state;
  self->bytecode->code[jump] = SYX_COMPAT_SWAP_16 (self->bytecode->code_top);
  return jump;
}