forked from Matway/mpl-sl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
interface.mpl
129 lines (111 loc) · 3.02 KB
/
interface.mpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Copyright (C) Matway Burkow
#
# This repository and all its contents belong to Matway Burkow (referred here and below as "the owner").
# The content is for demonstration purposes only.
# It is forbidden to use the content or any part of it for any purpose without explicit permission from the owner.
# By contributing to the repository, contributors acknowledge that ownership of their work transfers to the owner.
"control.Natx" use
"control.Ref" use
"control.drop" use
"control.dup" use
"control.pfunc" use
"control.when" use
"control.while" use
cloneField: [
index: object:;;
index @object @ @object index fieldIsRef [Ref] [newVarOfTheSameType] if
];
interface: [
virtual methods: call dup virtual? ~ [Ref] when;
index: 0;
inputIndex: 0;
fillInputs: [
inputIndex index @methods @ fieldCount 1 - = [] [
inputIndex index @methods @ cloneField index @methods @ inputIndex fieldName def
inputIndex 1 + !inputIndex
@fillInputs ucall
] uif
];
fillVtable: [
index @methods fieldCount = [] [
{
self: Natx;
0 !inputIndex
@fillInputs ucall
}
index @methods @ fieldCount 1 - index @methods @ cloneField
{} codeRef
@methods index fieldName def
index 1 + !index
@fillVtable ucall
] uif
];
{
Vtable: {
DIE_FUNC: {self: Natx;} {} {} codeRef;
[drop] !DIE_FUNC
SIZE: {self: Natx;} Natx {} codeRef;
@fillVtable ucall
};
CALL: [
fillMethods: [
index @Vtable fieldCount = [] [
@Vtable index fieldName "CALL" = [
[@closure storageAddress @vtable.CALL]
] [
{
virtual NAME: @Vtable index fieldName;
CALL: [@self storageAddress @vtable NAME callField];
}
] if
@Vtable index fieldName def
index 1 + !index
@fillMethods ucall
] uif
];
index: 1;
{
vtable: @Vtable;
DIE: [@closure storageAddress @vtable.DIE_FUNC];
@fillMethods ucall
}
];
}
];
implement: [
getBase: getObject:;;
{
virtual Base: getBase Ref;
virtual getObject: @getObject;
vtable: @Base.@vtable newVarOfTheSameType;
CALL: [
moveFields: [
index @object fieldCount = [] [
index @object @ @object index fieldIsRef ~ [new] when @object index fieldName def
index 1 + !index
@moveFields ucall
] uif
];
object: getObject;
index: 0;
{
base: {
virtual Base: @Base;
vtable: @vtable;
CALL: [@self storageAddress @Base addressToReference];
};
@moveFields ucall
}
];
[
virtual Object: CALL Ref;
[@Object addressToReference manuallyDestroyVariable] @vtable.!DIE_FUNC
[drop @Object storageSize] @vtable.!SIZE
i: 2; [i @vtable fieldCount = ~] [
virtual NAME: @vtable i fieldName;
[@Object addressToReference NAME callField] i @vtable !
i 1 + !i
] while
] call
}
];