private Expr doShift(Expr left, int level) { string op = lookahead.Text; EatToken(); Expr right = factor(); Precedence next; while ((next = nextOperator()) != null && rightIsExpr(level, next)) { right = doShift(right, next.Level); } BinaryExpr exp = new BinaryExpr(); exp.Left = left; exp.Right = right; exp.Op = op; return(exp); }
private void GenStmt(Stmt stmt, Env table, ILGenerator il) { if (stmt is Sequence) { Sequence seq = (Sequence)stmt; GenStmt(seq.First, table, il); GenStmt(seq.Second, table, il); } else if (stmt is ImportStmt) { // 只能导入.Net模块 ImportStmt import = (ImportStmt)stmt; Reflect.Assembly asm = null; if (import.Name == "System") { // 首先在核心模块中查找 // 获取int类型所在的程序集(mscorlib.dll) asm = Reflect.Assembly.GetAssembly(typeof(int)); } else { string root = Framework.GetFrameworkDirectory(); string assembly = IO.Path.Combine(root, import.Name + ".dll"); asm = Reflect.Assembly.LoadFile(assembly); // TODO 错误处理 } table.AddModule(new Module(import.Name, asm)); } else if (stmt is DeclareVar) { DeclareVar declare = (DeclareVar)stmt; Type type = declare.Type; if (type == null) { type = TypeOfExpr(declare.Expr, table); } if (table.IsDeclared(declare.Name)) { throw new Exception(String.Format("A local variable named '{0}' is already defined in this scope", declare.Name)); } // TODO 保存本地变量的位置索引 table[declare.Name] = new LocalVariable(il.DeclareLocal(type)); // set the initial value BinaryExpr be = new BinaryExpr(); Variable var = new Variable(); var.Name = declare.Name; be.Left = var; be.Op = "="; if (declare.Expr is Undefined) { // FIXME 根据所声明变量的类型赋初值 IntLiteral expr = new IntLiteral(); expr.Value = 0; be.Right = expr; } else { be.Right = declare.Expr; } GenExpr(be, table, il); } else if (stmt is Return) { Return ret = (Return)stmt; GenExpr(ret.Expr, table, il); } else if (stmt is Function) { // 定义全局函数 DefineGlobalMethod((Function)stmt, table); } else if (stmt is Print) { Print print = (Print)stmt; GenExpr(print.Expr, table, il); Reflect.MethodInfo mi = typeof(Console).GetMethod("WriteLine", new Type[] { TypeOfExpr(print.Expr, table) }); il.Emit(OpCodes.Call, mi); } else if (stmt is IfStmt) { IfStmt ifStmt = (IfStmt)stmt; // 代码块的结束位置 Label End = il.DefineLabel(); // 生成条件表达式 GenExpr(ifStmt.Cond, table, il); il.Emit(OpCodes.Brfalse, End); // then代码块 //il.BeginScope(); GenStmt(ifStmt.Then, table, il); //il.EndScope(); il.MarkLabel(End); } else if (stmt is IfElseStmt) { IfElseStmt ifElseStmt = (IfElseStmt)stmt; // 分支标签 Label ThenEnd = il.DefineLabel(); Label End = il.DefineLabel(); // 条件表达式 GenExpr(ifElseStmt.Cond, table, il); il.Emit(OpCodes.Brfalse, ThenEnd); // then分支 GenStmt(ifElseStmt.Then, table, il); il.Emit(OpCodes.Br, End); il.MarkLabel(ThenEnd); // else分支 GenStmt(ifElseStmt.Else, table, il); il.MarkLabel(End); } else if (stmt is WhileLoop) { WhileLoop whileLoop = (WhileLoop)stmt; Label LoopStart = il.DefineLabel(); Label LoopEnd = il.DefineLabel(); il.MarkLabel(LoopStart); GenExpr(whileLoop.Cond, table, il); il.Emit(OpCodes.Brfalse, LoopEnd); GenStmt(whileLoop.Body, table, il); il.Emit(OpCodes.Br, LoopStart); il.MarkLabel(LoopEnd); } //else if (stmt is ForLoop) //{ // ForLoop forLoop = (ForLoop)stmt; // Assign assign = new Assign(); // assign.Ident = forLoop.Name; // assign.Expr = forLoop.From; // GenStmt(assign, table, il); // // jump to the test // Label test = il.DefineLabel(); // il.Emit(OpCodes.Br, test); // // statements in the body of the for loop // Label body = il.DefineLabel(); // il.MarkLabel(body); // GenStmt(forLoop.Body, table, il); // // to (increment the value of x) // il.Emit(OpCodes.Ldloc, table[forLoop.Name]); // il.Emit(OpCodes.Ldc_I4, 1); // il.Emit(OpCodes.Add); // Store(forLoop.Name, table, il); // // **test** does x equal 100? (do the test) // il.MarkLabel(test); // il.Emit(OpCodes.Ldloc, table[forLoop.Name]); // GenExpr(forLoop.To, table, il); // il.Emit(OpCodes.Blt, body); //} //else if (stmt is Expr) //{ // GenExpr((Expr)stmt, table, il); //} else if (stmt is Simple) { Simple simple = (Simple)stmt; GenExpr(simple.Expr, table, il); // TODO 无括号的函数调用 } else if (stmt is EmptyStmt) { // empty statement // do nothing } else { throw new Exception("don't know how to gen a " + stmt.GetType().Name); } }
private void GenExpr(Expr expr, Env table, ILGenerator il) { if (expr is StrLiteral) { il.Emit(OpCodes.Ldstr, ((StrLiteral)expr).Value); } else if (expr is IntLiteral) { il.Emit(OpCodes.Ldc_I4, ((IntLiteral)expr).Value); } else if (expr is BoolLiteral) { il.Emit(OpCodes.Ldc_I4, ((BoolLiteral)expr).Value); } else if (expr is Variable) { string name = ((Variable)expr).Name; Load(name, table, il); } else if (expr is PrimaryExpr) { PrimaryExpr pe = (PrimaryExpr)expr; //GenExpr(pe.Lhs, table, il); if (pe.Lhs is Variable) // LHS此时可能是命名空间、类型名、实例变量(包括函数名)等 { string name = ((Variable)pe.Lhs).Name; if (pe.Postfix is CallExpr) { // TODO 目前不考虑链式调用 CallExpr ce = (CallExpr)pe.Postfix; // 函数调用 if (globalFunctions.ContainsKey(name)) { // 载入参数 foreach (var arg in ce.Args) { GenExpr(arg, table, il); } // 调用函数 Reflect.MethodInfo mi = globalFunctions[name]; il.Emit(OpCodes.Call, mi); } else if (table.HasInstance(name)) { throw new Exception(String.Format("'{0}'是变量,不是函数", name)); } else { throw new Exception(String.Format("当前上下文中不存在名称'{0}'", name)); } } else if (pe.Postfix is MemberAccessExpr) { // 目前只实现了导入模块,还没有实现Class MemberAccessExpr mae = (MemberAccessExpr)pe.Postfix; if (mae.Postfix is MemberAccessExpr) { string ns = ns = name + "." + mae.Ident;; // 合并命名空间(CLR的类型名在运行时是命名空间的一部分) PrimaryExpr exp = new PrimaryExpr(); Variable var = new Variable(); var.Name = ns; exp.Lhs = var; exp.Postfix = mae.Postfix; // 递归生成合并后的表达式 GenExpr(exp, table, il); } else if (mae.Postfix is CallExpr) { // 调用C#模块中的方法 CallExpr ce = (CallExpr)mae.Postfix; // 在所有模块中间查找类型和方法 Type type = FirstMatchType(name, table); if (type != null) { // 载入参数 List <Type> typelist = new List <Type>(); foreach (var arg in ce.Args) { typelist.Add(TypeOfExpr(arg, table)); GenExpr(arg, table, il); } // 调用函数 Reflect.MethodInfo mi = type.GetMethod(mae.Ident, typelist.ToArray()); if (mi != null) { il.Emit(OpCodes.Call, mi); } else { throw new Exception(String.Format("方法{0}未发现", mae.Ident)); } } else { throw new Exception(String.Format("类型{0}未发现", name)); } } else { //此时 Postfix == null // 访问属性 // 例如 a.Length throw new NotImplementedException(); } } } else { // TODO OO语言中,可以考虑在字面量上访问方法 // 例如 10.to_s() => "10" throw new NotImplementedException(); } } else if (expr is BinaryExpr) { BinaryExpr be = (BinaryExpr)expr; // 赋值 if (be.Op.Equals("=")) { GenExpr(be.Right, table, il); if (be.Left is Variable) { Store(((Variable)be.Left).Name, table, il); } else { throw new Exception("except a lvalue at assign"); } } else { // 算术运算 // FIXME IL没有一些条件运算,需要单独提出来实现 GenExpr(be.Left, table, il); GenExpr(be.Right, table, il); switch (be.Op) { case "+": il.Emit(OpCodes.Add); break; case "-": il.Emit(OpCodes.Sub); break; case "*": il.Emit(OpCodes.Mul); break; case "/": il.Emit(OpCodes.Div); break; case "%": il.Emit(OpCodes.Rem); break; case "<": il.Emit(OpCodes.Clt); break; case ">": il.Emit(OpCodes.Cgt); break; case "==": il.Emit(OpCodes.Ceq); break; case "<=": //il.Emit(OpCodes.Cgt); // FIXME //break; case ">=": //il.Emit(OpCodes.Clt); // FIXME //break; case "!=": //il.Emit(OpCodes.Ceq); // FIXME //break; default: throw new Exception("Unrecognized operator: " + be.Op); } } } else if (expr is Undefined) { return; } else { throw new Exception("don't know how to generate " + expr.GetType().Name); } }