Inheritance: EmitValHLSL
        public IEnumerable<string> DeclareBaseImpl(
            TupleValHLSL val,
            string prefix,
            string semantic,
            string suffix)
        {
            int fieldCount = val.GetFieldCount();
            for (int ff = 0; ff < fieldCount; ++ff)
            {
                var decls = DeclareBase(
                    val.GetFieldVal(ff),
                    prefix,
                    semantic == null ? null : semantic + val.AggType.GetFieldName(ff),
                    suffix).Eager();

                foreach (var d in decls)
                    yield return d;
            }
        }
        public void DeclareAndInitLocalImpl(
            TupleValHLSL local,
            TupleValHLSL init,
            Span span)
        {
            int fieldCount = local.GetFieldCount();
            if (fieldCount != init.GetFieldCount())
            {
                Diagnostics.Add(
                    Severity.Error,
                    new SourceRange(),
                    "Mismatch between initializer and variable in HLSL emit!");
                return;
            }

            for (int ii = 0; ii < fieldCount; ++ii)
            {
                DeclareAndInitLocal(
                    local.GetFieldVal(ii),
                    init.GetFieldVal(ii),
                    span);
            }
        }
        public void DeclareAndInitLocalImpl(
            TupleValHLSL local,
            EmitValHLSL init,
            Span span)
        {
            int fieldCount = local.GetFieldCount();

            var aggType = local.AggType;

            for (int ii = 0; ii < fieldCount; ++ii)
            {
                var fieldInit = GetField(
                    init,
                    aggType.GetFieldType(ii),
                    aggType.GetFieldName(ii),
                    ii,
                    span);

                DeclareAndInitLocal(
                    local.GetFieldVal(ii),
                    fieldInit,
                    span);
            }
        }
 private EmitValHLSL GetFieldImpl(
     TupleValHLSL objVal,
     EmitTypeHLSL fieldType,
     string fieldName,
     int fieldIndex,
     Span span)
 {
     return objVal.GetFieldVal(fieldIndex);
 }
        public void DeclareAndInitLocalImpl(
            SimpleValHLSL local,
            TupleValHLSL init,
            Span span)
        {
            // If the record has *no* non-void fields, then
            // we shouldn't initialize
            if (!init.FieldVals.Any((fv) => !(fv is VoidValHLSL)))
            {
                span.WriteLine("{0};",
                    local.RealType.DeclareVar(local.Name));
                return;
            }

            span.WriteLine("{0} = {1};",
                local.RealType.DeclareVar(local.Name),
                init);
        }
        private EmitValHLSL EvaluateRecordAttrs(
            Span span,
            MidElementDecl record )
        {
            var recordType = EmitType(record);
            var attribVals = (from a in record.Attributes
                              where a.IsOutput
                              select EmitAttribRef(a, span)).Eager();

            var recordVal = new TupleValHLSL(
                recordType,
                attribVals);
            return recordVal;
        }
        private ElementCtorInfo GetElementCtor(MidElementDecl elementDecl)
        {
            ElementCtorInfo result;
            if (_elementCtors.TryGetValue(elementDecl, out result))
                return result;

            string name = "Ctor_" + elementDecl.Name.ToString();
            var inputAttributes = (from a in elementDecl.Attributes
                                   where a.Exp == null // \todo: real test for input-ness
                                   select a).ToArray();

            result = new ElementCtorInfo(
                name,
                elementDecl,
                inputAttributes);

            var span = new Span();

            span.WriteLine("void {0}(", name);

            var resultType = EmitType(elementDecl);

            bool first = true;
            var resultParam = DeclareOutParam("__result", resultType, span, ref first);

            foreach (var a in inputAttributes)
            {
                var attrName = MapName(a);
                var attrType = EmitType(a.Type);

                var attrParam = DeclareParam(
                    attrName,
                    attrType,
                    span,
                    ref first);

                _attrVals[a] = attrParam;

            }
            span.WriteLine(")");
            span.WriteLine("{");

            var resultAttrs = (from a in elementDecl.Attributes
                               where a.IsOutput
                               select EmitAttribRef(a, span)).ToArray();

            var resultVal = new TupleValHLSL(
                (IAggTypeHLSL) resultType,
                resultAttrs);

            Assign(resultParam, resultVal, span);

            span.WriteLine("}");

            _subroutineHeaderSpan.Add(span);

            _elementCtors[elementDecl] = result;
            return result;
        }
 private void DeclareLocalImpl(
     TupleValHLSL val,
     Span span)
 {
     int fieldCount = val.GetFieldCount();
     for (int ii = 0; ii < fieldCount; ++ii)
     {
         DeclareLocal(
             val.GetFieldVal(ii),
             span);
     }
 }
        private void AssignImpl(
            SimpleValHLSL dest,
            TupleValHLSL src,
            Span span)
        {
            int fieldCount = src.GetFieldCount();
            var aggType = src.AggType;

            for (int ii = 0; ii < fieldCount; ++ii)
            {
                var destField = GetField(
                    dest,
                    aggType.GetFieldType(ii),
                    aggType.GetFieldName(ii),
                    ii,
                    span);
                Assign(
                    destField,
                    src.GetFieldVal(ii),
                    span);
            }
        }
        private void AssignImpl(
            TupleValHLSL dest,
            TupleValHLSL src,
            Span span)
        {
            int fieldCount = src.GetFieldCount();

            for (int ii = 0; ii < fieldCount; ++ii)
            {
                Assign(
                    dest.GetFieldVal(ii),
                    src.GetFieldVal(ii),
                    span);
            }
        }
 private void AddArgsImpl(
     TupleValHLSL val,
     ref bool first,
     Span span)
 {
     int fieldCount = val.GetFieldCount();
     for (int ii = 0; ii < fieldCount; ++ii)
     {
         AddArgs(
             val.GetFieldVal(ii),
             ref first,
             span);
     }
 }
 public EmitValHLSL GetElemImpl(
     TupleValHLSL obj,
     EmitValHLSL idx)
 {
     int fieldCount = obj.GetFieldCount();
     EmitValHLSL[] fieldVals = new EmitValHLSL[fieldCount];
     TupleTypeHLSL resultType = new TupleTypeHLSL("temp");
     for (int ff = 0; ff < fieldCount; ++ff)
     {
         fieldVals[ff] = GetElem(
             obj.GetFieldVal(ff),
             idx);
         resultType.AddField(
             obj.AggType.GetFieldName(ff),
             fieldVals[ff].Type);
     }
     return new TupleValHLSL(
         resultType,
         fieldVals);
 }