⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 things.cpp

📁 c-smile 一个语法类似与JS 又有点像C++的 编译器
💻 CPP
字号:
/*
*
* things.cpp
*
* Copyright (c) 2001, 2002
* Andrew Fedoniouk - andrew@terra-informatica.org
* Portions: Serge Kuznetsov -  kuznetsov@deeptown.org
*
* See the file "COPYING" for information on usage 
* and redistribution of this file
*
*/
#include <stdlib.h>
#include "c-smile.h"
#include "vm.h"
#include "mm.h"
#include "compiler.h"

namespace c_smile
{
  void*
    THING::operator new ( size_t size  )
  {
    return memory.alloc_thing ( size );
  }

  void*
    THING::operator new ( size_t size, int moresize  )
  {
    return memory.alloc_thing ( ( size_t ) ( (int ) size + moresize ) );
  }

  void
    THING::operator delete ( void* p )
  {
    /*do nothing*/
  }

  void
    THING::operator delete ( void* p, int moresize )
  {
    /*do nothing*/
  }

  THING::operator VALUE ()
  {
    return VALUE ( this );
  }

  bool
    THING::instance_of ( CLASS *cls )
  {
    CLASS *klass = get_class ();
    while ( klass  )
    {
      if ( klass == cls )
        return true;
      klass = klass->base;
    }
    return false;
  }

  STRING *
    STRING::slice ( int start, int end  )
  {
    int st = start >= 0 ? start : ( size () + start );
    int en = end >= 0 ? end : ( size () + end );

    if ( en > ( int ) size () ) en = size ();

    int length = en - st;

    if ( length <= 0 || st >= ( int ) size () ) return new STRING ();

    STRING *s = new STRING ( _data.substr ( st, length ) );

    return s;
  }

  CLASS *
    STRING::get_class  ()
  {
    return VM::class_string;
  }

  OBJECT::OBJECT ( CLASS *k ) : klass ( k ), tag ( 0 )
  {
    int n = klass->instance_size;
    VALUE *p = members;
    for ( int i = 0; i < n; ++i, ++p )
      p->init ();
  }

  void
    OBJECT::mark ()
  {
      THING::mark ();
      VALUE *p;
      int n;
      p = members;
      n = klass->instance_size;
      while ( --n >= 0 )
        ( p++ )->mark ();
      mark_thing ( klass );

  }

  CLASS *
    OBJECT::get_class  ()
  {
    return klass;
  }

  CODE::CODE ( symbol_t name, BUFFER *bytecode, CLASS *klass )
      : _name ( name ), _klass ( klass )
  {
    _code.bc = bytecode;
    _is_native = false;
  }

  CODE::CODE ( symbol_t name, BUILTIN_FUNC *code, CLASS *klass )
      : _name ( name ), _klass ( klass )
  {
      _code.native = code;
      _is_native = true;
  }

  void
    CODE::mark ()
  {
      THING::mark ();
      mark_thing ( _klass );
  }

  CLASS *
    CODE::get_class  ()
  {
      return 0;
  }

  string
    CODE::full_name ()
  {
      string t;
      t.printf ( "%s::%s", (const char *) _klass->full_name (),
                           VM::voc [ _name ] );
      return t;
  }

    // class
  CLASS::CLASS ( const char *name, CLASS *base, PACKAGE *package )
       : instance_size ( 0 ), ctor_function ( 0 ), item_function ( 0 ),
         cast_function ( 0 ), dtor_function ( 0 )
  {
    this->instance_size = 0;
    this->base = base;
    this->package = package;
    this->name = name ? VM::voc [ name ] : undefined_symbol;

    if ( base  )
    {
      ctor_function = base->ctor_function;
      item_function = base->item_function;
      cast_function = base->cast_function;
    }

    members = new DICTIONARY ();
    if ( package )
    {
      ENTRY e = package->add ( name, ST_SDATA );
      *( e.value () ) = this;
    }
  }

  void
    CLASS::mark ()
  {
    THING::mark ();

    mark_thing ( base );
    mark_thing ( members );
    mark_thing ( package );

    mark_thing ( ctor_function );
    mark_thing ( item_function );
    mark_thing ( cast_function );
    mark_thing ( dtor_function );

  }

  VALUE
    CLASS::create_instance ()
  {
    return VALUE ( new ( ( instance_size - 1 ) * sizeof ( VALUE ) )
                       OBJECT ( this ) );
  }

  string
    CLASS::full_name ()
  {
    string s;
    if ( package )
    {
      s += package->full_name ();
      s += "::";
    }
    s += VM::voc [ name ];
    return s;
  }

  CLASS *
    CLASS::get_class  ()
  {
    return 0;
  }

#define DICT_GRAN 8

