Qwerrdy

Nice idea, would you want to be able to change the 'THIS' ptr if needed, what I mean is ...



.INLINE Blah, [argList]
.THIS ebx
; do something
.THIS edx
; do something
ENDM


or would setting it once at the top be sufficient?

If so, I should be able to modify the .INLINE macro like this ...



.INLINE Blah, ebx, [argList]
; do something
ENDM


bitRAKE

I understand what you mean, I had a similar thought. Do you prefer your suggestions syntax to that of the original syntax?



; original syntax
.CTEST ebx, Method, [argList]

; bitRAKES
.ebx CTEST, Method, [argList]


Your syntax does reduce the number of equates as you say and doesn't effect calling methods via name.



.m_test Method, [argList]


Keep the feedback coming guys.

EDIT

You also asked above if the methods could all be inline, I was tossing around the idea of a PURE interface class. The interface would have no substance, wouldn't need to be created or destroyed, wouldn't contain any data, but would be made up entirely of inline methods. Since no physical object exists, there'd be no need for a 'THIS' ptr so inline methods should be a little more robust. The interface could still use inheritance but would lack polymorphic behaviour.

Your thoughts ?

:alright:
Maelstrom
Posted on 2002-10-17 20:50:51 by Maelstrom
Both methods could be provided as options?

Just thought to mention, THIS is an MASM keyword!

Create_A_Label EQU THIS QWORD

BYTE 8 dup(55)

movq mm0, Create_A_Label
Posted on 2002-10-17 22:34:32 by bitRAKE
BitRAKE - Would that mean you can't use .THIS either? Wouldn't the dot make it valid?

I prefer the .THIS variant, the one with the register in the .INLINE may be shorter but it might be confused with a "uses" directive in a normal proc. Moving the this pointer into multiple registers might be a added bonus, but I wouldn't miss it if you don't want to implement it. If you do, perhpas you could add a ".THIS nothing" to clean up the last "assume" (I'm assuming here you do a "assume reg:ptr MYCLASS" on the THIS register)

Lol @ all the assumes in that last sentence :)
Posted on 2002-10-18 07:46:49 by Qweerdy
If look at his files, he disables THIS as a keyword.

BitRAKE, from your thread of seldom use MASM directive, you listed and alternate from equivilent to THIS.
Posted on 2002-10-18 09:57:12 by ThoughtCriminal
bitRAKE

Yes I know THIS is a keyword but as ThoughtCriminal pointed out I disable it.

Is the THIS keyword really used that much? Doesn't LABEL do the same thing?

I suppose to eliminate any protential conflicts I could rename 'this', any suggestions ( t, pthis, @this )

I've decided to adopt the .ebx syntax for 2 reasons, consistancy and less equates required. I won't however support both calling conventions, no need to complicate matters any further.

Qweerdy

The dot makes .THIS okay

I prefer the .THIS variant, the one with the register in the .INLINE may be shorter but it might be confused with a "uses" directive in a normal proc


Oh, I didn't think of that, I'll see if I can get the .THIS option working today. Using .THIS would be more consistant since the static/virtual methods already have a .THIS macro to change their 'this' ptr

Yes you .ASSUME correctly :tongue:

Keep the feedback coming guys!

:alright:
Maelstrom
Posted on 2002-10-18 18:24:16 by Maelstrom
Okay guys lend me your opinions

At present we can create objects and access their methods as shown



.CREATE ebx, CTEST, [args]
.NEW ebx, CTEST, [args]

.ebx CTEST, method, args

; and

.CREATE m_test, CTEST, [args]
.NEW m_test, CTEST, [args]
.LOCAL m_test, CTEST, [args]

.m_test method, args


When using .ASSUME you can access methods as shown



.ASSUME ebx, CTEST, edx
.ASSUME ebx, CTEST, m_test
.ASSUME ebx, CTEST, struct.m_render ; structure reference ( must be a ptr )
.ASSUME ebx, CTEST, [this].m_render ; embedded/referenced objects
.ASSUME ebx, CTEST, g_app.m_render ; embedded/referenced objects

.ebx CTEST, method, args


Would you like to be able to access methods using a name like you can when creating objects?
If so, should the data name ( m_test ) and the name after the dot ( .m_render ) be used as default?



.m_test method, args
.m_render method, args


Also would you like the ability to generate a custom name?



.ASSUME ebx, CTEST, esi, TEST
.ASSUME ebx, CTEST, m_test, TEST

.TEST method, args


Qweerdy

I've implemented the .THIS system for inline methods, but what a pain in the butt :grin:
I've only tested it quickly so there could still be some problems.



