2014-03-31 65 views
0

我正在使用由Joel Pobar编写的这个示例项目。我得到这个来自:如何实现if和else语句?当编写一个语言编译器

http://msdn.microsoft.com/en-us/magazine/cc136756.aspx

好了,所以要实现一个简单的打印命令我需要:

首先声明在Ast.cs类:

// print <expr> 
public class Print : Stmt 
{ 
    public Expr Expr; 
} 

其次我将该方法应用到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; 
     } 

最后我实现了在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) })); 
    } 

现在,这允许我创建了一个翻译,编译一个文件,如果它的语法匹配。该解释器支持变量,循环和基本打印文本和变量值。然而,我对如何实现if和else语句有些困惑。

+0

我编辑了自己的冠军。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 –

+0

你说你有循环工作? 'if-else'非常像循环控制表达式。 –

回答

1

MSIL有条件分支指令。您必须安排条件表达式的结果位于值栈顶部,然后use a conditional branch跳转到else-stuff(跳过then-stuff)或不。然后东西的结尾将无条件地分支到其他东西。

当然,您需要为else-stuff的开头和结尾定义和标记标签。以上链接涵盖标签创建。

这里是条件转移指令,在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 

注意,许多这些结合难熬的条件分支的比较。例如,

ble指令将控制转移到指定的目标指令,如果VALUE1小于或等于VALUE2。其效果与执行cgt指令(针对浮点数的cgt.un)相同,后跟brfalse分支到特定目标指令。

The documentation for ILGenerator.DefineLabel()有一个条件,实现一个完整的示例:

IF A < 100 AND B < 100 
    RETURN A + B 
ELSE 
    RETURN -1 
+0

你认为你可以分享一些代码来实现'if'和'else'语句吗? – user2874682

+0

@ user2874682:我刚刚添加了一个链接到'DefineLabel()'文档,它们恰好具有这样的样本。 –

+0

ILGenerator.DefineLabel()文档令我困惑。我不知道应该将哪些代码放入哪个文件/类中 – user2874682