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
Заметки о тестировании, программировании и прочий "поток сознания", который жалко писать "в стол"
Комментариев нет:
Отправить комментарий