public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); if (statement.IsEmptyStatement()) { throw new CompilerException(statement, string.Format(Resource.Culture, Resource.LoopStatementHasNoBody)); } generator.Resolver.EnterContext(); JumpToken loopToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(loopToken); expression.Prepare(generator, null); // boolean expression.Generate(generator); generator.Resolver.EnterContext(); JumpToken skipToken = generator.Assembler.CreateJumpToken(); generator.Resolver.RegisterGoto("@continue", loopToken); generator.Resolver.RegisterGoto("@break", skipToken); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.JumpIfFalse(skipToken); statement.Generate(generator, returnType); generator.Assembler.Jump(loopToken); generator.Assembler.SetDestination(skipToken); generator.Resolver.LeaveContext(); generator.Resolver.LeaveContext(); breaks = skipToken.JumpCount > 1; }
public Method(ILocation location, Modifiers modifiers, TypeName returnTypeName, Identifier name, Parameters parametersMetadata, Statement statementMetadata, List <Identifier> methodTemplateParameters, bool implicitConverter) : base(location) { if (modifiers == null) { throw new ArgumentNullException("modifiers"); } if (name == null) { throw new ArgumentNullException("name"); } if (parametersMetadata == null) { throw new ArgumentNullException("parametersMetadata"); } if (statementMetadata == null) { throw new ArgumentNullException("statementMetadata"); } if (methodTemplateParameters == null) { throw new ArgumentNullException("methodTemplateParameters"); } this.modifiers = modifiers; this.returnTypeName = returnTypeName; this.name = name; this.parametersMetadata = parametersMetadata; this.statementMetadata = statementMetadata; this.methodTemplateParameters = methodTemplateParameters; modifiers.EnsureMethodModifiers(); if (!modifiers.AllowsMethodBody()) { if (!statementMetadata.IsEmptyStatement()) { throw new CompilerException(modifiers, Resource.BodyNotCompatibleWithModifier); } } this.implicitConverter = implicitConverter; }
public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); if (statement.IsEmptyStatement()) { throw new CompilerException(statement, string.Format(Resource.Culture, Resource.LoopStatementHasNoBody)); } generator.Resolver.EnterContext(); expression.Prepare(generator, null); expression.Generate(generator); // Iterator<slot> ? // create the field, and the hidden enumerator if (enumeratorType == null) { enumeratorType = expression.TypeReference; } else { enumeratorType.GenerateConversion(expression, generator, expression.TypeReference); } generator.Resolver.AddVariable(enumeratorName, enumeratorType, enumeratorSlot, true); generator.Resolver.AssignSlot(enumeratorSlot); // get the enumerator from the expression generator.Assembler.StoreVariable(enumeratorSlot); // start of the loop JumpToken loopToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(loopToken); // move the enumerator and check if something is available move.Prepare(generator, null); move.Generate(generator); boolType.GenerateConversion(this, generator, move.TypeReference); JumpToken skipToken = generator.Assembler.CreateJumpToken(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.JumpIfFalse(skipToken); // something is available so put it in the field current.Prepare(generator, null); current.Generate(generator); if (type == null) { type = current.TypeReference; } if (name != null) { generator.Resolver.AddVariable(name, type, slot, true); type.GenerateConversion(this, generator, current.TypeReference); generator.Resolver.AssignSlot(slot); generator.Assembler.StoreVariable(slot); } // for body generator.Resolver.EnterContext(); generator.Resolver.RegisterGoto("@continue", loopToken); generator.Resolver.RegisterGoto("@break", skipToken); statement.Generate(generator, returnType); generator.Resolver.LeaveContext(); generator.Assembler.Jump(loopToken); generator.Assembler.SetDestination(skipToken); generator.Resolver.LeaveContext(); }