public int Finish() { // Assuming current block is last block CurrentBlock.PositionBuilderAtEnd(Builder); if (!CurrentBlock.HasTerminator()) { if (Self.ReturnType != InstanceTypes.Void) { // TODO: fix your sh*tty error system (and error generator too) // ALSO: possibly add (and improve) super konsole lib NamespaceContext.Context.AddError(new GamaError("Function did not return a value, did you meant to use void return type? Expected {0} got nothing.", Self.ReturnType.Name)); return(-1); } // If self is void, no need to worry, just BuildRetVoid() Builder.BuildRetVoid(); } Builder.Dispose(); // Run optimizations of self // new Optimizers.AllocToEntry().Visit(this); // new Optimizers.ControlFlowEliminator().Visit(this); // new Optimizers.DeadBlockEliminator().Visit(this); return(0); }
public override bool VisitStmtWhileBase([NotNull] GamaParser.StmtWhileBaseContext context) { var wlecontrol = Self.AddBlock("while.if"); var wleblock = Self.AddBlock("while.loop"); var wleend = Self.AddBlock("while.end"); CurrentBlock.PositionBuilderAtEnd(Builder); Builder.BuildBr(wlecontrol.Block); SetBlock(wlecontrol); CurrentBlock.PositionBuilderAtEnd(Builder); var expr = VisitExpression(context.expr()); if (expr == null) { return(false); } if (expr.Type != InstanceTypes.Bool) { NamespaceContext.Context.AddError(new ErrorTypeMismatch(context.expr())); return(false); } Builder.BuildCondBr(expr.Value, wleblock.Block, wleend.Block); SetBlock(wleblock); Push(); { Visit(context.block()); } if (!wleblock.HasTerminator()) { wleblock.PositionBuilderAtEnd(Builder); Builder.BuildBr(wlecontrol.Block); } if (CurrentBlock != wleblock) /* Block nesting */ { CurrentBlock.PositionBuilderAtEnd(Builder); Builder.BuildBr(wlecontrol.Block); } Pop(); if (wleend != CurrentBlock) { if (!CurrentBlock.HasTerminator()) { CurrentBlock.PositionBuilderAtEnd(Builder); Builder.BuildBr(wleend.Block); } } SetBlock(wleend); return(true); }