public override void Compile(Emitter.Emitter emitter) { var type = Expression.GetExpressionType(emitter); if (type.IsAnyOf("int", "float", "complex")) { if(type == "complex") { // simple case: the complex is a constant if(Expression is ComplexNode) { (Expression as ComplexNode).Imaginary *= -1; Expression.Compile(emitter); } // complex case: complex is an expression result else { Expression.Compile(emitter); // tmp = ... var tmpVar = emitter.CurrentMethod.Scope.Introduce("complex", emitter.FindType("complex").Type); emitter.EmitSaveVariable(tmpVar); // tmp.real emitter.EmitLoadVariableAddress(tmpVar); emitter.EmitCall(emitter.AssemblyImport(typeof(SN.Complex).GetMethod("get_Real"))); // tmp.imaginary * -1 emitter.EmitLoadVariableAddress(tmpVar); emitter.EmitCall(emitter.AssemblyImport(typeof(SN.Complex).GetMethod("get_Imaginary"))); emitter.EmitLoadFloat(-1); emitter.EmitMul(); // new complex emitter.EmitNewObj(emitter.FindMethod("complex", ".ctor", "float", "float")); } } else { // multiply by -1 Expression.Compile(emitter); if (type == "int") emitter.EmitLoadInt(-1); else emitter.EmitLoadFloat(-1); emitter.EmitMul(); } } else Error(String.Format(Resources.errInvertType, type)); }
public override void Compile(Emitter.Emitter emitter) { var leftType = Left.GetExpressionType(emitter); var rightType = Right.GetExpressionType(emitter); var type = GetExpressionType(emitter); // repeat a string if (type == "string") { Left.Compile(emitter); Right.Compile(emitter); emitter.EmitCall(emitter.FindMethod("string", "repeat", "int")); } // multiply matrices else if(type == "matrix") { var matrixType = typeof(MN.Matrix<double>); // matrix by matrix if(leftType == rightType) { Left.Compile(emitter); Right.Compile(emitter); var method = emitter.AssemblyImport(matrixType.GetMethod("Multiply", new[] { matrixType })); emitter.EmitCall(method); } else { // matrix should be the first in stack if(leftType == "matrix") { Left.Compile(emitter); Right.Compile(emitter); if (rightType != "float") emitter.EmitConvertToFloat(); } else { Right.Compile(emitter); Left.Compile(emitter); if (leftType != "float") emitter.EmitConvertToFloat(); } var method = emitter.AssemblyImport(matrixType.GetMethod("Multiply", new[] { typeof(double) })); emitter.EmitCall(method); } } // multiply complex numbers else if (type == "complex") { Left.Compile(emitter); if (leftType != "complex") { emitter.EmitUpcastBasicType(leftType, "float"); emitter.EmitLoadFloat(0); emitter.EmitNewObj(emitter.FindMethod("complex", ".ctor", "float", "float")); } Right.Compile(emitter); if (rightType != "complex") { emitter.EmitUpcastBasicType(rightType, "float"); emitter.EmitLoadFloat(0); emitter.EmitNewObj(emitter.FindMethod("complex", ".ctor", "float", "float")); } emitter.EmitCall(emitter.AssemblyImport(typeof(SN.Complex).GetMethod("op_Multiply", new[] { typeof(SN.Complex), typeof(SN.Complex) }))); } // repeat array else if (leftType.EndsWith("[]")) { Left.Compile(emitter); Right.Compile(emitter); var method = emitter.AssemblyImport(typeof(MirelleStdlib.ArrayHelper).GetMethod("RepeatArray", new[] { typeof(object), typeof(int) })); emitter.EmitCall(method); } // multiply floating point numbers or integers else if (type.IsAnyOf("int", "float")) { Left.Compile(emitter); emitter.EmitUpcastBasicType(leftType, type); Right.Compile(emitter); emitter.EmitUpcastBasicType(rightType, type); emitter.EmitMul(); } }