Пример #1
0
        /// <summary>
        /// Creates and initializes a new <see cref="CommandCompiler"/>.
        /// </summary>
        public CommandCompiler()
        {
            CommentHead      = String("//");
            LiteralMarker    = Char('#');
            CharMarker       = Char('\'');
            StringMarker     = Char('\"');
            AddressMarker    = Char('$');
            DirectiveMarker  = Char('.');
            ReferenceMarker  = Char('?');
            AnyCommandMarker = OneOf(LiteralMarker, AddressMarker, ReferenceMarker);
            EnumStart        = Char('{');
            EnumEnd          = Char('}');
            ExceptEndLine    = AnyCharExcept('\r', '\n');

            TrueString  = String("true");
            FalseString = String("false");
            NullString  = String("null");

            ReservedCommandNames = new string[]
            {
                "Define",
                "Var",
                "Constant"
            };

            NumLiteral =
                from l in CurrentPos
                from n in LiteralMarker.Then(Digit.Or(Char('.')).Or(Char('-')).ManyString())
                select new ValueToken()
            {
                Value = n, Type = ValueType.Immediate, Position = l
            };

            CharLiteral =
                from l in CurrentPos
                from c in Any.Between(CharMarker)
                select new ValueToken()
            {
                Value = c.ToString(), Type = ValueType.Immediate, Position = l
            };

            StringLiteral =
                from l in CurrentPos
                from c in AnyCharExcept('\"').ManyString().Between(StringMarker)
                select new ValueToken()
            {
                Value = c.ToString(), Type = ValueType.Immediate, Position = l
            };

            BoolLiteral =
                from l in CurrentPos
                from b in OneOf(Try(TrueString), FalseString)
                select new ValueToken()
            {
                Value = b, Type = ValueType.Immediate, Position = l
            };

            EnumLiteral =
                from l in CurrentPos
                from e in LetterOrDigit.ManyString().Between(EnumStart, EnumEnd)
                select new ValueToken()
            {
                Value = e, Type = ValueType.Immediate, Position = l
            };

            NullLiteral =
                from l in CurrentPos
                from n in NullString
                select new ValueToken()
            {
                Value = string.Empty, Type = ValueType.Immediate, Position = l
            };

            Address =
                from l in CurrentPos
                from a in AddressMarker
                from n in Num
                select new ValueToken()
            {
                Value = n.ToString(), Type = ValueType.Address, Position = l
            };

            Directive =
                from l in CurrentPos
                from d in DirectiveMarker
                from n in LetterOrDigit.Or(DirectiveMarker).ManyString()
                select new ValueToken()
            {
                Value = n, Type = ValueType.Directive, Position = l
            };

            Reference =
                from l in CurrentPos
                from r in ReferenceMarker
                from n in LetterOrDigit.Or(DirectiveMarker).ManyString()
                select new ValueToken()
            {
                Value = n, Type = ValueType.Reference, Position = l
            };

            Value = OneOf(
                NumLiteral.Labelled("number"),
                CharLiteral.Labelled("char"),
                StringLiteral.Labelled("string"),
                EnumLiteral.Labelled("enum"),
                Try(BoolLiteral).Labelled("bool"),
                Try(NullLiteral).Labelled("null"),
                Address.Labelled("address"),
                Directive.Labelled("directive"),
                Reference.Labelled("reference"));

            CompilerCommand =
                from l in CurrentPos
                from c in LetterOrDigit.AtLeastOnceString().Where(n => ReservedCommandNames.Contains(n)).Labelled("reserved command")
                from v in Try(SkipWhitespaces.Then(Value)).Many()
                select new CommandCall()
            {
                Name     = c,
                Inputs   = v.ToArray(),
                Type     = CallType.Compiler,
                Position = l
            };

            CallCommand =
                from l in CurrentPos
                from c in LetterOrDigit.Or(AnyCommandMarker).AtLeastOnceString().Where(n => KnownCommandNames.Contains(n)).Labelled("known command")
                from v in Try(SkipWhitespaces.Then(Value)).Many()
                select new CommandCall()
            {
                Name     = c,
                Inputs   = v.ToArray(),
                Type     = CallType.Command,
                Position = l
            };

            Command = OneOf(Try(CompilerCommand).Labelled("compiler call"), CallCommand.Labelled("command call"));
            Code    = OneOf(
                Try(CommentHead.Then(ExceptEndLine.SkipMany())).ThenReturn <CommandCall?>(null).Labelled("comment"),
                Command.Select <CommandCall?>(c => c))
                      .SeparatedAndOptionallyTerminatedAtLeastOnce(SkipWhitespaces);
        }