Exemplo n.º 1
0
/*!
  Parse a declaration file.

  \return TRUE if no error has occurred
*/
syx_bool
syx_cold_file_in (syx_symbol filename)
{
  SyxLexer *lexer;
  syx_string buffer;
  syx_int32 fd, count;
  syx_size size;
#ifdef HAVE_FSTAT
  struct stat statbuf;
#endif

  if ((fd = open (filename, O_RDONLY)) < 0)
     {
        syx_error ("can't open %s\n", filename);
        return FALSE;
     }
#ifdef HAVE_FSTAT
  if ((fstat (fd, &statbuf)) < 0)
     {
        syx_error ("can't obtain size of %s\n", filename);
        return FALSE;
     }
  size = statbuf.st_size;
#else
  size = 1000000;
#endif

  buffer = (syx_string) syx_malloc (size + 1);
  count = read (fd, buffer, size);
  buffer[count - 1] = '\0';
   
  close (fd);
   
  lexer = syx_lexer_new (buffer);
  if (!lexer)
    {
      syx_free (buffer);
      return FALSE;
    }

  if (!syx_cold_parse (lexer))
    {
      syx_lexer_free (lexer, TRUE);
      return FALSE;
    }

  syx_lexer_free (lexer, TRUE);
  return TRUE;
}
Exemplo n.º 2
0
/*!
  Free all memory used by the parser.

  \param free_segment TRUE frees the instance_names (not its contents) and the lexer
*/
void
syx_parser_free (SyxParser *self, syx_bool free_segment)
{
  syx_bytecode_free (self->bytecode);

  if (free_segment)
    {
      if (self->instance_names)
        syx_free (self->instance_names);
      syx_lexer_free (self->lexer, TRUE);
    }

  syx_free (self);
}
Exemplo n.º 3
0
/*!
  Free all memory used by the parser.

  \param free_segment TRUE frees the instance_names (not its contents) and the lexer
*/
void
syx_parser_free (SyxParser *self, syx_bool free_segment)
{
  syx_size i;
  syx_bytecode_free (self->bytecode);

  for (i=0; i < self->_temporary_names_top; i++)
    syx_free (self->_temporary_names[i]);
  for (i=0; i < self->_argument_names_top; i++)
    syx_free (self->_argument_names[i]);

  if (free_segment)
    {
      if (self->instance_names)
        syx_free (self->instance_names);
      syx_lexer_free (self->lexer, TRUE);
    }

  syx_free (self);
}
Exemplo n.º 4
0
int SYX_CDECL
main (int argc, char *argv[])
{
  SyxLexer *lexer;
  SyxToken token;

  syx_init (0, NULL, "..");

#ifdef HAVE_LIBGMP
  lexer = syx_lexer_new ("nameconst 123 16r123 16rFFFFFFFF 123.321 1e2 1.3e-2 $c $  #symbol #(aaa) \"comment\" 'string' + := -> !!");
#else
  lexer = syx_lexer_new ("nameconst 123 16r123 123.321 1e2 1.3e-2 $c $  #symbol #(aaa) \"comment\" 'string' + := -> !!");
#endif

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_NAME_CONST);
  assert (!strcmp (token.value.string, "nameconst"));
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_INT_CONST);
  assert (token.value.integer == 123);
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_INT_CONST);
  assert (token.value.integer == 0x123);

#ifdef HAVE_LIBGMP
  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_LARGE_INT_CONST);
  assert (mpz_cmp_si (*token.value.large_integer, 0xFFFFFFFF) == 0);
