c# StringBuilder with Linq-ish capabilities IfElse is this possible?

184 views Asked by At

I'm writing down an AST (abstract syntax tree) not in tree form but with the intent of correctly formatting my code.. similar to Clang for a custom language and I'm using a StringBuilder for the effect... Right now I have to do things like:

        public string Visit(IfStatement ifStatement, int indent = 0)
        {
            var sb = new StringBuilder()
                .Append('\t', indent)
                .Append(Token.IfKeyword.ToString())
                .AppendBetween(ifStatement.Test.Accept(this), "(", ")").AppendLine()
                .Append(ifStatement.Consequent.Accept(this, indent + 1));

            if (ifStatement.Consequent != null)
            {
                sb.AppendLine()
                    .Append('\t', indent)
                    .AppendLine(Token.ElseKeyword.ToString())
                    .Append(ifStatement.Consequent.Accept(this, indent + 1));
            }

            return sb.ToString();
        }

This sometimes gets pretty complex so I was hoping I could do something like:

sb.Append("Hello").IfElse(a > 5, sb => sb.Append("world!"), sb => sb.AppendLine("ME!!")).Append(...)

Can this be done using class extensions? Thank you very much for your time!

(BTW is there a better way to write down an AST? I'm currently using the Visitor pattern for the effect but if you know a better way please let me know... I also wanted to introduce text wrapping if certain line width is reached.. don't know how to do that though).

1

There are 1 answers

0
xDGameStudios On

I ended up following @GSerg suggestion.

public static StringBuilder IfElse(this StringBuilder sb, bool condition, Action<StringBuilder> if_true, Action<StringBuilder> if_false) 
{ 
    if (condition) { if_true(sb); } else { if_false(sb); } return sb; 
}

and then I can do:

new StringBuilder().Append("World").IfElse(!IsNight(), sb => sb.Insert(0, "Hello ".AppendFormat(", my name is {0}", GetName())), sb => sb.Insert(0, "Bye "))

I just didn't know how the lambda thing sb => sb.Whatever() worked (I need to use functions as arguments).