.INLINE method, [args]
.THIS ebx
mov eax, blah
.this method, args
mov [this].m_blah, blah

.THIS edi
mov ebx, [this].m_blah
ENDM


Is the small case .this, used to invoke methods from the current class, confusing? Does it need to be renamed as asked in my previous post?

Keep the feedback coming guys

:alright:
Maelstrom
Posted on 2002-10-18 22:23:14 by Maelstrom
The MASM keyword THIS has functionality beyond LABEL.
mov eax, OFFSET (THIS BYTE)
;)
I'm not saying you need to change the name - I've never seen the keyword used outside examples of what it can be used for, but it is good to be aware of conflict and to note it in the documentation. That is the only reason I mentioned it.

Personally, I don't see a need to add custom names as a integrated feature - what is wrong with EQU?
Posted on 2002-10-19 00:53:07 by bitRAKE
I'm just eager when we can finally use it?


Thanks,
_Shawn
Posted on 2002-10-19 00:58:13 by _Shawn
I'm still not completely happy with inline methods, but they're a lot safer than they were. I don't think I'll do much more with them since they're starting to mess up the framework. I'll hopefully be able to iron these out with a preprocesser I want to write, should be able to eliminate a lot of problems and limitations.

Slightly off topic, can someone tell me how to write a preprocessor or direct me to some resources/examples?

bitRAKE

The main reason I thought of custom names was the situation where your working with different classes each containing an embedded/referenced object of the same name.



.ASSUME ebx, CLASSA, [this].m_bugger
.ASSUME edx, CLASSB, [this].m_bugger

; the second .ASSUME would overwrite the .m_bugger equate generated by the first .ASSUME
; using custom names would solve this problem

.ASSUME ebx, CLASSA, [this].m_bugger, buggerA
.ASSUME edx, CLASSB, [this].m_bugger, buggerB

; you can also disable name generation

.ASSUME ebx, CLASS, blah, NONE


Wonder if disabling name generation should be made a global feature?

_Shawn

Glad to see some anticipation, hoping to release it real soon.

:alright:
Maelstrom
Posted on 2002-10-19 04:52:47 by Maelstrom

Slightly off topic, can someone tell me how to write a preprocessor or direct me to some resources/examples?
Might want to take a look at Jibz's byte scanner code...
http://www.asmcommunity.net/board/index.php?topic=6832&highlight=scanner
Posted on 2002-10-19 22:37:52 by bitRAKE
Drum roll please ..........

It's finally here, version 1.00 of my OOP framework.

I thank everyone for their feedback and suggestions so far, keep it coming.

