Beispiel #1
0
        public static Assignment ParseAssignment(this IEnumerator <Token> tokenStream, IdentifierToken id)
        {
            var valueToken = GetNext(tokenStream);

            switch (valueToken)
            {
            case IntegerToken:
                break;

            case FloatToken:
                break;

            case BooleanToken:
                break;

            case StringToken:
                break;

            default:
                throw ParsingException.CreateError(valueToken, "value");
            }

            ExpectNext <SemicolonToken>(tokenStream);

            return(new Assignment(id, valueToken));
        }
Beispiel #2
0
        private static List <string> ParseStringList(IEnumerator <Token> tokenStream)
        {
            var strings = new List <string>();

            tokenStream.ExpectNext <OpenBraceToken>();

            while (true)
            {
                var token = tokenStream.GetNext();
                switch (token)
                {
                case CommaToken:
                    break;

                case StringToken s:
                    strings.Add(s.Value);
                    break;

                case CloseBraceToken:
                    return(strings);

                default:
                    throw ParsingException.CreateError(token, "identifier or end of block");
                }
            }
        }
Beispiel #3
0
        public static IEnumerable <IExpression> Parse(IEnumerable <Token> tokens)
        {
            using var tokenStream = tokens.GetEnumerator();
            while (tokenStream.MoveNext())
            {
                if (tokenStream.Current is IdentifierToken i)
                {
                    switch (tokenStream.GetNext())
                    {
                    case OpenBraceToken _:
                        yield return(ParseBlock(i, tokenStream));

                        break;

                    case EqualsToken _:
                        yield return(tokenStream.ParseAssignment(i));

                        break;

                    default:
                        throw ParsingException.CreateError(tokenStream.Current, "open brace or equals");
                    }
                }
                else
                {
                    throw ParsingException.CreateError <IdentifierToken>(tokenStream.Current);
                }
            }
        }
