-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdoinheritance.m
106 lines (99 loc) · 3.2 KB
/
doinheritance.m
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
%==========================================================================
% Searches through some hierarchy and performs inheritance. Whenever finds
% struct field named 'parent' it tries to find all points, defined by its
% content and uses them as the struct ancestors. Example:
%
% Given:
%
% s.a.a = 1
% s.a.b = 2
% s.a.parent: 'b'
%
% s.b.a = 3
% s.b.c = 4
%
% the result of r = doinheritance(s) is:
%
% r.a = 1
% r.c = 4
% r.b = 2
% r.parent = 'b'
%
% Multiple inheritance is allowed using cell array of parent point strings
% instead of one simple string.
%
%==========================================================================
function result = doinheritance(r, tr)
if ~exist('tr','var')
tr = r;
end;
result = recurse(r, 0, {tr});
end
function result = recurse(data, level, addit)
if iscell(data) && ~ismymatrix(data)
result = iter_cell(data, level, addit);
elseif isstruct(data)
result = iter_struct(data, level, addit);
else
result = data;
end;
end
function result = iter_cell(data, level, addit)
result = {};
for i = 1:length(data)
result{i} = recurse(data{i}, level + 1, addit);
end;
for i = 1:length(data)
if isstruct(result{i}) && isfield(result{i}, kwd_parent())
result{i} = inherit(result{i}, result{i}.(kwd_parent()), [], addit{1}, {}); % !!!
end;
end;
end
function result = iter_struct(data, level, addit)
result = data;
for i = fields(data)'
fld = char(i);
result.(fld) = recurse(data.(fld), level + 1, addit);
end;
for i = fields(result)'
fld = char(i);
if isstruct(result.(fld)) && isfield(result.(fld), kwd_parent())
result.(fld) = inherit(result.(fld), result.(fld).(kwd_parent()), [], addit{1}, {});
end;
end;
end
function result = inherit(child, parent_chr, container, oaroot, loc_imported)
result = child;
if ~iscell(parent_chr)
parent_chr = {parent_chr};
end;
for i = length(parent_chr):-1:1
if contains(loc_imported, parent_chr{i})
error('MATLAB:MATYAML:inheritedtwice',['Cyclic inheritance: ', parent_chr{i}]);
end;
try
parentstruct = eval(['oaroot.',parent_chr{i}]);
catch ex
switch ex.identifier
case {'MATLAB:nonExistentField', 'MATLAB:badsubscript'}
error('MATLAB:MATYAML:NonExistentParent', ['Parent was not found: ',parent_chr{i}]);
end;
rethrow(ex);
end;
if isstruct(parentstruct) && isfield(parentstruct, kwd_parent())
next_loc_imported = loc_imported;
next_loc_imported{end + 1} = parent_chr{i};
result = merge_struct(inherit(parentstruct, parentstruct.(kwd_parent()), [], oaroot, next_loc_imported), result, {'import'});
end;
result = merge_struct(parentstruct, result, {'import'});
end;
end
function result = contains(list, chr)
for i = 1:length(list)
if strcmp(list{i}, chr)
result = true;
return;
end;
end;
result = false;
end