public override void CheckSemantics(TigerScope scope, Report report) { ContainingScope = scope; //Check children LValueNode.CheckSemantics(scope, report); AttributeNode.CheckSemantics(scope, report); if (!LValueNode.IsOK || !AttributeNode.IsOK) { return; } //Check children types if (!(LValueNode.TigerType is RecordType)) { report.AddError(SemanticErrors.NonRecordType(LValueNode, LValueNode.TigerType)); } else { var field = ((RecordType)LValueNode.TigerType).RecordFields.FirstOrDefault(f => f.Name == AttributeNode.Name); if (field == null) { report.AddError(SemanticErrors.InvalidField(AttributeNode, AttributeNode.Name, LValueNode.TigerType.Name)); } else { TigerType = field.TigerType; } } }
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)); } } } }