예제 #1
0
파일: codegen_c.cs 프로젝트: hlorenzi/trapl
        private string GenerateStructDecl(int structIndex)
        {
            var st = session.GetStruct(structIndex);

            if (st.primitive)
            {
                return("");
            }

            var result = "struct " + MangleName(session.GetStructName(structIndex)) + ";\n\n";

            return(result);
        }
예제 #2
0
        private static bool CheckField(
            Core.Session session, int structIndex, int fieldIndex,
            Core.Type innerType, Stack <int> seenStructs)
        {
            var fieldStruct = innerType as Core.TypeStruct;

            if (fieldStruct == null)
            {
                return(false);
            }

            var st = session.GetStruct(structIndex);

            Core.Name fieldName;
            st.fieldNames.FindByValue(fieldIndex, out fieldName);

            session.PushContext(
                "in struct '" + session.GetStructName(structIndex).GetString() + "', " +
                "field '" + fieldName.GetString() + "'",
                st.GetFieldNameSpan(fieldIndex));

            var err = false;

            if (seenStructs.Contains(fieldStruct.structIndex))
            {
                err = true;
                session.AddMessage(
                    Diagnostics.MessageKind.Error,
                    Diagnostics.MessageCode.StructRecursion,
                    "struct recursion",
                    session.GetStruct(fieldStruct.structIndex).GetNameSpan(),
                    st.GetFieldNameSpan(fieldIndex));
            }

            if (!err)
            {
                CheckStruct(session, fieldStruct.structIndex, seenStructs);
            }

            session.PopContext();
            return(err);
        }
예제 #3
0
        public static int GetFieldNum(
            Core.Session session,
            Core.Type baseType)
        {
            var baseStruct = baseType as Core.TypeStruct;

            if (baseStruct != null)
            {
                return(session.GetStruct(baseStruct.structIndex).fieldTypes.Count);
            }

            var baseTuple = baseType as Core.TypeTuple;

            if (baseTuple != null)
            {
                return(baseTuple.elementTypes.Length);
            }

            return(0);
        }
예제 #4
0
        public static Core.Type GetFieldType(
            Core.Session session,
            Core.Type baseType,
            int fieldIndex)
        {
            var baseStruct = baseType as Core.TypeStruct;

            if (baseStruct != null)
            {
                return(session.GetStruct(baseStruct.structIndex).fieldTypes[fieldIndex]);
            }

            var baseTuple = baseType as Core.TypeTuple;

            if (baseTuple != null)
            {
                return(baseTuple.elementTypes[fieldIndex]);
            }

            return(new Core.TypeError());
        }
예제 #5
0
        public static Core.Name GetFieldName(
            Core.Session session,
            Core.Type baseType,
            int fieldIndex)
        {
            var baseStruct = baseType as Core.TypeStruct;

            if (baseStruct != null)
            {
                Core.Name name;
                session.GetStruct(baseStruct.structIndex).fieldNames.FindByValue(fieldIndex, out name);
                return(name);
            }

            var baseTuple = baseType as Core.TypeTuple;

            if (baseTuple != null)
            {
                return(Core.Name.FromPath(fieldIndex.ToString()));
            }

            return(null);
        }
예제 #6
0
        private static bool CheckStruct(Core.Session session, int structIndex, Stack <int> seenStructs)
        {
            var st  = session.GetStruct(structIndex);
            var err = false;

            seenStructs.Push(structIndex);

            for (var i = 0; i < st.fieldTypes.Count; i++)
            {
                err |= CheckField(session, structIndex, i, st.fieldTypes[i], seenStructs);

                var fieldTuple = st.fieldTypes[i] as Core.TypeTuple;
                if (fieldTuple != null)
                {
                    for (var j = 0; j < fieldTuple.elementTypes.Length; j++)
                    {
                        err |= CheckField(session, structIndex, i, fieldTuple.elementTypes[j], seenStructs);
                    }
                }
            }

            seenStructs.Pop();
            return(err);
        }
