public override void Compile(Emitter.Emitter emitter) { if (Expression.GetExpressionType(emitter) != "bool") Error(Resources.errBoolExpected); Expression.Compile(emitter); emitter.EmitLoadBool(false); emitter.EmitCompareEqual(); }
public override void Compile(Emitter.Emitter emitter) { var args = new[] { Parameters.Count == 1 ? typeof(object) : typeof(IEnumerable<dynamic>), typeof(bool) }; var printMethod = emitter.AssemblyImport(typeof(MirelleStdlib.Printer).GetMethod("Print", args)); if (Parameters.Count == 1) { var currType = Parameters[0].GetExpressionType(emitter); Parameters[0].Compile(emitter); if (currType.IsAnyOf("int", "bool", "float", "complex")) emitter.EmitBox(emitter.ResolveType(currType)); } else { var objType = emitter.AssemblyImport(typeof(object)); var arrType = new ArrayType(objType); var tmpVariable = emitter.CurrentMethod.Scope.Introduce("object[]", arrType); // load count & create emitter.EmitLoadInt(Parameters.Count); emitter.EmitNewArray(objType); emitter.EmitSaveVariable(tmpVariable); int idx = 0; foreach (var curr in Parameters) { var currType = curr.GetExpressionType(emitter); emitter.EmitLoadVariable(tmpVariable); emitter.EmitLoadInt(idx); curr.Compile(emitter); if (currType.IsAnyOf("int", "bool", "float", "complex")) emitter.EmitBox(emitter.ResolveType(currType)); emitter.EmitSaveIndex("object"); idx++; } // return the created array emitter.EmitLoadVariable(tmpVariable); } emitter.EmitLoadBool(PrintLine); emitter.EmitCall(printMethod); }
public override void Compile(Emitter.Emitter emitter) { // check types var leftType = Left.GetExpressionType(emitter); var rightType = Right.GetExpressionType(emitter); if (leftType != "bool" || rightType != "bool") Error(String.Format(Resources.errOperatorTypesMismatch, "||", leftType, rightType)); // create labels var labelElse = emitter.CreateLabel(); var labelEnd = emitter.CreateLabel(); Left.Compile(emitter); emitter.EmitBranchFalse(labelElse); emitter.EmitLoadBool(true); emitter.EmitBranch(labelEnd); emitter.PlaceLabel(labelElse); Right.Compile(emitter); emitter.PlaceLabel(labelEnd); }
public override void Compile(Emitter.Emitter emitter) { emitter.EmitLoadBool(Value); }
/// <summary> /// Compare two values for their relative order: less and greater /// </summary> /// <param name="emitter">Emitter link</param> /// <param name="leftType">Left-hand argument type</param> /// <param name="rightType">Left-hand argument type</param> private void CompileRelation(Emitter.Emitter emitter, string leftType, string rightType) { if(leftType == "string") { var method = emitter.AssemblyImport(typeof(string).GetMethod("Compare", new[] { typeof(string), typeof(string) })); emitter.EmitCall(method); emitter.EmitLoadBool(false); } switch (ComparisonType) { case LexemType.Less: emitter.EmitCompareLess(); break; case LexemType.LessEqual: emitter.EmitCompareGreater(); emitter.EmitLoadBool(false); emitter.EmitCompareEqual(); break; case LexemType.Greater: emitter.EmitCompareGreater(); break; case LexemType.GreaterEqual: emitter.EmitCompareLess(); emitter.EmitLoadBool(false); emitter.EmitCompareEqual(); break; } }
/// <summary> /// Compare two values for their equality /// </summary> /// <param name="emitter">Emitter link</param> /// <param name="leftType">Left-hand argument type</param> /// <param name="rightType">Left-hand argument type</param> private void CompileEquality(Emitter.Emitter emitter, string leftType, string rightType) { var basicTypes = new[] { "bool", "int", "float", "string" }; if (leftType.IsAnyOf(basicTypes)) { // compare strings if (leftType == "string") { var method = emitter.AssemblyImport(typeof(string).GetMethod("Compare", new[] { typeof(string), typeof(string) })); emitter.EmitCall(method); emitter.EmitLoadBool(false); } emitter.EmitCompareEqual(); } // long, complex and others else { System.Reflection.MethodInfo method; if(leftType.IsAnyOf("long", "complex")) { var type = (leftType == "long" ? typeof(System.Numerics.BigInteger) : typeof(System.Numerics.Complex)); method = type.GetMethod("op_Equality", new[] { type, type }); } else method = typeof(MirelleStdlib.Compare).GetMethod("Equal", new[] { typeof(object), typeof(object) }); emitter.EmitCall(emitter.AssemblyImport(method)); } // invert ? if (ComparisonType == LexemType.NotEqual) { emitter.EmitLoadBool(false); emitter.EmitCompareEqual(); } }
/// <summary> /// Create iteration code for a range /// </summary> /// <param name="emitter"></param> public void CompileRange(Emitter.Emitter emitter) { // make local variables only visible inside the scope emitter.CurrentMethod.Scope.EnterSubScope(); var idxVar = emitter.CurrentMethod.Scope.Introduce("int", emitter.ResolveType("int"), Key == null ? null : Key.Data); var rangeVar = emitter.CurrentMethod.Scope.Introduce("range", emitter.ResolveType("range")); var currVar = emitter.CurrentMethod.Scope.Introduce("int", emitter.ResolveType("int"), Item.Data); // preface: range = ..., range.reset Iterable.Compile(emitter); emitter.EmitSaveVariable(rangeVar); emitter.EmitLoadVariable(rangeVar); emitter.EmitCall(emitter.FindMethod("range", "reset")); // set key if exists if(Key != null) { emitter.EmitLoadInt(-1); emitter.EmitSaveVariable(idxVar); } // range.next == false ? exit emitter.PlaceLabel(BodyStart); emitter.EmitLoadVariable(rangeVar); emitter.EmitCall(emitter.FindMethod("range", "next")); emitter.EmitLoadBool(false); emitter.EmitCompareEqual(); emitter.EmitBranchTrue(BodyEnd); // curr = range.current emitter.EmitLoadVariable(rangeVar); emitter.EmitCall(emitter.FindMethod("range", "current")); emitter.EmitSaveVariable(currVar); // increment key if exists if(Key != null) { emitter.EmitLoadVariable(idxVar); emitter.EmitLoadInt(1); emitter.EmitAdd(); emitter.EmitSaveVariable(idxVar); } // body var preCurrLoop = emitter.CurrentLoop; emitter.CurrentLoop = this; Body.Compile(emitter); emitter.CurrentLoop = preCurrLoop; emitter.EmitBranch(BodyStart); emitter.PlaceLabel(BodyEnd); emitter.CurrentMethod.Scope.LeaveSubScope(); }
/// <summary> /// Create iteration code for a dictionary /// </summary> /// <param name="emitter"></param> public void CompileDict(Emitter.Emitter emitter) { // check if key defined if (Key == null) Error(Resources.errDictIterKeyRequired); // make local variables only visible inside the scope emitter.CurrentMethod.Scope.EnterSubScope(); var dictVar = emitter.CurrentMethod.Scope.Introduce("dict", emitter.ResolveType("dict")); var currVar = emitter.CurrentMethod.Scope.Introduce("string[]", emitter.ResolveType("string[]")); var keyVar = emitter.CurrentMethod.Scope.Introduce("string", emitter.ResolveType("string"), Key.Data); var itemVar = emitter.CurrentMethod.Scope.Introduce("string", emitter.ResolveType("string"), Item.Data); // preface: dictVar = ...; Iterable.Compile(emitter); emitter.EmitSaveVariable(dictVar); emitter.EmitLoadVariable(dictVar); emitter.EmitCall(emitter.FindMethod("dict", "reset")); // dict.next == false ? exit emitter.PlaceLabel(BodyStart); emitter.EmitLoadVariable(dictVar); emitter.EmitCall(emitter.FindMethod("dict", "next")); emitter.EmitLoadBool(false); emitter.EmitCompareEqual(); emitter.EmitBranchTrue(BodyEnd); // curr = dict.current emitter.EmitLoadVariable(dictVar); emitter.EmitCall(emitter.FindMethod("dict", "current")); emitter.EmitSaveVariable(currVar); // (key, value) = curr emitter.EmitLoadVariable(currVar); emitter.EmitLoadInt(0); emitter.EmitLoadIndex("string"); emitter.EmitSaveVariable(keyVar); emitter.EmitLoadVariable(currVar); emitter.EmitLoadInt(1); emitter.EmitLoadIndex("string"); emitter.EmitSaveVariable(itemVar); // body var preCurrLoop = emitter.CurrentLoop; emitter.CurrentLoop = this; Body.Compile(emitter); emitter.CurrentLoop = preCurrLoop; emitter.EmitBranch(BodyStart); emitter.PlaceLabel(BodyEnd); emitter.CurrentMethod.Scope.LeaveSubScope(); }