The framework has been tested with simple stuff ( I'm not as good a coder as you guys ) and it works ( crosses fingers, throws salt over shoulder, knocks on wood :grin: ).
bitRAKE with probably take his scaple to it has reduce it to a third of its size and make it twice as fast and leave me wondering how the hang he did it :grin:

The next step is a preprocessor to eliminate the inline problems.

=================================

The ZIP includes the following

Class.inc - the framework
Class.txt - my attempt at documentation

Common.inc - my common macros used by the framework

CInterface.inc - the base class of all objects
CInterfaceRelease.asm

You'll have to do some editing of the framework to replace my function calls with the equivalent functions you use. Theres only a couple to change, just do a search for 'ADL_' to find them.

=================================

I hope it was worth the wait and is useful to someone.

Please post any bugs, suggestions, and opinions.

:alright:
Maelstrom
Posted on 2002-10-20 18:46:03 by Maelstrom
Does this syntax look okay so far?
.CLASS Tree_Node_Simple


key DWORD ? ; unique value
data DWORD ? ; object satelite data
left DWORD ? ; left child node
right DWORD ? ; right child node
parent DWORD ? ; parent node

.STATIC Successor
.STATIC Predecessor


.INLINE Minimum, dest:=<eax>, src:=<edx>
LOCAL _0, _1

.THIS src
xor dest, dest
jmp _1

_0: mov dest, this
mov this, [this].left
_1: test this, this
jne _0

ENDM


.INLINE Maximum, dest:=<eax>, src:=<edx>
LOCAL _0, _1

.THIS src
xor dest, dest
jmp _1
_0: mov dest, this
mov this, [this].right
_1: test this, this
jne _0

ENDM

.ENDC
Actually, this wouldn't work, but I don't know how to fix it just yet...
.CLASS Binary_Search_Tree


root Tree_Node PTR ?


.STATIC Constructor, 2
.STATIC Inorder_Walk, 1 ; this syntax isn't very self-documenting (one what?)
.STATIC Search
.STATIC Insert
.STATIC Delete

.VIRTUAL Compare, 2, PURE

.ENDC
I would like to create a tree class that is independant of the type of nodes in the tree - all nodes would need a left, right & parent of course. Then I would like to create node classes that are independant of the data they contain. There is a comparison function for each type of data. Ideally, the comparison function and type of node should be specified when creating a tree. How would this look syntaxwise? I have all the code - just need to fix it into this model.
Posted on 2002-10-20 22:06:48 by bitRAKE
bitRAKE

When you say the Tree_Node_Simple didn't work, do you mean you got a 'method not found' error when calling the inline methods :confused:

If so, you have the honor of finding a :eek: BUG :eek: when defining inlines with default values. The number of arguments is used as part of the method name, so when you call an inline with default values and pass no args, the generated name is wrong. The default functionality was added when each method had a unique name. Quick fix is to manually pass all arguments. I will see if I can fix it while retaining the default value functionality.

If not, I need more info.

I never actually thought of using LOCALs in the inline method, seems so obvious now. NICE :alright:

I do have to agree with you about the argument count not being very descriptive. It's no help if you want something other than a DWORD argument either. I'm going to change it back to normal for the preprocessor.


I would like to create a tree class that is independant of the type of nodes in the tree - all nodes would need a left, right & parent of course. Then I would like to create node classes that are independant of the data they contain. There is a comparison function for each type of data. Ideally, the comparison function and type of node should be specified when creating a tree. How would this look syntaxwise? I have all the code - just need to fix it into this model.


Sorry, you've lost me a little, tell me if I understand correctly.

1. You want a tree class that is not restricted to a specific node type? Can handle different node types
2. You want node classes that point to the data rather than encapsulating it?
3. You want to specify the comparison method and node type when you instance the tree?

Are all the comparison functions in the tree class?
Once created will the tree contain only one data type?

:alright:
Maelstrom
Posted on 2002-10-21 01:19:44 by Maelstrom

1. You want a tree class that is not restricted to a specific node type? Can handle different node types
2. You want node classes that point to the data rather than encapsulating it?
3. You want to specify the comparison method and node type when you instance the tree?

4. Are all the comparison functions in the tree class?
5. Once created will the tree contain only one data type?
Firstly, I haven't actually created any test classes - all my comments are suppositions based on what I have read thus far. In the next couple of days I'd like to finish some example classes to include with the macros. IMHO, it seriously needs some examples to help make it's usefullness more abundantly clear (especially to the OOP sceptics). ;)

1. yep
2. yep
3. yep
4. Only tree methods are in each type of tree. Only node specific methods are in each node, but tree methods will require executing node methods. The comparison is external because the same type of node can contain different data and even the same data can be sorted differently. Only tree methods will execute comparisons of nodes.
5. Yes, trees are homogenious with respect to the type of nodes and sort method, but none of the tree or node methods access the data - comparison does and that is another reason it is external. The data could be looked at as being another object with a comparison method, but I don't want to use an object for the data because of the overhead - I just want the ease of use of a tree data types.

Hope that makes it more clear. I'm very curious of how you would implement this with the macros and it should provide all the documentation I need to convert many algorithms into this object format. I just worked on it for an hour last night and will continue into the week as time allows. My interesting is in trying to maintain the speed of the code and helping others to understand algorithms through asm.

Great work BTW! I'm not going to fiddle with the macros until I have some solid test cases to ensure I don't break anything, but what I've read over so far looks very good. :alright:
Posted on 2002-10-21 19:45:38 by bitRAKE
Some examples would be great, thanks bitRAKE :alright:

Bear with me, I've never coded a binary search tree before, but based on your post, maybe something like this.




; CTREENODE is the base class for ALL tree node types
; All common data and methods required by the tree nodes should reside in this class

.CLASS CTREENODE

m_id dd ?
m_left dd ?
m_right dd ?
m_parent dd ?
m_data dd ?

; node methods

.ENDC

; CTREE is the base class for ALL tree types
; All common data and methods required by the tree should reside in this class

.CLASS CTREE

m_compare FUNCT2_PTR ?

.OBJECT m_root, CTREENODE, PTR

.STATIC Constructor, 2

.INLINE Compare, src:=<edx>, arg1, arg2
.THIS src
invoke (CTREE PTR [this]).m_compare, arg1, arg2
ENDM

.ENDC

.METHOD CTREE, Constructor, _cmpfunct, _ntype

.ENTER

.SUPERCLASS this, CTREE, Constructor

push _cmpfunct
pop [this].m_compare

.RET

.ENDM



Some way of overwriting a virtual ptr would be useful in a situation like this and would clean up the code as well.
A useful addition to the framework ?




.CLASS CTREE

.OBJECT m_root, CTREENODE, PTR

.STATIC Constructor, 2

.VIRTUAL Compare, 2, PURE

.ENDC

.METHOD CTREE, Constructor, _cmpfunct, _ntype

.ENTER

.SUPERCLASS this, CTREE, Constructor

.OVERLOAD this, CTREE, Compare, _cmpfunct

.RET

.ENDM



Something I forgot to ask, you said you want to specify the tree node type when you instance the tree, will the tree be responsible for creating the tree nodes?

The tree node methods that the tree must have access to, can be static/inline if they're generic, otherwise they'll have to be virtual so all nodes have the same interface. The external compare function would be the only function to be able to access the tree nodes type dependant methods.

With regards to fiddling the macros, I can post the simple filter proggy I wrote to view the macro output if you like. It filters the EP compiler switch output, eliminating most of the rubbish.

Am I close or am I sucking on my foot? :grin:

:alright:
Maelstrom
Posted on 2002-10-22 01:06:04 by Maelstrom
You seem to be right on track - trees are indeed going to be creating nodes. It would be real hard to prune the tree if we allowed nodes from different memory sources (ie stack and heap) to reside in the same tree - de-allocate the memory and all the node pointers become invalid. De-/Allocation of nodes will be part of the Insert and Delete methods in the tree class.

Sorry, I have not explained more. The thing is, as the code stands now, it was never designed with OOP in mind - it's just a lump of code with very minor structure to keep data and nodes and tree contained with minor cohesion between them. Like when I originally wrote it, I have more of a subconscious idea of what it is rather than a detailed map - meaning it has the consistancy of my mushy skull filling. OOP would serve to document those high-level relationships between code blobs.

Yeah, please post - that filter should provide another means to debug macros. I currently write messages to the screen using ECHO. This works good once you understand that MASM processes strings during assignment - this can have the effect of stripping spaces, " and <> from the strings.

You could do what I do: I always say I'm just chewing on my toe nail - I know it's hard to believe when only the heel can be seen sticking out of my mouth.
Posted on 2002-10-22 14:06:39 by bitRAKE
I'm just chewing on my toe nail - I know it's hard to believe when only the heel can be seen sticking out of my mouth.


:grin: ROFL :grin:

trees are indeed going to be creating nodes


Now your getting tricky.

My linked list Add() method recieves a pointer to a node that's created by the caller. When instancing the linked list you pass a user defined function which is responsible for destroying the node, adding it to a node cache, or whatever you want to do with the node once its removed from the list. I suppose I could also pass a user defined method which is responsible for creating the nodes. This would mean that all the nodes for the list are created the same way.

Maybe something similar could work here?

:alright:
Maelstrom
Posted on 2002-10-22 22:09:35 by Maelstrom
Doh!

I forgot the attachment

Pipe MASMs /EP compiler switch output to a file and pass that file to the filter

EPF /I:input filename /O:output filename

:alright:
Maelstrom
Posted on 2002-10-22 22:17:51 by Maelstrom

Now your getting tricky.
Not really. The way I see it the tree is just a structure for holding data. The only communication I want between the tree and the rest of the program is to send pointers to the data being stored/deleted/found. What benifit is there to building the node externally and then passing that pointer to the tree? ...or passing both a data pointer and a node pointer to the tree? The method you mention would be good to reuse the tree code. I really don't know - lets see how they work in use. :)
Posted on 2002-10-22 22:29:18 by bitRAKE
Okay, this is where my experience evaporates.

How can we tell a CTREE class to create nodes of type CTREENODE_A without the tree class knowing something about the node type?



.NEW tree, CTREE, ADDR cmpFunct_A, CTREENODE_A

.tree Insert, blah
.tree Delete, blah


It love the idea, it's nice and clean, but I have no idea how to implement it?

Could the tree class contain private creation methods for each node type? The equate sent to the constructor could be used to setup a pointer to the appropriate method. You'd be forced to add another method to the tree class everytime you created a new tree node class tho.

What about a generic tree node class? err, kinda defeats the purpose doesn't it.

We need something like a C++ template class, just define the data type and presto, all done.

I'm sinking faster than tonights dinner ... :confused:

edit

What about having each tree node class define its own creation function ( non-method ). Then you could pass the compare & create function ptrs to the tree constructor.



.NEW tree, CTREE, ADDR cmpfunct, ADDR CTREENODE_A_New


:alright:
Maelstrom
Posted on 2002-10-23 00:11:45 by Maelstrom