@@ -9,6 +9,48 @@ using namespace libscratchcpp;
9
9
static const std::unordered_set<LLVMInstruction::Type>
10
10
BEGIN_LOOP_INSTRUCTIONS = { LLVMInstruction::Type::BeginRepeatLoop, LLVMInstruction::Type::BeginWhileLoop, LLVMInstruction::Type::BeginRepeatUntilLoop };
11
11
12
+ Compiler::StaticType LLVMTypeAnalyzer::variableType (LLVMVariablePtr *varPtr, LLVMInstruction *pos, Compiler::StaticType previousType) const
13
+ {
14
+ if (!varPtr || !pos)
15
+ return Compiler::StaticType::Unknown;
16
+
17
+ // Check the last write operation before the instruction
18
+ LLVMInstruction *ins = pos;
19
+ LLVMInstruction *write = nullptr ;
20
+ LLVMInstruction *loopStart = nullptr ;
21
+ int level = 0 ;
22
+
23
+ while (ins) {
24
+ if (isLoopEnd (ins))
25
+ level++;
26
+ else if (isLoopStart (ins)) {
27
+ level--;
28
+
29
+ if (!loopStart)
30
+ loopStart = ins;
31
+ } else if (ins->type == LLVMInstruction::Type::WriteVariable && ins->workVariable == varPtr->var ) {
32
+ if (level <= 0 ) { // ignore nested loops (they're handled later)
33
+ write = ins;
34
+ break ;
35
+ }
36
+ }
37
+
38
+ ins = ins->previous ;
39
+ }
40
+
41
+ if (loopStart) {
42
+ // Analyze the first loop that was found
43
+ if (variableTypeChangesInLoop (varPtr, loopStart, previousType))
44
+ return write ? writeValueType (write) : Compiler::StaticType::Unknown;
45
+ } else if (write) {
46
+ // There wasn't any loop found, so we can just check the last write operation
47
+ return writeValueType (write);
48
+ }
49
+
50
+ // No write operation found
51
+ return previousType;
52
+ }
53
+
12
54
bool LLVMTypeAnalyzer::variableTypeChangesInLoop (LLVMVariablePtr *varPtr, LLVMInstruction *loopBody, Compiler::StaticType preLoopType) const
13
55
{
14
56
if (!varPtr || !loopBody)
0 commit comments