24
24
from som .interpreter .ast .nodes .specialized .literal_if import (
25
25
IfInlinedNode ,
26
26
IfElseInlinedNode ,
27
+ IfNilInlinedNode ,
28
+ IfNotNilInlinedNode ,
29
+ IfNilNotNilInlinedNode ,
27
30
)
28
31
from som .interpreter .ast .nodes .specialized .literal_while import WhileInlinedNode
29
32
from som .vm .symbols import symbol_for
@@ -249,6 +252,26 @@ def _try_inlining_if(if_true, receiver, arguments, source, mgenc):
249
252
body_expr = method .inline (mgenc )
250
253
return IfInlinedNode (receiver , body_expr , if_true , source )
251
254
255
+ @staticmethod
256
+ def _try_inlining_if_nil (receiver , arguments , source , mgenc ):
257
+ arg = arguments [0 ]
258
+ if not isinstance (arg , BlockNode ):
259
+ return None
260
+
261
+ method = arg .get_method ()
262
+ body_expr = method .inline (mgenc )
263
+ return IfNilInlinedNode (receiver , body_expr , source )
264
+
265
+ @staticmethod
266
+ def _try_inlining_if_not_nil (receiver , arguments , source , mgenc ):
267
+ arg = arguments [0 ]
268
+ if not isinstance (arg , BlockNode ):
269
+ return None
270
+
271
+ method = arg .get_method ()
272
+ body_expr = method .inline (mgenc )
273
+ return IfNotNilInlinedNode (receiver , body_expr , source )
274
+
252
275
@staticmethod
253
276
def _try_inlining_if_else (if_true , receiver , arguments , source , mgenc ):
254
277
arg1 = arguments [0 ]
@@ -263,6 +286,25 @@ def _try_inlining_if_else(if_true, receiver, arguments, source, mgenc):
263
286
false_expr = arg2 .get_method ().inline (mgenc )
264
287
return IfElseInlinedNode (receiver , true_expr , false_expr , if_true , source )
265
288
289
+ @staticmethod
290
+ def _try_inlining_if_nil_not_nil (is_if_nil , receiver , arguments , source , mgenc ):
291
+ arg1 = arguments [0 ]
292
+ if not isinstance (arg1 , BlockNode ):
293
+ return None
294
+
295
+ arg2 = arguments [1 ]
296
+ if not isinstance (arg2 , BlockNode ):
297
+ return None
298
+
299
+ arg1_expr = arg1 .get_method ().inline (mgenc )
300
+ arg2_expr = arg2 .get_method ().inline (mgenc )
301
+ return IfNilNotNilInlinedNode (
302
+ receiver ,
303
+ arg1_expr if is_if_nil else arg2_expr ,
304
+ arg2_expr if is_if_nil else arg1_expr ,
305
+ source ,
306
+ )
307
+
266
308
@staticmethod
267
309
def _try_inlining_while (while_true , receiver , arguments , source , mgenc ):
268
310
if not isinstance (receiver , BlockNode ):
@@ -321,6 +363,18 @@ def _keyword_message(self, mgenc, receiver):
321
363
)
322
364
if inlined is not None :
323
365
return inlined
366
+ elif keyword == "ifNil:" :
367
+ inlined = self ._try_inlining_if_nil (
368
+ receiver , arguments , source , mgenc
369
+ )
370
+ if inlined is not None :
371
+ return inlined
372
+ elif keyword == "ifNotNil:" :
373
+ inlined = self ._try_inlining_if_not_nil (
374
+ receiver , arguments , source , mgenc
375
+ )
376
+ if inlined is not None :
377
+ return inlined
324
378
elif keyword == "whileTrue:" :
325
379
inlined = self ._try_inlining_while (
326
380
True , receiver , arguments , source , mgenc
@@ -358,6 +412,18 @@ def _keyword_message(self, mgenc, receiver):
358
412
)
359
413
if inlined is not None :
360
414
return inlined
415
+ elif keyword == "ifNil:ifNotNil:" :
416
+ inlined = self ._try_inlining_if_nil_not_nil (
417
+ True , receiver , arguments , source , mgenc
418
+ )
419
+ if inlined is not None :
420
+ return inlined
421
+ elif keyword == "ifNotNil:ifNil:" :
422
+ inlined = self ._try_inlining_if_nil_not_nil (
423
+ False , receiver , arguments , source , mgenc
424
+ )
425
+ if inlined is not None :
426
+ return inlined
361
427
362
428
selector = symbol_for (keyword )
363
429
0 commit comments