/// <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); }