public override Value Visit(ForLoop node) { // store startval, id // forloop: // body // idval = load id // incr/decr idval // store idval, id // cmp idval, endval // br slt/sgt forloop, forend // forend: // NOTE: it is invalid to modify the id var inside the loop // func was set in Visit(RoutineDefinition node) Function func = evalCtx.func; Value id = traverse(node.var); Value startval = traverse(node.start); Value endval = traverse(node.end); builder.BuildStore(startval, id); Debug.Assert(!id.IsNull, "Invalid For var id"); Debug.Assert(!startval.IsNull, "Invalid For start value"); Debug.Assert(!endval.IsNull, "Invalid For end value"); BasicBlock forloop = func.AppendBasicBlock("forloop"); BasicBlock forend = func.AppendBasicBlock("forend"); evalCtx.EnterLoop(forloop, forend); builder.BuildBr(forloop); builder.ResetInsertPoint(func, forloop); Value body = traverse(node.block); Debug.Assert(!body.IsNull, "Invalid For loop body"); // emit the step and test Value idval = builder.BuildLoad(id); if (node.direction > 0) // incr { idval = builder.BuildAdd(idval, Value.CreateConstInt32(1)); } else // decr { idval = builder.BuildSub(idval, Value.CreateConstInt32(1)); } builder.BuildStore(idval, id); // persist the final value after the For var op = (node.direction > 0) ? LLVMIntPredicate.IntULT : LLVMIntPredicate.IntUGT; Value cmpres = builder.BuildICmp(idval, op, endval); builder.BuildCondBr(cmpres, forloop, forend); builder.ResetInsertPoint(func, forend); evalCtx.LeaveLoop(); return(Value.NonNull); }