• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tbklang / tlang / #973

03 Jan 2025 09:39AM UTC coverage: 79.97% (-0.4%) from 80.342%
#973

push

coveralls-ruby

deavmi
Dep-gen

- Added missing import

4839 of 6051 relevant lines covered (79.97%)

368.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.43
/source/tlang/compiler/codegen/instruction.d
1
module tlang.compiler.codegen.instruction;
2

3
import std.conv : to;
4
import tlang.compiler.typecheck.dependency.core : Context;
5
import std.string : cmp, format;
6
import tlang.compiler.symbols.data : SymbolType;
7
import tlang.compiler.symbols.check : getCharacter;
8
import gogga;
9
import tlang.compiler.symbols.typing.core : Type;
10
import tlang.compiler.codegen.render;
11

12
public class Instruction
13
{
14
    /* Context for the Instruction (used in emitter for name resolution) */
15
    private Context context; //TODO: Make this private and add a setCOntext
16

17
    protected string addInfo;
18

19
    public override string toString()
20
    {
21
        return "[Instruction: "~this.classinfo.name~":"~addInfo~"]";
3,191✔
22
    }
23

24
    private final string produceToStrEnclose(string addInfo)
25
    {
26
        return "[Instruction: "~this.classinfo.name~":"~addInfo~"]";
888✔
27
    }
28

29
    public final Context getContext()
30
    {
31
        return context;
252✔
32
    }
33

34
    public final void setContext(Context context)
35
    {
36
        this.context = context;
419✔
37
    }
38
}
39

40
public class Value : Instruction
41
{
42
    /* The type of the Value this instruction produces */
43
    private Type type;
44

45
    public final void setInstrType(Type type)
46
    {
47
        this.type = type;
311✔
48
    }
49

50
    public final Type getInstrType()
51
    {
52
        return type;
1,178✔
53
    }
54
}
55

56
public class StorageDeclaration : Instruction
57
{
58

59
}
60

61
public class ClassStaticInitAllocate : Instruction
62
{
63
    this(string className)
×
64
    {
65
        addInfo = "classStaticInitAllocate: "~className;
×
66
    }
67
}
68

69
public class VariableAssignmentInstr : Instruction, IRenderable
70
{
71
    /* Name of variable being declared */
72
    public string varName; /*TODO: Might not be needed */
73

74
    public Value data;
75

76
    this(string varName, Value data)
45✔
77
    {
78
        this.varName = varName;
45✔
79
        this.data = data;
45✔
80

81
        addInfo = "assignTo: "~varName~", valInstr: "~data.toString();
45✔
82
    }
83

84
    public string render()
85
    {
86
        return format("%s = %s", varName, tryRender(data));
1✔
87
    }
88
}
89

90
public final class VariableDeclaration : StorageDeclaration, IRenderable
91
{
92
    /* Name of variable being declared */
93
    public const string varName;
94

95
    /* Length */
96
    public const byte length;
97

98
    /* Type of the variable being declared */
99
    public Type varType;
100

101
    /* Value-instruction to be assigned */
102
    private Value varAssInstr;
103

104
    //TODO: This must take in type information
105
    this(string varName, byte len, Type varType, Value varAssInstr)
95✔
106
    {
107
        this.varName = varName;
95✔
108
        this.length = len;
95✔
109
        this.varType = varType;
95✔
110

111
        this.varAssInstr = varAssInstr;
95✔
112

113
        addInfo = "varName: "~varName;
95✔
114
    }
115

116
    public Value getAssignmentInstr()
117
    {
118
        return varAssInstr;
30✔
119
    }
120

121
    public bool hasAssignmentInstr()
122
    {
123
        return varAssInstr !is null;
1✔
124
    }
125

126
    public string render()
127
    {
128
        string varAssInstr_s = hasAssignmentInstr() ? format(" = %s", tryRender(getAssignmentInstr())) : "";
2✔
129
        return format("%s %s%s", varType.getName(), varName, varAssInstr_s);
1✔
130
    }
131
}
132

133
public final class FetchValueVar : Value, IRenderable
134
{
135
    /* Name of variable to fetch from */
136
    public string varName;
137

138
    /* Length */
139
    public byte length;
140

141
    this(string varName, byte len)
150✔
142
    {
143
        this.varName = varName;
150✔
144
        this.length = len;
150✔
145

146
        addInfo = "fetchVarValName: "~varName~", VarLen: "~to!(string)(length);
150✔
147
    }
148

149
    public string render()
150
    {
151
        return varName;
1✔
152
    }
153
}
154

