6
6
* available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE
7
7
*/
8
8
9
- using Hl7 . Fhir . ElementModel ;
10
- using System ;
9
+ #nullable enable
10
+
11
11
using System . Collections . Concurrent ;
12
12
using System . Collections . Generic ;
13
13
using System . Linq ;
14
14
using System . Text ;
15
15
16
- namespace Hl7 . FhirPath . Expressions
17
- {
16
+ namespace Hl7 . FhirPath . Expressions ;
18
17
19
- public class SymbolTable
18
+ /// <summary>
19
+ /// Holds the functions and constants available for the FhirPath engine to bind to.
20
+ /// </summary>
21
+ public class SymbolTable
22
+ {
23
+ /// <summary>
24
+ /// An empty symbol table.
25
+ /// </summary>
26
+ public SymbolTable ( )
20
27
{
21
- public SymbolTable ( )
22
- {
23
-
24
- }
28
+ // Nothing
29
+ }
25
30
26
- public SymbolTable ( SymbolTable parent )
27
- {
28
- Parent = parent ;
29
- }
31
+ /// <summary>
32
+ /// A local symbol table inside a parent scope.
33
+ /// </summary>
34
+ public SymbolTable ( SymbolTable parent )
35
+ {
36
+ Parent = parent ;
37
+ }
30
38
31
- public int Count ( )
32
- {
33
- var cnt = _entries . Count ;
34
- if ( Parent != null ) cnt += Parent . Count ( ) ;
39
+ /// <summary>
40
+ /// The number of entries in the symbol table, including the parent scope (if any).
41
+ /// </summary>
42
+ public int Count ( )
43
+ {
44
+ var cnt = _entries . Count ;
45
+ if ( Parent != null ) cnt += Parent . Count ( ) ;
35
46
36
- return cnt ;
37
- }
47
+ return cnt ;
48
+ }
38
49
39
- internal Invokee First ( )
40
- {
41
- return _entries . Any ( ) ? _entries . First ( ) . Body : ( Parent ? . First ( ) ) ;
42
- }
50
+ internal Invokee ? First ( ) => _entries . Any ( ) ? _entries . First ( ) . Body : ( Parent ? . First ( ) ) ;
43
51
44
- public SymbolTable Parent { get ; private set ; }
52
+ /// <summary>
53
+ /// The parent scope for this symbol table.
54
+ /// </summary>
55
+ public SymbolTable ? Parent { get ; private set ; }
45
56
46
- [ System . Diagnostics . DebuggerDisplay ( @"\{{DebuggerDisplayValue()}}" ) ]
47
- private class TableEntry
57
+ [ System . Diagnostics . DebuggerDisplay ( @"\{{DebuggerDisplayValue()}}" ) ]
58
+ private class TableEntry ( CallSignature signature , Invokee body )
59
+ {
60
+ public string DebuggerDisplayValue ( )
48
61
{
49
- public string DebuggerDisplayValue ( )
50
- {
51
- if ( Signature != null )
52
- {
53
- var sb = new StringBuilder ( ) ;
54
- sb . Append ( Signature . ReturnType . Name ) ;
55
- sb . Append ( ' ' ) ;
56
- sb . Append ( Signature . Name ) ;
57
- sb . Append ( " (" ) ;
58
- bool b = false ;
59
- foreach ( var item in Signature . ArgumentTypes )
60
- {
61
- if ( b )
62
- sb . Append ( ", " ) ;
63
- sb . Append ( item . Name ) ;
64
- b = true ;
65
- }
66
- sb . Append ( ')' ) ;
67
- return sb . ToString ( ) ;
68
- }
69
- return null ;
70
- }
71
-
72
- public CallSignature Signature { get ; private set ; }
73
- public Invokee Body { get ; private set ; }
62
+ var sb = new StringBuilder ( ) ;
63
+ sb . Append ( Signature . ReturnType . Name ) ;
64
+ sb . Append ( ' ' ) ;
65
+ sb . Append ( Signature . Name ) ;
66
+ sb . Append ( " (" ) ;
67
+ bool b = false ;
74
68
75
- public TableEntry ( CallSignature signature , Invokee body )
69
+ foreach ( var item in Signature . ArgumentTypes )
76
70
{
77
- Signature = signature ;
78
- Body = body ;
71
+ if ( b )
72
+ sb . Append ( ", " ) ;
73
+ sb . Append ( item . Name ) ;
74
+ b = true ;
79
75
}
80
- }
81
-
82
- private ConcurrentBag < TableEntry > _entries = new ( ) ;
76
+ sb . Append ( ')' ) ;
83
77
84
- internal void Add ( CallSignature signature , Invokee body )
85
- {
86
- _entries . Add ( new TableEntry ( signature , body ) ) ;
78
+ return sb . ToString ( ) ;
87
79
}
88
80
89
- public SymbolTable Filter ( string name , int argCount )
90
- {
91
- var result = new SymbolTable
92
- {
93
- _entries = new ( _entries . Where ( e => e . Signature . Matches ( name , argCount ) ) )
94
- } ;
95
-
96
- if ( Parent != null )
97
- result . Parent = Parent . Filter ( name , argCount ) ;
98
-
99
- return result ;
100
- }
101
-
102
- internal Invokee DynamicGet ( string name , IEnumerable < object > args )
103
- {
104
- var exactMatches = _entries . Where ( e => e . Signature . DynamicExactMatches ( name , args ) ) ;
105
- TableEntry entry = exactMatches . Union ( _entries . Where ( e => e . Signature . DynamicMatches ( name , args ) ) ) . FirstOrDefault ( ) ;
106
-
107
- if ( entry == null && Parent != null ) return Parent . DynamicGet ( name , args ) ;
108
-
109
- return entry ? . Body ;
110
- }
81
+ public CallSignature Signature { get ; } = signature ;
82
+ public Invokee Body { get ; } = body ;
111
83
}
112
84
85
+ private ConcurrentBag < TableEntry > _entries = [ ] ;
113
86
114
- public static class SymbolTableExtensions
87
+ internal void Add ( CallSignature signature , Invokee body )
115
88
{
116
- public static void Add < R > ( this SymbolTable table , string name , Func < R > func )
117
- {
118
- table . Add ( new CallSignature ( name , typeof ( R ) ) , InvokeeFactory . Wrap ( func ) ) ;
119
- }
120
-
121
- public static void Add < A , R > ( this SymbolTable table , string name , Func < A , R > func , bool doNullProp = false )
122
- {
123
- if ( typeof ( A ) != typeof ( EvaluationContext ) )
124
- table . Add ( new CallSignature ( name , typeof ( R ) , typeof ( A ) ) , InvokeeFactory . Wrap ( func , doNullProp ) ) ;
125
- else
126
- table . Add ( new CallSignature ( name , typeof ( R ) ) , InvokeeFactory . Wrap ( func , doNullProp ) ) ;
127
- }
128
-
129
- public static void Add < A , B , R > ( this SymbolTable table , string name , Func < A , B , R > func , bool doNullProp = false )
130
- {
131
- if ( typeof ( B ) != typeof ( EvaluationContext ) )
132
- table . Add ( new CallSignature ( name , typeof ( R ) , typeof ( A ) , typeof ( B ) ) , InvokeeFactory . Wrap ( func , doNullProp ) ) ;
133
- else
134
- table . Add ( new CallSignature ( name , typeof ( R ) , typeof ( A ) ) , InvokeeFactory . Wrap ( func , doNullProp ) ) ;
135
- }
89
+ _entries . Add ( new TableEntry ( signature , body ) ) ;
90
+ }
136
91
137
- public static void Add < A , B , C , R > ( this SymbolTable table , string name , Func < A , B , C , R > func , bool doNullProp = false )
92
+ public SymbolTable Filter ( string name , int argCount )
93
+ {
94
+ var result = new SymbolTable
138
95
{
139
- if ( typeof ( C ) != typeof ( EvaluationContext ) )
140
- table . Add ( new CallSignature ( name , typeof ( R ) , typeof ( A ) , typeof ( B ) , typeof ( C ) ) , InvokeeFactory . Wrap ( func , doNullProp ) ) ;
141
- else
142
- table . Add ( new CallSignature ( name , typeof ( R ) , typeof ( A ) , typeof ( B ) ) , InvokeeFactory . Wrap ( func , doNullProp ) ) ;
143
- }
96
+ _entries = new ConcurrentBag < TableEntry > ( _entries . Where ( e => e . Signature . Matches ( name , argCount ) ) )
97
+ } ;
144
98
145
- public static void Add < A , B , C , D , R > ( this SymbolTable table , string name , Func < A , B , C , D , R > func , bool doNullProp = false )
146
- {
147
- if ( typeof ( D ) != typeof ( EvaluationContext ) )
148
- table . Add ( new CallSignature ( name , typeof ( R ) , typeof ( A ) , typeof ( B ) , typeof ( C ) , typeof ( D ) ) , InvokeeFactory . Wrap ( func , doNullProp ) ) ;
149
- else
150
- table . Add ( new CallSignature ( name , typeof ( R ) , typeof ( A ) , typeof ( B ) , typeof ( C ) ) , InvokeeFactory . Wrap ( func , doNullProp ) ) ;
99
+ if ( Parent != null )
100
+ result . Parent = Parent . Filter ( name , argCount ) ;
151
101
152
- }
102
+ return result ;
103
+ }
153
104
154
- public static void AddLogic ( this SymbolTable table , string name , Func < Func < bool ? > , Func < bool ? > , bool ? > func )
155
- {
156
- table . Add ( new CallSignature ( name , typeof ( bool ? ) , typeof ( object ) , typeof ( Func < bool ? > ) , typeof ( Func < bool ? > ) ) ,
157
- InvokeeFactory . WrapLogic ( func ) ) ;
158
- }
105
+ internal Invokee ? DynamicGet ( string name , IEnumerable < object > args )
106
+ {
107
+ var exactMatches = _entries . Where ( e => e . Signature . DynamicExactMatches ( name , args ) ) ;
108
+ var entry = exactMatches . Union ( _entries . Where ( e => e . Signature . DynamicMatches ( name , args ) ) ) . FirstOrDefault ( ) ;
159
109
160
- public static void AddVar ( this SymbolTable table , string name , object value )
161
- {
162
- table . AddVar ( name , ElementNode . ForPrimitive ( value ) ) ;
163
- }
110
+ if ( entry == null && Parent != null ) return Parent . DynamicGet ( name , args ) ;
164
111
165
- public static void AddVar ( this SymbolTable table , string name , ITypedElement value )
166
- {
167
- table . Add ( new CallSignature ( name , typeof ( string ) ) , InvokeeFactory . Return ( value ) ) ;
168
- }
112
+ return entry ? . Body ;
169
113
}
170
- }
114
+ }
0 commit comments