 |
mircscripting.info #mIRCscripting Forum
|
| View previous topic :: View next topic |
| Author |
Message |
darkrift Quite Active
Joined: 22 Oct 2005 Posts: 33 Location: Quebec/Canada
|
Posted: Sun Dec 20, 2009 3:34 pm Post subject: OOP (Object oriented programming) |
|
|
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 |
|
 |
yochai
Joined: 20 Dec 2009 Posts: 1
|
Posted: Mon Dec 21, 2009 2:54 am Post subject: |
|
|
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 |
|
 |
darkrift Quite Active
Joined: 22 Oct 2005 Posts: 33 Location: Quebec/Canada
|
Posted: Sat Dec 26, 2009 12:20 pm Post subject: AVL tree |
|
|
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 |
|
 |
|
|
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
|