155
/* Used for integers */
156
public final class LiteralValue : Value, IRenderable
157
{
158
    /* Data */
159
    private string data;
160

161
    this(string data, Type type)
209✔
162
    {
163
        this.data = data;
209✔
164
        this.type = type;
209✔
165

166
        addInfo = "Data: "~to!(string)(data)~", Type: "~to!(string)(type);
209✔
167
    }
168

169
    public string getLiteralValue()
170
    {
171
        return data;
162✔
172
    }
173

174
    public override string toString()
175
    {
176
        return produceToStrEnclose("Data: "~to!(string)(data)~", Type: "~to!(string)(type));
888✔
177
    }
178

179
    public string render()
180
    {
181
        return data;
14✔
182
    }
183
}
184

185
public final class LiteralValueFloat : Value, IRenderable
186
{
187
    /* Data */
188
    private string data;
189

190
    this(string data, Type type)
×
191
    {
192
        this.data = data;
×
193
        this.type = type;
×
194

195
        addInfo = "Data: "~to!(string)(data)~", Type: "~to!(string)(type);
×
196
    }
197

198
    public string getLiteralValue()
199
    {
200
        return data;
×
201
    }
202

203
    public override string toString()
204
    {
205
        return produceToStrEnclose("Data: "~to!(string)(data)~", Type: "~to!(string)(type));
×
206
    }
207

208
    public string render()
209
    {
210
        return data;
×
211
    }
212
}
213

214
/* FIXME: Implement this */
215
/**
216
* TODO: This should take in:
217
*
218
* 1. The string literal
219
* 2. It should assign it to an interning pool and get the ID (associate one with the string literal if equal/in-the-pool)
220
*/
221
public final class StringLiteral : Value, IRenderable
222
{
223
    /* String interning pool */
224
    // private static int[string] internmentCamp;
225
    // private static int rollCount = 0;
226
    // private string stringLiteral;
227
    
228
    import tlang.compiler.symbols.strings;
229
    private StringInfo _s;
230

231
    this(StringInfo str)
×
232
    {
233
        this._s = str;
×
234
        addInfo = "StrLit: "~this._s.toString();
×
235
    }
236

237
    public StringInfo* str()
238
    {
239
        return &this._s;
×
240
    }
241

242
    // public static int intern(string strLit)
243
    // {
244
    //     /* Search for the string (if it exists return it's pool ID) */
245
    //     foreach(string curStrLit; internmentCamp.keys())
246
    //     {
247
    //         if(cmp(strLit, curStrLit) == 0)
248
    //         {
249
    //             return internmentCamp[strLit];
250
    //         }
251
    //     }
252

253
    //     /* If not, create a new entry (pool it) and return */
254
    //     internmentCamp[strLit] = rollCount;
255
    //     rollCount++; /* TODO: Overflow check */
256

257
    //     return rollCount-1;
258
    // }
259

260

261
    public string render()
262
    {
263
        return this._s.toString();
×
264
    }
265
}
266

267
/** 
268
 * Operator instruction
269
 *
270
 * This represents any instruction
271
 * which has a single operator.
272
 */
273
public abstract class OperatorInstruction : Value
274
{
275
    /** 
276
     * The operator
277
     */
278
    protected SymbolType operator;
279

280
    /** 
281
     * Constructs a new operator
282
     * instruction with the given
283
     * operator
284
     *
285
     * Params:
286
     *   operator = the operator
287
     */
288
    this(SymbolType operator)
103✔
289
    {
290
        this.operator = operator;
103✔
291
    }
292

293
    /** 
294
     * Sets the operator
295
     *
296
     * Params:
297
     *   operator = the new operator
298
     */
299
    public final void setOperator(SymbolType operator)
300
    {
301
        this.operator = operator;
×
302
    }
303

304
    /** 
305
     * Returns the operator
306
     *
307
     * Returns: the operator
308
     */
309
    public final SymbolType getOperator()
310
    {
311
        return this.operator;
79✔
312
    }
313
}
314