#endif

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_FLOAT_CONST);
  assert (token.value.floating == 123.321);
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_FLOAT_CONST);
  assert (token.value.floating == 100.0);
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_FLOAT_CONST);
  assert (token.value.floating == 0.013);
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_CHAR_CONST);
  assert (token.value.character == 'c');
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_CHAR_CONST);
  assert (token.value.character == ' ');
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_SYM_CONST);
  assert (!strcmp (token.value.string, "symbol"));
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_ARRAY_BEGIN);
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_NAME_CONST);
  assert (!strcmp (token.value.string, "aaa"));
  syx_token_free (token);
  
  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_CLOSING);
  assert (token.value.character == ')');
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_STR_CONST);
  assert (!strcmp (token.value.string, "string"));
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_BINARY);
  assert (!strcmp (token.value.string, "+"));
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_BINARY);
  assert (!strcmp (token.value.string, ":="));
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_BINARY);
  assert (!strcmp (token.value.string, "->"));
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_BINARY);
  assert (!strcmp (token.value.string, "!"));
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  assert (token.type == SYX_TOKEN_BINARY);
  assert (!strcmp (token.value.string, "!"));
  syx_token_free (token);

  syx_lexer_free (lexer, FALSE);

  return 0;
}
Exemplo n.º 5
0
static syx_bool
_syx_cold_parse_class (SyxLexer *lexer)
{
  SyxToken token = syx_lexer_get_last_token (lexer);
  SyxOop superclass, subclass;
  syx_string subclass_name;
  syx_bool existing_class = TRUE;

  SyxOop inst_vars, class_vars;
  SyxLexer *inst_vars_lexer, *class_vars_lexer;
  syx_varsize super_inst_vars_size;
  syx_int32 i;

  if (token.type != SYX_TOKEN_NAME_CONST)
    {
      syx_error ("Expected a name constant\n");
      syx_token_free (token);
      return FALSE;
    }

  if (!strcmp (token.value.string, "nil"))
    superclass = syx_nil;
  else
    superclass = syx_globals_at (token.value.string);
  
  token = syx_lexer_next_token (lexer);
  if (!(token.type == SYX_TOKEN_NAME_COLON && !strcmp (token.value.string, "subclass:")))
    {
      syx_token_free (token);
      syx_error ("Expected #subclass:\n");
      return FALSE;
    }
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  if (token.type != SYX_TOKEN_SYM_CONST)
    {
      syx_token_free (token);
      syx_error ("Expected a symbol constant\n");
      return FALSE;
    }

  subclass_name = syx_strdup (token.value.string);
  syx_token_free (token);
  subclass = syx_globals_at_if_absent (subclass_name, syx_nil);

  if (strcmp (subclass_name, "Object"))
    {
      if (SYX_IS_NIL (subclass))
        existing_class = FALSE;
      else
        {
          existing_class = TRUE;
          if (SYX_OOP_NE (SYX_CLASS_SUPERCLASS(subclass), superclass))
            {
              syx_array_remove (SYX_CLASS_SUBCLASSES (SYX_CLASS_SUPERCLASS (subclass)),
                                subclass);
              SYX_CLASS_SUPERCLASS(subclass) = superclass;
              syx_array_add (SYX_CLASS_SUBCLASSES (superclass), subclass, TRUE);

              syx_array_remove (SYX_CLASS_SUBCLASSES (SYX_CLASS_SUPERCLASS(syx_object_get_class (subclass))),
                                syx_object_get_class (subclass));
              SYX_CLASS_SUPERCLASS(syx_object_get_class (subclass)) = syx_object_get_class (superclass);
              syx_array_add (SYX_CLASS_SUBCLASSES (syx_object_get_class (superclass)),
                             syx_object_get_class (subclass), TRUE);
            }
        }
    }

  token = syx_lexer_next_token (lexer);
  if (token.type != SYX_TOKEN_NAME_COLON)
    {
      syx_token_free (token);
      syx_error ("Expected #instanceVariableNames:\n");
      return FALSE;
    }
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  if (token.type != SYX_TOKEN_STR_CONST)
    {
      syx_token_free (token);
      syx_error ("Expected a string as argument for #instanceVariableNames:\n");
      return FALSE;
    }
  inst_vars_lexer = syx_lexer_new (token.value.string);

  token = syx_lexer_next_token (lexer);
  if (token.type != SYX_TOKEN_NAME_COLON)
    {
      syx_token_free (token);
      syx_error ("Expected #classVariableNames:\n");
      return FALSE;
    }
  syx_token_free (token);

  token = syx_lexer_next_token (lexer);
  if (token.type != SYX_TOKEN_STR_CONST)
    {
      syx_token_free (token);
      syx_error ("Expected a string as argument for #classVariableNames:\n");
      return FALSE;
    }
  class_vars_lexer = syx_lexer_new (token.value.string);

  token = syx_lexer_next_token (lexer);
  if (!_IS_EXL_MARK (token))
    {
      syx_token_free (token);
      syx_error ("Class definition must terminate with an exlamation mark\n");
      return FALSE;
    }
  syx_token_free (token);

  if (!existing_class)
    {
      subclass = syx_class_new (superclass);
      SYX_CLASS_NAME(subclass) = syx_symbol_new (subclass_name);
      syx_globals_at_put (SYX_CLASS_NAME(subclass), subclass);
    }
  syx_free (subclass_name);

  /* Parse instance variables */
  inst_vars = _syx_cold_parse_vars (inst_vars_lexer, FALSE);
  syx_lexer_free (inst_vars_lexer, TRUE);

  /* Fetch superclass instanceSize */
  if (SYX_IS_NIL (superclass))
    super_inst_vars_size = 0;
  else
    super_inst_vars_size = SYX_SMALL_INTEGER (SYX_CLASS_INSTANCE_SIZE (superclass));

  SYX_CLASS_INSTANCE_VARIABLES(subclass) = inst_vars;
  SYX_CLASS_INSTANCE_SIZE(subclass) = syx_small_integer_new (super_inst_vars_size
                                                             + SYX_OBJECT_DATA_SIZE (inst_vars));

  /* Now parse class variables */
  class_vars = _syx_cold_parse_vars (class_vars_lexer, TRUE);
  syx_lexer_free (class_vars_lexer, TRUE);

  SYX_CLASS_CLASS_VARIABLES(subclass) = syx_dictionary_new (SYX_OBJECT_DATA_SIZE (class_vars) + 10); 

  /* translate from array to dictionary */
  for (i=0; i < SYX_OBJECT_DATA_SIZE(class_vars); i++)
    syx_dictionary_at_symbol_put (SYX_CLASS_CLASS_VARIABLES(subclass),
                                  SYX_OBJECT_DATA(class_vars)[i], syx_nil);
  /* get rid of this */
  syx_object_free (class_vars);

  return TRUE;
}