構文要素に対応するクラス(DomainOperation クラス:数値の単項演算・二項演算を表す)
<summary>
</summary>
internal class DomainOperation : DomainExpression
{
<summary>
</summary>
private readonly string op;
<summary>
</summary>
private readonly int arity;
<summary>
</summary>
private readonly DomainExpression exp1;
<summary>
</summary>
private readonly DomainExpression exp2;
<summary>
</summary>
private readonly string[][] precedence_list = [["*", "/", "%"], ["+", "-"]];
<summary>
</summary>
<param name="op"></param>
<param name="exp"></param>
public DomainOperation(string op, DomainExpression exp)
{
this.op = op;
arity = 1;
this.exp1 = exp;
}
<summary>
</summary>
<param name="op"></param>
<param name="exp1"></param>
<param name="exp2"></param>
public DomainOperation(string op, DomainExpression exp1, DomainExpression exp2)
{
this.op = op;
arity = 2;
this.exp1 = exp1;
this.exp2 = exp2;
}
<summary>
</summary>
<param name="env"></param>
<returns></returns>
public Number Eval(Env<FreeMonoidUnion> env)
{
if (arity == 1)
{
switch (op)
{
case "-":
return -exp1.Eval(env);
default:
return Number.Zero;
}
}
else
{
switch (op)
{
case "+":
return exp1.Eval(env) + exp2.Eval(env);
case "-":
return exp1.Eval(env) - exp2.Eval(env);
case "*":
return exp1.Eval(env) * exp2.Eval(env);
case "/":
return exp1.Eval(env) / exp2.Eval(env);
case "%":
return exp1.Eval(env) % exp2.Eval(env);
default:
return Number.Zero;
}
}
}
<summary>
</summary>
<returns></returns>
private int precedence()
{
for (int i = 0; i < precedence_list.Length; i++)
{
if (precedence_list[i].Contains(op))
{
return i;
}
}
return -1;
}
<summary>
</summary>
<returns></returns>
public string Print()
{
if (arity == 1)
{
if (exp1 is DomainOperation opexp && opexp.arity == 2)
{
return $"{op}({exp1.Print()})";
}
else
{
return $"{op} {exp1.Print()}";
}
}
else
{
string exp1_str = exp1.Print();
if (exp1 is DomainOperation opexp1 && opexp1.arity == 2 && precedence() < opexp1.precedence())
{
exp1_str = $"({exp1_str})";
}
string exp2_str = exp2.Print();
if (exp2 is DomainOperation opexp2 && opexp2.arity == 2 && precedence() < opexp2.precedence())
{
exp2_str = $"({exp2_str})";
}
return $"{exp1_str} {op} {exp2_str}";
}
}
<summary>
</summary>
<param name="yieldp"></param>
<param name="typep"></param>
<param name="indp"></param>
<param name="indcount"></param>
<param name="perf"></param>
<returns></returns>
public string GeneratePython(bool yieldp, bool typep, bool indp, int indcount, Func<string, string> perf)
{
return Print();
}
<summary>
</summary>
<param name="yieldp"></param>
<param name="typep"></param>
<param name="indp"></param>
<param name="indcount"></param>
<param name="perf"></param>
<returns></returns>
public string GenerateCS(bool yieldp, bool typep, bool indp, int indcount, Func<string, string> perf)
{
return Print();
}
}
