@@ -73,6 +73,8 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
73
73
if (Function .currFunction !is Generic <* > && Function .currFunction.returnType != MCFPPBaseType .Void && ! Function .currFunction.hasReturnStatement){
74
74
LogProcessor .error(" Function should return a value: " + Function .currFunction.namespaceID)
75
75
}
76
+ // 释放指针
77
+ Function .currFunction.disposeClassPtr()
76
78
Function .currFunction = Function .nullFunction
77
79
if (Class .currClass == null ) {
78
80
// 不在类中
@@ -305,6 +307,8 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
305
307
if (Function .currFunction.returnType != MCFPPBaseType .Void && ! Function .currFunction.hasReturnStatement) {
306
308
LogProcessor .error(" A 'return' expression required in function: " + Function .currFunction.namespaceID)
307
309
}
310
+ // 释放指针
311
+ Function .currFunction.disposeClassPtr()
308
312
Function .currFunction = Function .nullFunction
309
313
}
310
314
@@ -565,8 +569,10 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
565
569
// 进入if函数
566
570
Project .ctx = ctx
567
571
Function .addComment(" while start" )
572
+ // 外while函数。这个函数中包含了while循环的逻辑
568
573
val whileFunction = InternalFunction (" _while_" , Function .currFunction)
569
- Function .addCommand(" function " + whileFunction.namespaceID)
574
+ Function .addCommand(Commands .stackIn())
575
+ Function .addCommand(Commands .function(whileFunction))
570
576
Function .addCommand(Commands .stackOut())
571
577
Function .currFunction = whileFunction
572
578
if (! GlobalField .localNamespaces.containsKey(whileFunction.namespace))
@@ -603,20 +609,18 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
603
609
Function .addCommand(Commands .stackIn())
604
610
Function .addComment(" while start" )
605
611
val parent: mcfppParser.WhileStatementContext = ctx.parent as mcfppParser.WhileStatementContext
606
- val exp = MCFPPExprVisitor ().visitExpression(parent.expression())
607
- // 匿名函数的定义
612
+ // while语句块编译的目标函数,即内while函数
608
613
val f: Function = InternalFunction (" _while_block_" , Function .currFunction)
609
614
f.child.add(f)
610
615
f.parent.add(f)
611
616
if (! GlobalField .localNamespaces.containsKey(f.namespace))
612
617
GlobalField .localNamespaces[f.namespace] = Namespace (f.namespace)
613
618
GlobalField .localNamespaces[f.namespace]!! .field.addFunction(f,false )
614
- // 条件判断
615
- when (exp){
619
+ // 循环条件判断,此时目标函数是外while函数。条件表达式在外while中计算。
620
+ when (val exp = MCFPPExprVisitor ().visitExpression(parent.expression()) ){
616
621
is ScoreBoolConcrete -> {
617
622
if (exp.value){
618
- // 给子函数开栈
619
- Function .addCommand(Commands .stackIn())
623
+ // 内while函数的返回值表示循环是否被阻断,使用execute if判断。若成立,则继续运行外while函数
620
624
Function .addCommand(" execute " +
621
625
" if function " + f.namespaceID + " " +
622
626
" run function " + Function .currFunction.namespaceID)
@@ -626,17 +630,13 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
626
630
}
627
631
628
632
is ExecuteBool -> {
629
- // 给子函数开栈
630
- Function .addCommand(Commands .stackIn())
631
633
Function .addCommand(Command (" execute" )
632
634
.build(exp.toCommandPart())
633
635
.build(" if function " + f.namespaceID)
634
636
.build(" run function " + Function .currFunction.namespaceID))
635
637
}
636
638
637
639
is BaseBool -> {
638
- // 给子函数开栈
639
- Function .addCommand(Commands .stackIn())
640
640
Function .addCommand(Command (" execute" )
641
641
.build(" if" ).build(exp.toCommandPart())
642
642
.build(" if function " + f.namespaceID)
@@ -661,17 +661,13 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
661
661
@InsertCommand
662
662
fun exitWhileBlock (ctx : mcfppParser.WhileBlockContext ) {
663
663
Project .ctx = ctx
664
- // 调用完毕,将子函数的栈销毁
665
- // 由于在同一个命令中完成了两个函数的调用,因此需要在子函数内部进行子函数栈的销毁工作
666
- Function .addCommand(Commands .stackOut())
667
- // 这里取出while函数的栈
668
- Function .addCommand(Commands .stackOut())
664
+ Function .currFunction.disposeClassPtr()
669
665
Function .addCommand(" return 1" )
670
666
Function .currFunction = Function .currFunction.parent[0 ]
671
667
Function .addComment(" while loop end" )
672
668
Function .currFunction.field.forEachVar {
673
- if (it.trackLost){
674
- it.trackLost = false
669
+ if (! it.trackLost){
670
+ it.trackLost = true
675
671
if (it is MCFPPValue <* >) it.toDynamic(true )
676
672
}
677
673
}
@@ -691,6 +687,10 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
691
687
Project .ctx = ctx
692
688
Function .addComment(" do-while start" )
693
689
doWhileFunction = InternalFunction (" _dowhile_" , Function .currFunction)
690
+ // 这里不能急着调用循环函数,因为循环体必定会执行一次。参见enterDoWhileBlock的代码
691
+ // Function.addCommand(Commands.stackIn())
692
+ // Function.addCommand(Commands.function(doWhileFunction))
693
+ // Function.addCommand(Commands.stackOut())
694
694
Function .currFunction = doWhileFunction
695
695
if (! GlobalField .localNamespaces.containsKey(doWhileFunction.namespace))
696
696
GlobalField .localNamespaces[doWhileFunction.namespace] = Namespace (doWhileFunction.namespace)
@@ -738,19 +738,23 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
738
738
}
739
739
GlobalField .localNamespaces[f.namespace]!! .field.addFunction(f,false )
740
740
// 给子函数开栈
741
- Function .currFunction.parent[0 ].commands.add(Commands .stackIn())
742
- Function .currFunction.parent[0 ].commands.add(" execute unless function ${f.namespaceID} run return 1" )
743
- Function .currFunction.parent[0 ].commands.add(Commands .stackOut())
744
- Function .currFunction.parent[0 ].commands.add(Commands .stackIn())
745
- Function .currFunction.parent[0 ].commands.add(" function " + doWhileFunction.namespaceID)
746
- Function .currFunction.parent[0 ].commands.add(Commands .stackOut())
741
+ Function .currFunction.parent[0 ].commands.addAll(
742
+ arrayOf(
743
+ // 必然调用一次循环体内的函数
744
+ Commands .stackIn(),
745
+ Commands .function(f),
746
+ Commands .stackOut(),
747
+ // 然后才开始调用do-while外函数。此时就是先判断再执行,转换为了while语句
748
+ Commands .stackIn(),
749
+ Commands .function(doWhileFunction),
750
+ Commands .stackOut()
751
+ )
752
+ )
747
753
// 递归调用
748
754
val parent = ctx.parent as mcfppParser.DoWhileStatementContext
749
755
when (val exp = MCFPPExprVisitor ().visitExpression(parent.expression())){
750
756
is ScoreBoolConcrete -> {
751
757
if (exp.value){
752
- // 给子函数开栈
753
- Function .addCommand(Commands .stackIn())
754
758
Function .addCommand(" execute " +
755
759
" if function " + f.namespaceID + " " +
756
760
" run function " + Function .currFunction.namespaceID)
@@ -762,17 +766,13 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
762
766
}
763
767
764
768
is ExecuteBool -> {
765
- // 给子函数开栈
766
- Function .addCommand(Commands .stackIn())
767
769
Function .addCommand(Command (" execute" )
768
770
.build(exp.toCommandPart())
769
771
.build(" if function " + f.namespaceID)
770
772
.build(" run function " + Function .currFunction.namespaceID))
771
773
}
772
774
773
775
is BaseBool -> {
774
- // 给子函数开栈
775
- Function .addCommand(Commands .stackIn())
776
776
Function .addCommand(Command (" execute" )
777
777
.build(" if" ).build(exp.toCommandPart())
778
778
.build(" if function " + f.namespaceID)
@@ -792,8 +792,7 @@ open class MCFPPImVisitor: mcfppParserBaseVisitor<Any?>() {
792
792
@InsertCommand
793
793
fun exitDoWhileBlock (ctx : mcfppParser.DoWhileBlockContext ) {
794
794
Project .ctx = ctx
795
- // 调用完毕,将子函数的栈销毁
796
- Function .addCommand(Commands .stackOut())
795
+ Function .currFunction.disposeClassPtr()
797
796
// 返回1
798
797
Function .addCommand(" return 1" )
799
798
Function .currFunction = Function .currFunction.parent[0 ]
0 commit comments