public override void CaseACastExp(ACastExp node) { InACastExp(node); if (node.GetExp() != null) { node.GetExp().Apply(this); } if (node.GetType() != null) { node.GetType().Apply(this); } if (node.GetToken() != null) { node.GetToken().Apply(this); } OutACastExp(node); }
public override void OutACastExp(ACastExp node) { string toType = ((AAName)((ANamedType) node.GetType()).GetName()).AsString(); string fromType; PType fromPType = data.ExpTypes[node.GetExp()]; AStructDecl toEnum = null; AStructDecl fromEnum = null; if (data.StructTypeLinks.ContainsKey((ANamedType)node.GetType())) { AStructDecl str = data.StructTypeLinks[(ANamedType)node.GetType()]; if (data.Enums.ContainsKey(str)) toEnum = str; } if (fromPType is ANamedType) { fromType = ((AAName)((ANamedType)fromPType).GetName()).AsString(); //Namespace ignored if (data.StructTypeLinks.ContainsKey((ANamedType) fromPType)) { AStructDecl str = data.StructTypeLinks[(ANamedType) fromPType]; if (data.Enums.ContainsKey(str)) fromEnum = str; } } else { errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText121"))); throw new ParserException(node.GetToken(), "Invalid cast"); } if (toEnum != null && (fromType == "int" || fromType == "byte")) { ANamedType type = new ANamedType(new TIdentifier(toEnum.GetName().Text), null); data.StructTypeLinks[type] = toEnum; data.ExpTypes[node.GetExp()] = type; node.ReplaceBy(node.GetExp()); return; } if (fromEnum != null && (toType == "int" || toType == "byte")) { int enumDefinitions = 0; foreach (PLocalDecl local in fromEnum.GetLocals()) { if (local is AALocalDecl) enumDefinitions++; } string typeName = enumDefinitions > 255 ? "int" : "byte"; ANamedType type = new ANamedType(new TIdentifier(typeName), null); data.ExpTypes[node.GetExp()] = new ANamedType(new TIdentifier(typeName), null); node.ReplaceBy(node.GetExp()); return; } if (fromEnum != null && toType == "string") { AMethodDecl targetMethod = data.StructMethods[fromEnum][0]; ASimpleInvokeExp invokeExp = new ASimpleInvokeExp(new TIdentifier("toString"), new ArrayList(){node.GetExp()}); data.SimpleMethodLinks[invokeExp] = targetMethod; data.ExpTypes[invokeExp] = targetMethod.GetReturnType(); node.ReplaceBy(invokeExp); return; } ASimpleInvokeExp replacementMethod = null; switch (toType) { case "string": switch (fromType) { case "wave": replacementMethod = new ASimpleInvokeExp(new TIdentifier("AIWaveToString"), new ArrayList{node.GetExp()}); break; case "fixed"://Implicit AFieldLvalue precisionArg = new AFieldLvalue(new TIdentifier("c_fixedPrecisionAny")); ALvalueExp exp = new ALvalueExp(precisionArg); data.FieldLinks[precisionArg] = data.Libraries.Fields.First(field => field.GetName().Text == precisionArg.GetName().Text); replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToString"), new ArrayList { node.GetExp(), exp}); break; case "int"://Implicit case "byte"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList { node.GetExp()}); break; case "bool"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertBooleanToString"), new ArrayList { node.GetExp() }); break; case "color"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertColorToString"), new ArrayList { node.GetExp() }); break; } break; case "text": switch (fromType) { case "wave": replacementMethod = new ASimpleInvokeExp(new TIdentifier("AIWaveToText"), new ArrayList { node.GetExp() }); break; case "fixed"://Implicit AFieldLvalue precisionArg = new AFieldLvalue(new TIdentifier("c_fixedPrecisionAny")); ALvalueExp exp = new ALvalueExp(precisionArg); data.FieldLinks[precisionArg] = data.Libraries.Fields.First(field => field.GetName().Text == precisionArg.GetName().Text); replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToText"), new ArrayList { node.GetExp(), exp }); break; case "int"://Implicit case "byte": replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToText"), new ArrayList { node.GetExp() }); break; case "bool"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertBooleanToText"), new ArrayList { node.GetExp() }); break; case "string"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToText"), new ArrayList { node.GetExp() }); break; } break; case "int": switch (fromType) { case "bool": replacementMethod = new ASimpleInvokeExp(new TIdentifier("BoolToInt"), new ArrayList {node.GetExp()}); break; case "fixed": replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToInt"), new ArrayList { node.GetExp() }); break; case "string": replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToInt"), new ArrayList { node.GetExp() }); break; } break; case "fixed": switch (fromType) { case "int"://Already implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToFixed"), new ArrayList { node.GetExp() }); break; case "string": replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToFixed"), new ArrayList { node.GetExp() }); break; } break; case "bool": switch (fromType) { case "int": case "byte": case "fixed": //Replace by //exp != 0 AIntConstExp zero = new AIntConstExp(new TIntegerLiteral("0")); ABinopExp binop = new ABinopExp(node.GetExp(), new ANeBinop(new TNeq("!=")), zero); node.ReplaceBy(binop); binop.Apply(this); return; } break; } if (replacementMethod == null) { errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText122") + fromType + LocRM.GetString("ErrorText123") + toType)); throw new ParserException(node.GetToken(), LocRM.GetString("ErrorText121")); } data.SimpleMethodLinks[replacementMethod] = data.Libraries.Methods.First(method => method.GetName().Text == replacementMethod.GetName().Text); data.ExpTypes[replacementMethod] = data.SimpleMethodLinks[replacementMethod].GetReturnType(); node.ReplaceBy(replacementMethod); for (int i = 1; i < replacementMethod.GetArgs().Count; i++) { ((Node)replacementMethod.GetArgs()[i]).Apply(this); } }