  DICTIONARY *
    DICTIONARY::create ( int size )
  {
    int gran_size = ( size / DICT_GRAN + 1 ) * DICT_GRAN - 1;
    DICTIONARY *d = new ( sizeof ( DICTIONARY::item ) * gran_size )
                        DICTIONARY ();
    d->_size = size;
    d->_allocated_size = gran_size + 1;
    for ( int i = 0; i < d->_size; i++ ) d->_items [ i ].init ();
      return d;
  }

  DICTIONARY *
    DICTIONARY::realloc ( int newsize )
  {
    if ( newsize < _allocated_size  )
    {
      _size = newsize;
      return this;
    }
    else
    {
      DICTIONARY * nd = DICTIONARY::create ( newsize );
      for ( int i = 0; i < _size; i++ ) nd->_items [ i ] = _items [ i ];
        return nd;
    }
  }

  void
    DICTIONARY::mark  ()
  {
    THING::mark ();
    for ( int i = 0; i < _size; i++ )
      _items [ i ].value.mark ();
  }

  CLASS *
    DICTIONARY::get_class ()
  {
      return 0;
  }

  ENTRY
    CLASS::add ( const char *name, int type )
  {
    ENTRY e;
    symbol_t sym = VM::voc [ name ];

    if ( members->find ( sym ) >= 0 )
      return ENTRY::undefined (); //already defined

    e.index = members->size ();
    e.klass = this;

    members = members->realloc ( e.index + 1 );
    members->_items [ e.index  ].type = type;
    members->_items [ e.index  ].symbol = sym;

    return e;
  }

  ENTRY
    CLASS::find ( const char *name )
  {
    return find ( VM::voc [ name ] );
  }

  ENTRY
    CLASS::find ( symbol_t sym )
  {
    int idx = members->find ( sym );
    if ( idx < 0 )
      return ENTRY::undefined ();

    ENTRY e;
    e.index = idx;
    e.klass = this;
    return e;
  }

  VALUE
    CLASS::get ( unsigned int idx  )
  {
    const DICTIONARY::item& item = members->get ( idx );
    assert ( item.type != ST_DATA );
    return item.value;
  }

  int
    CLASS::get_type ( unsigned int idx  )
  {
    const DICTIONARY::item& item = members->get ( idx );
    return item.type;
  }

  void
    CLASS::set ( unsigned int idx, const VALUE& v  )
  {
    DICTIONARY::item& item = members->get ( idx );
    assert ( item.type == ST_SDATA );
    item.value = v;
  }

  int
    CLASS::add_function ( const char *name, BUILTIN_FUNC *fcn  )
  {
    VALUE *v = add ( name, ST_FUNCTION ) .value ();
    symbol_t sym = VM::voc [ name ];

    assert ( v );
    CODE *c = new CODE ( sym, fcn, this );
    *v = c;
    check_name ( sym, c, ST_FUNCTION );
    return members->find ( sym );
  }

  void
    CLASS::check_name ( symbol_t ns, CODE *c, int symbol_type )
  {
    switch ( ns  )
    {
    case sym_item:
      if ( symbol_type == ST_FUNCTION )
        item_function = c;
      break;
    case sym_cast:
      if ( symbol_type == ST_SFUNCTION )
        cast_function = c;
      break;
    default:
      if ( ns == name )
        ctor_function = c;
      break;
    }
  }

  int
    CLASS::add_static_function ( const char *name, BUILTIN_FUNC *fcn  )
  {
    VALUE *v = add ( name, ST_SFUNCTION ).value ();
    symbol_t sym = VM::voc [ name ];
    assert ( v );
    CODE *c = new CODE ( sym, fcn, this );
    *v = c;
    check_name ( sym, c, ST_SFUNCTION );
    return members->find ( sym );
  }

  int
    CLASS::add_property ( const char *name, BUILTIN_FUNC *fcn  )
  {
    VALUE *v = add ( name, ST_PROPERTY ).value ();
    assert ( v );
    symbol_t sym = VM::voc [ name ];
    *v = new CODE ( sym, fcn, this );
    return members->find ( sym );
  }

  int
    CLASS::add_static_data ( const char *name, const VALUE& vd  )
  {
    symbol_t sym = VM::voc [ name ];
    VALUE *v = add ( name, ST_SDATA ).value ();
    assert ( v );
    *v = vd;
    return members->find ( sym );
  }

  int
    CLASS::add_const ( const char *name, const VALUE& vd  )
  {
    VALUE *v = add ( name, ST_CONST ).value ();
    assert ( v );
    *v = vd;
    return members->find ( VM::voc [ name ] );
  }

  int
    CLASS::add_data ( const char *name, const VALUE& /*not used so far*/ )
  {
    ENTRY en = add ( name, ST_DATA );
    if ( !en.is_valid () )
      VM::error ( "Field '%s' already defined.", (const char *) name );
    VALUE *v = en.value ();
    int n = instance_size++;
    *v = n;
    return n;
  }

