/// <summary> /// /// </summary> /// <param name="op"></param> /// <param name="ilg"></param> /// <param name="scope"></param> /// <param name="args"></param> /// <exception cref="DynException"></exception> public void EmitOperand(DynAstNodeOperand op, ILGenerator ilg, Dictionary <string, LocalBuilder> scope, Dictionary <string, int> args) { switch (op.Lexeme.Token) { case DynToken.Number: ilg.Emit(OpCodes.Ldc_R8, op.Lexeme.Number.Value); ilg.Emit(OpCodes.Newobj, anyType.GetConstructor(new Type[] { typeof(double) })); return; case DynToken.Identifier: if (scope.ContainsKey(op.Lexeme.Identifier)) { LocalBuilder lb = scope[op.Lexeme.Identifier]; ilg.Emit(OpCodes.Ldloc, lb.LocalIndex); } else if (args.ContainsKey(op.Lexeme.Identifier)) { ilg.Emit(OpCodes.Ldarg, args[op.Lexeme.Identifier]); } else if (GlobalVariables.Contains(op.Lexeme.Identifier)) { ilg.Emit(OpCodes.Ldfld, op.Lexeme.Identifier); } else { throw new DynException($"语法错误,未知变量 {op.Lexeme}"); } return; } throw new DynException($"语法错误,未知的操作数 {op.Lexeme}"); }
/// <summary> /// /// </summary> /// <param name="e"></param> /// <param name="ilg"></param> /// <param name="scope"></param> /// <param name="args"></param> /// <exception cref="DynException"></exception> public void EmitExpression(DynAstNodeExpression e, ILGenerator ilg, Dictionary <string, LocalBuilder> scope, Dictionary <string, int> args) { if (e.Operation is null) { EmitOperand(e.Left, ilg, scope, args); return; } switch (e.Operation.Token) { case DynToken.SymbolEqual: { if (e.Left.Lexeme.Token != DynToken.Identifier) { throw new DynException($"语法错误,赋值操作只可作用于左值。"); } // Right EmitExpression(e.Right, ilg, scope, args); if (GlobalVariables.Contains(e.Left.Lexeme.Identifier)) { ilg.Emit(OpCodes.Stfld, e.Left.Lexeme.Identifier); break; } if (!scope.ContainsKey(e.Left.Lexeme.Identifier)) { LocalBuilder lbt = ilg.DeclareLocal(anyType); scope.Add(e.Left.Lexeme.Identifier, lbt); } LocalBuilder lb = scope[e.Left.Lexeme.Identifier]; ilg.Emit(OpCodes.Stloc, lb.LocalIndex); break; } case DynToken.SymbolPlus: { // Left EmitOperand(e.Left, ilg, scope, args); // Right EmitExpression(e.Right, ilg, scope, args); //ilg.Emit(OpCodes.Add); ilg.Emit(OpCodes.Call, anyType.GetMethod("add_operator")); break; } case DynToken.SymbolMinus: { // Left EmitOperand(e.Left, ilg, scope, args); // Right EmitExpression(e.Right, ilg, scope, args); ilg.Emit(OpCodes.Sub); break; } case DynToken.SymbolStar: { // Left EmitOperand(e.Left, ilg, scope, args); // Right EmitExpression(e.Right, ilg, scope, args); ilg.Emit(OpCodes.Mul); break; } default: throw new DynException($"语法错误,未知的表达式 {e.Operation}"); } }