예제 #1
0
        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));
                    }
                }
            }
        }