315
/**
316
* Binary operator instruction
317
*
318
* Any sort of binary operation
319
*/
320
public final class BinOpInstr : OperatorInstruction, IRenderable
321
{
322
    private Value lhs;
323
    private Value rhs;
324

325
    /** 
326
     * Constructs a new binary operator
327
     * instruction with the given
328
     * parameters
329
     *
330
     * Params:
331
     *   lhs = the left-hand operand 
332
     *   rhs = the right-hand operand
333
     *   operator = the operator
334
     */
335
    this(Value lhs, Value rhs, SymbolType operator)
82✔
336
    {
337
        super(operator);
82✔
338
        this.lhs = lhs;
82✔
339
        this.rhs = rhs;
82✔
340

341
        addInfo = "BinOpType: "~to!(string)(operator)~", LhsValInstr: "~lhs.toString()~", RhsValInstr: "~rhs.toString();
82✔
342
    }
343

344
    /** 
345
     * Returns the left-hand operand
346
     * instruction
347
     *
348
     * Returns: the instruction
349
     */
350
    public Value getLHSInstr()
351
    {
352
        return this.lhs;
122✔
353
    }
354

355
    /** 
356
     * Returns the right-hand operand
357
     * instruction
358
     *
359
     * Returns: the instruction
360
     */
361
    public Value getRHSInstr()
362
    {
363
        return this.rhs;
127✔
364
    }
365

366
    public string render()
367
    {
368
        // TODO: Remove casts from const
369
        return format
5✔
370
        (
371
            "%s %s %s",
372
            tryRender(cast(Instruction)this.lhs),
373
            getCharacter(this.operator),
374
            tryRender(cast(Instruction)this.rhs)
375
        );
376
    }
377
}
378

379
/**
380
* Unary operator instruction
381
*
382
* Any sort of unary operation
383
*/
384
public final class UnaryOpInstr : OperatorInstruction, IRenderable
385
{
386
    private Value exp;
387

388
    /** 
389
     * Constructs a new unary operator
390
     * instruction with the given
391
     * parameters
392
     *
393
     * Params:
394
     *   exp = the singular operand
395
     *   operator = the operator
396
     */
397
    this(Value exp, SymbolType operator)
21✔
398
    {
399
        super(operator);
21✔
400
        this.exp = exp;
21✔
401

402
        addInfo = "UnaryOpType: "~to!(string)(operator)~", Instr: "~exp.toString();
21✔
403
    }
404

405
    /** 
406
     * Returns the singular opernad
407
     * instruction
408
     *
409
     * Returns: the instruction
410
     */
411
    public Value getOperand()
412
    {
413
        return exp;
18✔
414
    }
415

416
    public string render()
417
    {
418
        return format("%s%s", getCharacter(operator), tryRender(exp));
×
419
    }
420
}
421

422
//public class CallInstr : Instruction
423
public class CallInstr : Value
424
{
425

426
}
427

428
public class FuncCallInstr : CallInstr, IRenderable
429
{
430
    /** 
431
     * This is described in the corresponding AST node
432
     * `FunctionCall`. See that. For short, function calls
433
     * from within expressions and those as appearing as statements
434
     * require a tiny different code gen but for Instructions
435
     * their emit also needs a tiny difference
436
     */
437
    private bool statementLevel = false;
438

439
    /* Per-argument instrructions */
440
    private Value[] evaluationInstructions;
441

442
    public const string functionName;
443

444
    this(string functionName, ulong argEvalInstrsSize)
41✔
445
    {
446
        this.functionName = functionName;
41✔
447
        evaluationInstructions.length = argEvalInstrsSize;
41✔
448

449
        updateAddInfo();
41✔
450
    }
451

452
    /**
453
    * FuncCallInstr is built-bit-by-bit so toString information will change
454
    */
455
    private void updateAddInfo()
456
    {
457
        addInfo = "FunctionName: "~functionName ~" EvalInstrs: "~ to!(string)(getEvaluationInstructions());
78✔
458
    }
459

460
    public void setEvalInstr(ulong argPos, Value instr)
461
    {
462
        evaluationInstructions[argPos] = instr;
37✔
463
        updateAddInfo();
37✔
464
    }
465

466
    public Value[] getEvaluationInstructions()
467
    {
468
        return evaluationInstructions;
128✔
469
    }
470

471
    /** 
472
     * Determines whether this function call instruction
473
     * is within an expression or a statement itself
474
     *
475
     * Returns: true if statement-level, false otherwise
476
     */
477
    public bool isStatementLevel()
478
    {
479
        return statementLevel;
15✔
480
    }
481

482
    /** 
483
     * Marks this function call instruction as statement
484
     * level
485
     */
486
    public void markStatementLevel()
487
    {
488
        statementLevel = true;
3✔
489
    }
490

491
    public string render()
492
    {
493
        string arg_s;
1✔
494
        foreach(Value arg; evaluationInstructions)
9✔
495
        {
496
            arg_s ~= format("%s, ", tryRender(arg));
2✔
497
        }
498
        import std.string : strip;
499
        arg_s = strip(arg_s, ", ");
1✔
500

501
        return format("%s(%s)", functionName, arg_s);
1✔
502
    }
503
}
504

