@@ -48,7 +48,7 @@ function Compiler:new()
4848 AstKind .DivExpression ,
4949 AstKind .ModExpression ,
5050 AstKind .PowExpression ,
51- }
51+ };
5252 };
5353
5454 setmetatable (compiler , self );
@@ -260,6 +260,12 @@ function Compiler:emitContainerFuncBody()
260260 return a .id < b .id ;
261261 end );
262262
263+ local function buildIfBlock (scope , id , lBlock , rBlock )
264+ return Ast .Block ({
265+ Ast .IfStatement (Ast .LessThanExpression (self :pos (scope ), Ast .NumberExpression (id )), lBlock , {}, rBlock );
266+ }, scope );
267+ end
268+
263269 local function buildWhileBody (tb , l , r , pScope , scope )
264270 local len = r - l + 1 ;
265271 if len == 1 then
@@ -270,14 +276,13 @@ function Compiler:emitContainerFuncBody()
270276 end
271277
272278 local mid = l + math.ceil (len / 2 );
279+ local bound = math.random (tb [mid - 1 ].id , tb [mid ].id );
273280 local ifScope = scope or Scope :new (pScope );
274281
275282 local lBlock = buildWhileBody (tb , l , mid - 1 , ifScope );
276283 local rBlock = buildWhileBody (tb , mid , r , ifScope );
277284
278- return Ast .Block ({
279- Ast .IfStatement (Ast .LessThanExpression (self :pos (ifScope ), Ast .NumberExpression (tb [mid ].id )), lBlock , {}, rBlock );
280- }, ifScope );
285+ return buildIfBlock (ifScope , bound , lBlock , rBlock )
281286 end
282287
283288 local whileBody = buildWhileBody (blocks , 1 , # blocks , self .containerFuncScope , self .whileScope );
506511
507512function Compiler :jmp (scope , to )
508513 scope :addReferenceToHigherScope (self .containerFuncScope , self .posVar );
509- return Ast .AssignmentStatement ({Ast .AssignmentVariable (self .containerFuncScope , self .posVar )},{Ast . NumberExpression ( to ) });
514+ return Ast .AssignmentStatement ({Ast .AssignmentVariable (self .containerFuncScope , self .posVar )},{to });
510515end
511516
512517function Compiler :setPos (scope , val )
@@ -560,6 +565,10 @@ function Compiler:compileBlock(block, funcDepth)
560565 for i , stat in ipairs (block .statements ) do
561566 self :compileStatement (stat , funcDepth );
562567 end
568+
569+ for id , name in ipairs (block .scope .variables ) do
570+ self :freeRegister (self :getVarRegister (block .scope , id , nil ), true );
571+ end
563572end
564573
565574function Compiler :compileStatement (statement , funcDepth )
@@ -682,6 +691,8 @@ function Compiler:compileStatement(statement, funcDepth)
682691 -- Assignment Statement
683692 if (statement .kind == AstKind .AssignmentStatement ) then
684693 local exprregs = {};
694+ local assignments = {};
695+
685696 for i , expr in ipairs (statement .rhs ) do
686697 if (i == # statement .rhs and # statement .lhs > # statement .rhs ) then
687698 local regs = self :compileExpression (expr , funcDepth , # statement .lhs - # statement .expressions + 1 );
@@ -728,6 +739,186 @@ function Compiler:compileStatement(statement, funcDepth)
728739 return
729740 end
730741
742+ -- If Statement
743+ if (statement .kind == AstKind .IfStatement ) then
744+ local conditionReg = self :compileExpression (statement .condition , funcDepth , 1 )[1 ];
745+ local finalBlock = self :createBlock ();
746+
747+ local nextBlock
748+ if statement .elsebody or # statement .elseifs > 0 then
749+ nextBlock = self :createBlock ();
750+ else
751+ nextBlock = finalBlock ;
752+ end
753+ local innerBlock = self :createBlock ();
754+
755+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (innerBlock .id )), Ast .NumberExpression (nextBlock .id ))), {self .POS_REGISTER }, {conditionReg }, false );
756+
757+ self :freeRegister (conditionReg , false );
758+
759+ self :setActiveBlock (innerBlock );
760+ self :compileBlock (statement .body , funcDepth );
761+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .NumberExpression (finalBlock .id )), {self .POS_REGISTER }, {}, false );
762+
763+ for i , eif in ipairs (statement .elseifs ) do
764+ self :setActiveBlock (nextBlock );
765+ conditionReg = self :compileExpression (eif .condition , funcDepth , 1 )[1 ];
766+
767+
768+
769+ self :setActiveBlock (nextBlock );
770+ local innerBlock = self :createBlock ();
771+ if statement .elsebody or i < # statement .elseifs then
772+ nextBlock = self :createBlock ();
773+ else
774+ nextBlock = finalBlock ;
775+ end
776+
777+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (innerBlock .id )), Ast .NumberExpression (nextBlock .id ))), {self .POS_REGISTER }, {conditionReg }, false );
778+
779+ self :freeRegister (conditionReg , false );
780+
781+ self :setActiveBlock (innerBlock );
782+ self :compileBlock (eif .body , funcDepth );
783+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .NumberExpression (finalBlock .id )), {self .POS_REGISTER }, {}, false );
784+ end
785+
786+ if statement .elsebody then
787+ self :setActiveBlock (nextBlock );
788+ self :compileBlock (statement .elsebody , funcDepth );
789+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .NumberExpression (finalBlock .id )), {self .POS_REGISTER }, {}, false );
790+ end
791+
792+ self :setActiveBlock (finalBlock );
793+
794+ return ;
795+ end
796+
797+ -- Do Statement
798+ if (statement .kind == AstKind .DoStatement ) then
799+ self :compileBlock (statement .body , funcDepth );
800+ return ;
801+ end
802+
803+ -- While Statement
804+ if (statement .kind == AstKind .WhileStatement ) then
805+ local innerBlock = self :createBlock ();
806+ local finalBlock = self :createBlock ();
807+
808+ local conditionReg = self :compileExpression (statement .condition , funcDepth , 1 )[1 ];
809+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (innerBlock .id )), Ast .NumberExpression (finalBlock .id ))), {self .POS_REGISTER }, {conditionReg }, false );
810+ self :freeRegister (conditionReg , false );
811+
812+ self :setActiveBlock (innerBlock );
813+ self :compileBlock (statement .body , funcDepth );
814+ local conditionReg = self :compileExpression (statement .condition , funcDepth , 1 )[1 ];
815+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (innerBlock .id )), Ast .NumberExpression (finalBlock .id ))), {self .POS_REGISTER }, {conditionReg }, false );
816+ self :freeRegister (conditionReg , false );
817+
818+ self :setActiveBlock (finalBlock );
819+
820+ return ;
821+ end
822+
823+ -- Repeat Statement
824+ if (statement .kind == AstKind .RepeatStatement ) then
825+ local innerBlock = self :createBlock ();
826+ local finalBlock = self :createBlock ();
827+
828+ local conditionReg = self :compileExpression (statement .condition , funcDepth , 1 )[1 ];
829+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .NumberExpression (innerBlock .id )), {self .POS_REGISTER }, {}, false );
830+ self :freeRegister (conditionReg , false );
831+
832+ self :setActiveBlock (innerBlock );
833+ self :compileBlock (statement .body , funcDepth );
834+ local conditionReg = self :compileExpression (statement .condition , funcDepth , 1 )[1 ];
835+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (finalBlock .id )), Ast .NumberExpression (innerBlock .id ))), {self .POS_REGISTER }, {conditionReg }, false );
836+ self :freeRegister (conditionReg , false );
837+
838+ self :setActiveBlock (finalBlock );
839+
840+ return ;
841+ end
842+
843+ -- For Statement
844+ if (statement .kind == AstKind .ForStatement ) then
845+ local checkBlock = self :createBlock ();
846+ local innerBlock = self :createBlock ();
847+ local finalBlock = self :createBlock ();
848+
849+ local posState = self .registers [self .POS_REGISTER ];
850+ self .registers [self .POS_REGISTER ] = self .VAR_REGISTER ;
851+
852+ local initialReg = self :compileExpression (statement .initialValue , funcDepth , 1 )[1 ];
853+
854+ local finalExprReg = self :compileExpression (statement .finalValue , funcDepth , 1 )[1 ];
855+ local finalReg = self :allocRegister (false );
856+ self :addStatement (self :copyRegisters (scope , {finalReg }, {finalExprReg }), {finalReg }, {finalExprReg }, false );
857+ self :freeRegister (finalExprReg );
858+
859+ local incrementExprReg = self :compileExpression (statement .incrementBy , funcDepth , 1 )[1 ];
860+ local incrementReg = self :allocRegister (false );
861+ self :addStatement (self :copyRegisters (scope , {incrementReg }, {incrementExprReg }), {incrementReg }, {incrementExprReg }, false );
862+ self :freeRegister (incrementExprReg );
863+
864+ local tmpReg = self :allocRegister (false );
865+ self :addStatement (self :setRegister (scope , tmpReg , Ast .NumberExpression (0 )), {tmpReg }, {}, false );
866+ local incrementIsNegReg = self :allocRegister (false );
867+ self :addStatement (self :setRegister (scope , incrementIsNegReg , Ast .LessThanExpression (self :register (scope , incrementReg ), self :register (scope , tmpReg ))), {incrementIsNegReg }, {incrementReg , tmpReg }, false );
868+ self :freeRegister (tmpReg );
869+
870+ local currentReg = self :allocRegister (true );
871+ self :addStatement (self :setRegister (scope , currentReg , Ast .SubExpression (self :register (scope , initialReg ), self :register (scope , incrementReg ))), {currentReg }, {initialReg , incrementReg }, false );
872+ self :freeRegister (initialReg );
873+
874+ self :addStatement (self :jmp (scope , Ast .NumberExpression (checkBlock .id )), {self .POS_REGISTER }, {}, false );
875+
876+ self :setActiveBlock (checkBlock );
877+
878+ scope = checkBlock .scope ;
879+ self :addStatement (self :setRegister (scope , currentReg , Ast .AddExpression (self :register (scope , currentReg ), self :register (scope , incrementReg ))), {currentReg }, {currentReg , incrementReg }, false );
880+ local tmpReg1 = self :allocRegister (false );
881+ local tmpReg2 = self :allocRegister (false );
882+ self :addStatement (self :setRegister (scope , tmpReg2 , Ast .NotExpression (self :register (scope , incrementIsNegReg ))), {tmpReg2 }, {incrementIsNegReg }, false );
883+ self :addStatement (self :setRegister (scope , tmpReg1 , Ast .LessThanOrEqualsExpression (self :register (scope , currentReg ), self :register (scope , finalReg ))), {tmpReg1 }, {currentReg , finalReg }, false );
884+ self :addStatement (self :setRegister (scope , tmpReg1 , Ast .AndExpression (self :register (scope , tmpReg2 ), self :register (scope , tmpReg1 ))), {tmpReg1 }, {tmpReg1 , tmpReg2 }, false );
885+ self :addStatement (self :setRegister (scope , tmpReg2 , Ast .GreaterThanOrEqualsExpression (self :register (scope , currentReg ), self :register (scope , finalReg ))), {tmpReg2 }, {currentReg , finalReg }, false );
886+ self :addStatement (self :setRegister (scope , tmpReg2 , Ast .AndExpression (self :register (scope , incrementIsNegReg ), self :register (scope , tmpReg2 ))), {tmpReg2 }, {tmpReg2 , incrementIsNegReg }, false );
887+ self :addStatement (self :setRegister (scope , tmpReg1 , Ast .OrExpression (self :register (scope , tmpReg2 ), self :register (scope , tmpReg1 ))), {tmpReg1 }, {tmpReg1 , tmpReg2 }, false );
888+ self :freeRegister (tmpReg2 );
889+ tmpReg2 = self :compileExpression (Ast .NumberExpression (innerBlock .id ), funcDepth , 1 )[1 ];
890+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .AndExpression (self :register (scope , tmpReg1 ), self :register (scope , tmpReg2 ))), {self .POS_REGISTER }, {tmpReg1 , tmpReg2 }, false );
891+ self :freeRegister (tmpReg2 );
892+ self :freeRegister (tmpReg1 );
893+ tmpReg2 = self :compileExpression (Ast .NumberExpression (finalBlock .id ), funcDepth , 1 )[1 ];
894+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (self :register (scope , self .POS_REGISTER ), self :register (scope , tmpReg2 ))), {self .POS_REGISTER }, {self .POS_REGISTER , tmpReg2 }, false );
895+ self :freeRegister (tmpReg2 );
896+
897+ self :setActiveBlock (innerBlock );
898+ self .registers [self .POS_REGISTER ] = posState ;
899+
900+ local varReg = self :getVarRegister (statement .scope , statement .id , nil );
901+ self :addStatement (self :setRegister (scope , varReg , self :register (scope , currentReg )), {varReg }, {currentReg }, false );
902+ self :compileBlock (statement .body , funcDepth );
903+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .NumberExpression (checkBlock .id )), {self .POS_REGISTER }, {}, false );
904+
905+ self .registers [self .POS_REGISTER ] = self .VAR_REGISTER ;
906+ self :freeRegister (finalReg );
907+ self :freeRegister (incrementIsNegReg );
908+ self :freeRegister (incrementReg );
909+ self :freeRegister (currentReg , true );
910+
911+ self .registers [self .POS_REGISTER ] = posState ;
912+ self :setActiveBlock (finalBlock );
913+
914+ return ;
915+ end
916+
917+ -- Do Statement
918+ if (statement .kind == AstKind .DoStatement ) then
919+ self :compileBlock (statement .body , funcDepth );
920+ end
921+
731922 -- TODO
732923
733924 logger :error (string.format (" %s is not a compileable statement!" , statement .kind ));
@@ -859,18 +1050,35 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
8591050 for i = 1 , numReturns do
8601051 retRegs [i ] = self :allocRegister (false );
8611052 end
862- local tmpReg = retRegs [ 1 ] or self : allocRegister ( false );
1053+
8631054 local argRegs = { baseReg };
8641055
865- -- TODO: Function call multi return pass
8661056 for i , expr in ipairs (expression .args ) do
8671057 table.insert (argRegs , self :compileExpression (expr , funcDepth , 1 )[1 ]);
8681058 end
8691059
870- self :addStatement (self :setRegister (scope , tmpReg , Ast .StringExpression (expression .passSelfFunctionName )), {tmpReg }, {}, false );
871- self :addStatement (self :setRegister (scope , tmpReg , Ast .IndexExpression (self :register (scope , baseReg ), self :register (scope , tmpReg ))), {tmpReg }, {baseReg , tmpReg }, false );
1060+ if (numReturns > 1 ) then
1061+ local tmpReg = self :allocRegister (false );
1062+
1063+ self :addStatement (self :setRegister (scope , tmpReg , Ast .StringExpression (expression .passSelfFunctionName )), {tmpReg }, {}, false );
1064+ self :addStatement (self :setRegister (scope , tmpReg , Ast .IndexExpression (self :register (scope , baseReg ), self :register (scope , tmpReg ))), {tmpReg }, {baseReg , tmpReg }, false );
1065+
1066+ self :addStatement (self :setRegister (scope , tmpReg , Ast .TableConstructorExpression {Ast .TableEntry (Ast .FunctionCallExpression (self :register (scope , tmpReg ), self :registerList (scope , argRegs )))}), {tmpReg }, {baseReg , unpack (argRegs )}, true );
1067+
1068+ for i , reg in ipairs (retRegs ) do
1069+ self :addStatement (self :setRegister (scope , reg , Ast .IndexExpression (self :register (scope , tmpReg ), Ast .NumberExpression (i ))), {reg }, {tmpReg }, false );
1070+ end
1071+
1072+ self :freeRegister (tmpReg , false );
1073+ else
1074+ local tmpReg = retRegs [1 ] or self :allocRegister (false );
1075+
1076+ self :addStatement (self :setRegister (scope , tmpReg , Ast .StringExpression (expression .passSelfFunctionName )), {tmpReg }, {}, false );
1077+ self :addStatement (self :setRegister (scope , tmpReg , Ast .IndexExpression (self :register (scope , baseReg ), self :register (scope , tmpReg ))), {tmpReg }, {baseReg , tmpReg }, false );
1078+
1079+ self :addStatement (self :setRegister (scope , retRegs [1 ], Ast .FunctionCallExpression (self :register (scope , tmpReg ), self :registerList (scope , argRegs ))), {retRegs [1 ]}, {baseReg , unpack (argRegs )}, true );
1080+ end
8721081
873- self :addStatement (self :setRegisters (scope , retRegs , {Ast .FunctionCallExpression (self :register (scope , tmpReg ), self :registerList (scope , argRegs ))}), retRegs , {tmpReg , unpack (argRegs )}, true )
8741082 self :freeRegister (baseReg , false );
8751083 for i , reg in ipairs (argRegs ) do
8761084 self :freeRegister (reg , false );
@@ -888,7 +1096,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
8881096 local baseReg = self :compileExpression (expression .base , funcDepth , 1 )[1 ];
8891097 local indexReg = self :compileExpression (expression .index , funcDepth , 1 )[1 ];
8901098
891- self :addStatement (self :setRegister (scope , regs [i ], Ast .IndexExpression (self :register (scope , baseReg ), self :register (scope , indexReg ))), {regs [i ]}, {baseReg , indexReg }, false );
1099+ self :addStatement (self :setRegister (scope , regs [i ], Ast .IndexExpression (self :register (scope , baseReg ), self :register (scope , indexReg ))), {regs [i ]}, {baseReg , indexReg }, true );
8921100 self :freeRegister (baseReg , false );
8931101 self :freeRegister (indexReg , false )
8941102 else
@@ -907,7 +1115,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
9071115 local lhsReg = self :compileExpression (expression .lhs , funcDepth , 1 )[1 ];
9081116 local rhsReg = self :compileExpression (expression .rhs , funcDepth , 1 )[1 ];
9091117
910- self :addStatement (self :setRegister (scope , regs [i ], Ast [expression .kind ](self :register (scope , lhsReg ), self :register (scope , rhsReg ))), {regs [i ]}, {lhsReg , rhsReg }, false );
1118+ self :addStatement (self :setRegister (scope , regs [i ], Ast [expression .kind ](self :register (scope , lhsReg ), self :register (scope , rhsReg ))), {regs [i ]}, {lhsReg , rhsReg }, true );
9111119 self :freeRegister (rhsReg , false );
9121120 self :freeRegister (lhsReg , false )
9131121 else
@@ -940,7 +1148,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
9401148 if (i == 1 ) then
9411149 local rhsReg = self :compileExpression (expression .rhs , funcDepth , 1 )[1 ];
9421150
943- self :addStatement (self :setRegister (scope , regs [i ], Ast .NegateExpression (self :register (scope , rhsReg ))), {regs [i ]}, {rhsReg }, false );
1151+ self :addStatement (self :setRegister (scope , regs [i ], Ast .NegateExpression (self :register (scope , rhsReg ))), {regs [i ]}, {rhsReg }, true );
9441152 self :freeRegister (rhsReg , false )
9451153 else
9461154 self :addStatement (self :setRegister (scope , regs [i ], Ast .NilExpression ()), {regs [i ]}, {}, false );
0 commit comments