12
12
extern "C" {
13
13
#endif
14
14
15
+ #define _equal_wchar_ (x , y , ctx ) ((x) == (y))
16
+ #define _hash_wchar_ (x , ctx ) inthash((uint32_t) ((uintptr_t) (x)))
17
+ #include "htable.inc"
18
+ HTIMPL_R (wcharhash , _hash_wchar_ , _equal_wchar_ )
19
+
15
20
static int is_uws (uint32_t wc )
16
21
{
17
22
return (wc == 9 || wc == 10 || wc == 11 || wc == 12 || wc == 13 || wc == 32 ||
@@ -134,6 +139,28 @@ JL_DLLEXPORT int jl_id_char(uint32_t wc)
134
139
return 0 ;
135
140
}
136
141
142
+ #include "julia_opsuffs.h"
143
+
144
+ // chars that can follow an operator (e.g. +) and be parsed as part of the operator
145
+ int jl_op_suffix_char (uint32_t wc )
146
+ {
147
+ static htable_t jl_opsuffs ;
148
+ if (!jl_opsuffs .size ) { // initialize hash table of suffixes
149
+ size_t i , opsuffs_len = sizeof (opsuffs ) / (sizeof (uint32_t ));
150
+ htable_t * h = htable_new (& jl_opsuffs , opsuffs_len );
151
+ assert (sizeof (uint32_t ) <= sizeof (void * ));
152
+ for (i = 0 ; i < opsuffs_len ; ++ i )
153
+ wcharhash_put_r (h , (void * )((uintptr_t )opsuffs [i ]), NULL , NULL );
154
+ }
155
+ if (wc < 0xA1 || wc > 0x10ffff ) return 0 ;
156
+ utf8proc_category_t cat = utf8proc_category ((utf8proc_int32_t ) wc );
157
+ if (cat == UTF8PROC_CATEGORY_MN || cat == UTF8PROC_CATEGORY_MC ||
158
+ cat == UTF8PROC_CATEGORY_ME )
159
+ return 1 ;
160
+ // use hash table of other allowed characters: primes and sub/superscripts
161
+ return HT_NOTFOUND != wcharhash_get_r (& jl_opsuffs , (void * )((uintptr_t )wc ), NULL );
162
+ }
163
+
137
164
value_t fl_julia_identifier_char (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
138
165
{
139
166
argcount (fl_ctx , "identifier-char?" , nargs , 1 );
@@ -152,33 +179,57 @@ value_t fl_julia_identifier_start_char(fl_context_t *fl_ctx, value_t *args, uint
152
179
return jl_id_start_char (wc ) ? fl_ctx -> T : fl_ctx -> F ;
153
180
}
154
181
155
- #include "julia_charmap.h"
156
- #define _equal_wchar_ (x , y , ctx ) ((x) == (y))
157
- #define _hash_wchar_ (x , ctx ) inthash((uint32_t) ((uintptr_t) (x)))
158
- #include "htable.inc"
159
- HTIMPL_R (wcharhash , _hash_wchar_ , _equal_wchar_ )
182
+ value_t fl_julia_op_suffix_char (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
183
+ {
184
+ argcount (fl_ctx , "op-suffix-char?" , nargs , 1 );
185
+ if (!iscprim (args [0 ]) || ((cprim_t * )ptr (args [0 ]))-> type != fl_ctx -> wchartype )
186
+ type_error (fl_ctx , "op-suffix-char?" , "wchar" , args [0 ]);
187
+ uint32_t wc = * (uint32_t * )cp_data ((cprim_t * )ptr (args [0 ]));
188
+ return jl_op_suffix_char (wc ) ? fl_ctx -> T : fl_ctx -> F ;
189
+ }
160
190
161
- void jl_charmap_init (fl_context_t * fl_ctx )
191
+ value_t fl_julia_strip_op_suffix (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
162
192
{
163
- size_t charmap_len = sizeof (charmap ) / (2 * sizeof (uint32_t ));
164
- size_t i ;
165
- htable_t * h = htable_new (& fl_ctx -> jl_charmap , charmap_len );
166
- assert (sizeof (uint32_t ) <= sizeof (void * ));
167
- for (i = 0 ; i < charmap_len ; ++ i ) {
168
- /* Store charmap in a hash table. Typecasting codepoints
169
- directly to pointer keys works because pointers are at
170
- least 32 bits on all Julia-supported systems, and because
171
- we never map anything to U+0001 (since HT_NOTFOUND is (void*)1). */
172
- assert ((void * )(uintptr_t )charmap [i ][1 ] != HT_NOTFOUND );
173
- wcharhash_put_r (h , (void * )((uintptr_t )charmap [i ][0 ]),
174
- (void * )((uintptr_t )charmap [i ][1 ]), (void * )fl_ctx );
193
+ argcount (fl_ctx , "strip-op-suffix" , nargs , 1 );
194
+ if (!issymbol (args [0 ]))
195
+ type_error (fl_ctx , "strip-op-suffix" , "symbol" , args [0 ]);
196
+ char * op = symbol_name (fl_ctx , args [0 ]);
197
+ size_t i = 0 ;
198
+ while (op [i ]) {
199
+ size_t j = i ;
200
+ if (jl_op_suffix_char (u8_nextchar (op , & j )))
201
+ break ;
202
+ i = j ;
175
203
}
204
+ if (!op [i ]) return args [0 ]; // no suffix to strip
205
+ if (!i ) lerror (fl_ctx , symbol (fl_ctx , "error" ), "invalid operator" );
206
+ char * opnew = strncpy (malloc (i + 1 ), op , i );
207
+ opnew [i ] = 0 ;
208
+ value_t opnew_symbol = symbol (fl_ctx , opnew );
209
+ free (opnew );
210
+ return opnew_symbol ;
176
211
}
177
- utf8proc_int32_t jl_charmap_map (utf8proc_int32_t c , void * fl_ctx_ )
212
+
213
+ #include "julia_charmap.h"
214
+
215
+ utf8proc_int32_t jl_charmap_map (utf8proc_int32_t c , void * ctx )
178
216
{
179
- fl_context_t * fl_ctx = (fl_context_t * ) fl_ctx_ ;
180
- htable_t * h = & fl_ctx -> jl_charmap ;
181
- void * v = wcharhash_get_r (h , (void * )((uintptr_t )c ), (void * ) fl_ctx );
217
+ static htable_t jl_charmap ;
218
+ if (!jl_charmap .size ) { // initialize hash table
219
+ size_t i , charmap_len = sizeof (charmap ) / (2 * sizeof (uint32_t ));
220
+ htable_t * h = htable_new (& jl_charmap , charmap_len );
221
+ assert (sizeof (uint32_t ) <= sizeof (void * ));
222
+ for (i = 0 ; i < charmap_len ; ++ i ) {
223
+ /* Store charmap in a hash table. Typecasting codepoints
224
+ directly to pointer keys works because pointers are at
225
+ least 32 bits on all Julia-supported systems, and because
226
+ we never map anything to U+0001 (since HT_NOTFOUND is (void*)1). */
227
+ assert ((void * )(uintptr_t )charmap [i ][1 ] != HT_NOTFOUND );
228
+ wcharhash_put_r (h , (void * )((uintptr_t )charmap [i ][0 ]),
229
+ (void * )((uintptr_t )charmap [i ][1 ]), NULL );
230
+ }
231
+ }
232
+ void * v = wcharhash_get_r (& jl_charmap , (void * )((uintptr_t )c ), NULL );
182
233
return v == HT_NOTFOUND ? c : (utf8proc_int32_t ) ((uintptr_t ) v );
183
234
}
184
235
@@ -191,7 +242,7 @@ static char *normalize(fl_context_t *fl_ctx, char *s)
191
242
ssize_t result ;
192
243
size_t newlen ;
193
244
result = utf8proc_decompose_custom ((uint8_t * ) s , 0 , NULL , 0 , (utf8proc_option_t )options ,
194
- jl_charmap_map , ( void * ) fl_ctx );
245
+ jl_charmap_map , NULL );
195
246
if (result < 0 ) goto error ;
196
247
newlen = result * sizeof (int32_t ) + 1 ;
197
248
if (newlen > fl_ctx -> jlbuflen ) {
@@ -200,7 +251,7 @@ static char *normalize(fl_context_t *fl_ctx, char *s)
200
251
if (!fl_ctx -> jlbuf ) lerror (fl_ctx , fl_ctx -> OutOfMemoryError , "error allocating UTF8 buffer" );
201
252
}
202
253
result = utf8proc_decompose_custom ((uint8_t * )s ,0 , (int32_t * )fl_ctx -> jlbuf ,result , (utf8proc_option_t )options ,
203
- jl_charmap_map , ( void * ) fl_ctx );
254
+ jl_charmap_map , NULL );
204
255
if (result < 0 ) goto error ;
205
256
result = utf8proc_reencode ((int32_t * )fl_ctx -> jlbuf ,result , (utf8proc_option_t )options );
206
257
if (result < 0 ) goto error ;
@@ -245,6 +296,8 @@ static const builtinspec_t julia_flisp_func_info[] = {
245
296
{ "accum-julia-symbol" , fl_accum_julia_symbol },
246
297
{ "identifier-char?" , fl_julia_identifier_char },
247
298
{ "identifier-start-char?" , fl_julia_identifier_start_char },
299
+ { "op-suffix-char?" , fl_julia_op_suffix_char },
300
+ { "strip-op-suffix" , fl_julia_strip_op_suffix },
248
301
{ NULL , NULL }
249
302
};
250
303
0 commit comments