USES axiom:CompiledWordWorkerWord axiom:Finder axiom:Compiler macro.ms.dict NoCapsLock.ms.dict params.ms.dict integer.ms.dict ; Test PointTest // Понятное дело, что всю обвязку потом упрячем в отдельный словарь object.ms.dict IMMEDIATE operator implementation ^ LINK IN aWordToWork Ctx:PushCompiler Ctx:PushFinder OBJECT VAR l_NewCompiler aWordToWork |^@ =: l_NewCompiler if ( l_NewCompiler Is class::TkwCompiledWordWorkerWord ) then begin l_NewCompiler pop:CompiledWordWorkerWord:Compiled =: l_NewCompiler end l_NewCompiler pop:Compiler:SetToCtx l_NewCompiler pop:Finder:SetToCtx ; // implementation IMMEDIATE operator end. pop:Finder:SetToCtx pop:Compiler:SetToCtx ; // end. NamedWordProducer %FIELDS %Fld OBJECT FUNCTION DoMember OBJECT IN aMember aMember DO =: Result ; // DoMember BOOLEAN FUNCTION FilterMember OBJECT IN aMember Result := ( aMember NotValid ! ) ; // FilterMember ARRAY FUNCTION ELEMLIST STRING IN aListName IN %S if ( %S NotValid ) then ( Result := [ ] ) else ( VAR l_List l_List := ( %S %% aListName ) if ( l_List NotValid ) then ( Result := [ ] ) else // ( Result := ( [ l_List DO ] ) ) ( Result := ( @ FilterMember ( @ DoMember ( l_List CodeIterator ) MAP ) FILTER ) ) ) ; // ELEMLIST ARRAY FUNCTION %R IN %S Result := ( '%R' %S ELEMLIST ) ; ARRAY FUNCTION %G IN %S Result := ( '%G' %S ELEMLIST ) ; ARRAY FUNCTION %Fld IN %S //Result := ( '%Fld' %S ELEMLIST ) VAR l_List %S %% '%Fld' =: l_List if ( l_List NotValid ) then ( Result := [ ] ) else ( Result := ( l_List CodeIterator ) ) ; VOID OPERATOR class_impl // - имплементация класса, пока "фиктивная" // Тут мы будем хранить всю информацию о классе - предки, поля, методы ; // class_impl //MACRO class_impl //// - имплементация класса, пока "фиктивная" // Literal IN aName // @SELF Ctx:SetWordProducerForCompiledClass // axiom:PushSymbol : // aName |N Ctx:Parser:PushSymbol // // axiom:PushSymbol ; //; // class_imp STRING var g_CurrentClass g_CurrentClass := '' STRING var g_CurrentClassImpl g_CurrentClassImpl := '' PRIVATE STRING operator MakeFieldOffsetName STRING IN aName [ 'c:' g_CurrentClass ':Offset:' aName ] strings:Cat =: Result ; // MakeFieldOffsetName VOID operator define_member STRING IN aName INTEGER IN aOffset axiom:PushSymbol private axiom:PushSymbol Const aName MakeFieldOffsetName Ctx:Parser:PushSymbol aOffset Ctx:Parser:PushInt ; // define_member INTEGER VAR g_ClassFieldOffset [EXECUTE] ( g_ClassFieldOffset := 0 ) g_ClassFieldOffset := 0 ARRAY VAR g_CurrentClassMembers [EXECUTE] ( g_CurrentClassMembers := [ ] ) ( g_CurrentClassMembers := [ ] ) MACRO member Literal IN aName Ctx:ClearTypeInfo aName |N g_ClassFieldOffset define_member Inc g_ClassFieldOffset aName |N array:AddTo g_CurrentClassMembers ; // member MACRO classExpander ^ IN anImpl // Тут можно копировать поля и методы for ( ( anImpl |@ ) %G ) ( IN anItem for ( anItem %Fld ) ( IN anItem axiom:PushSymbol member anItem |N Ctx:Parser:PushSymbol ) ) ; // classExpander CONST cObjectName 'Object' MACRO class Literal IN aName g_CurrentClassMembers := [ ] g_ClassFieldOffset := 0 aName |N =: g_CurrentClass // axiom:PushSymbol class_impl // - вообще должно быть так, почему не работает - надо разбираться [ ':' @ class_impl Ctx:SetWordProducerForCompiledClass [ '_:' g_CurrentClass ] strings:Cat =: g_CurrentClassImpl g_CurrentClassImpl if ( g_CurrentClass !== cObjectName ) then begin '%INHERITS' '@' [ '_:' cObjectName ] strings:Cat ';' end //'%FIELDS' //';' ';' ] Ctx:Parser:PushArray [ 'array' 'type' g_CurrentClass ] Ctx:Parser:PushArray axiom:PushSymbol classExpander g_CurrentClassImpl Ctx:Parser:PushSymbol ; // class MACRO class-end ; // class-end INTEGER type FieldOffset // - смещение поля PRIVATE VOID operator MakeMethodSignature STRING IN aName axiom:PushSymbol : [ g_CurrentClass ':' aName ] strings:Cat Ctx:Parser:PushSymbol ; // MakeMethodSignature MACRO constructor // - конструктор объектов, пока "фиктивный" Literal IN aName @SELF Ctx:SetWordProducerForCompiledClass g_CurrentClass Ctx:Parser:PushSymbol aName |N MakeMethodSignature ; // constructor PRIVATE VOID operator MakeSelfParam g_CurrentClass Ctx:Parser:PushSymbol axiom:PushSymbol in 'Self' Ctx:Parser:PushSymbol ; // MakeSelfParam MACRO method // - метод объекта, пока "фиктивный" Literal IN aName @SELF Ctx:SetWordProducerForCompiledClass aName |N MakeMethodSignature MakeSelfParam ; // method MACRO readonly // - read-only свойство объекта, пока "фиктивное" Literal IN aName @SELF Ctx:SetWordProducerForCompiledClass aName |N MakeMethodSignature MakeSelfParam ; // readonly MACRO new[ axiom:PushSymbol [ axiom:PushSymbol @ g_CurrentClassImpl Ctx:Parser:PushSymbol ; // new[ MACRO RunCompileFields [ 'implementation' g_CurrentClassImpl '%FIELDS' for g_CurrentClassMembers ( STRING IN aName [ '`' aName '`' ] strings:Cat ) ';' 'end.' ] Ctx:Parser:PushArray ; // RunCompileFields MACRO members-end axiom:PushSymbol private axiom:PushSymbol Const [ 'c:' g_CurrentClass ':Instance:Size' ] strings:Cat Ctx:Parser:PushSymbol g_ClassFieldOffset Ctx:Parser:PushInt axiom:PushSymbol RunCompileFields ; // members-end class Object : FieldByOffset Object in Self FieldOffset right anOffset anOffset Self [i] ; // FieldByOffset VIRTUAL STRING method ToPrintable Self ToPrintable =: Result ; // ToPrintable PRIVATE operator do-get-member STRING IN aName axiom:PushSymbol FieldByOffset aName MakeFieldOffsetName Ctx:Parser:PushSymbol ; // do-get-member MACRO get-member Literal IN aName aName |N do-get-member ; // get-member MACRO read Literal IN aName 'Self' Ctx:Parser:PushSymbol aName |N do-get-member axiom:PushSymbol =: 'Result' Ctx:Parser:PushSymbol axiom:PushSymbol ; ; // read INTEGER member VMT members-end TtfwWord readonly class read VMT STRING : getClassName IN Self Self |N ':' string:Split =: Result DROP ; // getClassName STRING readonly ClassName Self Object:class getClassName =: Result ; // Object:ClassName class-end // Object INTEGER type Pixel // - пиксель List type PixelList // - список пикселей class Point Pixel member X Pixel member Y members-end constructor : Pixel right aX Pixel right aY new[ aX aY ] =: Result ; // : constructor 0 Point:: 0 0 =: Result ; // 0 constructor XY PixelList right aPoint array var Points [ aPoint ] =: Points Point:: ( Points FieldByOffset 0 ) ( Points FieldByOffset 1 ) =: Result ; // XY Pixel readonly X read X Pixel readonly Y read Y constructor OF Point right aPoint Point:: ( aPoint Point:X ) ( aPoint Point:Y ) =: Result ; // OF Point method + Point right aPoint Point:: ( Self Point:X (+) ( aPoint Point:X ) ) ( Self Point:Y (+) ( aPoint Point:Y ) ) =: Result ; // + Point method Neg Point:: Neg ( Self Point:X ) Neg ( Self Point:Y ) =: Result ; // Neg Point method - Point right aPoint Point:OF ( Self Point:+ ( aPoint Point:Neg ) ) =: Result ; // - OVERRIDE STRING method ToPrintable [ '( ' 'X: ' Self Point:X ToPrintable ', Y: ' Self Point:Y ToPrintable ' )' ] strings:Cat =: Result ; // ToPrintable void method Print Self Point:ToPrintable Print ; // Print class-end // Point class Rectangle Point member TopLeft Point member BottomRight members-end Point readonly TopLeft read TopLeft Point readonly BottomRight read BottomRight constructor : Point right aTopLeft Point right aBottomRight new[ aTopLeft aBottomRight ] =: Result ; // : OVERRIDE STRING method ToPrintable [ '( ' 'TopLeft: ' Self Rectangle:TopLeft Point:ToPrintable ', BottomRight: ' Self Rectangle:BottomRight Point:ToPrintable ' )' ] strings:Cat =: Result ; // ToPrintable void method Print Self Rectangle:ToPrintable Print ; // Print class-end // Rectangle USES CodeDump.ms.dict ; @SELF DumpElement Point var P1 Point var P2 Point var P3 Point var P4 Point var P5 Point var P6 Point var P7 Point var P8 Point var P9 Point var P10 Point var P11 P1 := Point:0 P2 := Point:0 P3 := Point:: 1 1 P4 := Point:XY ( 2 2 ) P5 := Point:OF P4 P6 := ( P3 Point:+ P4 ) P7 := ( P3 Point:- P4 ) P8 := ( P4 Point:- P3 ) P9 := ( P4 Point:Neg ) P10 := ( P3 Point:Neg ) P11 := Point:XY ( -2 2 ) Object var O1 O1 := P1 O1 Point:Print array var l_Points [ P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 ] =: l_Points for l_Points Point:Print for l_Points ( Point:X Print ) for l_Points ( Point:Y Print ) for l_Points ( Object:class Print ) for l_Points ( Object:ClassName Print ) for l_Points ( for ( Object:class %G ) ( getClassName Print ) ) Rectangle var R1 Rectangle var R2 R1 := Rectangle:: P1 P4 R2 := Rectangle:: P6 P7 array var l_Rectangles [ R1 R2 ] =: l_Rectangles for l_Rectangles Rectangle:Print 'Hello ' (+) 'world' Print 'Hello ' (+) 'world' Print 'Hello ' (+) 'world' Print 1 (+) 2 Print 10 (+) 20 Print 0 (-) 10 Print Neg 10 Print Neg -10 Print ; // PointTest PointTest
Заметки о тестировании, программировании и прочий "поток сознания", который жалко писать "в стол"
вторник, 18 августа 2015 г.
Эмуляция объектов. Продолжаем
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий