Эмуляция объектов на скриптах. Добавлено наследование классов.
Реализация:
Object.ms.dict
Тест:
Object.ms.script
Запись Object2 class Object3 - описывает Object3 наследующийся от Object2.
Реализация:
Object.ms.dict
UNIT Object.ms.dict
USES
Bind.ms.dict
;
EXPORTS
Bind.ms.dict
USES
core.ms.dict
macro.ms.dict
NoCapsLock.ms.dict
implementation.ms.dict
params.ms.dict
axiom_push.ms.dict
Documentation.ms.dict
WordsRTTI.ms.dict
arrays.ms.dict
io.ms.dict
Debug.ms.dict
CompileTimeVar.ms.dict
;
EXPORTS
CompileTimeVar.ms.dict
EXPORTS
implementation.ms.dict
USES
InheritsAndImplementsNew.ms.dict
;
EXPORTS
InheritsAndImplementsNew.ms.dict
WordAlias Log .
WordAlias %R .Implemented.Words
WordAlias %G .Inherited.Words
OBJECT FUNCTION DoMember
OBJECT IN aMember
aMember DO >>> Result
; // DoMember
BOOLEAN FUNCTION FilterMember
OBJECT IN aMember
Result := ( aMember NotValid ! )
; // FilterMember
ARRAY FUNCTION %ClassRTTIList
IN %S
Literal IN aName
VAR l_List
%S %% ( aName |N ) >>> l_List
if ( l_List NotValid ) then
( Result := [] )
else
( Result := ( l_List CodeIterator ) )
; // %ClassRTTIList
ARRAY CompileTime-VAR g_MetaListPoducerNames []
%REMARK 'Список содержащий пары (имя списка, указатель на массив)'
CONST cMetaListPoducerNamesElementSize 2
ARRAY FUNCTION MetaListPoducerIt
g_MetaListPoducerNames .slice> cMetaListPoducerNamesElementSize >>> Result
; // MetaListPoducerIt
CONST cMetaListPrefix '%'
ARRAY FUNCTION MapToName
ARRAY IN aArray
aArray .map> |N >>> Result
; // MapToName
CONST cResult 'Result'
CONST cSelf 'Self'
MACRO DefineMetaList
Literal IN aWordName
Literal IN aDoc
%SUMMARY 'Определяет список мета-информации к элементу. И итератор к нему' ;
STRING VAR l_WordName
aWordName |N >>> l_WordName
[ cMetaListPrefix l_WordName ] strings:Cat >>> l_WordName
STRING VAR l_ListName
[ '.' l_WordName '.It' ] strings:Cat >>> l_ListName
l_WordName array:AddTo g_MetaListPoducerNames
STRING VAR l_ListForValues
[ 'g_' l_WordName ] strings:Cat >>> l_ListForValues
axiom:PushSymbol ARRAY
axiom:PushSymbol CompileTime-VAR
axiom:PushStringAsSymbol l_ListForValues
axiom:PushSymbol []
axiom:PushSymbol [EXECUTE]
axiom:PushSymbol (
axiom:PushSymbol @
axiom:PushStringAsSymbol l_ListForValues
axiom:PushSymbol array:AddTo
axiom:PushSymbol g_MetaListPoducerNames
axiom:PushSymbol )
axiom:PushSymbol NamedWordProducer
[
l_WordName
l_ListName
] Ctx:Parser:PushArray
axiom:PushSymbol ARRAY
axiom:PushSymbol FUNCTION
axiom:PushStringAsSymbol l_ListName
axiom:PushSymbol TtfwWord
axiom:PushSymbol IN
axiom:PushStringAsSymbol cSelf
axiom:PushSymbol %SUMMARY
aDoc |N Ctx:Parser:PushString
axiom:PushSymbol ;
axiom:PushStringAsSymbol cSelf
axiom:PushSymbol %ClassRTTIList
axiom:PushStringAsSymbol l_ListName
axiom:PushSymbol MapToName
axiom:PushSymbol >>>
axiom:PushStringAsSymbol cResult
axiom:PushSymbol ;
; // DefineMetaList
PROCEDURE MakeAlias
STRING IN aProp
^ IN aLambda
axiom:PushSymbol WordAlias
aProp aLambda DO
; // MakeAlias
DefineMetaList Properties 'Свойства класса'
DefineMetaList Methods 'Методы класса'
DefineMetaList MetaMethods 'Методы мета-класса'
DefineMetaList Constructors 'Конструкторы класса'
: CompileSetWordProducerForCompiledClass
TtfwWord IN aWord
aWord
axiom:PushImmediateSymbol Ctx:SetWordProducerForCompiledClass
; // CompileSetWordProducerForCompiledClass
STACK_CHANGING_MACRO class_impl
Literal IN aName
%SUMMARY 'Реализация класса.
Тут мы будем хранить всю информацию о классе - предки, поля, методы'
;
@SELF CompileSetWordProducerForCompiledClass
axiom:PushSymbol :
aName |N Ctx:Parser:PushSymbol
; // class_impl
STRING CompileTime-VAR g_CurrentClass ''
BOOLEAN CompileTime-VAR g_InstanceSizeDefined false
BOOLEAN CompileTime-VAR g_ConstructorsCopied false
TtfwWord type ObjectClass
ObjectClass CompileTime-VAR g_CurrentClassImpl nil
ObjectClass CompileTime-VAR g_CurrentClassParent nil
CONST cMetaPrefix 'c:'
CONST cFieldPrefix 'Offset:'
STRING FUNCTION FieldPrefix
[ cMetaPrefix cFieldPrefix ] strings:Cat >>> Result
; // FieldPrefix
PRIVATE STRING operator MakeFieldOffsetName
STRING IN aName
%SUMMARY 'Делает имя для доступа к полю' ;
[ FieldPrefix aName ] strings:Cat >>> Result
; // MakeFieldOffsetName
INTEGER type FieldOffset
// - смещение поля
FieldOffset CompileTime-VAR g_ClassFieldOffset 0
VOID operator define_member
STRING IN aName
FieldOffset IN aOffset
axiom:PushSymbol implementation
g_CurrentClassImpl pop:Word:Name Ctx:Parser:PushSymbol
axiom:PushSymbol Const
aName MakeFieldOffsetName Ctx:Parser:PushSymbol
aOffset Ctx:Parser:PushInt
axiom:PushSymbol end.
; // define_member
MACRO member
Literal IN aName
STRING VAR l_Name
%SUMMARY 'Определяет член текущего класса' ;
g_InstanceSizeDefined ?FAIL [ 'Класс ' g_CurrentClass ' уже определён. Нельзя доопределять его члены.' ]
aName |N >>> l_Name
Ctx:ClearTypeInfo
l_Name g_ClassFieldOffset define_member
Inc g_ClassFieldOffset
; // member
PRIVATE STRING operator MakeMethodSignaturePrim
STRING IN aClass
STRING IN aName
[ aClass ':' aName ] strings:Cat >>> Result
; // MakeMethodSignaturePrim
CONST cClassImplPrefix '_:'
STRING FUNCTION ClassImplName
STRING IN aName
[ cClassImplPrefix aName ] strings:Cat >>> Result
; // ClassImplName
Const ClassRefSuffix 'Class'
STRING FUNCTION ClassRefName
STRING IN aName
[ aName ClassRefSuffix ] strings:Cat >>> Result
; // ClassRefName
STRING CompileTime-VAR g_CurrentClassMethod ''
STRING CompileTime-VAR g_CurrentClassMethodModifiers ''
PRIVATE VOID operator MakeMethodSignature
STRING IN aName
STRING VAR l_Signature
g_CurrentClass aName MakeMethodSignaturePrim >>> l_Signature
if ( l_Signature IsWordDeclared ) then
begin
axiom:PushSymbol REDEFINITION
end
axiom:PushSymbol :
axiom:PushStringAsSymbol l_Signature
; // MakeMethodSignature
PRIVATE VOID operator MakeSelfParam
axiom:PushStringAsSymbol g_CurrentClass
axiom:PushSymbol in
axiom:PushStringAsSymbol cSelf
; // MakeSelfParam
MACRO method
Literal IN aName
^ IN aParams
%SUMMARY 'Метод объекта' ;
STRING VAR l_Name
aName |N >>> l_Name
l_Name @SELF bindInPlace
l_Name MakeMethodSignature
MakeSelfParam
@SELF NameOf right aParams axiom:Params:PushWithOtherStereo
l_Name array:?AddTo g_%Methods
; // method
MACRO readonly
Literal IN aName
%SUMMARY 'read-only свойство объекта' ;
STRING VAR l_Name
aName |N >>> l_Name
l_Name @SELF bindInPlace
l_Name MakeMethodSignature
MakeSelfParam
l_Name array:?AddTo g_%Properties
; // readonly
STACK_CHANGING_MACRO class_method
Literal IN aName
%SUMMARY 'Метод класса' ;
g_CurrentClassMethod '' == ?ASSURE 'Вложенные методы класса пока не поддерживаются'
TtfwWordInfo VAR l_WordInfo
Ctx:WordInfo >>> l_WordInfo
STRING VAR l_TypeInfo
l_WordInfo pop:WordInfo:TypeName >>> g_CurrentClassMethodModifiers
STRING VAR l_Name
aName |N >>> l_Name
l_Name >>> g_CurrentClassMethod
l_Name bindAndRestoreContext
@SELF CompileSetWordProducerForCompiledClass
axiom:PushSymbol :
STRING VAR l_ClassName
g_CurrentClass >>> l_ClassName
l_ClassName ClassRefName >>> l_ClassName
STRING VAR l_ClassMethodName
l_ClassName l_Name MakeMethodSignaturePrim >>> l_ClassMethodName
axiom:PushStringAsSymbol l_ClassMethodName
axiom:PushStringAsSymbol l_ClassName
axiom:PushSymbol in
axiom:PushStringAsSymbol cSelf
l_Name array:?AddTo g_%MetaMethods
; // class_method
CONST cObjectName 'Object'
CONST cInstanceSizeName 'Instance:Size'
STRING FUNCTION InstanceSizeName
[ cMetaPrefix cInstanceSizeName ] strings:Cat >>> Result
; // InstanceSizeName
CONST cClassParentName 'Class:Parent'
STRING FUNCTION ClassParentName
[ cMetaPrefix cClassParentName ] strings:Cat >>> Result
; // ClassParentName
CONST cClassTypePrefix 'ClassOf::'
STRING FUNCTION ClassOfName
STRING IN aClassName
[ cClassTypePrefix aClassName ] strings:Cat >>> Result
; // ClassOfName
MACRO ClassOf
Literal IN aName
STRING VAR l_ClassName
aName |N ClassOfName >>> l_ClassName
l_ClassName IsWordDeclared ?ASSURE [ 'Класс ' l_ClassName ' не определён' ]
axiom:PushStringAsSymbol l_ClassName
; // ClassOf
PROCEDURE ClearMetaLists
MetaListPoducerIt .for> (
STRING IN aName
TtfwWord IN aVar
[] aVar pop:Word:SetValue
) // MetaListPoducerIt .for>
; // ClearMetaLists
PROCEDURE ClearClassInfo
g_CurrentClass := ''
g_CurrentClassImpl := nil
g_CurrentClassParent := nil
g_InstanceSizeDefined := false
g_ConstructorsCopied := false
g_ClassFieldOffset := 0
ClearMetaLists
; // ClearClassInfo
MACRO class
Literal IN aName
( g_CurrentClass = '' ) ?ASSURE 'Вложенные классы пока не поддерживаются'
TtfwWordInfo VAR l_WordInfo
Ctx:WordInfo >>> l_WordInfo
Ctx:ClearTypeInfo
ClearClassInfo
aName |N >>> g_CurrentClass
STRING VAR l_TypeInfo
l_WordInfo pop:WordInfo:TypeName >>> l_TypeInfo
STRING VAR l_CurrentClassParentName
if ( l_TypeInfo <> '' ) then
begin
l_TypeInfo 'ARRAY' == ?FAIL [ 'Множественное наследование пока не поддерживается. Класс: ' g_CurrentClass ' Заявленные предки ' l_TypeInfo ]
l_TypeInfo ' ' string:Pos -1 == ?ASSURE [ 'Множественное наследование пока не поддерживается. Класс: ' g_CurrentClass ' Заявленные предки ' l_TypeInfo ]
l_TypeInfo >>> l_CurrentClassParentName
end
else
begin
cObjectName >>> l_CurrentClassParentName
end
STRING VAR l_CurrentClassImpl
g_CurrentClass ClassImplName >>> l_CurrentClassImpl
STRING VAR l_ClassRefName
g_CurrentClass ClassRefName >>> l_ClassRefName
if ( g_CurrentClass !== cObjectName ) then
begin
axiom:PushImmediateSymbol (
l_CurrentClassParentName ClassOfName Ctx:Parser:PushSymbol
axiom:PushSymbol >>>
axiom:PushSymbol g_CurrentClassParent
axiom:PushSymbol )
axiom:PushSymbol ObjectClass
axiom:PushSymbol type
axiom:PushStringAsSymbol l_ClassRefName
end // g_CurrentClass !== cObjectName
axiom:PushStringAsSymbol l_ClassRefName
axiom:PushSymbol class_impl
axiom:PushStringAsSymbol l_CurrentClassImpl
if ( g_CurrentClass !== cObjectName ) then
begin
axiom:PushSymbol %INHERITS
axiom:PushSymbol @
l_CurrentClassParentName ClassImplName Ctx:Parser:PushSymbol
axiom:PushSymbol ;
end
axiom:PushSymbol @SELF
axiom:PushSymbol >>>
axiom:PushStringAsSymbol cResult
axiom:PushSymbol FieldOffset
axiom:PushSymbol CompileTime-VAR
axiom:PushStringAsSymbol InstanceSizeName
0 Ctx:Parser:PushInt
axiom:PushSymbol ObjectClass
axiom:PushSymbol CompileTime-VAR
axiom:PushStringAsSymbol ClassParentName
axiom:PushSymbol g_CurrentClassParent
axiom:PushSymbol ;
axiom:PushImmediateSymbol (
axiom:PushStringAsSymbol l_CurrentClassImpl
axiom:PushSymbol >>>
axiom:PushSymbol g_CurrentClassImpl
axiom:PushSymbol )
axiom:PushSymbol array
axiom:PushSymbol type
axiom:PushStringAsSymbol g_CurrentClass
axiom:PushSymbol WordAlias
g_CurrentClass ClassOfName Ctx:Parser:PushSymbol
axiom:PushStringAsSymbol l_CurrentClassImpl
if ( g_CurrentClass !== cObjectName ) then
begin
axiom:PushStringAsSymbol 'classExpander'
axiom:PushStringAsSymbol l_CurrentClassImpl
end
; // class
class Object
ObjectClass member VMT
//STRING member Fake
//INTEGER member Fake1
: FieldByOffset
Object in Self
FieldOffset right anOffset
anOffset Self [i]
; // FieldByOffset
PRIVATE operator do_get_member
STRING IN aName
%SUMMARY 'Определяет способ доступа к члену класса' ;
axiom:PushSymbol FieldByOffset
axiom:PushSymbol (
g_CurrentClass ClassImplName Ctx:Parser:PushSymbol
axiom:PushSymbol ::
aName MakeFieldOffsetName Ctx:Parser:PushSymbol
axiom:PushSymbol )
; // do_get_member
MACRO read
Literal IN aName
axiom:PushStringAsSymbol cSelf
aName |N do_get_member
axiom:PushSymbol >>>
axiom:PushStringAsSymbol cResult
axiom:PushSymbol ;
; // read
ObjectClass readonly class read VMT
MACRO class_method_end
axiom:PushSymbol ;
g_CurrentClassMethodModifiers axiom:PushWordInfo
axiom:PushSymbol readonly
axiom:PushStringAsSymbol g_CurrentClassMethod
axiom:PushStringAsSymbol cSelf
axiom:PushStringAsSymbol '.class'
[ '.' g_CurrentClassMethod ] strings:Cat Ctx:Parser:PushSymbol
if ( g_CurrentClassMethodModifiers IsNil ! ) then
begin
axiom:PushSymbol >>>
axiom:PushStringAsSymbol cResult
end // g_CurrentClassMethodModifiers IsNil !
axiom:PushSymbol ;
'' >>> g_CurrentClassMethod
'' >>> g_CurrentClassMethodModifiers
; // class_method_end
STRING class_method ClassName
%SUMMARY 'Возвращает имя класса' ;
Self |N ':' string:Split >>> Result DROP
class_method_end // ClassName
FieldOffset class_method FieldOffset
// - этод метод можно сделать КОМПИЛИРУЕМЫМ
Literal IN aFieldName
%SUMMARY 'Вычисляет смещение поля класса' ;
STRING VAR l_FieldName
aFieldName |N >>> l_FieldName
l_FieldName MakeFieldOffsetName >>> l_FieldName
TtfwWord VAR l_FieldVAR
Self %% l_FieldName >>> l_FieldVAR
l_FieldVAR IsNil ?FAIL [ 'Поле ' l_FieldName ' на классе ' Self .ClassName ' не определено' ]
l_FieldVAR DO >>> Result
class_method_end // FieldOffset
INTEGER class_method InstanceSize
%SUMMARY 'Возвращает размер экземпляров класса' ;
Self %% InstanceSizeName DO >>> Result
class_method_end // InstanceSize
ObjectClass class_method ClassParent
%SUMMARY 'Возвращает родительский класс' ;
Self %% ClassParentName DO >>> Result
class_method_end // ClassParent
STRING class_method ClassParentName
%SUMMARY 'Возвращает имя родительского класса' ;
ObjectClass VAR l_ClassParent
Self %% ClassParentName DO >>> l_ClassParent
if ( l_ClassParent IsNil ) then
begin
'<base>' >>> Result
end
else
begin
l_ClassParent .ClassName >>> Result
end
class_method_end // ClassParentName
class_method Print
%SUMMARY 'Печатает класс' ;
if ( Self IsNil ) then
begin
'<base>' .
end
else
begin
Self .ClassName Print
end
class_method_end // Print
CONST cDefConstructorName 'new'
PROCEDURE DefineInstanceSize
%SUMMARY 'Определяем размер экземпляров класса' ;
if ( g_InstanceSizeDefined ! ) then
begin
g_InstanceSizeDefined := true
TtfwWord VAR l_InstanceSizeVAR
g_CurrentClassImpl %% InstanceSizeName >>> l_InstanceSizeVAR
l_InstanceSizeVAR IsNil ?FAIL [ 'Переменная для размера класса ' g_CurrentClass ' почему-то не определена' ]
l_InstanceSizeVAR DO =0 ?ASSURE [ 'Размер класса ' g_CurrentClass ' почему-то уже определён' ]
g_ClassFieldOffset l_InstanceSizeVAR pop:Word:SetValue
end // g_InstanceSizeDefined !
; // DefineInstanceSize
FORWARD CopyConstructors
STACK_CHANGING_MACRO constructor
Literal IN aName
^ IN aParams
%SUMMARY 'Конструктор объектов';
STRING VAR l_Name
aName |N >>> l_Name
DefineInstanceSize
// - тут определяем размер экземпляров класса
if ( l_Name <> cDefConstructorName ) then
begin
if ( g_ConstructorsCopied ! ) then
begin
l_Name Log
CopyConstructors
end // g_ConstructorsCopied !
end // l_Name <> cDefConstructorName
else
begin
g_ConstructorsCopied := true
end // l_Name <> cDefConstructorName
g_CurrentClass l_Name MakeMethodSignaturePrim Log
@SELF CompileSetWordProducerForCompiledClass
axiom:PushStringAsSymbol g_CurrentClass
l_Name MakeMethodSignature
@SELF NameOf right aParams axiom:Params:PushWithOtherStereo
axiom:PushSymbol WordAlias
axiom:PushStringAsSymbol cSelf
axiom:PushStringAsSymbol cResult
l_Name array:?AddTo g_%Constructors
; // constructor
PROCEDURE def_constructor_do
axiom:PushSymbol constructor
axiom:PushStringAsSymbol cDefConstructorName
axiom:PushSymbol ()
; // def_constructor_do
MACRO def_constructor
def_constructor_do
; // def_constructor
PROCEDURE def_constructor_empty_do
def_constructor_do
axiom:PushStringAsSymbol 'new['
axiom:PushSymbol ]
axiom:PushSymbol >>>
axiom:PushStringAsSymbol cResult
axiom:PushSymbol ;
; // def_constructor_empty_do
MACRO def_constructor_empty
def_constructor_empty_do
; // def_constructor_empty
PROCEDURE CopyConstructors
DefineInstanceSize
if ( g_ConstructorsCopied ! ) then
begin
if ( g_CurrentClass !== cObjectName ) then
begin
g_CurrentClassImpl IsNil ?FAIL [ 'Нет текущего определяемого класса. Возможное имя класса ' g_CurrentClass ]
g_ConstructorsCopied := true
g_CurrentClassImpl %G .for> (
ObjectClass IN anItem
anItem .%Constructors.It .for> (
STRING IN aProp
if ( aProp = cDefConstructorName ) then
begin
def_constructor_empty_do
end
) // anItem .%Constructors.It .for>
) // anImpl %G .for>
end // ( g_CurrentClass !== cObjectName )
end // ( g_ConstructorsCopied ! )
; // CopyConstructors
MACRO classExpander
^ IN anImpl
ObjectClass VAR l_Impl
anImpl |@ >>> l_Impl
%SUMMARY 'Тут можно копировать поля и методы' ;
l_Impl %G .for> (
ObjectClass IN anItem
anItem MembersIterator
.filter> ( pop:Word:Producer pop:Word:Name NameOf CONST == )
.filter> ( pop:Word:Name FieldPrefix SWAP StartsStr )
.for>
(
TtfwWord IN aMember
STRING VAR l_MemberName
[ aMember pop:Word:Name FieldPrefix '' string:ReplaceFirst ] strings:Cat >>> l_MemberName
FieldOffset VAR l_ClassFieldOffset
aMember DO >>> l_ClassFieldOffset
l_MemberName l_ClassFieldOffset define_member
if ( l_ClassFieldOffset >= g_ClassFieldOffset ) then
// - тут исправляем "кривизну" с сортировкой
begin
g_ClassFieldOffset := l_ClassFieldOffset
Inc g_ClassFieldOffset
end
) // anItem MembersIterator
PROCEDURE MakeAliasAndAdd
STRING IN aProp
^ IN anArray
^ IN aLambda
ARRAY VAR l_Array
anArray DO >>> l_Array
aProp array:?AddTo l_Array
aProp MakeAlias ( aLambda DO )
; // MakeAliasAndAdd
PROCEDURE PushMethodSignature
STRING IN aClass
STRING IN aName
aClass aName MakeMethodSignaturePrim Ctx:Parser:PushSymbol
; // PushMethodSignature
PROCEDURE PushMethodSignatureAlias
STRING IN aProp
g_CurrentClass aProp PushMethodSignature
anItem .ClassName aProp PushMethodSignature
; // PushMethodSignatureAlias
PROCEDURE .for.MakeAliasAndAdd>
ARRAY IN aArray
^ IN anRArray
^ IN aLambda
aArray .for> MakeAliasAndAdd ( anRArray DO ) ( aLambda DO )
; // .for.MakeAliasAndAdd>
anItem .%Properties.It .for.MakeAliasAndAdd> g_%Properties PushMethodSignatureAlias
anItem .%Methods.It .for.MakeAliasAndAdd> g_%Methods PushMethodSignatureAlias
anItem .%MetaMethods.It .for.MakeAliasAndAdd> g_%MetaMethods (
STRING IN aProp
g_CurrentClass ClassRefName aProp PushMethodSignature
anItem .ClassName ClassRefName aProp PushMethodSignature
)
) // l_Impl %G .for>
; // classExpander
: ListToNameAsString
STRING IN aName
ARRAY IN aList
%SUMMARY 'Выводит элементы массива как строки в список метаинформации aName' ;
//aList DO >>> l_List
//ARRAY VAR l_List
aName
%REMARK 'Открываем список'
aList .for> NameAsString
';'
%REMARK 'Закрываем список'
; // ListToNameAsString
PROCEDURE FinishClassDefinition
axiom:PushSymbol implementation
g_CurrentClassImpl pop:Word:Name Ctx:Parser:PushSymbol
[
MetaListPoducerIt .for> (
STRING IN aName
TtfwWord IN aVar
aName aVar DO ListToNameAsString
) // MetaListPoducerIt .for>
] Ctx:Parser:PushArray
axiom:PushSymbol end.
ClearClassInfo
; // FinishClassDefinition
MACRO class-end
//DefineInstanceSize
axiom:PushImmediateSymbol CopyConstructors
axiom:PushImmediateSymbol FinishClassDefinition
; // class-end
MACRO new[
INTEGER VAR l_InstanceSize
ClassOf Object .InstanceSize >>> l_InstanceSize
Dec l_InstanceSize
//l_InstanceSize .
axiom:PushSymbol [
axiom:PushSymbol @
g_CurrentClassImpl pop:Word:Name Ctx:Parser:PushSymbol
l_InstanceSize LOOP ( 'uninited member' Ctx:Parser:PushString )
; // new[
def_constructor_empty
VIRTUAL STRING readonly ToPrintable
Self ToPrintable >>> Result
[ Self .ClassName ' : ' Result ] strings:Cat >>> Result
//Self .ClassName >>> Result
; // ToPrintable
VIRTUAL void readonly Print
Self .ToPrintable Print
; // Print
class-end // Object
Тест:
Object.ms.script
USES io.ms.dict Object.ms.dict Testing.ms.dict ; USES axiom:WordInfo ; Test&Dump ObjectTest ClassOf Object DumpElement ClassOf Object pop:Word:Name Print Object VAR l_Obj l_Obj := Object:new l_Obj .Print l_Obj .ClassName Print //@ l_Obj pop:Word:Info pop:WordInfo:ValueTypes Print //@ l_Obj pop:Word:Info pop:WordInfo:ValueTypes pop:ValueTypes:Name Print l_Obj .ClassName Print ClassOf Object pop:Word:Name Print '--------' Print l_Obj .InstanceSize Print ClassOf Object .FieldOffset VMT Print ClassOf Object .ClassParent Print ClassOf Object .ClassParent .Print ClassOf Object .ClassParentName Print ClassOf Object pop:Word:Name Print ClassOf Object pop:Word:Name Print l_Obj .class Print l_Obj .class .Print class Object1 //def_constructor_empty class-end // Object1 Object1 VAR l_Obj1 l_Obj1 := Object1:new l_Obj1 .Print l_Obj1 .ClassName Print '--------' Print l_Obj1 .InstanceSize Print ClassOf Object1 .FieldOffset VMT Print ClassOf Object1 .ClassParent Print ClassOf Object1 .ClassParent .Print ClassOf Object1 .ClassParentName Print l_Obj1 .class Print l_Obj1 .class .Print class Object2 INTEGER member FakeField INTEGER readonly FakeField read FakeField def_constructor //[EXECUTE] ( g_InstanceSizeDefined Msg ) new[ 256 ] >>> Result //Self .FieldOffset 'VMT' Msg ; // new class-end // Object2 Object2 VAR l_Obj2 l_Obj2 := Object2:new l_Obj2 .Print l_Obj2 .ClassName Print '--------' Print l_Obj2 .InstanceSize Print ClassOf Object2 .FieldOffset VMT Print ClassOf Object2 .FieldOffset FakeField Print ClassOf Object2 .ClassParent Print ClassOf Object2 .ClassParent .Print ClassOf Object2 .ClassParentName Print ClassOf Object2 .FieldOffset FakeField Print l_Obj2 .FakeField Print l_Obj2 .class Print l_Obj2 .class .Print //l_Obj2 .member FakeField Print Object2 class Object3 def_constructor new[ 257 ] >>> Result ; // new class-end // Object3 '--------' Print ClassOf Object3 Print ClassOf Object3 ObjectClass:ClassName Print ClassOf Object3 ObjectClass:ClassParent Print ClassOf Object3 ObjectClass:ClassParentName Print '--------' Print ClassOf Object3 .Print ClassOf Object3 .ClassName Print ClassOf Object3 .ClassParent Print ClassOf Object3 .ClassParentName Print Object3 VAR l_Obj3 l_Obj3 := Object3:new l_Obj3 .Print l_Obj3 .ClassName Print '--------' Print l_Obj3 .InstanceSize Print ClassOf Object3 .FieldOffset VMT Print ClassOf Object3 .FieldOffset FakeField Print ClassOf Object3 .ClassParent Print ClassOf Object3 .ClassParent .Print ClassOf Object3 .ClassParentName Print ClassOf Object3 .FieldOffset FakeField Print l_Obj3 .FakeField Print l_Obj3 .class Print l_Obj3 .class .Print class Object4 //def_constructor_empty class-end // Object4 Object4 VAR l_Obj4 l_Obj4 := Object4:new l_Obj4 .Print l_Obj4 .ClassName Print '--------' Print l_Obj4 .InstanceSize Print ClassOf Object4 .FieldOffset VMT Print ClassOf Object4 .ClassParent Print ClassOf Object4 .ClassParent .Print ClassOf Object4 .ClassParentName Print l_Obj4 .class Print l_Obj4 .class .Print ; // ObjectTest ObjectTest
Запись Object2 class Object3 - описывает Object3 наследующийся от Object2.
Комментариев нет:
Отправить комментарий