Beispiel #1
0
static void
_syx_parser_parse_temporaries (SyxParser *self)
{
  SyxToken token = syx_lexer_get_last_token (self->lexer);
  SyxParserScope scope;
  scope.start = self->_temporary_names_top;
  scope.end = self->_temporary_names_top;

  if (token.type == SYX_TOKEN_BINARY && !strcmp (token.value.string, "|"))
    {
      syx_token_free (token);
      token = syx_lexer_next_token (self->lexer);
      while (token.type == SYX_TOKEN_NAME_CONST)
        {
          self->_temporary_names[self->_temporary_names_top++] = token.value.string;
          scope.end++;
          token = syx_lexer_next_token (self->lexer);
        }
      if (! (token.type == SYX_TOKEN_BINARY && !strcmp (token.value.string, "|")))
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Temporary list not terminated by bar"));
      syx_token_free (token);

      syx_lexer_next_token (self->lexer);
    }

  self->_temporary_scopes.stack[(syx_int32) self->_temporary_scopes.top++] = scope;
}
Beispiel #2
0
static SyxOop 
_syx_parser_parse_literal_array (SyxParser *self)
{
  SyxOop elements[256];
  syx_varsize top = 0;
  SyxToken token;

  token = syx_lexer_next_token (self->lexer);
  while (! (token.type == SYX_TOKEN_END || (token.type == SYX_TOKEN_CLOSING && token.value.character == ')')))
    {
      switch (token.type)
        {
        case SYX_TOKEN_ARRAY_BEGIN:
          elements[top++] = _syx_parser_parse_literal_array (self);
          break;
        case SYX_TOKEN_INT_CONST:
          elements[top++] = syx_small_integer_new (token.value.integer);
          break;
        case SYX_TOKEN_BINARY:
          if (!strcmp (token.value.string, "("))
            {
              elements[top++] = _syx_parser_parse_literal_array (self);
              syx_token_free (token);
              break;
            }
        case SYX_TOKEN_NAME_CONST:
        case SYX_TOKEN_NAME_COLON:
        case SYX_TOKEN_SYM_CONST:
          elements[top++] = syx_symbol_new (token.value.string);
          syx_token_free (token);
          break;
        case SYX_TOKEN_STR_CONST:
          elements[top++] = syx_string_new (token.value.string);
          syx_token_free (token);
          break;
        case SYX_TOKEN_CHAR_CONST:
          elements[top++] = syx_character_new (token.value.character);
          break;
        default:
          syx_signal (SYX_ERROR_INTERP, syx_string_new ("Illegal text in literal array\n"));
          break;
        }

      token = syx_lexer_next_token (self->lexer);
    }

  return syx_array_new_ref (top, elements);
}
Beispiel #3
0
static void
_syx_parser_parse_primitive (SyxParser *self)
{
  SyxToken token = syx_lexer_get_last_token (self->lexer);
  syx_int32 prim_index;

  SYX_METHOD_PRIMITIVE(self->method) = syx_small_integer_new (-1);

  if (! (token.type == SYX_TOKEN_BINARY && !strcmp (token.value.string, "<")))
    return;
  syx_token_free (token);

  token = syx_lexer_next_token (self->lexer);
  if (token.type != SYX_TOKEN_NAME_COLON)
    syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected name colon"));

  if (!strcmp (token.value.string, "primitive:"))
    {
      syx_token_free (token);

      token = syx_lexer_next_token (self->lexer);
      if (token.type != SYX_TOKEN_STR_CONST)
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected a string containing the primitive to be called"));
      
      prim_index = syx_primitive_get_index (token.value.string);
      if (prim_index < 0)
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Unknown primitive named", token.value.string));
      syx_token_free (token);
      
      token = syx_lexer_next_token (self->lexer);
      if (! (token.type == SYX_TOKEN_BINARY && !strcmp (token.value.string, ">")))
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected >"));
      syx_token_free (token);
      
      SYX_METHOD_PRIMITIVE (self->method) = syx_small_integer_new (prim_index);
      
      syx_lexer_next_token (self->lexer);
    }
  else if (!strcmp (token.value.string, "cCall:"))
    {
      syx_token_free (token);
      
      token = syx_lexer_next_token (self->lexer);

      if (token.type != SYX_TOKEN_STR_CONST)
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected a string containing the primitive to be called"));
      syx_bytecode_gen_literal (self->bytecode, syx_symbol_new (token.value.string));
      syx_token_free (token);

      token = syx_lexer_next_token (self->lexer);
      if (token.type == SYX_TOKEN_BINARY && !strcmp (token.value.string, ">"))
        {
          syx_token_free (token);
          syx_bytecode_gen_literal (self->bytecode, syx_nil);
          SYX_METHOD_PRIMITIVE (self->method) = syx_small_integer_new (-2);
          syx_lexer_next_token (self->lexer);
          return;
        }

      if (! (token.type == SYX_TOKEN_NAME_COLON && !strcmp (token.value.string, "plugin:")))
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected plugin:"));
      syx_token_free (token);

      token = syx_lexer_next_token (self->lexer);
      if (token.type != SYX_TOKEN_STR_CONST)
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected a string containing the plugin name"));
      syx_bytecode_gen_literal (self->bytecode, syx_symbol_new (token.value.string));
      syx_token_free (token);

      token = syx_lexer_next_token (self->lexer);
      if (! (token.type == SYX_TOKEN_BINARY && !strcmp (token.value.string, ">")))
        syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected >"));
      syx_token_free (token);

      syx_lexer_next_token (self->lexer);

      SYX_METHOD_PRIMITIVE(self->method) = syx_small_integer_new (-2);
    }
  else
    syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected primitive or cCall"));

  return;
}
Beispiel #4
0
static syx_bool
_syx_parser_parse_term (SyxParser *self)
{
  SyxToken token = syx_lexer_get_last_token (self->lexer);
  syx_bool super_term = FALSE;
  switch (token.type)
    {
    case SYX_TOKEN_NAME_CONST:
      super_term = _syx_parser_parse_name_term (self, token.value.string);
      syx_token_free (token);
      break;
    case SYX_TOKEN_STR_CONST:
      syx_bytecode_push_literal (self->bytecode, syx_string_new (token.value.string));
      syx_token_free (token);
      break;
    case SYX_TOKEN_INT_CONST:
      syx_bytecode_push_literal (self->bytecode, syx_small_integer_new (token.value.integer));
      syx_token_free (token);
      break;
#ifdef HAVE_LIBGMP
    case SYX_TOKEN_LARGE_INT_CONST:
      syx_bytecode_push_literal (self->bytecode,
                                 syx_large_integer_new_mpz (token.value.large_integer));
      syx_token_free (token);
      break;
#endif
    case SYX_TOKEN_FLOAT_CONST:
      syx_bytecode_push_literal (self->bytecode, syx_float_new (token.value.floating));
      syx_token_free (token);
      break;
    case SYX_TOKEN_SYM_CONST:
      syx_bytecode_push_literal (self->bytecode, syx_symbol_new (token.value.string));
      syx_token_free (token);
      break;
    case SYX_TOKEN_CHAR_CONST:
      syx_bytecode_push_literal (self->bytecode, syx_character_new (token.value.character));
      syx_token_free (token);
      break;
    case SYX_TOKEN_ARRAY_BEGIN:
      syx_bytecode_push_literal (self->bytecode, _syx_parser_parse_literal_array (self));
      syx_token_free (token);
      break;
    case SYX_TOKEN_BINARY:
      if (!strcmp (token.value.string, "("))
        {
          syx_token_free (token);
          token = syx_lexer_next_token (self->lexer);
          _syx_parser_parse_expression (self);
          token = syx_lexer_get_last_token (self->lexer);
          if (! (token.type == SYX_TOKEN_CLOSING && token.value.character == ')'))
            syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected ) after sub expression"));
          break;
        }
      else if (!strcmp (token.value.string, "["))
        {
          _syx_parser_parse_block (self);
          break;
        }
      else if (!strcmp (token.value.string, "{"))
        {
          _syx_parser_parse_array (self);
          break;
        }
      else if (!strcmp (token.value.string, "-"))
        {
          syx_token_free (token);
          token = syx_lexer_next_token (self->lexer);
          if (token.type == SYX_TOKEN_INT_CONST)
            syx_bytecode_push_literal (self->bytecode, syx_small_integer_new (-token.value.integer));

#ifdef HAVE_LIBGMP
          else if (token.type == SYX_TOKEN_LARGE_INT_CONST)
            {
              mpz_neg (*token.value.large_integer, *token.value.large_integer);
              syx_bytecode_push_literal (self->bytecode,
                                         syx_large_integer_new_mpz (token.value.large_integer));
            }
#endif /* HAVE_LIBGMP */

          else if (token.type == SYX_TOKEN_FLOAT_CONST)
            syx_bytecode_push_literal (self->bytecode, syx_float_new (-token.value.floating));
          else
            syx_signal(SYX_ERROR_INTERP, syx_string_new ("Negation not followed by number"));

          syx_token_free (token);
          break;
        }
      /* We continue here because of weird binary token used as expression start */

    default:
      switch (token.type)
        {
        case SYX_TOKEN_END:
          syx_signal (SYX_ERROR_INTERP, syx_string_new ("Unexpected end of input"));
          break;
        case SYX_TOKEN_STRING_ENTRY:
          syx_signal (SYX_ERROR_INTERP, syx_string_new ("Invalid expression start: %s", token.value.string));
          syx_token_free (token);
          break;
        case SYX_TOKEN_CLOSING:
          syx_signal (SYX_ERROR_INTERP, syx_string_new ("Unexpected closing: %c", token.value.character));
          break;
        default:
          syx_signal (SYX_ERROR_INTERP, syx_string_new ("Expected expression"));
          break;
        }
    }

  syx_lexer_next_token (self->lexer);
  return super_term;
}