private void CompileDoWhileLoop(Parser parser, ByteBuffer buffer, DoWhileLoop doWhileLoop) { ByteBuffer loopBody = new ByteBuffer(); this.Compile(parser, loopBody, doWhileLoop.Code); loopBody.ResolveContinues(true); // continues should jump to the condition, hence the true. ByteBuffer condition = new ByteBuffer(); this.CompileExpression(parser, condition, doWhileLoop.Condition, true); loopBody.Concat(condition); loopBody.Add(doWhileLoop.Condition.FirstToken, OpCode.JUMP_IF_TRUE, -loopBody.Size - 1); loopBody.ResolveBreaks(); buffer.Concat(loopBody); }
private void CompileForLoop(Parser parser, ByteBuffer buffer, ForLoop forLoop) { this.Compile(parser, buffer, forLoop.Init); ByteBuffer codeBuffer = new ByteBuffer(); this.Compile(parser, codeBuffer, forLoop.Code); codeBuffer.ResolveContinues(true); // resolve continues as jump-to-end before you add the step instructions. this.Compile(parser, codeBuffer, forLoop.Step); ByteBuffer forBuffer = new ByteBuffer(); this.CompileExpression(parser, forBuffer, forLoop.Condition, true); forBuffer.Add(forLoop.Condition.FirstToken, OpCode.JUMP_IF_FALSE, codeBuffer.Size + 1); // +1 to go past the jump I'm about to add. forBuffer.Concat(codeBuffer); forBuffer.Add(null, OpCode.JUMP, -forBuffer.Size - 1); forBuffer.ResolveBreaks(); buffer.Concat(forBuffer); }
private void CompileWhileLoop(Parser parser, ByteBuffer buffer, WhileLoop whileLoop) { ByteBuffer loopBody = new ByteBuffer(); this.Compile(parser, loopBody, whileLoop.Code); ByteBuffer condition = new ByteBuffer(); this.CompileExpression(parser, condition, whileLoop.Condition, true); condition.Add(whileLoop.Condition.FirstToken, OpCode.JUMP_IF_FALSE, loopBody.Size + 1); condition.Concat(loopBody); condition.Add(null, OpCode.JUMP, -condition.Size - 1); condition.ResolveBreaks(); condition.ResolveContinues(); buffer.Concat(condition); }
private void CompileForEachLoop(Parser parser, ByteBuffer buffer, ForEachLoop forEachLoop) { buffer.Add(null, OpCode.LITERAL, parser.GetIntConstant(0)); buffer.Add(null, OpCode.LITERAL, parser.GetIntConstant(forEachLoop.IterationVariableId)); this.CompileExpression(parser, buffer, forEachLoop.IterationExpression, true); buffer.Add(forEachLoop.IterationExpression.FirstToken, OpCode.VERIFY_TYPE_IS_ITERABLE); ByteBuffer body = new ByteBuffer(); ByteBuffer body2 = new Crayon.ByteBuffer(); this.Compile(parser, body2, forEachLoop.Code); body.Add(forEachLoop.FirstToken, OpCode.ITERATION_STEP, body2.Size + 1); body2.Add(null, OpCode.JUMP, -body2.Size - 2); body.Concat(body2); body.ResolveBreaks(); body.ResolveContinues(); buffer.Concat(body); buffer.Add(null, OpCode.POP); // list buffer.Add(null, OpCode.POP); // var ID buffer.Add(null, OpCode.POP); // index }