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)
 
Комментариев нет:
Отправить комментарий