Reputation: 640
I am using this example project written by Joel Pobar. I got this from:
http://msdn.microsoft.com/en-us/magazine/cc136756.aspx
Okay so to implement a simple Print command I need to:
First declare the class in the Ast.cs:
// print <expr>
public class Print : Stmt
{
public Expr Expr;
}
Secondly I implemented the method into Parser.cs:
// <stmt> := print <expr>
// <expr> := <string>
// | <int>
// | <arith_expr>
// | <ident>
if (this.tokens[this.index].Equals("Printl"))
{
this.index++;
Print print = new Print();
print.Expr = this.ParseExpr();
result = print;
}
Lastly I implemented a check in the CodeGen.cs:
else if (stmt is Print)
{
// the "print" statement is an alias for System.Console.WriteLine.
// it uses the string case
this.GenExpr(((Print)stmt).Expr, typeof(string));
this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) }));
}
Now this allows me to create an interpreter and compiles a file if it matches the syntax. This interpreter supports variables, loops, and basic printing text and variable values. However I am a bit confused on how to implement if and else statements.
Upvotes: 0
Views: 491
Reputation: 283634
MSIL has conditional branch instructions. You'll have to arrange for the result of the conditional expression to be on top of the value stack, and then use a conditional branch to jump to the else-stuff (skipping the then-stuff) or not. The end of the then-stuff will unconditionally branch over the else-stuff.
Of course, you'll need to define and mark labels for the beginning and end of the else-stuff. The above link covers label creation.
Here are the conditional branch instructions, found in the OpCodes class:
Beq Field
Beq_S Field
Bge Field
Bge_S Field
Bge_Un Field
Bge_Un_S Field
Bgt Field
Bgt_S Field
Bgt_Un Field
Bgt_Un_S Field
Ble Field
Ble_S Field
Ble_Un Field
Ble_Un_S Field
Blt Field
Blt_S Field
Blt_Un Field
Blt_Un_S Field
Bne_Un Field
Bne_Un_S Field
Brfalse Field
Brfalse_S Field
Brtrue Field
Brtrue_S Field
Switch Field
Note that many of these combine a comparison witha conditional branch. For example,
The
ble
instruction transfers control to the specified target instruction if value1 is less than or equal to value2. The effect is identical to performing acgt
instruction (cgt.un
for floats) followed by abrfalse
branch to the specific target instruction.
The documentation for ILGenerator.DefineLabel()
has a complete example of a conditional, implementing:
IF A < 100 AND B < 100
RETURN A + B
ELSE
RETURN -1
Upvotes: 1