1 Programming Language အသစ္ထြင္ၾကမယ္ (၅) 12th May 2009, 4:26 pm
sHa92
Founder
Control Statements
ခုဆို ကၽြန္ေတာ္တို႕ရဲ႕ ကိုယ္ပိုင္ Assembly language ကိုသုံးၿပီး သခ်ာၤ
equation ေတြတြက္လို႕ရေနပါၿပီ။ ဒါေပမဲ့ programming
အေရးအႀကီးဆုံးေတြျဖစ္တဲ့ if, switch, for, while တို႕ကို implement
လုပ္ဖို႕က်န္ပါေသးတယ္။ ဒါေတြသာရရင္ ကၽြန္ေတာ္တို႕ရဲ႕ language ေလးက
programming language တခုအျဖစ္ ေတာ္ေတာ္ ရုပ္လုံးေပၚလာပါလိမ့္မယ္။
ခုထက္ထိ ကၽြန္ေတာ္တို႕ ေရးခဲ့သမွ်၊ testing လုပ္သမွ် script ေတြက linear
run တဲ့ script ေတြကိုဘဲ ေရးခဲ့ပါတယ္။ ဆိုလိုတာက အစကေန အဆုံးထိ
ေတာက္ေလွ်ာက္ run တဲ့ script ေတြပါ။ Virtual Machine ရဲ႕ run လုပ္တဲ့ code
ကိုျပန္ၾကည့္မယ္ဆိုရင္၊
ျပင္ရပါမယ္။ ေလာေလာဆယ္ program.Next() function က nCurrent မွာရွိတဲ့
instruction ကို return ျပန္ပါတယ္။ ဒီေတာ့ ကၽြန္ေတာ္တို႕က ကိုယ္ run
ေစခ်င္တဲ့ code line ကို nCurrent ဆိုတဲ့ variable ထဲထည့္ေပးလိုက္ရင္ run
ေစခ်င္တဲ့ line က instruction ကို run ခိုင္းလို႔ရပါတယ္။ ဒီေတာ့ nCurrent
variable ကို script ကေနေပးဖို႕ go to ဆိုတဲ့ op-code အသစ္တခုထပ္ထည့္ပါမယ္။
ခ်င္တဲ့ instruction ရဲ႕ Line number ကို operand 0 ကေနေပးလိုက္ရုံနဲ႔
program ကို execute လုပ္ခိုင္းလို႕ရပါၿပီ။
Note: ဒီေနရာမွာ valid မျဖစ္တဲ့ line number (ဥပမာ၊ -1, 564654
စသည္ျဖင့္) ေပးရင္ error တက္ပါလိမ့္မယ္။ ဒီအတြက္ error checking
ေလးတခုေတာ့ Program::SetInstruction() ထဲမွာ ေရးထားသင့္ပါတယ္။
Assembly ရဲ႕ AssemblyCodeTable မွာလဲ OP_GOTO အတြက္ string ID သြားေရးဖို႕လိုပါလိမ့္မယ္။ ဒါမွ Assembler က compile လုပ္ႏိုင္မွာပါ။
Entry အသစ္တိုးလာတဲ့အတြက္ ASM_ENTRY_COUNT ကိုလဲ တစ္တိုးေပးဖို႔လိုပါလိမ့္မယ္။
const int ASM_ENTRY_COUNT = 17;
ကဲဒါဆို goto ဆိုတဲ့ code အသစ္ကို "test.asm" ဆိုတဲ့ assembly file ထဲမွာ
သြားစမ္းၾကည့္ရေအာင္။ "test.asm" ထဲမွာ ေအာက္ကလို သြားေရးပါမယ္။
ဒါဆို number 40 ကို screen ေပၚမွာအၿမဲ print ထုတ္ေနပါလိမ့္မယ္။
ဘာနဲ႕သြားဆင္လဲဆိုရင္ while (true) လို infinite loop နဲ႔ဆင္ပါတယ္။ ဒီလို
infinite loop ကသိပ္ေတာ့ အသုံး၀င္မွာ မဟုတ္ပါဘူး။
ဒီအတြက္ ခုကၽြန္ေတာ္တို႕ Boolean နဲ႔ logic တြက္တာကို ေရးဖို႕လိုပါတယ္။
ဒီလို true/false တြက္လို႕ရမွ loop ကိုကိုယ္ခ်င္သလို break လုပ္လို႕ရမွာ
မဟုတ္လား။ Logic တြက္ဖို႕အတြက္ ခု Logic operator ေတြျဖစ္တဲ့ >
(greater than), < (less than), == (equal) တုိ႕ကို ေရးဖို႕လိုပါတယ္။
ဒီအတြက္ ေအာက္က op-code အသစ္ေတြကို ထည့္လိုက္ပါမယ္။
ဒီ op-code ၆ ခုက >, >=, ==, != < နဲ႔ <= sign ေတြအတြက္ပါဘဲ။
Boolean value ေတြျဖစ္တဲ့ true နဲ႔ false အတြက္ ကိုယ္ပိုင္ definition
ေတြေရးဖို႕လိုပါလိမ့္မယ္။
ဒါဆို Virtual Machine ရဲ႕ Run() function မွာ ကၽြန္ေတာ္တို႕ရဲ႕ op-code အသစ္ေတြသြား ေရးလို႕ရပါၿပီ။ ကဲေရးၾကည့္ရေအာင္ပါ။
ခုဆို ကၽြန္ေတာ္တို႕ရဲ႕ ကိုယ္ပိုင္ Assembly language ကိုသုံးၿပီး သခ်ာၤ
equation ေတြတြက္လို႕ရေနပါၿပီ။ ဒါေပမဲ့ programming
အေရးအႀကီးဆုံးေတြျဖစ္တဲ့ if, switch, for, while တို႕ကို implement
လုပ္ဖို႕က်န္ပါေသးတယ္။ ဒါေတြသာရရင္ ကၽြန္ေတာ္တို႕ရဲ႕ language ေလးက
programming language တခုအျဖစ္ ေတာ္ေတာ္ ရုပ္လုံးေပၚလာပါလိမ့္မယ္။
ခုထက္ထိ ကၽြန္ေတာ္တို႕ ေရးခဲ့သမွ်၊ testing လုပ္သမွ် script ေတြက linear
run တဲ့ script ေတြကိုဘဲ ေရးခဲ့ပါတယ္။ ဆိုလိုတာက အစကေန အဆုံးထိ
ေတာက္ေလွ်ာက္ run တဲ့ script ေတြပါ။ Virtual Machine ရဲ႕ run လုပ္တဲ့ code
ကိုျပန္ၾကည့္မယ္ဆိုရင္၊
- Code:
void Run(Program& program) { while (true)
{
Instruction inst = program.Next();
switch (inst.code)
{
case OP_TALK:
printf("Hello, I am simplest language!\\n");
break;
....................
....................
}
}
};
ျပင္ရပါမယ္။ ေလာေလာဆယ္ program.Next() function က nCurrent မွာရွိတဲ့
instruction ကို return ျပန္ပါတယ္။ ဒီေတာ့ ကၽြန္ေတာ္တို႕က ကိုယ္ run
ေစခ်င္တဲ့ code line ကို nCurrent ဆိုတဲ့ variable ထဲထည့္ေပးလိုက္ရင္ run
ေစခ်င္တဲ့ line က instruction ကို run ခိုင္းလို႔ရပါတယ္။ ဒီေတာ့ nCurrent
variable ကို script ကေနေပးဖို႕ go to ဆိုတဲ့ op-code အသစ္တခုထပ္ထည့္ပါမယ္။
- Code:
enum OpCode{ OP_TALK,
.......................
.......................
OP_GOTO,
OP_END
};
- Code:
class Program{public:
vector InstructionList;
int nCurrent;
.......................
.......................
void SetInstruction(int line_no) {
nCurrent = line_no;
}
};
- Code:
void Run(Program& program) { while (true)
{
Instruction inst = program.Next();
switch (inst.code)
{
....................
....................
case OP_GOTO:
program.SetInstruction(inst.operand[0]);
break;
}
}
};
ခ်င္တဲ့ instruction ရဲ႕ Line number ကို operand 0 ကေနေပးလိုက္ရုံနဲ႔
program ကို execute လုပ္ခိုင္းလို႕ရပါၿပီ။
Note: ဒီေနရာမွာ valid မျဖစ္တဲ့ line number (ဥပမာ၊ -1, 564654
စသည္ျဖင့္) ေပးရင္ error တက္ပါလိမ့္မယ္။ ဒီအတြက္ error checking
ေလးတခုေတာ့ Program::SetInstruction() ထဲမွာ ေရးထားသင့္ပါတယ္။
Assembly ရဲ႕ AssemblyCodeTable မွာလဲ OP_GOTO အတြက္ string ID သြားေရးဖို႕လိုပါလိမ့္မယ္။ ဒါမွ Assembler က compile လုပ္ႏိုင္မွာပါ။
- Code:
static const AssemblyCodeTableEntry AssemblyCodeTable[ASM_ENTRY_COUNT] = { { OP_TALK, "talk" },
........................
........................
{ OP_GOTO, "goto" },
{ OP_END, "end" }
};
Entry အသစ္တိုးလာတဲ့အတြက္ ASM_ENTRY_COUNT ကိုလဲ တစ္တိုးေပးဖို႔လိုပါလိမ့္မယ္။
const int ASM_ENTRY_COUNT = 17;
ကဲဒါဆို goto ဆိုတဲ့ code အသစ္ကို "test.asm" ဆိုတဲ့ assembly file ထဲမွာ
သြားစမ္းၾကည့္ရေအာင္။ "test.asm" ထဲမွာ ေအာက္ကလို သြားေရးပါမယ္။
- Code:
000 put_stack 40001 num
002 goto 0
003 end
ဒါဆို number 40 ကို screen ေပၚမွာအၿမဲ print ထုတ္ေနပါလိမ့္မယ္။
ဘာနဲ႕သြားဆင္လဲဆိုရင္ while (true) လို infinite loop နဲ႔ဆင္ပါတယ္။ ဒီလို
infinite loop ကသိပ္ေတာ့ အသုံး၀င္မွာ မဟုတ္ပါဘူး။
ဒီအတြက္ ခုကၽြန္ေတာ္တို႕ Boolean နဲ႔ logic တြက္တာကို ေရးဖို႕လိုပါတယ္။
ဒီလို true/false တြက္လို႕ရမွ loop ကိုကိုယ္ခ်င္သလို break လုပ္လို႕ရမွာ
မဟုတ္လား။ Logic တြက္ဖို႕အတြက္ ခု Logic operator ေတြျဖစ္တဲ့ >
(greater than), < (less than), == (equal) တုိ႕ကို ေရးဖို႕လိုပါတယ္။
ဒီအတြက္ ေအာက္က op-code အသစ္ေတြကို ထည့္လိုက္ပါမယ္။
- Code:
enum OpCode{ .......................
.......................
OP_GREATER_THAN,
OP_GREATER_EQUAL,
OP_EQUAL,
OP_NOT_EQUAL,
OP_LESS_THAN,
OP_LESS_EQUAL,
OP_END
};
ဒီ op-code ၆ ခုက >, >=, ==, != < နဲ႔ <= sign ေတြအတြက္ပါဘဲ။
Boolean value ေတြျဖစ္တဲ့ true နဲ႔ false အတြက္ ကိုယ္ပိုင္ definition
ေတြေရးဖို႕လိုပါလိမ့္မယ္။
- Code:
enum Boolean { _FALSE = 0,
_TRUE = 1
};
ဒါဆို Virtual Machine ရဲ႕ Run() function မွာ ကၽြန္ေတာ္တို႕ရဲ႕ op-code အသစ္ေတြသြား ေရးလို႕ရပါၿပီ။ ကဲေရးၾကည့္ရေအာင္ပါ။
- Code:
void Run(Program& program) { while (true)
{
Instruction inst = program.Next();
switch (inst.code)
{
....................
....................
case OP_GREATER_THAN:
Data1 = program.PopStack();
Data2 = program.PopStack();
if (Data2 > Data1)
program.PushStack(_TRUE);
else
program.PushStack(_FALSE);
break;
case OP_GREATER_EQUAL:
Data1 = program.PopStack();
Data2 = program.PopStack();
if (Data2 >= Data1)
program.PushStack(_TRUE);
else
program.PushStack(_FALSE);
break;
case OP_EQUAL:
Data1 = program.PopStack();
Data2 = program.PopStack();
if (Data2 == Data1)
program.PushStack(_TRUE);
else
program.PushStack(_FALSE);
break;
case OP_NOT_EQUAL:
Data1 = program.PopStack();
Data2 = program.PopStack();
if (Data2 != Data1)
program.PushStack(_TRUE);
else
program.PushStack(_FALSE);
break;
case OP_LESS_THAN:
Data1 = program.PopStack();
Data2 = program.PopStack();
if (Data2 < Data1)
program.PushStack(_TRUE);
else
program.PushStack(_FALSE);
break;
case OP_LESS_EQUAL:
Data1 = program.PopStack();
Data2 = program.PopStack();
if (Data2 <= Data1)
program.PushStack(_TRUE);
else
program.PushStack(_FALSE);
break;
}
}
};
Last edited by SYKO on 12th May 2009, 4:28 pm; edited 2 times in total