505

506
public final class ReturnInstruction : Instruction, IRenderable
507
{
508
    private Value returnExprInstr;
509

510
    this(Value returnExprInstr)
36✔
511
    {
512
        this.returnExprInstr = returnExprInstr;
36✔
513
    }
514

515
    this()
1✔
516
    {
517

518
    }
519

520
    public Value getReturnExpInstr()
521
    {
522
        return returnExprInstr;
21✔
523
    }
524

525
    public bool hasReturnExpInstr()
526
    {
527
        return returnExprInstr !is null;
21✔
528
    }
529

530
    public string render()
531
    {
532
        return format("return %s", tryRender(returnExprInstr));
×
533
    }
534
}
535

536
public final class IfStatementInstruction : Instruction, IRenderable
537
{
538
    private BranchInstruction[] branchInstructions;
539

540
    this(BranchInstruction[] branchInstructions)
9✔
541
    {
542
        this.branchInstructions = branchInstructions;
9✔
543

544
        addInfo = "Branches: "~to!(string)(branchInstructions);
9✔
545
    }
546

547
    public BranchInstruction[] getBranchInstructions()
548
    {
549
        return branchInstructions;
8✔
550
    }
551

552
    public string render()
553
    {
554
        bool fst = true;
1✔
555
        string s;
1✔
556
        foreach(BranchInstruction b; branchInstructions)
12✔
557
        {
558
            if(b.hasConditionInstr()) // `if` or `else if`
3✔
559
            {
560
                if(fst) // `if`
2✔
561
                {
562
                    s ~= format("if(%s) {}\n", tryRender(b.getConditionInstr()));
1✔
563
                    fst = false;
1✔
564
                }
565
                else // `else if`
566
                {
567
                    s ~= format("else if(%s) {}\n", tryRender(b.getConditionInstr()));
1✔
568
                }
569
            }
570
            else // `else`
571
            {
572
                s ~= "else {}";
1✔
573
            }
574
        }
575

576
        return s;
1✔
577
    }
578
}
579

580
public final class WhileLoopInstruction : Instruction, IRenderable
581
{
582
    private BranchInstruction branchInstruction;
583

584
    this(BranchInstruction branchInstruction)
2✔
585
    {
586
        this.branchInstruction = branchInstruction;
2✔
587

588
        addInfo = "Branch: "~to!(string)(branchInstruction);
2✔
589
    }
590

591
    public BranchInstruction getBranchInstruction()
592
    {
593
        return branchInstruction;
1✔
594
    }
595

596
    public string render()
597
    {
598
        return format("while(%s) {}", tryRender(branchInstruction.getConditionInstr()));
1✔
599
    }
600
}
601

602
public final class ForLoopInstruction : Instruction, IRenderable
603
{
604
    private Instruction preRunInstruction;
605
    private BranchInstruction branchInstruction;
606
    private bool hasPostIterate;
607

608
    this(BranchInstruction branchInstruction, Instruction preRunInstruction = null, bool hasPostIterate = false)
3✔
609
    {
610
        this.branchInstruction = branchInstruction;
3✔
611
        this.preRunInstruction = preRunInstruction;
3✔
612

613
        addInfo = (hasPreRunInstruction() ? "PreRun: "~to!(string)(preRunInstruction)~", " : "")~"Branch: "~to!(string)(branchInstruction);
6✔
614

615
        this.hasPostIterate = hasPostIterate;
3✔
616
    }
617

618
    public bool hasPostIterationInstruction()
619
    {
620
        return hasPostIterate;
1✔
621
    }
622

623
    public Instruction getPreRunInstruction()
624
    {
625
        return preRunInstruction;
2✔
626
    }
627

628
    public bool hasPreRunInstruction()
629
    {
630
        return !(preRunInstruction is null);
5✔
631
    }
632

633
    public BranchInstruction getBranchInstruction()
634
    {
635
        return branchInstruction;
2✔
636
    }
637

638
    public string render()
639
    {
640
        string postIterate_s = hasPostIterationInstruction() ? tryRender(branchInstruction.getBodyInstructions()[$-1]) : "";
2✔
641
        string preRun_s = hasPreRunInstruction() ? tryRender(getPreRunInstruction()) : "";
2✔
642
        string iterInstr_s = tryRender(getBranchInstruction().getConditionInstr());
1✔
643
        return format("for(%s; %s; %s) {}", preRun_s, iterInstr_s, postIterate_s);
1✔
644
    }
645
}
646

