@@ -319,7 +319,21 @@ func forStmtToMLOG(ctx context.Context, statement *ast.ForStmt) ([]MLOGStatement
319
319
var loopStartJump * MLOGJump
320
320
var intoLoopJump * MLOGJump
321
321
322
+ var loopStartOverride * MLOGStatement
323
+
322
324
if statement .Cond != nil {
325
+ loopStartJump = & MLOGJump {
326
+ MLOG : MLOG {
327
+ Comment : "Jump to start of loop" ,
328
+ },
329
+ }
330
+
331
+ intoLoopJump = & MLOGJump {
332
+ MLOG : MLOG {
333
+ Comment : "Jump into the loop" ,
334
+ },
335
+ }
336
+
323
337
if binaryExpr , ok := statement .Cond .(* ast.BinaryExpr ); ok {
324
338
if translatedOp , ok := jumpOperators [binaryExpr .Op ]; ok {
325
339
leftSide , leftExprInstructions , err := exprToResolvable (ctx , binaryExpr .X )
@@ -342,32 +356,70 @@ func forStmtToMLOG(ctx context.Context, statement *ast.ForStmt) ([]MLOGStatement
342
356
return nil , Err (ctx , "unknown error" )
343
357
}
344
358
345
- loopStartJump = & MLOGJump {
346
- MLOG : MLOG {
347
- Comment : "Jump to start of loop" ,
348
- },
349
- Condition : []Resolvable {
350
- & Value {Value : translatedOp },
351
- leftSide [0 ],
352
- rightSide [0 ],
353
- },
359
+ loopStartJump .Condition = []Resolvable {
360
+ & Value {Value : translatedOp },
361
+ leftSide [0 ],
362
+ rightSide [0 ],
354
363
}
355
364
356
- intoLoopJump = & MLOGJump {
357
- MLOG : MLOG {
358
- Comment : "Jump into the loop" ,
359
- },
360
- Condition : []Resolvable {
361
- & Value {Value : translatedOp },
362
- leftSide [0 ],
363
- rightSide [0 ],
364
- },
365
+ intoLoopJump .Condition = []Resolvable {
366
+ & Value {Value : translatedOp },
367
+ leftSide [0 ],
368
+ rightSide [0 ],
365
369
}
366
370
} else {
367
- return nil , Err (ctx , fmt .Sprintf ("jump statement cannot use this operation: %T" , binaryExpr .Op ))
371
+ expr , exprInstructions , err := exprToResolvable (ctx , binaryExpr .X )
372
+ if err != nil {
373
+ return nil , err
374
+ }
375
+
376
+ results = append (results , exprInstructions ... )
377
+
378
+ if len (expr ) != 1 {
379
+ return nil , Err (ctx , "unknown error" )
380
+ }
381
+
382
+ loopStartJump .Condition = []Resolvable {
383
+ & Value {Value : "always" },
384
+ }
385
+
386
+ intoLoopJump .Condition = []Resolvable {
387
+ & Value {Value : jumpOperators [token .EQL ]},
388
+ expr [0 ],
389
+ & Value {Value : "true" },
390
+ }
391
+
392
+ loopStartOverride = & exprInstructions [0 ]
393
+ }
394
+ } else if unaryExpr , ok := statement .Cond .(* ast.UnaryExpr ); ok {
395
+ if unaryExpr .Op != token .NOT {
396
+ return nil , Err (ctx , fmt .Sprintf ("loop unary expresion cannot use this operation: %T" , binaryExpr .Op ))
397
+ }
398
+
399
+ expr , exprInstructions , err := exprToResolvable (ctx , unaryExpr .X )
400
+ if err != nil {
401
+ return nil , err
402
+ }
403
+
404
+ results = append (results , exprInstructions ... )
405
+
406
+ if len (expr ) != 1 {
407
+ return nil , Err (ctx , "unknown error" )
408
+ }
409
+
410
+ loopStartJump .Condition = []Resolvable {
411
+ & Value {Value : jumpOperators [token .NEQ ]},
412
+ expr [0 ],
413
+ & Value {Value : "true" },
414
+ }
415
+
416
+ intoLoopJump .Condition = []Resolvable {
417
+ & Value {Value : jumpOperators [token .NEQ ]},
418
+ expr [0 ],
419
+ & Value {Value : "true" },
368
420
}
369
421
} else {
370
- return nil , Err (ctx , "for loop can only have binary conditional expressions" )
422
+ return nil , Err (ctx , "for loop can only have unary or binary conditional expressions" )
371
423
}
372
424
} else {
373
425
loopStartJump = & MLOGJump {
@@ -425,7 +477,12 @@ func forStmtToMLOG(ctx context.Context, statement *ast.ForStmt) ([]MLOGStatement
425
477
blockCtxStruct .Extra = append (blockCtxStruct .Extra , instructions ... )
426
478
}
427
479
428
- loopStartJump .JumpTarget = bodyMLOG [0 ]
480
+ if loopStartOverride != nil {
481
+ loopStartJump .JumpTarget = * loopStartOverride
482
+ } else {
483
+ loopStartJump .JumpTarget = bodyMLOG [0 ]
484
+ }
485
+
429
486
results = append (results , loopStartJump )
430
487
blockCtxStruct .Extra = append (blockCtxStruct .Extra , loopStartJump )
431
488
0 commit comments