Skip to content

Commit 92076c2

Browse files
Merge pull request #60 from CompilerProgramming/next
Add a semantic analysis pass to perform checks on nullable types
2 parents aa87faf + 10529a0 commit 92076c2

13 files changed

Lines changed: 2090 additions & 134 deletions

File tree

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/Compiler.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.compilerprogramming.ezlang.lexer.Lexer;
44
import com.compilerprogramming.ezlang.parser.Parser;
5+
import com.compilerprogramming.ezlang.semantic.NullableAnalysis;
56
import com.compilerprogramming.ezlang.semantic.SemaAssignTypes;
67
import com.compilerprogramming.ezlang.semantic.SemaDefineTypes;
78
import com.compilerprogramming.ezlang.types.Symbol;
@@ -35,6 +36,7 @@ public TypeDictionary compileSrc(String src, EnumSet<Options> options) {
3536
sema.analyze(program);
3637
var sema2 = new SemaAssignTypes(typeDict);
3738
sema2.analyze(program);
39+
NullableAnalysis.analyze(typeDict);
3840
compile(typeDict, options);
3941
return typeDict;
4042
}

optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestSSADestructB.java

Lines changed: 147 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -4578,7 +4578,8 @@ public void testSSA15() {
45784578
func foo()->Int
45794579
{
45804580
var f = new [Foo?] { new Foo{i = 1}, null }
4581-
return null == f[1] && 1 == f[0].i
4581+
var f0 = f[0]
4582+
return null == f[1] && f0 != null && 1 == f0.i
45824583
}
45834584
""";
45844585
String result = compileSrc(src);
@@ -4587,136 +4588,196 @@ func foo()->Int
45874588
Before SSA
45884589
==========
45894590
L0:
4590-
%t1 = New([Foo?], len=2)
4591-
%t2 = New(Foo)
4592-
%t2.i = 1
4593-
%t1[0] = %t2
4594-
%t1[1] = null
4595-
f = %t1
4596-
%t3 = f[1]
4597-
%t4 = null==%t3
4598-
if %t4 goto L2 else goto L3
4591+
%t2 = New([Foo?], len=2)
4592+
%t3 = New(Foo)
4593+
%t3.i = 1
4594+
%t2[0] = %t3
4595+
%t2[1] = null
4596+
f = %t2
4597+
%t4 = f[0]
4598+
f0 = %t4
4599+
%t5 = f[1]
4600+
%t6 = null==%t5
4601+
if %t6 goto L5 else goto L6
4602+
L5:
4603+
%t7 = f0!=null
4604+
goto L7
4605+
L7:
4606+
if %t7 goto L2 else goto L3
45994607
L2:
4600-
%t5 = f[0]
4601-
%t6 = %t5.i
4602-
%t7 = 1==%t6
4608+
%t8 = f0.i
4609+
%t9 = 1==%t8
46034610
goto L4
46044611
L4:
4605-
ret %t7
4612+
ret %t9
46064613
goto L1
46074614
L1:
46084615
L3:
4609-
%t7 = 0
4616+
%t9 = 0
46104617
goto L4
4618+
L6:
4619+
%t7 = 0
4620+
goto L7
46114621
After SSA
46124622
=========
46134623
L0:
4614-
%t1_0 = New([Foo?], len=2)
4615-
%t2_0 = New(Foo)
4616-
%t2_0.i = 1
4617-
%t1_0[0] = %t2_0
4618-
%t1_0[1] = null
4619-
f_0 = %t1_0
4620-
%t3_0 = f_0[1]
4621-
%t4_0 = null==%t3_0
4622-
if %t4_0 goto L2 else goto L3
4624+
%t2_0 = New([Foo?], len=2)
4625+
%t3_0 = New(Foo)
4626+
%t3_0.i = 1
4627+
%t2_0[0] = %t3_0
4628+
%t2_0[1] = null
4629+
f_0 = %t2_0
4630+
%t4_0 = f_0[0]
4631+
f0_0 = %t4_0
4632+
%t5_0 = f_0[1]
4633+
%t6_0 = null==%t5_0
4634+
if %t6_0 goto L5 else goto L6
4635+
L5:
4636+
%t7_1 = f0_0!=null
4637+
goto L7
4638+
L7:
4639+
%t7_2 = phi(%t7_1, %t7_0)
4640+
if %t7_2 goto L2 else goto L3
46234641
L2:
4624-
%t5_0 = f_0[0]
4625-
%t6_0 = %t5_0.i
4626-
%t7_1 = 1==%t6_0
4642+
%t8_0 = f0_0.i
4643+
%t9_1 = 1==%t8_0
46274644
goto L4
46284645
L4:
4629-
%t7_2 = phi(%t7_1, %t7_0)
4630-
ret %t7_2
4646+
%t9_2 = phi(%t9_1, %t9_0)
4647+
ret %t9_2
46314648
goto L1
46324649
L1:
46334650
L3:
4634-
%t7_0 = 0
4651+
%t9_0 = 0
46354652
goto L4
4653+
L6:
4654+
%t7_0 = 0
4655+
goto L7
46364656
After converting from SSA to CSSA
46374657
L0:
4638-
%t1_0 = New([Foo?], len=2)
4639-
%t2_0 = New(Foo)
4640-
%t2_0.i = 1
4641-
%t1_0[0] = %t2_0
4642-
%t1_0[1] = null
4643-
f_0 = %t1_0
4644-
%t3_0 = f_0[1]
4645-
%t4_0 = null==%t3_0
4646-
if %t4_0 goto L2 else goto L3
4658+
%t2_0 = New([Foo?], len=2)
4659+
%t3_0 = New(Foo)
4660+
%t3_0.i = 1
4661+
%t2_0[0] = %t3_0
4662+
%t2_0[1] = null
4663+
f_0 = %t2_0
4664+
%t4_0 = f_0[0]
4665+
f0_0 = %t4_0
4666+
%t5_0 = f_0[1]
4667+
%t6_0 = null==%t5_0
4668+
if %t6_0 goto L5 else goto L6
4669+
L5:
4670+
%t7_1 = f0_0!=null
4671+
(%t7_1_27) = (%t7_1)
4672+
goto L7
4673+
L7:
4674+
%t7_2_29 = phi(%t7_1_27, %t7_0_28)
4675+
(%t7_2) = (%t7_2_29)
4676+
if %t7_2 goto L2 else goto L3
46474677
L2:
4648-
%t5_0 = f_0[0]
4649-
%t6_0 = %t5_0.i
4650-
%t7_1 = 1==%t6_0
4651-
(%t7_1_18) = (%t7_1)
4678+
%t8_0 = f0_0.i
4679+
%t9_1 = 1==%t8_0
4680+
(%t9_1_24) = (%t9_1)
46524681
goto L4
46534682
L4:
4654-
%t7_2_20 = phi(%t7_1_18, %t7_0_19)
4655-
(%t7_2) = (%t7_2_20)
4656-
ret %t7_2
4683+
%t9_2_26 = phi(%t9_1_24, %t9_0_25)
4684+
(%t9_2) = (%t9_2_26)
4685+
ret %t9_2
46574686
goto L1
46584687
L1:
46594688
L3:
4660-
%t7_0 = 0
4661-
(%t7_0_19) = (%t7_0)
4689+
%t9_0 = 0
4690+
(%t9_0_25) = (%t9_0)
46624691
goto L4
4692+
L6:
4693+
%t7_0 = 0
4694+
(%t7_0_28) = (%t7_0)
4695+
goto L7
46634696
After removing phis from CSSA
46644697
L0:
4665-
%t1_0 = New([Foo?], len=2)
4666-
%t2_0 = New(Foo)
4667-
%t2_0.i = 1
4668-
%t1_0[0] = %t2_0
4669-
%t1_0[1] = null
4670-
f_0 = %t1_0
4671-
%t3_0 = f_0[1]
4672-
%t4_0 = null==%t3_0
4673-
if %t4_0 goto L2 else goto L3
4698+
%t2_0 = New([Foo?], len=2)
4699+
%t3_0 = New(Foo)
4700+
%t3_0.i = 1
4701+
%t2_0[0] = %t3_0
4702+
%t2_0[1] = null
4703+
f_0 = %t2_0
4704+
%t4_0 = f_0[0]
4705+
f0_0 = %t4_0
4706+
%t5_0 = f_0[1]
4707+
%t6_0 = null==%t5_0
4708+
if %t6_0 goto L5 else goto L6
4709+
L5:
4710+
%t7_1 = f0_0!=null
4711+
(%t7_1_27) = (%t7_1)
4712+
%t7_2_29 = %t7_1_27
4713+
goto L7
4714+
L7:
4715+
(%t7_2) = (%t7_2_29)
4716+
if %t7_2 goto L2 else goto L3
46744717
L2:
4675-
%t5_0 = f_0[0]
4676-
%t6_0 = %t5_0.i
4677-
%t7_1 = 1==%t6_0
4678-
(%t7_1_18) = (%t7_1)
4679-
%t7_2_20 = %t7_1_18
4718+
%t8_0 = f0_0.i
4719+
%t9_1 = 1==%t8_0
4720+
(%t9_1_24) = (%t9_1)
4721+
%t9_2_26 = %t9_1_24
46804722
goto L4
46814723
L4:
4682-
(%t7_2) = (%t7_2_20)
4683-
ret %t7_2
4724+
(%t9_2) = (%t9_2_26)
4725+
ret %t9_2
46844726
goto L1
46854727
L1:
46864728
L3:
4687-
%t7_0 = 0
4688-
(%t7_0_19) = (%t7_0)
4689-
%t7_2_20 = %t7_0_19
4729+
%t9_0 = 0
4730+
(%t9_0_25) = (%t9_0)
4731+
%t9_2_26 = %t9_0_25
46904732
goto L4
4733+
L6:
4734+
%t7_0 = 0
4735+
(%t7_0_28) = (%t7_0)
4736+
%t7_2_29 = %t7_0_28
4737+
goto L7
46914738
After exiting SSA
46924739
=================
46934740
L0:
4694-
%t1_0 = New([Foo?], len=2)
4695-
%t2_0 = New(Foo)
4696-
%t2_0.i = 1
4697-
%t1_0[0] = %t2_0
4698-
%t1_0[1] = null
4699-
f_0 = %t1_0
4700-
%t3_0 = f_0[1]
4701-
%t4_0 = null==%t3_0
4702-
if %t4_0 goto L2 else goto L3
4741+
%t2_0 = New([Foo?], len=2)
4742+
%t3_0 = New(Foo)
4743+
%t3_0.i = 1
4744+
%t2_0[0] = %t3_0
4745+
%t2_0[1] = null
4746+
f_0 = %t2_0
4747+
%t4_0 = f_0[0]
4748+
f0_0 = %t4_0
4749+
%t5_0 = f_0[1]
4750+
%t6_0 = null==%t5_0
4751+
if %t6_0 goto L5 else goto L6
4752+
L5:
4753+
%t7_1 = f0_0!=null
4754+
%t7_1_27 = %t7_1
4755+
%t7_2_29 = %t7_1_27
4756+
goto L7
4757+
L7:
4758+
%t7_2 = %t7_2_29
4759+
if %t7_2 goto L2 else goto L3
47034760
L2:
4704-
%t5_0 = f_0[0]
4705-
%t6_0 = %t5_0.i
4706-
%t7_1 = 1==%t6_0
4707-
%t7_1_18 = %t7_1
4708-
%t7_2_20 = %t7_1_18
4761+
%t8_0 = f0_0.i
4762+
%t9_1 = 1==%t8_0
4763+
%t9_1_24 = %t9_1
4764+
%t9_2_26 = %t9_1_24
47094765
goto L4
47104766
L4:
4711-
%t7_2 = %t7_2_20
4712-
ret %t7_2
4767+
%t9_2 = %t9_2_26
4768+
ret %t9_2
47134769
goto L1
47144770
L1:
47154771
L3:
4716-
%t7_0 = 0
4717-
%t7_0_19 = %t7_0
4718-
%t7_2_20 = %t7_0_19
4772+
%t9_0 = 0
4773+
%t9_0_25 = %t9_0
4774+
%t9_2_26 = %t9_0_25
47194775
goto L4
4776+
L6:
4777+
%t7_0 = 0
4778+
%t7_0_28 = %t7_0
4779+
%t7_2_29 = %t7_0_28
4780+
goto L7
47204781
""", result);
47214782
}
47224783

0 commit comments

Comments
 (0)