647
public final class BranchInstruction : Instruction
648
{
649
    private Value branchConditionInstr;
650
    private Instruction[] bodyInstructions;
651

652
    this(Value conditionInstr, Instruction[] bodyInstructions)
23✔
653
    {
654
        this.branchConditionInstr = conditionInstr;
23✔
655
        this.bodyInstructions = bodyInstructions;
23✔
656

657
        addInfo = "CondInstr: "~to!(string)(branchConditionInstr)~", BBodyInstrs: "~to!(string)(bodyInstructions);
23✔
658
    }
659

660
    public bool hasConditionInstr()
661
    {
662
        return !(branchConditionInstr is null);
18✔
663
    }
664

665
    public Value getConditionInstr()
666
    {
667
        return branchConditionInstr;
17✔
668
    }
669

670
    public Instruction[] getBodyInstructions()
671
    {
672
        return bodyInstructions;
18✔
673
    }
674
}
675

676
public final class PointerDereferenceAssignmentInstruction : Instruction, IRenderable
677
{
678
    private Value pointerEvalInstr;
679
    private Value assigmnetExprInstr;
680
    private ulong derefCount;
681

682
    this(Value pointerEvalInstr, Value assigmnetExprInstr, ulong derefCount)
7✔
683
    {
684
        this.pointerEvalInstr = pointerEvalInstr;
7✔
685
        this.assigmnetExprInstr = assigmnetExprInstr;
7✔
686
        this.derefCount = derefCount;
7✔
687
    }
688

689
    public Value getPointerEvalInstr()
690
    {
691
        return pointerEvalInstr;
7✔
692
    }
693

694
    public Value getAssExprInstr()
695
    {
696
        return assigmnetExprInstr;
7✔
697
    }
698

699
    public ulong getDerefCount()
700
    {
701
        return derefCount;
13✔
702
    }
703

704
    public string render()
705
    {
706
        import niknaks.text : genX;
707

708
        return format
1✔
709
        (
710
            "%s%s = %s",
711
            genX(getDerefCount(), "*"),
712
            tryRender(getPointerEvalInstr()),
713
            tryRender(getAssExprInstr())
714
        );
715
    }
716
}
717

718
public final class DiscardInstruction : Instruction, IRenderable
719
{
720
    private Value exprInstr;
721

722
    this(Value exprInstr)
8✔
723
    {
724
        this.exprInstr = exprInstr;
8✔
725
    }
726

727
    public Value getExpressionInstruction()
728
    {
729
        return exprInstr;
3✔
730
    }
731

732
    public string render()
733
    {
734
        return format("discard %s", tryRender(exprInstr));
×
735
    }
736
}
737

738
public final class CastedValueInstruction : Value, IRenderable
739
{
740
    /* The uncasted original instruction that must be executed-then-trimmed (casted) */
741
    private Value uncastedValue;
742

743
    /** 
744
     * Used in code emitting, this is related to
745
     * #140. Really just a C+DGen thing.
746
     *
747
     * Signals that we shouldn't emit any special
748
     * casting syntax in the underlying emitter.
749
     */
750
    private bool relax;
751

752
    this(Value uncastedValue, Type castToType)
55✔
753
    {
754
        this.uncastedValue = uncastedValue;
55✔
755
        this.type = castToType;
55✔
756

757
        // Relaxing is disabled by default
758
        this.relax = false;
55✔
759
    }
760

761
    public Value getEmbeddedInstruction()
762
    {
763
        return uncastedValue;
17✔
764
    }
765

766
    public Type getCastToType()
767
    {
768
        return type;
17✔
769
    }
770

771
    public bool isRelaxed()
772
    {
773
        return relax;
17✔
774
    }
775

776
    public void setRelax(bool relax)
777
    {
778
        this.relax = relax;
5✔
779
    }
780

781
    public string render()
782
    {
783
        return format("cast(%s)%s", getCastToType(), tryRender(getEmbeddedInstruction()));
×
784
    }
785
}
786