Beispiel #4
0
        private static IExpression ParseBlock(IdentifierToken name, IEnumerator <Token> tokenStream)
        {
            var token = tokenStream.GetNext();

            return(token switch
            {
                CloseBraceToken _ => new Block(name, ImmutableArray <Assignment> .Empty),
                IdentifierToken i => ParseBlock(name, i, tokenStream),
                _ => throw ParsingException.CreateError(token, "identifier or end of block"),
            });
Beispiel #5
0
        private static Elevator ParseElevator(IEnumerator <Token> tokenStream, IdentifierToken id)
        {
            var oldNum =
                tokenStream
                .ExpectNext <IntegerToken>()
                .ValueAsUshort(token => ParsingException.CreateError(token, "UShort value"));

            tokenStream.ExpectNext <SemicolonToken>();

            return(new Elevator(oldNum));
        }
Beispiel #6
0
        private static IExpression ParseBlockOrTupleList(IdentifierToken name, IEnumerator <Token> tokenStream)
        {
            var token = tokenStream.GetNext();

            return(token switch
            {
                OpenBraceToken ob => ParseIntTupleList(name, ob.Location, tokenStream),
                CloseBraceToken _ => new Block(name, ImmutableArray <Assignment> .Empty),
                IdentifierToken i => ParseBlock(name, i, tokenStream),
                _ => throw ParsingException.CreateError(token, "identifier, end of block, or start of tuple"),
            });
Beispiel #7
0
        private static TileMappings ParseTileMappings(IEnumerator <Token> tokenStream)
        {
            tokenStream.ExpectNext <OpenBraceToken>();

            var ambushModzones        = new List <AmbushModzone>();
            var changeTriggerModzones = new List <ChangeTriggerModzone>();
            var tileTemplates         = new List <TileTemplate>();
            var triggerTemplates      = new List <TriggerTemplate>();
            var zoneTemplates         = new List <ZoneTemplate>();

            while (true)
            {
                var token = tokenStream.GetNext();
                switch (token)
                {
                case IdentifierToken id:
                    switch (id.Id.ToLower())
                    {
                    case "modzone":
                        ParseModzone(tokenStream, id, ambushModzones, changeTriggerModzones);
                        break;

                    case "tile":
                        tileTemplates.Add(ParseTileTemplate(tokenStream, id));
                        break;

                    case "trigger":
                        triggerTemplates.Add(ParseTriggerTemplate(tokenStream, id));
                        break;

                    case "zone":
                        zoneTemplates.Add(ParseZone(tokenStream, id));
                        break;

                    default:
                        throw ParsingException.CreateError(id, "unknown identifier");
                    }
                    break;

                case CloseBraceToken:
                    return(new TileMappings(
                               ambushModzones.ToImmutableArray(),
                               changeTriggerModzones.ToImmutableArray(),
                               tileTemplates.ToImmutableArray(),
                               triggerTemplates.ToImmutableArray(),
                               zoneTemplates.ToImmutableArray()));

                default:
                    throw ParsingException.CreateError(token, "identifier or end of block");
                }
            }
        }
Beispiel #8
0
        private static TriggerTemplate ParseTriggerTemplate(IEnumerator <Token> tokenStream, IdentifierToken id)
        {
            var oldNum =
                tokenStream
                .ExpectNext <IntegerToken>()
                .ValueAsUshort(token => ParsingException.CreateError(token, "UShort value"));

            tokenStream.ExpectNext <OpenBraceToken>();

            var block = tokenStream.ParseBlock(id);

            return(ReadTriggerTemplate(oldNum, block));
        }
Beispiel #9
0
        private static ZoneTemplate ParseZone(IEnumerator <Token> tokenStream, IdentifierToken id)
        {
            var oldNum =
                tokenStream
                .ExpectNext <IntegerToken>()
                .ValueAsUshort(token => ParsingException.CreateError(token, "UShort value"));

            tokenStream.ExpectNext <OpenBraceToken>();

            var block  = tokenStream.ParseBlock(id);
            var fields = block.GetFieldAssignments();

            return(new ZoneTemplate(
                       oldNum,
                       Comment: fields.GetOptionalFieldValue("comment", "")));
        }
Beispiel #10
0
        private static void ParseModzone(
            IEnumerator <Token> tokenStream,
            IdentifierToken id,
            List <AmbushModzone> ambushModzones,
            List <ChangeTriggerModzone> changeTriggerModzones)
        {
            var oldNum =
                tokenStream
                .ExpectNext <IntegerToken>()
                .ValueAsUshort(token => ParsingException.CreateError(token, "UShort value"));

            bool fillZone = false;

            var next = tokenStream.ExpectNext <IdentifierToken>();

            if (next.Id.ToLower() == "fillzone")
            {
                fillZone = true;
                next     = tokenStream.ExpectNext <IdentifierToken>();
            }

            if (next.Id.ToLower() == "ambush")
            {
                tokenStream.ExpectNext <SemicolonToken>();

                ambushModzones.Add(new AmbushModzone(oldNum, fillZone));
            }
            else if (next.Id.ToLower() == "changetrigger")
            {
                var action = tokenStream.ExpectNext <StringToken>().Value;

                tokenStream.ExpectNext <OpenBraceToken>();

                var block = tokenStream.ParseBlock(id);

                var triggerTemplate = ReadTriggerTemplate(oldNum, block);

                changeTriggerModzones.Add(new ChangeTriggerModzone(oldNum, action, triggerTemplate, fillZone));
            }
            else
            {
                throw ParsingException.CreateError(next, "ambush or changetrigger");
            }
        }
Beispiel #11
0
        public static Block ParseBlock(this IEnumerator <Token> tokenStream, IdentifierToken name)
        {
            var assignments = new List <Assignment>();

            while (true)
            {
                var token = GetNext(tokenStream);
                switch (token)
                {
                case IdentifierToken i:
                    ExpectNext <EqualsToken>(tokenStream);
                    assignments.Add(tokenStream.ParseAssignment(i));
                    break;

                case CloseBraceToken:
                    return(new Block(name, assignments.ToImmutableArray()));

                default:
                    throw ParsingException.CreateError(token, "identifier or end of block");
                }
            }
        }
Beispiel #12
0
        private static IEnumerable <IMapping> ParseThingMappings(IEnumerator <Token> tokenStream)
        {
            tokenStream.ExpectNext <OpenBraceToken>();

            var thingMappings = new List <IMapping>();

            while (true)
            {
                var token = tokenStream.GetNext();
                switch (token)
                {
                case IdentifierToken id:
                    switch (id.Id.ToLower())
                    {
                    case "elevator":
                        thingMappings.Add(ParseElevator(tokenStream, id));
                        break;

                    case "trigger":
                        thingMappings.Add(ParseTriggerTemplate(tokenStream, id));
                        break;

                    default:
                        throw ParsingException.CreateError(id, "unknown identifier");
                    }
                    break;

                case OpenBraceToken:
                    thingMappings.Add(ParseThingTemplate(tokenStream));
                    break;

                case CloseBraceToken:
                    return(thingMappings);

                default:
                    throw ParsingException.CreateError(token, "identifier or end of block");
                }
            }
        }
Beispiel #13
0
        private static FlatMappings ParseFlatMappings(IEnumerator <Token> tokenStream)
        {
            var ceilings = new List <string>();
            var floors   = new List <string>();

            tokenStream.ExpectNext <OpenBraceToken>();

            while (true)
            {
                var token = tokenStream.GetNext();
                switch (token)
                {
                case IdentifierToken id:
                    switch (id.Id.ToLower())
                    {
                    case "ceiling":
                        ceilings.AddRange(ParseStringList(tokenStream));
                        break;

                    case "floor":
                        floors.AddRange(ParseStringList(tokenStream));
                        break;

                    default:
                        throw ParsingException.CreateError(id, "unknown identifier");
                    }
                    break;

                case CloseBraceToken:
                    return(new FlatMappings(
                               ceilings.ToImmutableArray(),
                               floors.ToImmutableArray()));

                default:
                    throw ParsingException.CreateError(token, "identifier or end of block");
                }
            }
        }
Beispiel #14
0
        private static (string mapLump, string?mapName, bool isMapNameLookup) ParseMapHeader(
            IdentifierToken context,
            IEnumerator <Token> tokenStream)
        {
            var    mapLump         = tokenStream.ExpectNext <StringToken>().Value;
            string?mapName         = null;
            bool   isMapNameLookup = false;

            var next = tokenStream.GetNextSkippingNewlines();

            if (next is StringToken nameToken)
            {
                mapName = nameToken.Value;
                tokenStream.ExpectNextSkippingNewlines <OpenBraceToken>();
            }
            else if (next is IdentifierToken lookupToken)
            {
                if (lookupToken.Id.ToLower() != "lookup")
                {
                    throw ParsingException.CreateError(lookupToken, "lookup");
                }

                isMapNameLookup = true;
                mapName         = tokenStream.ExpectNext <StringToken>().Value;
                tokenStream.ExpectNextSkippingNewlines <OpenBraceToken>();
            }
            else if (next is OpenBraceToken)
            {
                // expected, do nothing
            }
            else
            {
                throw new ParsingException("Messed up map definition: " + context);
            }

            return(mapLump, mapName, isMapNameLookup);
        }
Beispiel #15
0
        private static IEnumerable <VariableAssignment> ParseBlock(IEnumerator <Token> tokenStream, bool alreadyOpened)
        {
            if (!alreadyOpened)
            {
                tokenStream.ExpectNextSkippingNewlines <OpenBraceToken>();
            }

            while (true)
            {
                var token = tokenStream.GetNextSkippingNewlines();
                switch (token)
                {
                case IdentifierToken id:
                    var next         = tokenStream.GetNext();
                    var valueBuilder = ImmutableArray.CreateBuilder <Token>();

                    switch (next)
                    {
                    case NewLineToken:
                        yield return(new VariableAssignment(id, valueBuilder.ToImmutable()));

                        break;

                    case EqualsToken:
                        next = tokenStream.GetNext();
                        if (next == null || next is NewLineToken)
                        {
                            throw new ParsingException($"Messed up line staring with {id}");
                        }
                        valueBuilder.Add(next);

                        bool continueLoop = true;
                        while (continueLoop)
                        {
                            next = tokenStream.GetNext();
                            switch (next)
                            {
                            case NewLineToken:
                                yield return(new VariableAssignment(id, valueBuilder.ToImmutable()));

                                continueLoop = false;
                                break;

                            case null:
                                throw new ParsingException("Unexpected end of file");

                            default:
                                valueBuilder.Add(next);
                                break;
                            }
                        }

                        break;

                    default:
                        throw new ParsingException($"Messed up line starting with {id}");
                    }

                    break;

                case CloseBraceToken:
                    yield break;

                default:
                    throw ParsingException.CreateError(token, "identifier or close brace");
                }
            }
        }
Beispiel #16
0
        private static ThingTemplate ParseThingTemplate(IEnumerator <Token> tokenStream)
        {
            var oldNum =
                tokenStream
                .ExpectNext <IntegerToken>()
                .ValueAsUshort(token => ParsingException.CreateError(token, "UShort value"));

            tokenStream.ExpectNext <CommaToken>();

            var actor = tokenStream.ExpectNext <IdentifierToken>().Id.ToString();

            tokenStream.ExpectNext <CommaToken>();

            var angles = tokenStream.ExpectNext <IntegerToken>().Value;

            tokenStream.ExpectNext <CommaToken>();

            var flags = new HashSet <string>();

            var next = tokenStream.GetNext();

            if (next is IntegerToken i)
            {
                if (i.Value != 0)
                {
                    throw ParsingException.CreateError(i, "Expected 0 value for flags");
                }

                tokenStream.ExpectNext <CommaToken>();
            }
            else if (next is IdentifierToken flagToken)
            {
                flags.Add(flagToken.Id.ToLower());

                while (true)
                {
                    next = tokenStream.GetNext();

                    if (next is CommaToken)
                    {
                        break;
                    }
                    else if (next is PipeToken)
                    {
                        flags.Add(tokenStream.ExpectNext <IdentifierToken>().Id.ToLower());
                    }
                    else
                    {
                        throw ParsingException.CreateError(next, "Comma or pipe");
                    }
                }
            }
            else
            {
                throw ParsingException.CreateError(next, "Expected number or flags");
            }

            var minSkill = tokenStream.ExpectNext <IntegerToken>().Value;

            tokenStream.ExpectNext <CloseBraceToken>();

            return(new ThingTemplate(
                       oldNum,
                       actor,
                       angles,
                       Holowall: flags.Contains("holowall"),
                       Pathing: flags.Contains("pathing"),
                       Ambush: flags.Contains("ambush"),
                       Minskill: minSkill));
        }