internal override void ResolveVariableOrigins(ParserContext parser, VariableScope varIds, VariableIdAllocPhase phase) { this.Condition.ResolveVariableOrigins(parser, varIds, phase); if (phase != VariableIdAllocPhase.REGISTER_AND_ALLOC || this.chunks.Length <= 1) { foreach (Chunk chunk in this.chunks) { foreach (Expression ex in chunk.Cases) { if (ex != null) // default { ex.ResolveVariableOrigins(parser, varIds, phase); } } foreach (Executable ex in chunk.Code) { ex.ResolveVariableOrigins(parser, varIds, phase); } } } else { VariableScope[] varIdBranches = new VariableScope[this.chunks.Length]; for (int i = 0; i < this.chunks.Length; ++i) { Chunk chunk = this.chunks[i]; varIdBranches[i] = VariableScope.CreatedNestedBlockScope(varIds); foreach (Executable ex in chunk.Code) { ex.ResolveVariableOrigins(parser, varIdBranches[i], phase); } } foreach (VariableScope branch in varIdBranches) { branch.MergeToParent(); } if (!this.CompilationScope.IsStaticallyTyped) { for (int i = 0; i < this.chunks.Length; ++i) { Chunk chunk = this.chunks[i]; foreach (Executable ex in chunk.Code) { ex.ResolveVariableOrigins(parser, varIds, VariableIdAllocPhase.ALLOC); } } } } }
internal override void ResolveVariableOrigins(ParserContext parser, VariableScope varIds, VariableIdAllocPhase phase) { this.Condition.ResolveVariableOrigins(parser, varIds, phase); if (phase != VariableIdAllocPhase.REGISTER_AND_ALLOC || this.TrueCode.Length == 0 || this.FalseCode.Length == 0) { foreach (Executable ex in this.TrueCode.Concat(this.FalseCode)) { ex.ResolveVariableOrigins(parser, varIds, phase); } } else { // branch the variable ID allocator. VariableScope trueVars = VariableScope.CreatedNestedBlockScope(varIds); VariableScope falseVars = VariableScope.CreatedNestedBlockScope(varIds); // Go through and register and allocate all variables. // The allocated ID's are going to be garbage, but this enforces that they must be // declared before being used. foreach (Executable ex in this.TrueCode) { ex.ResolveVariableOrigins(parser, trueVars, VariableIdAllocPhase.REGISTER_AND_ALLOC); } foreach (Executable ex in this.FalseCode) { ex.ResolveVariableOrigins(parser, falseVars, VariableIdAllocPhase.REGISTER_AND_ALLOC); } // Now that the code is as correct as we can verify, merge the branches back together // creating a new set of variable ID's. trueVars.MergeToParent(); falseVars.MergeToParent(); if (!this.CompilationScope.IsStaticallyTyped) { // Go back through and do another allocation pass and assign the correct variable ID's. foreach (Executable ex in this.TrueCode.Concat(this.FalseCode)) { ex.ResolveVariableOrigins(parser, varIds, VariableIdAllocPhase.ALLOC); } } } }