私はC言語を使ってPLC言語インタープリタを書いています。そのPLC言語には、20種類以上のデータ型と25種類の命令が含まれています。C#でインタプリタを書く:命令を実装する最良の方法は?
1)あらゆる種類の命令は、データ型を選択するために大きいswitch
を含む1つのクラスで表されます。例:
public class ADD : Instruction
{
private string type;
public ADD(string type)
{
this.type = type;
}
public bool Exec(Context c)
{
switch (type)
{
case "INT":
short valor2 = c.PopINT();
short valor = c.PopINT();
short result = (short)(valor + valor2);
c.PushINT(result);
break;
case "DINT":
int valor4 = c.PopDINT();
int valor3 = c.PopDINT();
int result2 = (int)(valor4 + valor3);
c.PushDINT(result2);
break;
case "BOOL":
// Implement BOOL
break;
// Implement other types...
default:
break;
}
c.IP++;
return false; ;
}
}
2)各クラスは、1つのデータ型を持つ単一の命令を表します。この方法は大きなswitch
を避けます。例:
public class ADDi : Instruction
{
public bool Exec(Context c)
{
short valor = c.PopINT();
short valor2 = c.PopINT();
short result = (short)(valor + valor2);
c.PushINT(result);
c.IP++;
return false;
}
}
私は命令を書くためにCOMMAND desingパターン(Exec()
)を使用しています。 2番目の選択肢は、大きなスイッチを避けるために優れていると思いますが、その選択肢には400以上の命令を書き込む必要があります。
この場合、実行パフォーマンスは翻訳のパフォーマンスよりも重要であることに常に注意してください。
私の正確な質問は次のとおりです。命令やデータ型を分解する他の方法はありますか?私はパフォーマンスを犠牲にすることなく、より少ない量の指示書を書くことを望んでいます。
EDIT:
この絵は私のタイプの階層を示しています
これは、INTクラスの実装です:
public class INT : ANY_INT
{
public override string DefaultInitValue()
{
return "0";
}
public override int GetBytes()
{
return 2;
}
public override string GetLastType()
{
return this.ToString();
}
public override string ToString()
{
return "INT";
}
}
は、いくつかのクラスは、より複雑な(構造体、配列されています、。 ..)。
public void PushINT(short value)
{
//SP -> Stack Pointer
resMem.WriteINT(SP, value);
SP += 2;
}
public short PopINT()
{
SP -= 2;
short value = resMem.ReadINT(SP);
return value;
}
そして、最後に、操作を読み取ってメモリに書き込むために:
操作は次のように定義されているpushとpop。
public void WriteINT(int index, short entero)
{
SetCapacity(index + 2); // Memory grows up dinamically
memory[index] = (sbyte)((ushort)entero >> 8 & 0x00FF);
memory[index + 1] = (sbyte)((ushort)entero >> 0 & 0x00FF);
}
public short ReadINT(int index)
{
return (short)(((short)(memory[index]) << 8 & 0xFF00) |
((short)(memory[index + 1]) & 0x00FF));
}
この情報が役立ちますようお願いいたします。ありがとうございました。
私は言語で非終端記号ごとに一つのクラスで行くだろう、解決策に向かって私の道を分け合って征服してください。 – Alex
このプロジェクトを終了し、あなたのコードオープンソースですか? –