private Compiler(Context context) { context.put(CONTEX_KEY, this); options = CommandLineOptions.instance(context); parser = ParserRunner.instance(context); declarationAnalysis = DeclarationAnalysis.instance(context); codeTypeAnalysis = CodeTypeAnalysis.instance(context); flowAnalysis = FlowAnalysis.instance(context); codeGeneration = CodeGeneration.instance(context); log = Log.instance(context); }
internal static TypeSymbol EmitPow(CodeGenerator cg, TypeSymbol xtype, FlowAnalysis.TypeRefMask xtype_hint, BoundExpression right) { var il = cg.Builder; TypeSymbol ytype; xtype = cg.EmitConvertIntToLong(xtype); // int|bool -> long switch (xtype.SpecialType) { case SpecialType.System_Int64: ytype = cg.EmitConvertIntToLong(cg.Emit(right)); // int|bool -> long if (ytype.SpecialType == SpecialType.System_Int64) { // i8 ** i8 : number return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_long_long); } else if (ytype.SpecialType == SpecialType.System_Double) { // i8 ** r8 : r8 return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_long_double); } else if (ytype == cg.CoreTypes.PhpNumber) { // i8 ** number : number return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_long_number); } // y -> PhpValue cg.EmitConvert(ytype, right.TypeRefMask, cg.CoreTypes.PhpValue); ytype = cg.CoreTypes.PhpValue; // i8 ** value : number return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_long_value); case SpecialType.System_Double: ytype = cg.EmitConvertNumberToDouble(right); // int|bool|long|number -> double if (ytype.SpecialType == SpecialType.System_Double) { // r8 ** r8 : r8 return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_double_double); } // y -> PhpValue cg.EmitConvert(ytype, right.TypeRefMask, cg.CoreTypes.PhpValue); ytype = cg.CoreTypes.PhpValue; // r8 ** value : r8 return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_double_value); default: if (xtype == cg.CoreTypes.PhpNumber) { ytype = cg.EmitConvertIntToLong(cg.Emit(right)); // int|bool -> long if (ytype == cg.CoreTypes.Double) { // number ** r8 : r8 return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_number_double); } if (ytype.SpecialType == SpecialType.System_Int64) { // y -> number ytype = cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Create_Long); } if (ytype == cg.CoreTypes.PhpNumber) { // number ** number : number return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_number_number); } // y -> PhpValue ytype = cg.EmitConvertToPhpValue(ytype, right.TypeRefMask); // number ** value : number return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_number_value); } // x -> PhpValue xtype = cg.EmitConvertToPhpValue(xtype, xtype_hint); cg.EmitConvert(right, cg.CoreTypes.PhpValue); ytype = cg.CoreTypes.PhpValue; // value ** value : number return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_value_value); } }
public void Analyze(SyntaxNode node) { // do null flow analysis var flowAnalzyer = new FlowAnalyzer<NullFlowState>(this.context.SemanticModel, new NullFlowState(this.context.SemanticModel)); this.flowAnalysis = flowAnalzyer.Analyze(node); // check assignments and dereferences and report diagnostics this.Visit(node); }