public override void CheckSemantics(TigerScope scope, Report report) { ContainingScope = scope; //Check children TypeNode.CheckSemantics(scope, report); RecordFieldInitNodes.ToList().ForEach(f => f.CheckSemantics(scope, report)); if (!TypeNode.IsOK || RecordFieldInitNodes.Any(f => !f.IsOK)) { return; } //Check children types if (!(TypeNode.TigerType is RecordType)) { report.AddError(SemanticErrors.NonRecordType(TypeNode, TypeNode.TigerType)); } else { TigerType = TypeNode.TigerType; var fields = ((RecordType)TypeNode.TigerType).RecordFields; //Check fields length if (fields.Length != RecordFieldInitNodes.Length) { report.AddError(SemanticErrors.WrongNumberOfFields(TypeNode, TypeNode.TigerType.Name, fields.Length, RecordFieldInitNodes.Length)); } //Check field names and types for (int i = 0; i < Math.Min(fields.Length, RecordFieldInitNodes.Length); i++) { if (fields[i].Name != RecordFieldInitNodes[i].IdNode.Name) { report.AddError(SemanticErrors.WrongFieldPosition(RecordFieldInitNodes[i].IdNode, fields[i].Name, RecordFieldInitNodes[i].IdNode.Name)); } if (!fields[i].TigerType.Assignable(RecordFieldInitNodes[i].TigerType)) { report.AddError(SemanticErrors.InvalidFieldType(RecordFieldInitNodes[i].IdNode, fields[i].TigerType, RecordFieldInitNodes[i].TigerType)); } } } }