public override void CaseABinopExp(ABinopExp node) { if (folding) { node.GetLeft().Apply(this); int left = value; node.GetRight().Apply(this); int right = value; if (node.GetBinop() is APlusBinop) value = left + right; else if (node.GetBinop() is AMinusBinop) value = left - right; else if (node.GetBinop() is ATimesBinop) value = left * right; else if (node.GetBinop() is ADivideBinop) { if (right == 0) { errors.Add(new ErrorCollection.Error(((ADivideBinop)node.GetBinop()).GetToken(), LocRM.GetString("ErrorText58")), true); throw new ParserException(null, "SetArrayIndexes.CaseABinopExp"); } value = left / right; } else if (node.GetBinop() is AModuloBinop) { if (right == 0) { errors.Add(new ErrorCollection.Error(((AModuloBinop)node.GetBinop()).GetToken(), LocRM.GetString("ErrorText58")), true); throw new ParserException(null, "EnviromentChecking.CaseABinopExp"); } value = left % right; } else if (node.GetBinop() is AAndBinop) value = left & right; else if (node.GetBinop() is AOrBinop) value = left | right; else if (node.GetBinop() is AXorBinop) value = left ^ right; else if (node.GetBinop() is ALBitShiftBinop) value = left << right; else if (node.GetBinop() is ARBitShiftBinop) value = left >> right; } else base.CaseABinopExp(node); }
//Join string + string to string public override void CaseABinopExp(ABinopExp node) { if (node.GetBinop() is APlusBinop) { PType type = data.ExpTypes[node]; if (type is ANamedType && ((ANamedType)type).IsPrimitive("string")) { PExp other = null; if (node.GetLeft() is ANullExp) other = node.GetRight(); if (node.GetRight() is ANullExp) other = node.GetLeft(); if (other != null) { node.ReplaceBy(other); other.Apply(this); return; } } //Case (string + string) if (node.GetLeft() is AStringConstExp && node.GetRight() is AStringConstExp) { AStringConstExp left = (AStringConstExp) node.GetLeft(); AStringConstExp right = (AStringConstExp) node.GetRight(); if (!IsJoinAllowed(left.GetStringLiteral().Text, right.GetStringLiteral().Text)) { base.CaseABinopExp(node); return; } left.GetStringLiteral().Text = left.GetStringLiteral().Text.Substring(0, left.GetStringLiteral().Text. Length - 1); left.GetStringLiteral().Text += right.GetStringLiteral().Text.Substring(1); node.ReplaceBy(left); CaseAStringConstExp(left); return; } //Case (<exp> + string) + string if (node.GetLeft() is ABinopExp && node.GetRight() is AStringConstExp) { ABinopExp leftBinop = (ABinopExp) node.GetLeft(); if (leftBinop.GetBinop() is APlusBinop && leftBinop.GetRight() is AStringConstExp) { AStringConstExp left = (AStringConstExp) leftBinop.GetRight(); AStringConstExp right = (AStringConstExp) node.GetRight(); if (!IsJoinAllowed(left.GetStringLiteral().Text, right.GetStringLiteral().Text)) { base.CaseABinopExp(node); return; } left.GetStringLiteral().Text = left.GetStringLiteral().Text.Substring(0, left.GetStringLiteral(). Text. Length - 1); left.GetStringLiteral().Text += right.GetStringLiteral().Text.Substring(1); node.ReplaceBy(leftBinop); CaseABinopExp(leftBinop); return; } } //Case string + (string + <exp>) //Case (<exp> + string) + (string + <exp>) } //Case (int + int) /*if (node.GetLeft() is AIntConstExp && node.GetRight() is AIntConstExp) { AIntConstExp left = (AIntConstExp) node.GetLeft(); AIntConstExp right = (AIntConstExp) node.GetRight(); int a = int.Parse(left.GetIntegerLiteral().Text); int b = int.Parse(right.GetIntegerLiteral().Text); if (node.GetBinop() is APlusBinop) { a += b; } else if (node.GetBinop() is AMinusBinop) { a -= b; } else if (node.GetBinop() is ATimesBinop) { a *= b; } else if (node.GetBinop() is ADivideBinop) { if (b == 0) { base.CaseABinopExp(node); return; } a /= b; } else { base.CaseABinopExp(node); return; } left.GetIntegerLiteral().Text = a.ToString(); node.ReplaceBy(left); left.Apply(this); return; } //Case (<exp> + int) + int if (node.GetLeft() is ABinopExp && node.GetRight() is AIntConstExp && (node.GetBinop() is APlusBinop || node.GetBinop() is AMinusBinop)) { ABinopExp leftBinop = (ABinopExp) node.GetLeft(); PType leftType = data.ExpTypes[leftBinop]; if (leftBinop.GetRight() is AIntConstExp && leftType is ANamedType && ((ANamedType) leftType).GetName().Text == "int" && (leftBinop.GetBinop() is APlusBinop || leftBinop.GetBinop() is AMinusBinop)) { AIntConstExp left = (AIntConstExp)leftBinop.GetRight(); AIntConstExp right = (AIntConstExp)node.GetRight(); int a = int.Parse(left.GetIntegerLiteral().Text); int b = int.Parse(right.GetIntegerLiteral().Text); if (node.GetBinop() is APlusBinop) { if (leftBinop.GetBinop() is APlusBinop) { //(<exp> + int) + int int c = a + b; //Test for overflow if (a > 0 && b > 0 && (c < a || c < b) || a < 0 && b < 0 && (c > a || c > b)) { //Don't add them base.CaseABinopExp(node); return; } if (c < 0) { //Change binop to <exp> - c if (c != int.MinValue) { c = -c; leftBinop.SetBinop(new AMinusBinop(new TMinus("-"))); } } //Replace node with leftbinop left.GetIntegerLiteral().Text = c.ToString(); node.ReplaceBy(leftBinop); leftBinop.Apply(this); return; } else { //(<exp> - int) + int int c = b - a; //Test for overflow if (a < 0 && b > 0 && (c < a || c < b) || a > 0 && b < 0 && (c > a || c > b)) { //Don't add them base.CaseABinopExp(node); return; } if (c > 0 || c == int.MinValue) { //Change binop to <exp> + c leftBinop.SetBinop(new APlusBinop(new TPlus("+"))); } else c = -c; //Replace node with leftbinop left.GetIntegerLiteral().Text = c.ToString(); node.ReplaceBy(leftBinop); leftBinop.Apply(this); return; } } else { if (leftBinop.GetBinop() is APlusBinop) { //(<exp> + int) - int //ALso need to consider <exp> in the other position, and int on the other side of the binop //Make a more general algorithm } else { } } } }*/ base.CaseABinopExp(node); }
public override void OutABinopExp(ABinopExp node) { PBinop binop = node.GetBinop(); PExp left = node.GetLeft(); PType leftType = data.ExpTypes[left]; string leftTypeString = Util.TypeToString(leftType); PExp right = node.GetRight(); PType rightType = data.ExpTypes[right]; string rightTypeString = Util.TypeToString(rightType); bool wasDefined = false; Token token = null; while (true) { if (binop is APlusBinop) { token = ((APlusBinop) binop).GetToken(); //Check that types are okay for + if (!new[] {"int", "fixed", "string", "text", "byte", "point"}.Any(c => c == leftTypeString)) { errors.Add(new ErrorCollection.Error(token, currentSourceFile, LocRM.GetString("ErrorText103") + leftTypeString)); throw new ParserException(null, null); } if (!new[] {"int", "fixed", "string", "text", "byte", "point"}.Any(c => c == rightTypeString)) { errors.Add(new ErrorCollection.Error(token, currentSourceFile, LocRM.GetString("ErrorText103") + rightTypeString)); throw new ParserException(null, null); } //If you are using string or text, both sides must be same type if ((leftTypeString == "string" && rightTypeString != "string") || (leftTypeString == "text" && rightTypeString != "text") || (leftTypeString == "point" && rightTypeString != "point") || (rightTypeString == "string" && leftTypeString != "string") || (rightTypeString == "text" && leftTypeString != "text") || (rightTypeString == "point" && leftTypeString != "point")) { if (ImplicitAssignable(leftType, rightType)) { ANamedType namedTo = (ANamedType) rightType; ACastExp cast = new ACastExp(new TLParen("("), new ANamedType( new TIdentifier(((AAName) namedTo.GetName()).AsString()), null), node.GetLeft()); node.SetLeft(cast); OutACastExp(cast); leftType = rightType; } else if (ImplicitAssignable(rightType, leftType)) { ANamedType namedTo = (ANamedType) leftType; ACastExp cast = new ACastExp(new TLParen("("), new ANamedType( new TIdentifier(((AAName) namedTo.GetName()).AsString()), null), node.GetRight()); node.SetRight(cast); OutACastExp(cast); rightType = leftType; } else { //Not valid break; } } wasDefined = true; PType type = leftType; if (rightTypeString == "fixed") type = rightType; data.ExpTypes[node] = type; } else if (binop is AMinusBinop || binop is ATimesBinop || binop is ADivideBinop || binop is AModuloBinop) { token = null; if (binop is AMinusBinop) token = ((AMinusBinop) binop).GetToken(); else if (binop is ATimesBinop) token = ((ATimesBinop) binop).GetToken(); else if (binop is ADivideBinop) token = ((ADivideBinop) binop).GetToken(); else if (binop is AModuloBinop) token = ((AModuloBinop) binop).GetToken(); //Check that types are okay for whatever if (!new[] {"int", "fixed", "byte", "point"}.Any(c => c == leftTypeString)) { //Not valid break; } if (!new[] {"int", "fixed", "byte", "point"}.Any(c => c == rightTypeString)) { //Not valid break; } if ((leftTypeString == "point" || rightTypeString == "point") && !(leftTypeString == "point" && rightTypeString == "point" && binop is AMinusBinop)) { //Not valid break; } wasDefined = true; PType type = leftType; if (rightTypeString == "fixed") type = rightType; if (rightTypeString == "int" && leftTypeString == "byte") type = rightType; data.ExpTypes[node] = type; } else if (binop is AEqBinop || binop is ANeBinop || binop is ALtBinop || binop is ALeBinop || binop is AGtBinop || binop is AGeBinop) { token = null; if (binop is AEqBinop) token = ((AEqBinop) binop).GetToken(); else if (binop is ANeBinop) token = ((ANeBinop) binop).GetToken(); else if (binop is ALtBinop) token = ((ALtBinop) binop).GetToken(); else if (binop is ALeBinop) token = ((ALeBinop) binop).GetToken(); else if (binop is AGtBinop) token = ((AGtBinop) binop).GetToken(); else if (binop is AGeBinop) token = ((AGeBinop) binop).GetToken(); //Unless types are int and fixed, they must be the same type, or null and a nullable type if (leftTypeString == "void" || rightTypeString == "void" || !( GalaxyKeywords.NullablePrimitives.words.Any(s => s == leftTypeString) && rightTypeString == "null" || leftTypeString == "null" && GalaxyKeywords.NullablePrimitives.words.Any(s => s == rightTypeString) || (leftTypeString == "int" || leftTypeString == "fixed" || leftTypeString == "byte") && (rightTypeString == "int" || rightTypeString == "fixed" || rightTypeString == "byte") || leftTypeString == rightTypeString && !(IsDynamic(leftType) || IsDynamic(rightType)) || (binop is AEqBinop || binop is ANeBinop) && ( leftTypeString == rightTypeString || leftTypeString == "null" && IsDynamic(rightType) || IsDynamic(leftType) && rightTypeString == "null" || Util.TypesEqual(leftType, rightType, data) ) || leftType is ANamedType && data.DelegateTypeLinks.ContainsKey((ANamedType) leftType) && (rightTypeString == "null" || rightType is ANamedType && data.DelegateTypeLinks.ContainsKey((ANamedType) rightType)) || rightType is ANamedType && data.DelegateTypeLinks.ContainsKey((ANamedType) rightType) && leftTypeString == "null" ) ) { //Not valid break; } wasDefined = true; data.ExpTypes[node] = new ANamedType(new TIdentifier("bool"), null); } else if (binop is AAndBinop || binop is AOrBinop || binop is AXorBinop || binop is ALBitShiftBinop || binop is ARBitShiftBinop) { token = null; if (binop is AAndBinop) token = ((AAndBinop) binop).GetToken(); else if (binop is AOrBinop) token = ((AOrBinop) binop).GetToken(); else if (binop is AXorBinop) token = ((AXorBinop) binop).GetToken(); else if (binop is ALBitShiftBinop) token = ((ALBitShiftBinop) binop).GetToken(); else if (binop is ARBitShiftBinop) token = ((ARBitShiftBinop) binop).GetToken(); if ( !((leftTypeString == "int" || leftTypeString == "byte") && (rightTypeString == "int" || rightTypeString == "byte") && (binop is ALBitShiftBinop || binop is ARBitShiftBinop || leftTypeString == rightTypeString))) { if (rightTypeString == "int" && leftTypeString == "byte" && left is AIntConstExp) { data.ExpTypes[left] = leftType = new ANamedType(new TIdentifier("int"), null); leftTypeString = "int"; } else if (leftTypeString == "int" && rightTypeString == "byte" && right is AIntConstExp) { data.ExpTypes[right] = rightType = new ANamedType(new TIdentifier("int"), null); rightTypeString = "int"; } else { //Not valid break; } } wasDefined = true; data.ExpTypes[node] = leftType; if (rightTypeString == "int") data.ExpTypes[node] = rightType; } else if (binop is ALazyAndBinop || binop is ALazyOrBinop) { token = null; if (binop is ALazyAndBinop) token = ((ALazyAndBinop) binop).GetToken(); else if (binop is ALazyOrBinop) token = ((ALazyOrBinop) binop).GetToken(); if (leftTypeString != "bool" || rightTypeString != "bool") { errors.Add(new ErrorCollection.Error(token, currentSourceFile, token.Text + LocRM.GetString("ErrorText104") + token.Text + " bool). Got (" + leftTypeString + " " + token.Text + " " + rightTypeString + ")")); throw new ParserException(null, null); } wasDefined = true; data.ExpTypes[node] = leftType; } else throw new Exception("Unexpected binop (This should never happen)"); break; } List<AMethodDecl> possibleOperators = new List<AMethodDecl>(); List<IList> visibleDecls = Util.GetVisibleDecls(node, true); List<string> currentNamespace = Util.GetFullNamespace(node); AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node); foreach (IList declList in visibleDecls) { bool sameNS = false; bool sameFile = false; if (declList.Count > 0) { sameNS = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace((PDecl) declList[0])); sameFile = currentFile == Util.GetAncestor<AASourceFile>((PDecl) declList[0]); } foreach (PDecl decl in declList) { if (decl is AMethodDecl) { AMethodDecl method = (AMethodDecl) decl; if (method.GetName().Text == token.Text) { if (method.GetVisibilityModifier() is APrivateVisibilityModifier && !sameNS) continue; if (method.GetStatic() != null && !sameFile) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; List<PType> argTypes = new List<PType>(){leftType, rightType}; for (int i = 0; i < argTypes.Count; i++) { PType argType = argTypes[i]; AALocalDecl formal = (AALocalDecl)method.GetFormals()[i]; PType formalType = formal.GetType(); if (formal.GetOut() != null && !Assignable(formalType, argType) || formal.GetRef() != null && !(Assignable(argType, formalType) && Assignable(formalType, argType)) || formal.GetOut() == null && formal.GetRef() == null && !Assignable(argType, formalType)) { add = false; if (formal.GetOut() == null && formal.GetRef() == null && ImplicitAssignable(argType, formalType)) { matchImplicit = true; } else { matchImplicit = false; break; } } } if (!add && !matchImplicit) continue; if (add) possibleOperators.Add(method); } } } } if (possibleOperators.Count == 0 && !wasDefined) { errors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText105") + leftTypeString + " " + token.Text + " " + rightTypeString + ")")); throw new ParserException(token, "TypeChecking.OutABinopExp"); } if (possibleOperators.Count + (wasDefined ? 1 : 0) > 1) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); foreach (AMethodDecl method in possibleOperators) { subErrors.Add(new ErrorCollection.Error(method.GetName(), LocRM.GetString("ErrorText106"))); } if (wasDefined) subErrors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText107") + token.Text)); errors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText108") + leftTypeString + " " + token.Text + " " + rightTypeString + LocRM.GetString("ErrorText109"), false, subErrors.ToArray())); throw new ParserException(token, "TypeChecking.OutABinopExp"); } if (wasDefined) return; AMethodDecl op = possibleOperators[0]; ASimpleInvokeExp replacer = new ASimpleInvokeExp(new TIdentifier(op.GetName().Text), new ArrayList(){node.GetLeft(), node.GetRight()}); node.ReplaceBy(replacer); data.SimpleMethodLinks[replacer] = op; data.ExpTypes[replacer] = op.GetReturnType(); //base.OutABinopExp(node); }
public override void CaseABinopExp(ABinopExp node) { InABinopExp(node); if (node.GetRight() != null) { node.GetRight().Apply(this); } if (node.GetBinop() != null) { node.GetBinop().Apply(this); } if (node.GetLeft() != null) { node.GetLeft().Apply(this); } OutABinopExp(node); }
public override void CaseABinopExp(ABinopExp node) { if (!foldIntegerConstants) { base.CaseABinopExp(node); return; } CheckValidConstExp(node.GetLeft()); CheckValidConstExp(node.GetRight()); node.GetLeft().Apply(this); int left = integerConstant; node.GetBinop().Apply(this); node.GetRight().Apply(this); int right = integerConstant; if (node.GetBinop() is APlusBinop) integerConstant = left + right; else if (node.GetBinop() is AMinusBinop) integerConstant = left - right; else if (node.GetBinop() is ATimesBinop) integerConstant = left * right; else if (node.GetBinop() is ADivideBinop) { if (right == 0) { errors.Add(new ErrorCollection.Error(((ADivideBinop)node.GetBinop()).GetToken(), currentSourceFile, LocRM.GetString("ErrorText58"), false), true); throw new ParserException(null, "EnviromentChecking.CaseABinopExp"); } integerConstant = left / right; } else if (node.GetBinop() is AModuloBinop) { if (right == 0) { errors.Add(new ErrorCollection.Error(((AModuloBinop)node.GetBinop()).GetToken(), currentSourceFile, LocRM.GetString("ErrorText58"), false), true); throw new ParserException(null, "EnviromentChecking.CaseABinopExp"); } integerConstant = left % right; } else if (node.GetBinop() is AAndBinop) integerConstant = left & right; else if (node.GetBinop() is AOrBinop) integerConstant = left | right; else if (node.GetBinop() is AXorBinop) integerConstant = left ^ right; else if (node.GetBinop() is ALBitShiftBinop) integerConstant = left << right; else if (node.GetBinop() is ARBitShiftBinop) integerConstant = left >> right; }
public override void CaseADeleteStm(ADeleteStm node) { List<Node> visitMeNext = new List<Node>(); APointerType pointer = (APointerType) data.ExpTypes[node.GetExp()]; //Call deconstructor if it exists { AMethodDecl deconstructor = null; if (pointer.GetType() is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType) pointer.GetType())) { AStructDecl str = data.StructTypeLinks[(ANamedType) pointer.GetType()]; deconstructor = data.DeconstructorMap[data.StructDeconstructor[str]]; } else //Look for enrichment deconstructor { foreach (AEnrichmentDecl enrichment in data.Enrichments) { if (Util.TypesEqual(pointer.GetType(), enrichment.GetType(), data)) { foreach (PDecl decl in enrichment.GetDecl()) { if (decl is ADeconstructorDecl) { deconstructor = data.DeconstructorMap[(ADeconstructorDecl) decl]; break; } } if (deconstructor != null) break; } } } if (deconstructor != null) { /* * Convert delete <exp>; to * * var deleteVar = <exp>; * Deconstructor(deleteVar); * delete deleteVar; */ AALocalDecl deleteVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType( new TIdentifier(Util.IsIntPointer(node, pointer. GetType(), data) ? "int" : "string"), null), new TIdentifier("deleteVar"), node.GetExp()); ALocalLvalue deleteVarRef = new ALocalLvalue(new TIdentifier("deleteVar")); ALvalueExp deleteVarRefExp = new ALvalueExp(deleteVarRef); node.SetExp(deleteVarRefExp); AABlock pBlock = (AABlock) node.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new ALocalDeclStm(new TSemicolon(";"), deleteVarDecl)); data.LocalLinks[deleteVarRef] = deleteVarDecl; data.LvalueTypes[deleteVarRef] = data.ExpTypes[deleteVarRefExp] = data.ExpTypes[deleteVarDecl.GetInit()]; deleteVarRef = new ALocalLvalue(new TIdentifier("deleteVar")); deleteVarRefExp = new ALvalueExp(deleteVarRef); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier(deconstructor.GetName().Text), new ArrayList() {deleteVarRefExp}); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new AExpStm(new TSemicolon(";"), invoke)); data.LocalLinks[deleteVarRef] = deleteVarDecl; data.LvalueTypes[deleteVarRef] = data.ExpTypes[deleteVarRefExp] = data.ExpTypes[deleteVarDecl.GetInit()]; data.SimpleMethodLinks[invoke] = deconstructor; data.ExpTypes[invoke] = deconstructor.GetReturnType(); visitMeNext.Add(deleteVarDecl); } } if (pointer.GetType() is AArrayTempType || pointer.GetType() is ADynamicArrayType) { //If struct array, delete all struct data PType baseType; if (pointer.GetType() is AArrayTempType) baseType = ((AArrayTempType) pointer.GetType()).GetType(); else baseType = ((ADynamicArrayType)pointer.GetType()).GetType(); PExp pointerString = node.GetExp(); if (Util.IsBulkCopy(baseType)) { node.GetExp().Apply(new MoveMethodDeclsOut("pointerVar", data)); pointerString = node.GetExp(); ANamedType aBaseType = (ANamedType) baseType; /* Add the following * * string deleteMe = node.getExp(); <-- no * int i = 0; * while (i < array.length) * { * DeleteStruct<name>(deleteMe + StringToInt(i)); * i = i + 1; * } * */ //string deleteMe = node.getExp(); /*AALocalDecl deleteMeVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("deleteMe"), node.GetExp());*/ //pointerString = deleteMeVar; //int i = 0; AALocalDecl iVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("int"), null), new TIdentifier("i"), new AIntConstExp(new TIntegerLiteral("0"))); //i < array.length ASimpleInvokeExp lenghCall = new ASimpleInvokeExp(new TIdentifier("DataTableGetInt"), new ArrayList()); lenghCall.GetArgs().Add(new ABooleanConstExp(new ATrueBool())); //ALocalLvalue deleteMeUse1 = new ALocalLvalue(new TIdentifier("deleteMeVar")); ABinopExp arrayLengthString = new ABinopExp(Util.MakeClone(pointerString, data), new APlusBinop(new TPlus("+")), new AStringConstExp( new TStringLiteral("\"\\\\Length\""))); lenghCall.GetArgs().Add(arrayLengthString); ALocalLvalue iUse1 = new ALocalLvalue(new TIdentifier("i")); ABinopExp cond = new ABinopExp(new ALvalueExp(iUse1), new ALtBinop(new TLt("<")), lenghCall); //DeleteStruct<name>(deleteMe + StringToInt(i)); //ALocalLvalue deleteMeUse2 = new ALocalLvalue(new TIdentifier("deleteMeVar")); ALocalLvalue iUse2 = new ALocalLvalue(new TIdentifier("i")); ASimpleInvokeExp intToString = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList()); intToString.GetArgs().Add(new ALvalueExp(iUse2)); ABinopExp binopExp1 = new ABinopExp(Util.MakeClone(pointerString, data), new APlusBinop(new TPlus("+")), new AStringConstExp(new TStringLiteral("\"[\""))); ABinopExp binopExp2 = new ABinopExp(binopExp1, new APlusBinop(new TPlus("+")), intToString); ABinopExp binopExp3 = new ABinopExp(binopExp2, new APlusBinop(new TPlus("+")), new AStringConstExp(new TStringLiteral("\"]\""))); ASimpleInvokeExp deleteStructInvoke = new ASimpleInvokeExp(new TIdentifier("DeleteStruct" + aBaseType.AsIdentifierString()), new ArrayList()); deleteStructInvoke.GetArgs().Add(binopExp3); //i = i + 1; ALocalLvalue iUse3 = new ALocalLvalue(new TIdentifier("i")); ALocalLvalue iUse4 = new ALocalLvalue(new TIdentifier("i")); ABinopExp binopExp = new ABinopExp(new ALvalueExp(iUse4), new APlusBinop(new TPlus("+")), new AIntConstExp(new TIntegerLiteral("1"))); AAssignmentExp assign = new AAssignmentExp(new TAssign("="), iUse3, binopExp); //While (...){...} AABlock innerWhile = new AABlock(); innerWhile.GetStatements().Add(new AExpStm(new TSemicolon(";"), deleteStructInvoke)); innerWhile.GetStatements().Add(new AExpStm(new TSemicolon(";"), assign)); AWhileStm whileStm = new AWhileStm(new TLParen("("), cond, new ABlockStm(new TLBrace("{"), innerWhile)); AABlock pBlock = (AABlock) node.Parent(); //pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new ALocalDeclStm(new TSemicolon(";"), deleteMeVar)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new ALocalDeclStm(new TSemicolon(";"), iVar)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), whileStm); //visitMeNext.Add(deleteMeVar); visitMeNext.Add(whileStm); data.ExpTypes[iVar.GetInit()] = data.LvalueTypes[iUse1] = data.LvalueTypes[iUse2] = data.LvalueTypes[iUse3] = data.LvalueTypes[iUse4] = data.ExpTypes[cond.GetLeft()] = data.ExpTypes[lenghCall] = data.ExpTypes[(PExp) intToString.GetArgs()[0]] = data.ExpTypes[binopExp.GetLeft()] = data.ExpTypes[binopExp.GetRight()] = data.ExpTypes[binopExp] = data.ExpTypes[assign] = new ANamedType(new TIdentifier("int"), null); data.ExpTypes[(PExp) lenghCall.GetArgs()[0]] = data.ExpTypes[cond] = new ANamedType(new TIdentifier("bool"), null); data.ExpTypes[lenghCall] = // data.LvalueTypes[deleteMeUse1] = // data.LvalueTypes[deleteMeUse2] = data.ExpTypes[arrayLengthString.GetLeft()] = data.ExpTypes[arrayLengthString.GetRight()] = data.ExpTypes[arrayLengthString] = data.ExpTypes[intToString] = data.ExpTypes[binopExp1] = data.ExpTypes[binopExp1.GetLeft()] = data.ExpTypes[binopExp1.GetRight()] = data.ExpTypes[binopExp2] = data.ExpTypes[binopExp3] = data.ExpTypes[binopExp3.GetRight()] = data.ExpTypes[lenghCall] = data.ExpTypes[lenghCall] = data.ExpTypes[lenghCall] = data.ExpTypes[lenghCall] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[deleteStructInvoke] = new AVoidType(new TVoid("void")); data.Locals[pBlock].Add(iVar); //data.Locals[pBlock].Add(deleteMeVar); data.LocalLinks[iUse1] = data.LocalLinks[iUse2] = data.LocalLinks[iUse3] = data.LocalLinks[iUse4] = iVar; //data.LocalLinks[deleteMeUse1] = // data.LocalLinks[deleteMeUse2] = deleteMeVar; data.SimpleMethodLinks[lenghCall] = data.Libraries.Methods.First(method => method.GetName().Text == lenghCall.GetName().Text); data.SimpleMethodLinks[intToString] = data.Libraries.Methods.First(method => method.GetName().Text == intToString.GetName().Text); AStructDecl structDecl = data.StructTypeLinks[aBaseType]; if (!deleteStructMethod.ContainsKey(structDecl)) CreateDeleteStructMethod(node, structDecl, data); data.SimpleMethodLinks[deleteStructInvoke] = deleteStructMethod[structDecl]; } /* * Convert delete <exp> * to * DeleteArray(<exp>); * */ ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("DeleteArray"), new ArrayList(){pointerString}); /*if (pointerString == null) { invoke.GetArgs().Add(node.GetExp()); } else { ALocalLvalue local = new ALocalLvalue(new TIdentifier("pointerString")); invoke.GetArgs().Add(new ALvalueExp(local)); data.LocalLinks[local] = pointerString; data.LvalueTypes[local] = data.ExpTypes[(PExp) invoke.GetArgs()[0]] = new ANamedType(new TIdentifier("string"), null); }*/ data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); if (deleteArrayMethod == null) CreateDeleteArrayMethod(node, data); data.SimpleMethodLinks[invoke] = deleteArrayMethod; visitMeNext.Add(invoke); node.ReplaceBy(new AExpStm(new TSemicolon(";"), invoke)); } else { //Not array type PExp pointerString = node.GetExp(); bool isIntPointer = Util.IsIntPointer(node, pointer.GetType(), data); bool createdStructDelete = false; if (Util.IsBulkCopy(pointer.GetType())) { node.GetExp().Apply(new MoveMethodDeclsOut("pointerVar", data)); pointerString = node.GetExp(); ANamedType aBaseType = (ANamedType) pointer.GetType(); /* Insert * * string deleteMeVar = node.getExp(); * DeleteStruct<name>(deleteMeVar); * */ /* AALocalDecl deleteMeVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("deleteMe"), node.GetExp());*/ //pointerString = deleteMeVar; //ALocalLvalue deleteMeUse = new ALocalLvalue(new TIdentifier("deleteMeVar")); PExp deleteExp = Util.MakeClone(pointerString, data); AStructDecl structDecl = data.StructTypeLinks[aBaseType]; if (isIntPointer) { GlobalStructVars vars = CreateStructFields(node, structDecl, data); int allocateLimit = int.Parse(structDecl.GetIntDim().Text); if (vars.IdentifierArray != null) { int usedBits = allocateLimit == 0 ? 0 : ((int) Math.Floor(Math.Log(allocateLimit, 2)) + 1); int bitsLeft = 31 - usedBits; int biggestIdentifier = (1 << (bitsLeft + 1)) - 1; AIntConstExp bitsLeftConst = new AIntConstExp(new TIntegerLiteral(bitsLeft.ToString())); deleteExp = new ABinopExp(deleteExp, new ARBitShiftBinop(new TRBitShift(">>")), bitsLeftConst); data.ExpTypes[bitsLeftConst] = data.ExpTypes[deleteExp] = new ANamedType(new TIdentifier("int"), null); } } ASimpleInvokeExp deleteStructInvoke = new ASimpleInvokeExp(new TIdentifier("DeleteStruct" + aBaseType.AsIdentifierString()), new ArrayList()); deleteStructInvoke.GetArgs().Add(deleteExp); AABlock pBlock = (AABlock)node.Parent(); //pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new ALocalDeclStm(new TSemicolon(";"), deleteMeVar)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new AExpStm(new TSemicolon(";"), deleteStructInvoke)); //visitMeNext.Add(deleteMeVar); visitMeNext.Add(deleteStructInvoke); /*data.ExpTypes[(PExp) deleteStructInvoke.GetArgs()[0]] = data.LvalueTypes[deleteMeUse] = new ANamedType(new TIdentifier("string"), null);*/ data.ExpTypes[deleteStructInvoke] = new AVoidType(new TVoid("void")); //data.Locals[pBlock].Add(deleteMeVar); //data.LocalLinks[deleteMeUse] = deleteMeVar; if (!deleteStructMethod.ContainsKey(structDecl)) CreateDeleteStructMethod(node, structDecl, data); data.SimpleMethodLinks[deleteStructInvoke] = deleteStructMethod[structDecl]; createdStructDelete = true; } if (!isIntPointer) { /* * Convert delete <exp> * to * DeleteSimple(<exp>); * */ ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("DeleteObject"), new ArrayList() {pointerString}); /*if (pointerString == null) { invoke.GetArgs().Add(node.GetExp()); } else { ALocalLvalue local = new ALocalLvalue(new TIdentifier("pointerString")); invoke.GetArgs().Add(new ALvalueExp(local)); data.LocalLinks[local] = pointerString; data.LvalueTypes[local] = data.ExpTypes[(PExp)invoke.GetArgs()[0]] = new ANamedType(new TIdentifier("string"), null); }*/ data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); if (deleteObjectMethod == null) CreateDeleteObjectMethod(node, data); data.SimpleMethodLinks[invoke] = deleteObjectMethod; visitMeNext.Add(invoke); node.ReplaceBy(new AExpStm(new TSemicolon(";"), invoke)); } else if (createdStructDelete) { node.Parent().RemoveChild(node); } else { //There is an enrichment PExp deleteExp = pointerString; AEnrichmentDecl enrichmentDecl = data.EnrichmentTypeLinks[pointer.GetType()]; if (isIntPointer) { GlobalStructVars vars = CreateEnrichmentFields(node, enrichmentDecl, data); int allocateLimit = int.Parse(enrichmentDecl.GetIntDim().Text); if (vars.IdentifierArray != null) { int usedBits = allocateLimit == 0 ? 0 : ((int)Math.Floor(Math.Log(allocateLimit, 2)) + 1); int bitsLeft = 31 - usedBits; AIntConstExp bitsLeftConst = new AIntConstExp(new TIntegerLiteral(bitsLeft.ToString())); deleteExp = new ABinopExp(deleteExp, new ARBitShiftBinop(new TRBitShift(">>")), bitsLeftConst); data.ExpTypes[bitsLeftConst] = data.ExpTypes[deleteExp] = new ANamedType(new TIdentifier("int"), null); } } ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("DeleteObject"), new ArrayList() { deleteExp }); data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); data.SimpleMethodLinks[invoke] = CreateDeleteEnrichmentMethod(node, enrichmentDecl, data); visitMeNext.Add(invoke); node.ReplaceBy(new AExpStm(new TSemicolon(";"), invoke)); } } bool hadPointerPreviously = hadPointer; PExp previosNameExp = nameExp; for (int i = 0; i < visitMeNext.Count; i++) { hadPointer = false; nameExp = null; visitMeNext[i].Apply(this); } hadPointer = hadPointerPreviously; nameExp = previosNameExp; }
public override void CaseABinopExp(ABinopExp node) { if (node.GetBinop() is AEqBinop && node.GetRight() is ANullExp && data.ExpTypes[node.GetLeft()] is APointerType) { //We have a null check APointerType pointerType = (APointerType)data.ExpTypes[node.GetLeft()]; AMethodDecl nullCheckMethod = CreateNullCheckMethod(node, pointerType.GetType(), data); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("IsNull"), new ArrayList(){node.GetLeft()}); node.ReplaceBy(invoke); data.ExpTypes[invoke] = new ANamedType(new TIdentifier("bool"), null); data.SimpleMethodLinks[invoke] = nullCheckMethod; CaseASimpleInvokeExp(invoke); return; } base.CaseABinopExp(node); }
public override void OutABinopExp(ABinopExp node) { if (node.GetBinop() is AEqBinop || node.GetBinop() is ANeBinop) { if (node.GetLeft() is ANullExp || node.GetRight() is ANullExp) { if (node.GetLeft() is ANullExp) { //Swap left and right PExp temp = node.GetLeft(); node.SetLeft(node.GetRight()); node.SetRight(temp); } PExp exp = node.GetLeft(); PType type = data.ExpTypes[exp]; if (type is APointerType) { if (node.GetBinop() is ANeBinop) { //Convert a != null to !(a == null) AUnopExp unop = new AUnopExp(new AComplementUnop(new TComplement("!")), null); node.ReplaceBy(unop); unop.SetExp(node); node.SetBinop(new AEqBinop(new TEq("=="))); data.ExpTypes[unop] = new ANamedType(new TIdentifier("bool"), null); } if (Util.IsIntPointer(node, ((APointerType)type).GetType(), data)) { bool add = true; foreach (PType pType in TypesWithIdentifierArray) { if (Util.TypesEqual(((APointerType)type).GetType(), pType, data)) { add = false; break; } } if (add) TypesWithIdentifierArray.Add(((APointerType)type).GetType()); } } } } }
public override void CaseAPointerLvalue(APointerLvalue node) { //Build the list currentPointer.Clear(); base.CaseAPointerLvalue(node); //Todo: insert runtime check here //if (currentPointer.Count == 0 || !setPointers.Contains(MakePointer(currentPointer))) if (!isSet) { PStm pStm = Util.GetAncestor<PStm>(node); if (pStm != null) { AABlock pBlock = (AABlock) pStm.Parent(); /* * if (<pointer> == null) * { * UIDisplayMessage(PlayerGroupAll, messageAreaDebug, StringToText(<filename>[<lineNr>:<pos>] + " null pointer exception")); * int i = 1 / 0; * } */ AASourceFile currentSourceFile = Util.GetAncestor<AASourceFile>(node); node.GetBase().Apply(new MoveMethodDeclsOut("pointerVar", data)); PExp pointer = Util.MakeClone(node.GetBase(), data); ABinopExp cond = new ABinopExp(pointer, new AEqBinop(new TEq("==")), new ANullExp()); AABlock ifBlock = new AABlock(); ASimpleInvokeExp playerGroupAllInvoke = new ASimpleInvokeExp(new TIdentifier("PlayerGroupAll"), new ArrayList()); AFieldLvalue messageAreaDebugLink = new AFieldLvalue(new TIdentifier("c_messageAreaDebug")); ALvalueExp messageAreaDebugLinkExp = new ALvalueExp(messageAreaDebugLink); ASimpleInvokeExp stringToTextInvoke = new ASimpleInvokeExp(new TIdentifier("StringToText"), new ArrayList() { new AStringConstExp( new TStringLiteral("\"" + currentSourceFile . GetName () . Text + "[" + node. GetTokens () . Line + "," + node. GetTokens () . Pos + "]: Null pointer exception\"")) }); ASimpleInvokeExp displayMessageInvoke = new ASimpleInvokeExp( new TIdentifier("UIDisplayMessage"), new ArrayList() {playerGroupAllInvoke, messageAreaDebugLinkExp, stringToTextInvoke}); ifBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), displayMessageInvoke)); ABinopExp iDeclInit = new ABinopExp(new AIntConstExp(new TIntegerLiteral("1")), new ADivideBinop(new TDiv("/")), new AIntConstExp(new TIntegerLiteral("0"))); AALocalDecl iDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("int"), null), new TIdentifier("i"), iDeclInit); ifBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), iDecl)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new AIfThenStm(new TLParen("("), cond, new ABlockStm(new TLBrace("{"), ifBlock))); data.Locals[ifBlock] = new List<AALocalDecl>(){iDecl}; data.ExpTypes[cond.GetRight()] = new ANullType(); data.ExpTypes[cond] = new ANamedType(new TIdentifier("bool"), null); data.ExpTypes[playerGroupAllInvoke] = new ANamedType(new TIdentifier("playergroup"), null); data.ExpTypes[messageAreaDebugLinkExp] = data.LvalueTypes[messageAreaDebugLink] = data.ExpTypes[iDeclInit] = data.ExpTypes[iDeclInit.GetLeft()] = data.ExpTypes[iDeclInit.GetRight()] = new ANamedType(new TIdentifier("int"), null); data.ExpTypes[stringToTextInvoke] = new ANamedType(new TIdentifier("text"), null); data.ExpTypes[(PExp) stringToTextInvoke.GetArgs()[0]] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[displayMessageInvoke] = new AVoidType(new TVoid("void")); data.SimpleMethodLinks[playerGroupAllInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == playerGroupAllInvoke.GetName().Text); data.SimpleMethodLinks[displayMessageInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == displayMessageInvoke.GetName().Text); data.SimpleMethodLinks[stringToTextInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == stringToTextInvoke.GetName().Text); data.FieldLinks[messageAreaDebugLink] = data.Libraries.Fields.Find(f => f.GetName().Text == messageAreaDebugLink.GetName().Text); if (currentPointer.Count > 0) { setPointers.Add(MakePointer(currentPointer)); } } } currentPointer.Add(new PointerPointer()); currentPointer = MakePointer(currentPointer); isSet = Contains(setPointers, currentPointer); isExposed = Contains(exposedPointers, currentPointer); //If the currentPointer is in null pointers, report error.. and then again - we might not reach this statement - warning, and runtime check //If the currentPointer is not in setPointers, insert runtime check }