Ejemplo n.º 1
0
        public RuleNode(DeltinScriptParser.Ow_ruleContext context, BuildAstVisitor visitor) : base(new Location(visitor.file, Range.GetRange(context)))
        {
            Name  = context.STRINGLITERAL().GetText().Trim('"');
            Block = (BlockNode)visitor.VisitBlock(context.block());

            Conditions = new Node[context.rule_if().Length];
            Range[] conditionRanges = new Range          [context.rule_if().Length];

            for (int i = 0; i < context.rule_if().Length; i++)
            {
                if (context.rule_if(i).expr() != null)
                {
                    Conditions[i] = visitor.VisitExpr(context.rule_if(i).expr());
                }

                // Get the range between the ().
                conditionRanges[i] = Range.GetRange(
                    context.rule_if(i).LEFT_PAREN().Symbol,
                    context.rule_if(i).RIGHT_PAREN().Symbol
                    );
            }

            RuleEvent      eventType = RuleEvent.OngoingGlobal;
            Team           team      = Team.All;
            PlayerSelector player    = PlayerSelector.All;

            Range eventRange  = null;
            Range teamRange   = null;
            Range playerRange = null;

            foreach (var ruleOption in context.@enum())
            {
                string option      = ruleOption.PART(0).GetText();
                Range  optionRange = Range.GetRange(ruleOption.PART(0).Symbol);

                string value      = ruleOption.PART(1)?.GetText();
                Range  valueRange = null;
                if (value != null)
                {
                    valueRange = Range.GetRange(ruleOption.PART(1).Symbol);
                }

                Range totalRange;
                if (ruleOption.PART(1) != null)
                {
                    totalRange = Range.GetRange(ruleOption.PART(0).Symbol, ruleOption.PART(1).Symbol);
                }
                else
                {
                    totalRange = Range.GetRange(ruleOption.PART(0));
                }

                switch (option)
                {
                case "Event":
                    if (eventRange != null)
                    {
                        visitor._diagnostics.Error("Event already set.", new Location(visitor.file, totalRange));
                    }

                    if (!Enum.TryParse <RuleEvent>(value, out eventType))
                    {
                        visitor._diagnostics.Error($"{value} is not a valid Event type.", new Location(visitor.file, valueRange));
                    }

                    eventRange = Range.GetRange(ruleOption);
                    break;

                case "Team":
                    if (teamRange != null)
                    {
                        visitor._diagnostics.Error("Team already set.", new Location(visitor.file, totalRange));
                    }

                    if (!Enum.TryParse <Team>(value, out team))
                    {
                        visitor._diagnostics.Error($"{value} is not a valid Team type.", new Location(visitor.file, valueRange));
                    }

                    teamRange = Range.GetRange(ruleOption);
                    break;

                case "Player":
                    if (playerRange != null)
                    {
                        visitor._diagnostics.Error("Player already set.", new Location(visitor.file, totalRange));
                    }

                    if (!Enum.TryParse <PlayerSelector>(value, out player))
                    {
                        visitor._diagnostics.Error($"{value} is not a valid Player type.", new Location(visitor.file, valueRange));
                    }

                    playerRange = Range.GetRange(ruleOption);
                    break;

                default:
                    visitor._diagnostics.Error($"{option} is not a valid rule option.", new Location(visitor.file, optionRange));
                    break;
                }
            }
            Event  = eventType;
            Team   = team;
            Player = player;

            SubRanges = ArrayBuilder <Range> .Build(eventRange, teamRange, playerRange, conditionRanges);
        }