  int
    CLASS::add_static_property ( const char *name, BUILTIN_FUNC *fcn )
  {
    VALUE *v = add ( name, ST_SPROPERTY ).value ();
    assert ( v );
    *v = fcn;
    return members->find ( VM::voc [ name ] );
  }

  VALUE
    CLASS::to_string ( const VALUE *v  )
  {
    VM *vm = VM::current ();
    if ( vm )
    {
      return vm->send ( *(const_cast<VALUE *> ( v ) ), sym_to_string );
    }
    else
      return "<toString() undefined>";
  }

  VALUE::VALUE ( const char *c ) : v_type ( DT_STRING  )
  {
    v.v_string = new STRING ( c );
  }

  VALUE::VALUE ( const string& s ) : v_type ( DT_STRING )
  {
    v.v_string = new STRING ( s );
  }

  void
    VALUE::mark ()
  {
    switch ( v_type & 0xF  )
    {
    case DT_CLASS:
    case DT_OBJECT:
    case DT_ARRAY:
    case DT_CODE:
    case DT_STRING:
    case DT_EXT:
      mark_thing ( v.v_thing );
      break;
    case DT_VAR:
      v.v_var.mark ();
      break;
    case DT_OBJECT_METHOD:
      v.v_om.mark ();
    }
  }

  THING *
    VALUE::ext ( CLASS *klass ) const
  {
    if ( ( v_type == DT_EXT ) && ( v.v_thing->get_class () == klass ) )
      return v.v_thing;
    return 0;
  }

  void
    VALUE::OBJECT_METHOD::mark  ()
  {
    mark_thing ( thing );
    mark_thing ( code );
  }

  VALUE::operator bool ()  const
  {
    switch ( v_type )
    {
    case DT_NULL:	return false;
    case DT_STRING: return ( v.v_string->size ()  > 0 );
    case DT_FLOAT:  return ( v.v_float != 0.0 );
    case DT_INTEGER: return ( v.v_integer != 0 );
    }
    return true;
  }

  VALUE *
    ENTRY::value ()
  {
    if ( is_valid ()  )
      return ( &klass->members->get ( index ) .value );
    return 0;
  }

  bool
    ENTRY::is_valid ()
  {
    if ( klass )
      return ( (int) index < klass->members->size () );
    return false;
  }

  int &
    ENTRY::type  ()
  {
    assert ( klass );
    return klass->members->get ( index ) .type;
  }

  symbol_t &
    ENTRY::symbol  ()
  {
    assert ( klass );
    return klass->members->get ( index ).symbol;
  }

  symbol_t
    ENTRY::symbol () const
  {
    assert ( klass );
    return klass->members->get ( index ).symbol;
  }

  void
    ENTRY::mark ()
  {
    mark_thing ( klass );
  }

  // package
  PACKAGE::PACKAGE ( const char *name, const char *src ) : CLASS ( name, 0, 0 ), init_code ( 0 )
  {
    file_name = src? new STRING ( src ) : 0;
    literals = new ARRAY ( 0 );
  }

  // package
  PACKAGE::PACKAGE ( symbol_t t ) : CLASS ( t ), init_code ( 0 )
  {
    file_name = 0;
    literals = 0;
  }

  void
    PACKAGE::mark ()
  {
    CLASS::mark ();
    mark_thing ( literals );
    mark_thing ( file_name );
    mark_thing ( init_code );
  }

  int
    PACKAGE::add_literal ( const char *vs  )
  {
    size_t len = strlen ( vs );
    for ( int i = 0; i < literals->size (); i++  )
    {
      VALUE& v = ( *literals ) [ i ];
      if ( v.v_type == DT_STRING )
        if ( CSTR ( v.v.v_string ) == vs )
          return i;
    }

    return literals->push ( VALUE ( new STRING ( vs ) ) );
  }

  int
    PACKAGE::add_literal ( symbol_t vs  )
  {
    for ( int i = 0; i < literals->size (); i++  )
    {
      VALUE& v = ( *literals ) [ i ];
      if ( v.v_type == DT_SYMBOL && v.v.v_symbol == vs )
        return i;
    }

    VALUE v;
    v.set_symbol ( vs );
    return literals->push ( v );
  }

  int
    PACKAGE::add_literal ( const VALUE& vv  )
  {
    for ( int i = 0; i < literals->size (); i++  )
    {
      VALUE& v = ( *literals ) [ i ];
      if ( vv == v )
        return i;
    }

    return literals->push ( vv );
  }

  bool
    PACKAGE::has_reference_to ( symbol_t package_symbol )
  {
    for ( int i = 0; i < literals->size (); i++  )
    {
      VALUE& v = ( *literals ) [ i ];
      if ( v.v_type == DT_CLASS &&
           v.v.v_class->get_package ()  == 0 && // this is a package
           v.v.v_class->name == package_symbol  )
        return true;
    }
    return false;
  }

};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -