mircscripting.info Forum Index mircscripting.info
#mIRCscripting Forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

OOP (Object oriented programming)

 
Post new topic   Reply to topic    mircscripting.info Forum Index -> Addons
View previous topic :: View next topic  
Author Message
darkrift
Quite Active


Joined: 22 Oct 2005
Posts: 33
Location: Quebec/Canada

PostPosted: Sun Dec 20, 2009 3:34 pm    Post subject: OOP (Object oriented programming) Reply with quote

This topic is about the snippet/addon of Yochai's OOP script.

While waiting for yochai post, here are some of my classes (AVL is not finished so it's a merely first try on doing AVL trees)

http://rlavoie.gotdns.org:81/msl/darkrift_class.zip (class script is included but it's an old version, works for my classes tho for the moment)

I'll improve some and add a few soon
Back to top
View user's profile Send private message
yochai



Joined: 20 Dec 2009
Posts: 1

PostPosted: Mon Dec 21, 2009 2:54 am    Post subject: Reply with quote

I've made an API to allow scripters to write in an oop like syntax.

The main reason why i started this project, is that it's difficult and messy to create large databases in mIRC. (I had a script that stored like 15000 items of data)
Then i thought of other programing languages, and realized that most of the storage i need can be implemented in even simple classes.
So, i decided to make an API that lets you design classes with methods of and members with a fixed syntax, so I could design my databases easier.

The script handles the object creation and storage, which means you can make your own databases easily.
Classes are set up as constructors, which are called automatically each time you call $NewObject(classname) .
I got a simple inheritance system which allows you to inherit any number of other classes, while the methods act as virtual at the moment, at least until i implement encapsulation.

Example of the syntax, a simple stack database:

Code:
alias class_container {
   classmember data = $1
   classmember next = $2
}
alias class_stack {
   classmember first = 0
}
alias class~stack {
   while ($this().first) { var %temp = $this().pop() }
}
alias stack::push {
   var %new = $NewObject(container,$1,$this().first)
   Object $this first = %new
}
alias stack::pop {
   var %first = $this().first 
   if (!%first) return 0
   Object $this first = $this().first.next
   var %data = $Object(%first).data
   FreeObject %first
   return %data
}
;OK, now that the hard part is done, we can use the stack with ease.
alias example {
   set %stack $NewObject(stack)
   noop $Object(%stack).push(World)
   noop $Object(%stack).push(Hello)
   echo -a $Object(%stack).pop()
   echo -a $Object(%stack).pop()
   Freeobject stack
}




Just wanted to thank DarkRift again for the help and ideas he's given.

Here's the latest version:
http://www.mediafire.com/?ymommhoh0nn
Back to top
View user's profile Send private message
darkrift
Quite Active


Joined: 22 Oct 2005
Posts: 33
Location: Quebec/Canada

PostPosted: Sat Dec 26, 2009 12:20 pm    Post subject: AVL tree Reply with quote

for those who know about tree, I finished coding the core of an AVL tree class (I still have some work to do on the iterator side, but the parsing through end works, I only need to finish the == part for other iterators)


The only operators you need to declare when you create a class to be able to use this class with yours, are the operator== and operator< to be able to make them go at the right place in the subtrees.

here's the code:
Code:

; example: $newobject(avl,int)
alias class_AVL {
  classmember root = 0
  classmember type = $$1
  classmember end = $newobject(avl::iterator::item, $null)
}

alias AVL::max {
  if ($1 == $null) {
    return $object($this).max( [ $+ [ $this().root ] $+ ] )
  }
  ;$assert($1 != 0, $script, $scriptline)
  var %p = $1

  while ($object(%p).right != 0) {
    %p = $object(%p).right
  }

  return $object(%p).data
}



alias AVL::min {
  if ($1 == $null) {
    return $object($this).min( [ $+ [ $this().root ] $+ ] )
  }
  ;$assert($1 != 0, $script, $scriptline)
  var %p = $1

  while ($object(%p).left != 0) {
    %p = $object(%p).left
  }

  return $object(%p).data
}

alias class~AVL {
  $this().empty()
  freeobject $this().end
}

alias AVL::find {
  if ($0 == 1) {
    return $this().find( [ $+ [ $1 ] $+ ] , [ $+ [ $this().root ] $+ ] )
  }
  else {
    if ($2 == 0) return 0
    else if ($object($2).data.operator==( [ $+ [ $1 ] $+ ] ) ) {
      return $object($2).data
    }
    elseif ($object($2).data.operator<( [ $+ [ $1 ] $+ ] ) ) {
      return $this().find( [ $+ [ $1 ] $+ ] , [ $+ [ $object($2).left ] $+ ] )
    }
    else {
      return $this().find( [ $+ [ $1 ] $+ ] , [ $+ [ $object($2).right ] $+ ] )
    }
  }
}

alias AVL::insert {
  if ($classtype($1) != $this().type) {
    $assert($iif($classtype($1) != $null,$v1,$!null) == $!this().type, $script, $scriptline)
  }
  if ($this().root == 0) {
    object $this root = $newobject(AVLnode,$1)
    return $true
  }

  if ($0 == 1) {
    return $this().insert( [ $+ [ $1 ] $+ ] , [ $+ [ $this().root ] $+ ] ,0)
  }
  else {
    if ($2 == 0) {
      object $3 $4 = $newobject(AVLnode,$1)
      return $true
    }

    ; if the element is already inserted, return false in the recursive return ...
    if ($object($1).operator==( [ $+ [ $object($2).data ] $+ ] )) return $false
    elseif ($object($1).operator<( [ $+ [ $object($2).data ] $+ ] )) return $this().addLeft( [ $+ [ $1 ] $+ ] , [ $+ [ $2 ] $+ ] , [ $+ [ $3 ] $+ ] )
    else return $this().addRight( [ $+ [ $1 ] $+ ] , [ $+ [ $2 ] $+ ] , [ $+ [ $3 ] $+ ] )
  }
}

alias AVL::addLeft {
  var %pr = $iif($3 == 0, $this().root, $2)
  var %r = $this().insert( [ $+ [ $1 ] $+ ] , [ $+ [ $object($2).left ] $+ ] , [ $+ [ %pr ] $+ ] ,left)
  if (%r) {
    inco $2 equil 1
    var %p = $object($2).equil
    if (%p == 0) return $false
    if (%p == 1) return $true
    if ($object($2).left.equil == -1) {
      noop $this().rotateLeft( [ $+ [ $object($2).left ] $+ ] , [ $+ [ $2 ] $+ ] ,left)
    }
    noop $this().rotateRight( [ $+ [ $2 ] $+ ] , [ $+ [ $3 ] $+ ] ,left)
  }
  return $false
}

alias AVL::addRight {
  ; $1 = object to add
  ; $2 = node to insert into
  ; $3 = parent node

  var %pr = $iif($3 == 0, $this().root, $2)
  var %r = $this().insert( [ $+ [ $1 ] $+ ] , [ $+ [ $object($2).right ] $+ ] , [ $+ [ %pr ] $+ ] ,right)
  if (%r) {
    deco $2 equil 1
    var %p = $object($2).equil
    if (%p == 0) return $false
    if (%p == -1) return $true
    ; here the equil factor is -2

    if ($object($2).right.equil == 1) {
      noop $this().rotateRight( [ $+ [ $object($2).right ] $+ ] , [ $+ [ $2 ] $+ ] ,right)
    }

    noop $this().rotateLeft( [ $+ [ $2 ] $+ ] , [ $+ [ $3 ] $+ ] ,right)
  }
  return $false
}

alias AVL::rotateRight {
  ; $1 = child node
  ; $2 = parent node
  ; $3 = parent node subtree

  var %temp = $object($1).left

  var %ia = $iif(%temp == 0, 0, $object(%temp).equil)
  var %ib = $object($1).equil
  var %negia = $calc(-1 * %ia)
  var %nib = $calc(%negia - $max(0, %negia) -1 + %ib)
  var %nia = $calc(%ia - $max(0, $calc(-1 * %nib)) -1)

  object %temp equil = %nia
  object $1 equil = %nib

  object $1 left = $object(%temp).right

  if ($2 == 0) {
    object %temp right = $this().root
    object $this root = %temp
  }
  else {
    object %temp right = $1
    object $2 $3 = %temp
  }

}

alias AVL::rotateLeft {
  ; $1 = node to rotate to the left
  ; $2 = parent node
  ; $3 = side on the parent node to rotate

  var %temp = $object($1).right

  var %nia = $object($1).equil
  var %nib = $object($1).right.equil
  var %negib = $calc(-1 * %nib)
  var %ia = $calc(%nia + $max(0,%negib) + 1)
  var %ib = $calc(%nib + %ia + $max(0, $calc(-1 * %ia)) +1)

  object %temp equil = %ia
  object $1 equil = %ib

  object $1 right = $object(%temp).left

  if ($2 == 0) {
    object %temp left = $this().root
    object $this root = %temp
  }
  else {
    object %temp left = $1
    object $2 $3 = %temp
  }

}


alias max {
  return $iif($1 > $2, $1, $2)
}

alias AVL::empty {
  if ($1 == $null) {
    $this().empty( [ $+ [ $this().root ] $+ ] )
  }
  else if ($1 != 0) {
    $this().empty( [ $+ [ $object($1).left ] $+ ] )
    $this().empty( [ $+ [ $object($1).right ] $+ ] )

    freeobject $1
  }
}

/*
alias AVL::inordre {
  if ($1 == $null) {
    noop $this().inordre( [ $+ [ $this().root ] $+ ] )
  }
  else {
    if ($object($1).left) noop $this().inordre( [ $+ [ $object($1).left ] $+ ] )
    echo -a $object($1).data $object($1).data.data
    if ($object($1).right) noop $this().inordre( [ $+ [ $object($1).right ] $+ ] )
  }
}
*/


alias class_AVLnode {
  classmember data = $iif($1,$1,0)
  classmember left = 0
  classmember right = 0
  classmember equil = 0
}




/*
******************************************************************
*/

alias class_AVL::iterator {
  classmember stack = $newobject(deque)
  classmember AVL = $1

}

alias class~AVL::iterator {
  ;hlist
  while ($this().stack.empty() == $false) {
    var %item = $this().stack.pop_front()
    echo -a !! %item
    freeobject %item
  }
  hlist
}

alias class_AVL::iterator::item {
  classmember data = $1
}

alias AVL::begin {
  var %i = $newobject(AVL::iterator,$this)
  $object(%i).stack.push_front( [ $+ [ $this().end ] $+ ] )
  var %item = $this().root
  while (%item != 0) {
    $object(%i).stack.push_front( [ $+ [ $newobject(AVL::iterator::item, %item) ] $+ ] )
    %item = $object(%item).left
  }
  return %i
}

alias AVL::iterator::operator++ {
  if ($this().stack.empty() == $false) {
    var %t = $this().stack.pop_front()
    if ($object(%t).data.right != 0) {
      var %item = $object(%t).data.right
      while (%item != 0) {
        $this().stack.push_front( [ $+ [ $newobject(AVL::iterator::item, %item) ] $+ ] )
        %item = $object(%item).left
      }
    }
  }
}

alias AVL::iterator::dereference {
  return $this().stack.front().data.data
}

alias AVL::end {
  return $this().end
}

alias AVL::iterator::operator== {
  if ($this().stack.front().data == $1) return $true
  return $false
}

/*
******************************************************************
*/



if you want a testing alias to see the result here it is:

it adds 7 ints (with the use of int class):

here's int first:
Code:

; example : var %a = $newobject(int,1)
alias class_int {
  classmember data = $1
}

alias int::operator== {
  if ( $this().data == $object($1).data ) return $true
  return $false
}

alias int::operator< {
  if ($this().data < $object($1).data ) return $true
  return $false
}


now the testing part:

Code:

alias AVLtest {
  clear
  var %a = $newobject(AVL,int)
  var %i = 1
  var %i1 = $newobject(int,1)
  var %i2 = $newobject(int,2)
  var %i3 = $newobject(int,3)
  var %i4 = $newobject(int,4)
  var %i5 = $newobject(int,5)
  var %i6 = $newobject(int,6)
  var %i7 = $newobject(int,7)


  while (%i <= 7) {
    var %t =  %i [ $+ [ %i ] ]
    echo -a ! Insert %i ! $object(%a).insert( [ $+ [ %t ] $+ ] )
    inc %i
  }

  echo -a !! Root: $object(%a).root.data
  var %min = $object(%a).min()
  echo -a !! Min: %min $object(%min).data
  var %max = $object(%a).max()
  echo -a !! Max: %max $object(%max).data

  echo -a Schema
  echo -a $str($chr(160),6) $+ $object(%a).root.data.data
  echo -a $str($chr(160),6) $+ $object(%a).root.equil
  echo -a $str($chr(160),2) $object(%a).root.left.data.data $+ $str($chr(160),5) $+ $object(%a).root.right.data.data
  echo -a $str($chr(160),2) $object(%a).root.left.equil $+ $str($chr(160),5) $+ $object(%a).root.right.equil
  echo -a $str($chr(160),1) $object(%a).root.left.left.data.data $object(%a).root.left.right.data.data $str($chr(160),1) $object(%a).root.right.left.data.data $object(%a).root.right.right.data.data
  echo -a $str($chr(160),1) $object(%a).root.left.left.equil $object(%a).root.left.right.equil $str($chr(160),1) $object(%a).root.right.left.equil $object(%a).root.right.right.equil


  var %it = $object(%a).begin()
  var %end = $object(%a).end()
  while (!$object(%it).operator==( [ $+ [ %end ] $+ ] ))  {
    echo -a !ITERATOR! $object(%it).dereference().data.data
    object %it ++
  }

  freeobject %a
  freeobject %i1 
  freeobject %i2
  freeobject %i3
  freeobject %i4
  freeobject %i5
  freeobject %i6
  freeobject %i7
  freeobject %it
}

Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    mircscripting.info Forum Index -> Addons All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group