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); }
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); }
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); }
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()); }
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); }
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); }
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)); } }
public override bool IsZeroSized(Core.Session session) { var st = session.GetStruct(this.structIndex); return !st.primitive && st.fieldTypes.Count == 0; }