787
public final class ArrayIndexInstruction : Value, IRenderable
788
{
789
    /* Index-to instruction */
790
    private Value indexTo;
791

792
    /* The index */
793
    private Value index;
794

795
    this(Value indexTo, Value index)
19✔
796
    {
797
        this.indexTo = indexTo;
19✔
798
        this.index = index;
19✔
799
    }
800

801
    public Value getIndexInstr()
802
    {
803
        return index;
21✔
804
    }
805

806
    public Value getIndexedToInstr()
807
    {
808
        return indexTo;
21✔
809
    }
810

811
    public override string toString()
812
    {
813
        return "ArrayIndexInstr [IndexTo: "~indexTo.toString()~", Index: "~index.toString()~"]";
21✔
814
    }
815

816
    public string render()
817
    {
818
        return format("%s[%s]", tryRender(getIndexedToInstr()), tryRender(getIndexInstr()));
1✔
819
    }
820
}
821

822
//TODO: ArrayIndexAssignmentInstruction
823
public final class ArrayIndexAssignmentInstruction : Instruction, IRenderable
824
{
825
    // TODO: We then need the left hand side array evaluation instruction (a pointer value basically)
826
    // private Value arrayPtrEval;
827

828
    // TODO: We then also need a `Value` field for the index expression instruction
829
    // private Value index;
830

831
    // NOTE: We now to the above to using an ArrayIndexInstruction
832
    private ArrayIndexInstruction arrayPtrEval;
833

834
    // TODO: We then also need another `Value` field for the expression instruction
835
    // ... being assigned into the pointer-array
836
    private Value assignment;
837

838
    this(ArrayIndexInstruction arrayPtrEval, Value assignment)
12✔
839
    {
840
        this.arrayPtrEval = arrayPtrEval;
12✔
841
        // this.index = index;
842
        this.assignment = assignment;
12✔
843
    }
844

845
    public ArrayIndexInstruction getArrayPtrEval()
846
    {
847
        return arrayPtrEval;
6✔
848
    }
849

850
    public Value getAssignmentInstr()
851
    {
852
        return assignment;
6✔
853
    }
854

855
    public string render()
856
    {
857
        return format("%s = %s", tryRender(getArrayPtrEval()), tryRender(getAssignmentInstr()));
×
858
    }
859
}
860

861
// TODO: StackArrayIndexInstruction
862
public final class StackArrayIndexInstruction : Value, IRenderable
863
{
864
    /* Index-to instruction */
865
    private Value indexTo;
866

867
    /* The index */
868
    private Value index;
869

870
    this(Value indexTo, Value index)
12✔
871
    {
872
        this.indexTo = indexTo;
12✔
873
        this.index = index;
12✔
874
    }
875

876
    public Value getIndexInstr()
877
    {
878
        return index;
8✔
879
    }
880

881
    public Value getIndexedToInstr()
882
    {
883
        return indexTo;
8✔
884
    }
885

886
    public override string toString()
887
    {
888
        return "StackArrayIndexInstr [IndexTo: "~indexTo.toString()~", Index: "~index.toString()~"]";
44✔
889
    }
890

891
    public string render()
892
    {
893
        return format("%s[%s]", tryRender(getIndexedToInstr()), tryRender(getIndexInstr()));
×
894
    }
895
}
896

897
// TODO: StackArrayIndexAssignmentInstruction
898
public final class StackArrayIndexAssignmentInstruction : Instruction, IRenderable
899
{
900
    // TODO: We need a `string` field here which is looked up with the 
901
    // ... associated context of this instruction and refers to the
902
    // ... stack-array being index-assigned into
903
    private string arrayName;
904

905
    // TODO: We then also need a `Value` field for the index expression instruction
906
    private Value index;
907

908
    // TODO: We then also need another `Value` field for the expression instruction
909
    // ... being assigned into the stack-array at said index
910
    private Value assignment;
911

912
    this(string arrayName, Value index, Value assignment)
12✔
913
    {
914
        this.arrayName = arrayName;
12✔
915
        this.index = index;
12✔
916
        this.assignment = assignment;
12✔
917
    }
918

919
    public string getArrayName()
920
    {
921
        return arrayName;
4✔
922
    }
923

924
    public Value getIndexInstr()
925
    {
926
        return index;
4✔
927
    }
928

929
    public Value getAssignedValue()
930
    {
931
        return assignment;
4✔
932
    }
933

934
    public override string toString()
935
    {
936
        return "StackArrayASSIGN [name: "~arrayName~", index: "~index.toString()~", Assignment: "~assignment.toString()~"]";
135✔
937
    }
938

939
    public string render()
940
    {
941
        return format("%s[%s] = %s", getArrayName(), tryRender(getIndexInstr()), tryRender(getAssignedValue()));
×
942
    }
943
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc