neat IF condtion implementation in a scripting language
neat IF condtion implementation in a scripting language
I have a little helper class that generates a script, used later in my code, namely :
public class ScriptBuilder
{
public string Script { get; set; }
public ScriptBuilder NewLine(uint numberOfLines = 1)
{
if (numberOfLines == 0)
{
return this;
}
else
{
for (int i = 1; i <= numberOfLines; ++i)
{
Script += Environment.NewLine;
}
return this;
}
}
public ScriptBuilder WriteLine(string str = "")
{
if (str != "")
{
Script += str;
NewLine();
}
return this;
}
public ScriptBuilder(string line = "")
{
Script = line;
if (line != "")
{
NewLine();
}
}
public ScriptBuilder setLong(string longName, long x)
{
WriteLine("int " + longName + " " + x.ToString(System.Globalization.CultureInfo.InvariantCulture));
return this;
}
// + other set functions with different parameters/numbers of parameters
}
// ScriptBuilder is used like this :
ScriptBuilder scriptStringBuilder = new ScriptBuilder();
scriptStringBuilder
.WriteLine($"/!HEADSTART")
.WriteLine($"/! TYPE = {scriptType}")
.WriteLine($"/! NAME = {name}")
.WriteLine($"/! DESCRIPTION = {description}")
.WriteLine($"/!HEADEND")
/* the header is done now */
.NewLine(2);
It is pretty basic method chaining. I would like to implement IF and IF ELSE IF ELSE in this scripting language, but I don't see a really neat way for doing it.
IF
IF ELSE IF ELSE
For the IF I came up with the member function :
IF
public ScriptBuilder IF(bool condition, ScriptBuilder res)
{
if (condition)
{
return res;
}
else
{
return this;
}
}
that can be used as :
ScriptBuilder.IF(condition,
scriptStringBuilder
.setThis(...)
.setThat(...)
;
)
but I am not satisfied because
scriptStringBuilder.setThis(...).setThat(...);
scriptStringBuilder
IF ELSE IF ELSE
I could use delegates perhaps, like :
public delegate ScriptBuilder ScriptBuilderFunction(params object Parameters);
public ScriptBuilder IF(bool condition, ScriptBuilderFunction func)
{
// ...
}
but I don't even see how to implement that ...
Ideally, I would like to write :
scriptStringBuilder.
.setThis(...)
.setThat(...)
.IF(condition)
.THEN()
.setThis(...)
.doThat(...)
.ELSEIF(othercondition)
.makeThis(...)
.doThat(...)
.ENDIF()
.setThatNow(...)
;
MaxStringBuilder
IF
.setThis
It was a typo, sorry, it is
ScriptBuilder– ujsgeyrr1f0d0d0r0h1h0j0j_juj
Jul 3 at 9:22
ScriptBuilder
A it is flawed anyway per your right remark, yes
– ujsgeyrr1f0d0d0r0h1h0j0j_juj
Jul 3 at 9:23
You could try IF(condition, then_expression, else_expression).
– AndreiM
Jul 3 at 9:49
@AndreiM If I understand right, I don't see how this changes the evaluation question pointed by Lasse.
– ujsgeyrr1f0d0d0r0h1h0j0j_juj
Jul 3 at 9:57
1 Answer
1
This is a very rough sketch of how you could implement this:
class Program
{
static void Main(string args)
{
var number = 999;
ScriptBuilder scriptStringBuilder = new ScriptBuilder();
var text = scriptStringBuilder
.WriteLine($"/!HEADSTART")
.WriteLine($"/! TYPE = abc")
.WriteLine($"/! NAME = name")
.WriteLine($"/!HEADEND")
.NewLine(2)
.IfCondition(number != 999, ifCondition => {
ifCondition.NewLine(1);
ifCondition.WriteLine("SUCCESS");
}, elseCondition => {
elseCondition.NewLine(1);
elseCondition.WriteLine("FAIL");
},
elseIf1 => elseIf1.ElseIfCondition(number > 1, h1 => h1.WriteLine("NUMBER IS BIGGER THAN 1")),
elseIf2 => elseIf2.ElseIfCondition(number > 2, h2 => h2.WriteLine("NUMBER IS BIGGER THAN 2")))
.Build();
Console.WriteLine(text);
Console.ReadKey();
}
}
public class ScriptBuilder : IElseIfConditionable
{
private string _script;
public ScriptBuilder NewLine(uint numberOfLines = 1)
{
if (numberOfLines == 0)
{
return this;
}
else
{
for (int i = 1; i <= numberOfLines; ++i)
{
_script += Environment.NewLine;
}
return this;
}
}
public ScriptBuilder WriteLine(string str = "")
{
if (str != "")
{
_script += str;
NewLine();
}
return this;
}
public ScriptBuilder(string line = "")
{
_script = line;
if (line != "")
{
NewLine();
}
}
public ScriptBuilder SetLong(string longName, long x)
{
WriteLine("int " + longName + " " + x.ToString(System.Globalization.CultureInfo.InvariantCulture));
return this;
}
public string Build()
{
return _script;
}
public ScriptBuilder IfCondition(bool condition, Action<ScriptBuilder> trueCondition, Action<ScriptBuilder> falseCondition, params Func<IElseIfConditionable, Tuple<ScriptBuilder, bool>> elseIfs)
{
if (condition)
{
trueCondition(this);
return this;
}
foreach (var elseIf in elseIfs)
{
if (elseIf(this).Item2)
{
return this;
}
}
if (!condition)
{
falseCondition(this);
}
return this;
}
public Tuple<ScriptBuilder, bool> ElseIfCondition(bool condition, Action<ScriptBuilder> trueCondition)
{
if (condition)
{
trueCondition(this);
}
return Tuple.Create(this, condition);
}
}
public interface IElseIfConditionable
{
Tuple<ScriptBuilder, bool> ElseIfCondition(bool condition, Action<ScriptBuilder> trueCondition);
}
This is equivalent of:
var s = new ScriptBuilder();
if (number != 999)
{
s.NewLine(1);
s.WriteLine("SUCCESS");
}
else if (number > 1)
{
s.WriteLine("NUMBER IS BIGGER THAN 1");
}
else if (number > 2)
{
s.WriteLine("NUMBER IS BIGGER THAN 2");
}
else
{
s.NewLine(1);
s.WriteLine("FAIL");
}
That seems to work ! How would you do for a switch case statement ?
– ujsgeyrr1f0d0d0r0h1h0j0j_juj
Jul 3 at 12:35
@ujsgeyrr1f0d0d0r0h1h0j0j_juj if/elseif/else is the same as switch statement (I don't care if it doesn't use hashes internally), so there is no reason to implement it separately.
– FCin
Jul 3 at 12:37
Ok yes, point taken
– ujsgeyrr1f0d0d0r0h1h0j0j_juj
Jul 3 at 12:41
I don't understand why you couldn't use only param arrays ?
– ujsgeyrr1f0d0d0r0h1h0j0j_juj
Jul 3 at 15:05
@ujsgeyrr1f0d0d0r0h1h0j0j_juj param array
IElseIfConditionable, Tuple<ScriptBuilder, bool>? If you replace trueCondition and falseCondition with param array then you would have to write .IfCondition(s => s.ElseIfCondition(...)) and it would still work, but it doesn't look as nice. Also, here you make sure that if/else is always specified and with params you could end up with an empty IfCondition. As I wrote, this is only a very rough sketch. Play with it yourself and have fun :)– FCin
Jul 3 at 16:07
IElseIfConditionable, Tuple<ScriptBuilder, bool>
trueCondition
falseCondition
.IfCondition(s => s.ElseIfCondition(...))
IfCondition
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
I hope
MaxStringBuilderis an expression of some sort, otherwise the parameter to thatIFmethod has already been evaluated, any side effects of calling.setThisand so on will already have taken effect.– Lasse Vågsæther Karlsen
Jul 3 at 9:20