예제 #7
0
        private void ResolveExprLiteralStruct(Grammar.ASTNodeExprLiteralStruct exprLiteralStruct, ref int curSegment, Core.DataAccess output)
        {
            var type = TypeResolver.ResolveStruct(session, exprLiteralStruct.name, useDirectives, true);

            if (!type.IsResolved())
            {
                return;
            }

            var typeStruct     = type as Core.TypeStruct;
            var fieldNum       = TypeResolver.GetFieldNum(this.session, typeStruct);
            var fieldDestSpans = new Diagnostics.Span?[fieldNum];

            var fieldRegs = new int[fieldNum];

            for (var i = 0; i < fieldNum; i++)
            {
                fieldRegs[i] = funct.CreateRegister(
                    TypeResolver.GetFieldType(this.session, typeStruct, i), false);
            }

            var fieldRegAccesses = new Core.DataAccess[fieldNum];

            for (var i = 0; i < fieldNum; i++)
            {
                fieldRegAccesses[i] =
                    Core.DataAccessRegister.ForRegister(exprLiteralStruct.name.GetSpan(), fieldRegs[i]);
            }

            foreach (var fieldInit in exprLiteralStruct.fields)
            {
                var name = NameResolver.Resolve(fieldInit.name);

                int fieldIndex;
                if (!this.session.GetStruct(typeStruct.structIndex).fieldNames.FindByName(name, out fieldIndex))
                {
                    this.foundErrors = true;
                    session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.Unknown,
                        "unknown field '" + name.GetString() + "' in '" +
                        type.GetString(this.session) + "'",
                        fieldInit.name.GetSpan());
                    continue;
                }

                if (fieldDestSpans[fieldIndex].HasValue)
                {
                    this.foundErrors = true;
                    session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.Unknown,
                        "duplicate field '" + name.GetString() + "' initialization",
                        fieldInit.name.GetSpan(),
                        fieldDestSpans[fieldIndex].Value);
                    continue;
                }

                fieldRegAccesses[fieldIndex].span = fieldInit.name.GetSpan();
                fieldDestSpans[fieldIndex]        = fieldInit.name.GetSpan();
                this.ResolveExpr(fieldInit.expr, ref curSegment, fieldRegAccesses[fieldIndex]);
            }

            var missingFields = new List <int>();

            for (var i = 0; i < fieldNum; i++)
            {
                if (!fieldDestSpans[i].HasValue)
                {
                    missingFields.Add(i);
                }
            }

            if (missingFields.Count > 0)
            {
                Core.Name fieldName;
                session.GetStruct(typeStruct.structIndex).fieldNames.FindByValue(missingFields[0], out fieldName);

                this.foundErrors = true;
                session.AddMessage(
                    Diagnostics.MessageKind.Error,
                    Diagnostics.MessageCode.Unknown,
                    "missing initializer" + (missingFields.Count > 1 ? "s" : "") +
                    " for field '" + fieldName.GetString() + "'" +
                    (missingFields.Count > 1 ? " and other " + (missingFields.Count - 1) : ""),
                    exprLiteralStruct.GetSpan());
            }
            else
            {
                var finalFieldDestSpans = new Diagnostics.Span[fieldNum];
                for (var i = 0; i < fieldNum; i++)
                {
                    finalFieldDestSpans[i] = fieldDestSpans[i].Value;
                }

                funct.AddInstruction(curSegment, Core.InstructionMoveLiteralStruct.Of(
                                         exprLiteralStruct.GetSpan(), output,
                                         typeStruct.structIndex, fieldRegAccesses, finalFieldDestSpans));
            }
        }
예제 #8
0
 public override bool IsZeroSized(Core.Session session)
 {
     var st = session.GetStruct(this.structIndex);
     return !st.primitive && st.fieldTypes.Count == 0;
 }