Ejemplo n.º 1
0
        /// <summary>
        /// Implements the code to initialise the array.
        /// </summary>
        /// <param name="cg">The code generator object</param>
        public override void Generate(CodeGenerator cg)
        {
            if (cg == null) {
                throw new ArgumentNullException("cg");
            }
            Symbol sym = Identifier.Symbol;

            // Simple array initialisation - just initialise the
            // specified element. More complex initialisation requires
            // a loop across the elements.
            Debug.Assert(sym.IsArray);
            if (Identifier.Indexes != null && Identifier.Indexes.Count > 0) {
                if (Identifier.Indexes.Count == 1) {
                    NumberParseNode number = (NumberParseNode)Identifier.Indexes[0];
                    Debug.Assert(sym.Dimensions[0].LowerBound.IsConstant);
                    int index = number.Value.IntValue + (0 - sym.Dimensions[0].LowerBound.Value.IntValue);
                    GenerateStoreToArray(cg, sym, index, RangeValue);
                } else {
                    Type [] paramTypes = new Type[Identifier.Indexes.Count + 1];
                    int index = 0;

                    cg.LoadLocal(sym);
                    while (index < Identifier.Indexes.Count) {
                        NumberParseNode number = (NumberParseNode)Identifier.Indexes[index];
                        Debug.Assert(sym.Dimensions[index].LowerBound.IsConstant);
                        cg.Emitter.LoadInteger(number.Value.IntValue + (0 - sym.Dimensions[index].LowerBound.Value.IntValue));
                        paramTypes[index++] = typeof(Int32);
                    }
                    cg.GenerateLoad(RangeValue);
                    paramTypes[index] = Symbol.SymTypeToSystemType(RangeValue.Type);

                    cg.Emitter.Call(cg.GetMethodForType(sym.SystemType, "Set", paramTypes));
                }
            }
            else if (StartRange < EndRange + 4) {

                // When initialising arrays less than 4 values, unroll
                // the loop as it will be faster.
                int index = StartRange;
                while (index <= EndRange) {
                    GenerateStoreToArray(cg, sym, index++, RangeValue);
                }
            } else {

                // For large arrays, generate code to initialise the elements
                // to a specific value.
                Label label1 = cg.Emitter.CreateLabel();
                cg.Emitter.LoadInteger(StartRange);
                LocalDescriptor tempIndex = cg.Emitter.GetTemporary(typeof(int));
                cg.Emitter.StoreLocal(tempIndex);
                cg.Emitter.MarkLabel(label1);
                GenerateStoreToArray(cg, sym, tempIndex.Index, RangeValue);
                cg.Emitter.LoadLocal(tempIndex);
                cg.Emitter.LoadInteger(1);
                cg.Emitter.Add(SymType.INTEGER);
                cg.Emitter.Dup();
                cg.Emitter.StoreLocal(tempIndex);
                cg.Emitter.LoadInteger(EndRange);
                cg.Emitter.BranchLessOrEqual(label1);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Emit this code to load the value to the stack.
 /// </summary>
 /// <param name="cg">A CodeGenerator object</param>
 /// <param name="returnType">The type required by the caller</param>
 /// <returns>The symbol type of the value generated</returns>
 public override SymType Generate(CodeGenerator cg, SymType returnType)
 {
     if (cg == null) {
         throw new ArgumentNullException("cg");
     }
     if (ID == ParseID.LABEL) {
         if (Symbol.IsFixedStatic) {
             cg.Emitter.LoadString(Symbol.Value.StringValue);
             return Type;
         }
         return cg.LoadLocal(Symbol);
     }
     Debug.Assert(false, "Unsupported parse ID for SymbolParseNode");
     return Value.Type;
 }
Ejemplo n.º 3
0
 // Emit code that writes the variant value to the given array index where
 // the array is specified by the symbol..
 void GenerateStoreToArray(CodeGenerator cg, Symbol sym, int index, Variant value)
 {
     cg.LoadLocal(sym);
     cg.Emitter.LoadInteger(index);
     cg.GenerateLoad(value);
     cg.Emitter.ConvertType(value.Type, sym.Type);
     cg.Emitter.StoreElement(sym.Type);
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Emit this code to load the identifier to the stack.
        /// </summary>
        /// <param name="cg">A CodeGenerator object</param>
        /// <param name="returnType">The type required by the caller</param>
        /// <returns>The symbol type of the value generated</returns>
        public override SymType Generate(CodeGenerator cg, SymType returnType)
        {
            if (cg == null) {
                throw new ArgumentNullException("cg");
            }
            Symbol sym = Symbol;
            SymType thisType;

            if (sym.Class == SymClass.INLINE) {
                GenerateInline(cg);
                thisType = sym.Type;
            } else if (sym.IsArray) {
                thisType = cg.GenerateLoadFromArray(this, false);
            } else if (sym.IsIntrinsic || sym.IsExternal) {
                cg.Emitter.LoadFunction(sym);
                thisType = SymType.INTEGER;
            } else if (sym.IsParameter) {
                cg.GenerateLoadArgument(sym);
                thisType = sym.Type;
            } else if (sym.Class == SymClass.FUNCTION) {
                cg.Emitter.LoadFunction(sym);
                thisType = SymType.INTEGER;
            } else if (sym.IsLocal) {
                cg.LoadLocal(sym);
                thisType = sym.Type;
            } else {
                Debug.Assert(false, "Unknown identifier type (not local OR parameter)");
                thisType = SymType.NONE;
            }
            if (HasSubstring) {
                thisType = GenerateLoadSubstring(cg);
            }
            return thisType;
        }