In object-oriented programming class is a set (a transitive closure) of types bound by the relation of inheritance. It is said that all types derived from some base type T and the type T itself form a class T.

The first type T from the class T sometimes is called the root type of the class.

A class of types itself, as a type, has the values and operations of its own.
The operations of are usually called methods of the root type.
Both operations and values are called  polymorphic.

A polymorphic operation (method) selects an implementation depending on the actual specific type of the polymorphic argument.

The action of choice the type-specific implementation of a polymorphic operation is called dispatch. Correspondingly, polymorphic operations are often called dispatching or virtual.
Operations with multiple arguments and/or the results of the class are called multi-methods.
A further generalization of is the operation with arguments and/or results from different classes.

 single-dispatch languages are those that allow only one argument or result to control the dispatch. Usually it is the first parameter, often hidden, so that a prefix notation x.f() is used instead of mathematical f(x).
 multiple-dispatch languages allow many arguments and/or results to control the dispatch.


A polymorphic value has a type tag indicating its specific type from the class and the corresponding specific value of that type.
This type is sometimes called the most specific type of a [polymorphic] value.
The type tag of the value is used in order to resolve the dispatch.
The set of polymorphic values of a class is a transitive closure of the sets of values of all types from that class.

In many  OO languages
the type of the class of T and T itself are considered equivalent.
In some languages they are distinct (like in Ada).
When class T and T are equivalent, there is no way to distinguish
polymorphic and specific values.



Task

Create a basic class with a method, a constructor, an instance variable and how to instantiate it.




 
option casemap:none
 
ifndef __SOMECLASS_CLASS__
__SOMECLASS_CLASS__   equ 1
 
  ;; Once again, HeapAlloc/Free is REQUIRED by the class extention for windows.
  ;; Malloc/Free are used by Linux and OSX. So the function prototypes have to
  ;; be defined somewhere. If you have include files where they're defined, just
  ;; include them in the usual way and remove the option dllimports.
  if @Platform eq 1             ;; Windows 64
    ;; include windows.inc
    ;; includelib kernel32.lib
    option dllimport:<kernel32>
      HeapAlloc       proto :qword, :dword, :qword
      HeapFree        proto :qword, :dword, :qword
      ExitProcess     proto :dword
      GetProcessHeap  proto
    option dllimport:none
      exit            equ ExitProcess
  elseif @Platform eq 3         ;; Linux 64
    ;;include libc.inc
    malloc            proto SYSTEMV :qword
    free              proto SYSTEMV :qword
    exit              proto SYSTEMV :dword
  endif
 
  printf              proto :qword, :VARARG
 
  CLASS someClass
    CMETHOD someMethod
  ENDMETHODS
    var dd ?
  ENDCLASS
 
  ;; The OS' ABI has an effect on this class extention. That is, the class self pointetr
  ;; is usually refferenced in the first arg register. So for Windows it would be rcx and
  ;; Linux would be rdi. So to write code that will assemble on both we use a register
  ;; that ISN'T used to pass arguments in either ABI(Not sure about OSX's ABI however)
  METHOD someClass, Init, <VOIDARG>, <>, a:dword
    mov rbx, thisPtr
    assume rbx:ptr someClass
    mov [rbx].var, a
    mov rax, rbx
    assume rbx:nothing
    ret
  ENDMETHOD
 
  METHOD someClass, someMethod, <dword>, <>
    mov rbx, thisPtr
    assume rbx:ptr someClass
    mov eax, [rbx].var
    assume rbx:nothing
    ret
  ENDMETHOD
 
  METHOD someClass, Destroy, <VOIDARG>, <>
    ret
  ENDMETHOD
endif                         ;; __CLASS_CLASS_
 
.code
main proc
  local meh:ptr someClass
  ;; Create a new instance of someClass with an arg of 7
  mov meh, _NEW(someClass, 7)
  meh->someMethod()              ;;Get meh->var value and return it in RAX
  invoke printf, CSTR("class->someMethod = %i",10), rax
  _DELETE(meh)                   ;; DIIIIIIIE!
  invoke exit, 0                 ;; Crashy crashy without it.
  ret
main endp
 
end
 