public StructDescription(AStructDecl structDecl) { Parser parser = new Parser(structDecl); Name = parser.Name; IsEnum = Name.StartsWith("enum "); if (IsEnum) { Name = Name.Substring(5); foreach (VariableDescription field in parser.Fields) { field.PlacementPrefix = "Enum Field"; } } Fields = parser.Fields; Methods = parser.Methods; Constructors = parser.Constructors; Deconstructors = parser.Deconstructors; LineFrom = structDecl.GetName().Line; LineTo = structDecl.GetEndToken().Line; if (structDecl.GetBase() is AGenericType) BaseRef = (ANamedType) ((AGenericType) structDecl.GetBase()).GetBase(); else BaseRef = (ANamedType) structDecl.GetBase(); structDecl.RemoveChild(BaseRef); foreach (TIdentifier identifier in structDecl.GetGenericVars()) { GenericVars.Add(identifier.Text); } IsClass = structDecl.GetClassToken() != null; Visibility = (PVisibilityModifier)structDecl.GetVisibilityModifier().Clone(); Position = TextPoint.FromCompilerCoords(structDecl.GetName()); }
public static void GetMatchingTypes(ANamedType node, List<ATypedefDecl> typeDefs, List<AStructDecl> structs, List<AMethodDecl> delegates, List<TIdentifier> generics, out bool matchPrimitive) { List<string> names = new List<string>(); foreach (TIdentifier identifier in ((AAName)node.GetName()).GetIdentifier()) { names.Add(identifier.Text); } matchPrimitive = names.Count == 1 && GalaxyKeywords.Primitives.words.Contains(names[0]); GetMatchingTypes(node, names, typeDefs, structs, delegates, new List<ANamespaceDecl>(), generics); }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { PExp expNode = (PExp)node; PType type = data.ExpTypes[expNode]; if (type is APointerType) type = new ANamedType(new TIdentifier("string"), null); ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName", 0, 0)); ALvalueExp exp = new ALvalueExp(local); PStm stm = Util.GetAncestor<PStm>(node); AABlock block = (AABlock)stm.Parent(); node.ReplaceBy(exp); AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(type, data), new TIdentifier(varName, 0, 0), expNode); ALocalDeclStm newStm = new ALocalDeclStm(new TSemicolon(";"), localDecl); block.GetStatements().Insert(block.GetStatements().IndexOf(stm), newStm); NewStatements.Add(newStm); data.LvalueTypes[local] = type; data.ExpTypes[exp] = type; data.LocalLinks[local] = localDecl; //localDecl.Apply(this); exp.Apply(this); return; }
public override void OutANamedType(ANamedType node) { if (data.StructTypeLinks.ContainsKey(node)) { AStructDecl decl = data.StructTypeLinks[node]; if (decl.GetVisibilityModifier() is APrivateVisibilityModifier) PrivateTypes.Add(node); } else if (data.DelegateTypeLinks.ContainsKey(node)) { AMethodDecl decl = data.DelegateTypeLinks[node]; if (decl.GetVisibilityModifier() is APrivateVisibilityModifier) PrivateTypes.Add(node); } }
public override void CaseANamedType(ANamedType node) { AAName name = (AAName) node.GetName(); if (name.GetIdentifier().Count > 2) return; if (name.GetIdentifier().Count == 2 && ((TIdentifier)name.GetIdentifier()[0]).Text != "Dialogs") return; if (name.GetIdentifier().Count == 1) { bool foundDialogs = false; AASourceFile file = Util.GetAncestor<AASourceFile>(node); foreach (AUsingDecl usingDecl in file.GetUsings()) { if (usingDecl.GetNamespace().Count == 1) { TIdentifier identifer = (TIdentifier) usingDecl.GetNamespace()[0]; if (identifer.Text == "Dialogs") { foundDialogs = true; break; } } } if (!foundDialogs) { ANamespaceDecl ns = Util.GetAncestor<ANamespaceDecl>(node); if (!Util.HasAncestor<ANamespaceDecl>(ns.Parent()) && ns.GetName().Text == "Dialogs") { foundDialogs = true; } } if (!foundDialogs) return; } if (((TIdentifier)name.GetIdentifier()[name.GetIdentifier().Count - 1]).Text == oldName) types.Add((TIdentifier)name.GetIdentifier()[name.GetIdentifier().Count - 1]); }
public override void OutANamedType(ANamedType node) { //If using a generic type, you must us it as a generic if (data.StructTypeLinks.ContainsKey(node)) { AStructDecl str = data.StructTypeLinks[node]; if (str.GetGenericVars().Count > 0) { if (!(node.Parent() is AGenericType)) { errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText46"), false, new ErrorCollection.Error(str.GetName(), LocRM.GetString("ErrorText48") + Util.GetTypeName(str)))); } } } base.OutANamedType(node); }
public override void OutAStructDecl(AStructDecl node) { //Insert init in each constructor AThisLvalue thisLvalue = new AThisLvalue(new TThis("this")); ALvalueExp thisExp = new ALvalueExp(thisLvalue); APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), thisExp); ANamedType namedType = new ANamedType(new TIdentifier(node.GetName().Text), null); data.StructTypeLinks[namedType] = node; data.LvalueTypes[thisLvalue] = data.ExpTypes[thisExp] = new APointerType(new TStar("*"), namedType); data.LvalueTypes[pointerLvalue] = namedType; foreach (AConstructorDecl constructor in node.GetLocals().OfType<ADeclLocalDecl>().Select(decl => decl.GetDecl()).OfType<AConstructorDecl>()) { AABlock block = new AABlock(new ArrayList(), new TRBrace("}")); MakeAssignments(block, namedType, pointerLvalue, false); ((AABlock)constructor.GetBlock()).GetStatements().Insert(0, new ABlockStm(new TLBrace("{"), block)); } base.OutAStructDecl(node); }
public virtual void CaseANamedType(ANamedType node) { DefaultCase(node); }
public override void CaseANamedType(ANamedType node) { //Remember.. if you are the child of a fieldDecl, that field may have been moved if (!node.IsPrimitive())//GalaxyKeywords.Primitives.words.Any(word => word == node.GetName().Text))) { AStructDecl decl = finalTrans.data.StructTypeLinks[node]; Item currentItem = GetIncludeItem(node); if (Util.GetAncestor<AFieldDecl>(node) != null) { Item i = allItems.OfType<FieldItem>().FirstOrDefault(item => item.FieldDecl == Util.GetAncestor<AFieldDecl>(node)); if (i != null) currentItem = i; } if (Util.GetAncestor<AStructDecl>(node) != null) { Item i = allItems.OfType<StructItem>().FirstOrDefault( item => item.StructDecl == Util.GetAncestor<AStructDecl>(node)); if (i != null) currentItem = i; } Item declItem = ((Item)allItems.OfType<StructItem>().FirstOrDefault(item => item.StructDecl == decl)) ?? allItems.OfType<IncludeItem>().First( item => item.Current == Util.GetAncestor<AASourceFile>(decl)); List<Item> cPath = currentItem.Path; List<Item> dPath = declItem.Path; for (int i = 0; i < Math.Min(cPath.Count, dPath.Count); i++) { if (cPath[i] != dPath[i]) {//FORK!!!! //We have a fork. make sure that the field is visible int cI = cPath[i - 1].Children.IndexOf(cPath[i]); int dI = dPath[i - 1].Children.IndexOf(dPath[i]); if (dI < cI) {//The decl is okay break; } //Move the decl up if (declItem is StructItem) { declItem.Parent.Children.Remove(declItem); declItem.Parent = cPath[i - 1]; } else { declItem = new StructItem(decl, cPath[i - 1], new List<Item>()); allItems.Add(declItem); } cPath[i - 1].Children.Insert(cI, declItem); break; } if (i == cPath.Count - 1) { if (i == dPath.Count - 1) { //The decl and use is in same file. Ensure that the decl is before if (Util.TokenLessThan(decl.GetName(), node.GetToken())) break; //Add the decl item declItem = new StructItem(decl, cPath[i], new List<Item>()); allItems.Add(declItem); cPath[i].Children.Add(declItem); break; } else { //The decl is included here or somewhere deeper. But above the use break; } } else if (i == dPath.Count - 1) { //We have reached the file where the decl is, but the use is included deeper, so it is above. Insert decl int cI = cPath[i].Children.IndexOf(cPath[i + 1]); declItem = new StructItem(decl, cPath[i], new List<Item>()); allItems.Add(declItem); cPath[i].Children.Insert(cI, declItem); break; } } } base.CaseANamedType(node); }
public override void OutANamedType(ANamedType node) { if (node.Parent() is ATypedefDecl && ((ATypedefDecl)node.Parent()).GetName() == node) return; //Link named type to their definition (structs) List<ATypedefDecl> typeDefs = new List<ATypedefDecl>(); List<AStructDecl> structs = new List<AStructDecl>(); List<AMethodDecl> delegates = new List<AMethodDecl>(); List<TIdentifier> generics = new List<TIdentifier>(); bool matchPrimitive; GetMatchingTypes(node, typeDefs, structs, delegates, generics, out matchPrimitive); int matches = typeDefs.Count + structs.Count + delegates.Count + (matchPrimitive ? 1 : 0) + generics.Count; if (matches == 0) { errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText49") + ((AAName)node.GetName()).AsString()), true); } else if (generics.Count != 1 && matches > 1) { List<ErrorCollection.Error> subError = new List<ErrorCollection.Error>(); if (matchPrimitive) subError.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText50") + ((AAName)node.GetName()).AsString())); foreach (ATypedefDecl typeDef in typeDefs) { subError.Add(new ErrorCollection.Error(typeDef.GetToken(), LocRM.GetString("ErrorText51"))); } foreach (AStructDecl structDecl in structs) { subError.Add(new ErrorCollection.Error(structDecl.GetName(), LocRM.GetString("ErrorText52") + Util.GetTypeName(structDecl))); } foreach (AMethodDecl methodDecl in delegates) { subError.Add(new ErrorCollection.Error(methodDecl.GetName(), LocRM.GetString("ErrorText53"))); } foreach (TIdentifier identifier in generics) { subError.Add(new ErrorCollection.Error(identifier, LocRM.GetString("ErrorText54"))); } errors.Add( new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText55") + ((AAName)node.GetName()).AsString(), false, subError.ToArray()), true); } else { if (generics.Count == 1) { data.GenericLinks[node] = generics[0]; return; } if (typeDefs.Count == 1) { ATypedefDecl typeDef = typeDefs[0]; //data.TypeDefLinks[node] = typeDef; PType type = (PType) typeDef.GetType().Clone(); node.ReplaceBy(type); type.Apply(this); return; } if (structs.Count == 1) { data.StructTypeLinks[node] = structs[0]; } else if (delegates.Count == 1) { data.DelegateTypeLinks[node] = delegates[0]; } if (!matchPrimitive && !(structs.Count == 1 && data.Enums.ContainsKey(structs[0])) && node.Parent() is AEnrichmentDecl) //Not allowed to enrich a struct, class or delegate { errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText56"))); } } }
public virtual void InANamedType(ANamedType node) { DefaultIn(node); }
public override void CaseANamedType(ANamedType node) { Write(node.AsString()); }
private static void GetMatchingTypes(ANamedType node, List<string> names, List<ATypedefDecl> typeDefs, List<AStructDecl> structs, List<AMethodDecl> delegates, List<ANamespaceDecl> namespaces, List<TIdentifier> generics) { List<IList> decls = new List<IList>(); List<string> currentNamespace = Util.GetFullNamespace(node); AASourceFile currentSourceFile = Util.GetAncestor<AASourceFile>(node); if (names.Count == 1) { string name = names[0]; //Check generic vars AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node); if (currentStruct != null) { foreach (TIdentifier genericVar in currentStruct.GetGenericVars()) { if (genericVar.Text == name) generics.Add(genericVar); } } //Get all type decls and namespaces matching this name, visible from this location List<IList> visibleDecls = Util.GetVisibleDecls(node, ((AAName)node.GetName()).GetIdentifier().Count == 1); foreach (IList declList in visibleDecls) { bool sameFile = false; if (declList.Count > 0) sameFile = currentSourceFile == Util.GetAncestor<AASourceFile>((PDecl) declList[0]); foreach (PDecl decl in declList) { bool sameNS = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (decl is ANamespaceDecl) { ANamespaceDecl aDecl = (ANamespaceDecl) decl; if (aDecl.GetName().Text == name) namespaces.Add(aDecl); continue; } if (decl is ATypedefDecl) { if (Util.IsAncestor(node, decl)) continue; ATypedefDecl aDecl = (ATypedefDecl)decl; if (aDecl.GetStatic() != null && !sameFile || aDecl.GetVisibilityModifier() is APrivateVisibilityModifier && !sameNS) continue; ANamedType namedType = (ANamedType) aDecl.GetName(); AAName aName = (AAName) namedType.GetName(); string n = ((TIdentifier) aName.GetIdentifier()[0]).Text; if (n == name) typeDefs.Add(aDecl); continue; } if (decl is AStructDecl) { AStructDecl aDecl = (AStructDecl) decl; if (!sameNS && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier) continue; if (aDecl.GetName().Text == name) structs.Add(aDecl); continue; } if (decl is AMethodDecl) { AMethodDecl aDecl = (AMethodDecl)decl; if (!sameNS && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier || !sameFile && aDecl.GetStatic() != null) continue; if (aDecl.GetDelegate() != null && aDecl.GetName().Text == name) delegates.Add(aDecl); continue; } } } } else { string name = names[names.Count - 1]; List<ANamespaceDecl> baseNamespaces = new List<ANamespaceDecl>(); List<string> baseNames = new List<string>(); baseNames.AddRange(names); baseNames.RemoveAt(baseNames.Count - 1); GetMatchingTypes(node, baseNames, new List<ATypedefDecl>(), new List<AStructDecl>(), new List<AMethodDecl>(), baseNamespaces, generics); foreach (ANamespaceDecl ns in baseNamespaces) { bool sameFile = currentSourceFile == Util.GetAncestor<AASourceFile>(ns); foreach (PDecl decl in ns.GetDecl()) { bool sameNS = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (decl is ANamespaceDecl) { ANamespaceDecl aDecl = (ANamespaceDecl)decl; if (aDecl.GetName().Text == name) namespaces.Add(aDecl); continue; } if (decl is ATypedefDecl) { ATypedefDecl aDecl = (ATypedefDecl)decl; ANamedType namedType = (ANamedType)aDecl.GetName(); AAName aName = (AAName)namedType.GetName(); string n = ((TIdentifier)aName.GetIdentifier()[0]).Text; if (n == name) typeDefs.Add(aDecl); continue; } if (decl is AStructDecl) { AStructDecl aDecl = (AStructDecl)decl; if (!sameNS && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier) continue; if (aDecl.GetName().Text == name) structs.Add(aDecl); continue; } if (decl is AMethodDecl) { AMethodDecl aDecl = (AMethodDecl)decl; if (!sameNS && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier || !sameFile && aDecl.GetStatic() != null) continue; if (aDecl.GetDelegate() != null && aDecl.GetName().Text == name) delegates.Add(aDecl); continue; } } } } }
private static void GetTargets(AAName node, List<string> names, out List<List<Node>>[] targets, List<ANamespaceDecl> namespaces, SharedData data, ErrorCollection errors, out bool reportedError, bool first = false) { targets = new [] { new List<List<Node>>(),//0: Stuff starting with a local variable new List<List<Node>>(),//1: Stuff starting with a struct field/property new List<List<Node>>() //2: Stuff starting with a global declaration }; reportedError = false; string name = names[names.Count - 1]; if (names.Count == 1) { //Locals AConstructorDecl pConstructor = Util.GetAncestor<AConstructorDecl>(node); AMethodDecl pMethod = Util.GetAncestor<AMethodDecl>(node); AABlock pBlock = Util.GetAncestor<AABlock>(node); if (pBlock != null) { if (data.Locals.ContainsKey(pBlock)) { foreach (AALocalDecl local in data.Locals[pBlock]) { if (local.GetName().Text == name && Util.IsBefore(local, node)) targets[0].Add(new List<Node>(){local}); } } } else if (pConstructor != null) { foreach (AALocalDecl formal in pConstructor.GetFormals()) { if (formal.GetName().Text == name) targets[0].Add(new List<Node>(){formal}); } } //Fields/properties in current struct AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node); if (currentStruct != null) { bool isStaticContext = false; if (Util.HasAncestor<AMethodDecl>(node)) isStaticContext = Util.GetAncestor<AMethodDecl>(node).GetStatic() != null; else if (Util.HasAncestor<APropertyDecl>(node)) isStaticContext = Util.GetAncestor<APropertyDecl>(node).GetStatic() != null; else if (Util.HasAncestor<AALocalDecl>(node)) isStaticContext = Util.GetAncestor<AALocalDecl>(node).GetStatic() != null; foreach (AALocalDecl local in data.StructFields[currentStruct]) { if (local.GetName().Text != name) continue; //If it's an enherited private variable, you can't refer to it. if (local.GetVisibilityModifier() is APrivateVisibilityModifier && data.EnheritanceLocalMap.ContainsKey(local)) { continue; } if (local.GetStatic() != null) { //Add it to the dotted map targets[1].Add(new List<Node>(){currentStruct, local}); continue; } if (isStaticContext) continue;//Can't refference non static stuff from static context targets[1].Add(new List<Node>(){local}); } foreach (APropertyDecl local in data.StructProperties[currentStruct]) { if (local.GetName().Text != name) continue; //If it's an enherited private variable, you can't refer to it. if (local.GetVisibilityModifier() is APrivateVisibilityModifier && Util.GetAncestor<AStructDecl>(local) != currentStruct) { continue; } if (local.GetStatic() != null) { //Add it to the dotted map targets[1].Add(new List<Node>() { currentStruct, local }); continue; } if (isStaticContext) continue;//Can't refference non static stuff from static context targets[1].Add(new List<Node>(){local}); } } //Global field/property List<IList> visibleDecls = Util.GetVisibleDecls(node, true); AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node); List<string> currentNamespace = Util.GetFullNamespace(node); foreach (IList declList in visibleDecls) { bool isSameFile = false; if (declList.Count > 0) isSameFile = currentFile == Util.GetAncestor<AASourceFile>((PDecl) declList[0]); foreach (PDecl decl in declList) { if (decl is AFieldDecl) { AFieldDecl aDecl = (AFieldDecl)decl; if (aDecl.GetName().Text != name) continue; bool isSameNamespace = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (!isSameNamespace && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier || !isSameFile && aDecl.GetStatic() != null) continue; targets[2].Add(new List<Node>(){decl}); } else if (decl is APropertyDecl) { APropertyDecl aDecl = (APropertyDecl)decl; if (aDecl.GetName().Text != name) continue; bool isSameNamespace = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (!isSameNamespace && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier || !isSameFile && aDecl.GetStatic() != null) continue; targets[2].Add(new List<Node>() { decl }); } else if (decl is AStructDecl && !first) { AStructDecl aDecl = (AStructDecl)decl; if (aDecl.GetName().Text != name) continue; bool isSameNamespace = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (!isSameNamespace && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier) continue; targets[2].Add(new List<Node>() { decl }); } } } //Look in lib fields foreach (AFieldDecl field in data.Libraries.Fields) { if (field.GetName().Text == name) { targets[2].Add(new List<Node>() { field }); } } //Namespaces visibleDecls = Util.GetVisibleDecls(node, false); foreach (IList declList in visibleDecls) { foreach (PDecl decl in declList) { if (decl is ANamespaceDecl) { ANamespaceDecl aDecl = (ANamespaceDecl)decl; if (aDecl.GetName().Text != name) continue; namespaces.Add(aDecl); } } } } else { /*private static void GetTargets(AAName node, List<string> names, List<AALocalDecl> locals, List<Node> structDecls, //<AAlocaldecl/APropertyDecl> List<PDecl> globalDecls, List<AStructDecl> structType, List<List<Node>> dotted, //<any of the above>.<AAlocaldecl/APropertyDecl> List<ANamespaceDecl> namespaces, SharedData data, ErrorCollection errors, out bool reportedError)*/ List<string> baseNames = new List<string>(); baseNames.AddRange(names); baseNames.RemoveAt(baseNames.Count - 1); List<List<Node>>[] baseTargets; List<ANamespaceDecl> baseNamespaces = new List<ANamespaceDecl>(); GetTargets(node, baseNames, out baseTargets, baseNamespaces, data, errors, out reportedError); AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node); for (int i = 0; i < baseTargets.Length; i++) { foreach (List<Node> list in baseTargets[i]) { Node last = list[list.Count - 1]; PType type = null; if (last is AALocalDecl) { type = ((AALocalDecl) last).GetType(); } else if (last is APropertyDecl) { type = ((APropertyDecl) last).GetType(); } else if (last is AFieldDecl) { type = ((AFieldDecl) last).GetType(); } else if (last is TIdentifier) { type = new ANamedType(new TIdentifier("int"), null); } if (last is AStructDecl) { //Special. Static only AStructDecl structDecl = ((AStructDecl) last); foreach (AALocalDecl local in data.StructFields[structDecl]) { if (local.GetName().Text != name) continue; //Must be public if we are outside the struct //If it's an enherited private variable, you can't refer to it. if (currentStruct != structDecl && !(local.GetVisibilityModifier() is APublicVisibilityModifier) || currentStruct == structDecl && local.GetVisibilityModifier() is APrivateVisibilityModifier && data.EnheritanceLocalMap.ContainsKey(local)) { continue; } if (local.GetStatic() == null) { //non Static types doesn't work in this context continue; } List<Node> nodeList = new List<Node>(); nodeList.Add(structDecl); nodeList.Add(local); targets[i].Add(nodeList); } foreach (APropertyDecl local in data.StructProperties[structDecl]) { if (local.GetName().Text != name) continue; //Must be public if we are outside the struct //If it's an enherited private variable, you can't refer to it. if (currentStruct != structDecl && !(local.GetVisibilityModifier() is APublicVisibilityModifier)) { continue; } if (local.GetStatic() == null) { //non Static types doesn't work in this context continue; } List<Node> nodeList = new List<Node>(); nodeList.Add(structDecl); nodeList.Add(local); targets[i].Add(nodeList); } } else { if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)type) && !(data.Enums.ContainsKey(data.StructTypeLinks[(ANamedType)type]))) { AStructDecl targetStruct = data.StructTypeLinks[(ANamedType)type]; foreach (AALocalDecl local in data.StructFields[targetStruct]) { if (local.GetName().Text != name) continue; //Must be public if we are outside the struct //If it's an enherited private variable, you can't refer to it. if (currentStruct != targetStruct && !(local.GetVisibilityModifier() is APublicVisibilityModifier) || currentStruct == targetStruct && local.GetVisibilityModifier() is APrivateVisibilityModifier && data.EnheritanceLocalMap.ContainsKey(local)) { continue; } if (local.GetStatic() != null) { //Static types doesn't work in this context continue; } List<Node> nodeList = new List<Node>(); nodeList.AddRange(list); nodeList.Add(local); targets[i].Add(nodeList); } foreach (APropertyDecl local in data.StructProperties[targetStruct]) { if (local.GetName().Text != name) continue; //Must be public if we are outside the struct //If it's an enherited private variable, you can't refer to it. if (currentStruct != targetStruct && !(local.GetVisibilityModifier() is APublicVisibilityModifier)) { continue; } if (local.GetStatic() != null) { //Static types doesn't work in this context continue; } List<Node> nodeList = new List<Node>(); nodeList.AddRange(list); nodeList.Add(local); targets[i].Add(nodeList); } } else//Find matching enrichment { List<IList> visibleDecls = Util.GetVisibleDecls(node, true); AEnrichmentDecl currentEnrichment = Util.GetAncestor<AEnrichmentDecl>(node); foreach (IList declList in visibleDecls) { foreach (PDecl decl in declList) { if (decl is AEnrichmentDecl) { AEnrichmentDecl aDecl = (AEnrichmentDecl)decl; if (Util.TypesEqual(aDecl.GetType(), type, data)) { foreach (PDecl enrichmentDecl in aDecl.GetDecl()) { if (enrichmentDecl is APropertyDecl) { APropertyDecl local = (APropertyDecl)enrichmentDecl; if (local.GetName().Text != name) continue; //Must be public if we are outside the struct if (currentEnrichment != aDecl && !(local.GetVisibilityModifier() is APublicVisibilityModifier)) { continue; } if (local.GetStatic() != null) { //Static types doesn't work in this context continue; } List<Node> nodeList = new List<Node>(); nodeList.AddRange(list); nodeList.Add(local); targets[i].Add(nodeList); } } } } } } //Could be array.length if ((type is AArrayTempType || type is ADynamicArrayType) && name == "length") { List<Node> nodeList = new List<Node>(); nodeList.AddRange(list); nodeList.Add((TIdentifier)node.GetIdentifier()[names.Count - 1]); targets[i].Add(nodeList); } } } } } AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node); List<string> currentNamespace = Util.GetFullNamespace(node); foreach (ANamespaceDecl ns in baseNamespaces) { bool isSameFile = currentFile == Util.GetAncestor<AASourceFile>(ns); foreach (PDecl decl in ns.GetDecl()) { if (decl is AFieldDecl) { AFieldDecl aDecl = (AFieldDecl)decl; if (aDecl.GetName().Text != name) continue; bool isSameNamespace = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (!isSameNamespace && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier || !isSameFile && aDecl.GetStatic() != null) continue; targets[2].Add(new List<Node>(){decl}); } else if (decl is APropertyDecl) { APropertyDecl aDecl = (APropertyDecl)decl; if (aDecl.GetName().Text != name) continue; bool isSameNamespace = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (!isSameNamespace && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier || !isSameFile && aDecl.GetStatic() != null) continue; targets[2].Add(new List<Node>() { decl }); } else if (decl is AStructDecl) { AStructDecl aDecl = (AStructDecl)decl; if (aDecl.GetName().Text != name) continue; bool isSameNamespace = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (!isSameNamespace && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier) continue; targets[2].Add(new List<Node>() { decl }); } else if (decl is ANamespaceDecl) { ANamespaceDecl aDecl = (ANamespaceDecl)decl; if (aDecl.GetName().Text != name) continue; namespaces.Add(aDecl); } } } } //If we got no matches, and we are not last, report error if (errors != null && node.GetIdentifier().Count > names.Count && targets[0].Count + targets[1].Count + targets[2].Count + namespaces.Count == 0) { string dotList = ""; foreach (string s in names) { if (dotList != "") dotList += "."; dotList += s; } errors.Add(new ErrorCollection.Error((TIdentifier)node.GetIdentifier()[names.Count - 1], dotList + LocRM.GetString("ErrorText174"))); reportedError = true; } }
ArrayList New260() { ArrayList nodeList = new ArrayList(); ArrayList nodeArrayList1 = (ArrayList) Pop(); TypedList listNode4 = new TypedList(); TypedList listNode3 = (TypedList)nodeArrayList1[0]; if ( listNode3 != null ) { listNode4.AddAll(listNode3); } AAName pnameNode2 = new AAName ( listNode4 ); ANamedType ptypeNode1 = new ANamedType ( pnameNode2 ); nodeList.Add(ptypeNode1); return nodeList; }
/*private class IsThisOnLeftSide : DepthFirstAdapter { private PType type; private SharedData data; public bool IsAssignedTo; private List<AMethodDecl> investigatedMethods = new List<AMethodDecl>(); public IsThisOnLeftSide(PType type, SharedData data) { this.type = type; this.data = data; } //Check assignments, method invocations and nonstatic method invocations. public override void CaseAMethodDecl(AMethodDecl node) { investigatedMethods.Add(node); } public override void CaseAThisLvalue(AThisLvalue node) { if (IsAssignedTo) return; Node iParent = GetClosestNodeOfType(node, typeof (AAssignmentExp), typeof (ASimpleInvokeExp), typeof (ANonstaticInvokeExp), typeof (AAsyncInvokeStm), typeof (ASyncInvokeExp), typeof(AArrayLvalue), typeof(APointerLvalue), typeof(APropertyLvalue), typeof(AStructLvalue)); if (iParent == null) return; if (iParent is AAssignmentExp) { AAssignmentExp aParent = (AAssignmentExp) iParent; if (Util.IsAncestor(node, aParent.GetLvalue())) { IsAssignedTo = true; } return; } if (iParent is ASimpleInvokeExp) { ASimpleInvokeExp aParent = (ASimpleInvokeExp) iParent; AMethodDecl method = data.SimpleMethodLinks[aParent]; if (investigatedMethods.Contains(method)) return; if (Util.IsAncestor(node, aParent.GetLvalue())) { IsAssignedTo = true; } return; } } private Node GetClosestNodeOfType(Node node, params Type[] types) { if (node == null) return null; if (types.Contains(node.GetType())) return node; return GetClosestNodeOfType(node.Parent(), types); } }*/ public override void CaseADeconstructorDecl(ADeconstructorDecl node) { AStructDecl str = Util.GetAncestor<AStructDecl>(node); AEnrichmentDecl enrichment = Util.GetAncestor<AEnrichmentDecl>(node); AMethodDecl replacer = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new AVoidType(new TVoid("void")), node.GetName(), new ArrayList(), node.GetBlock()); replacer.GetName().Text += "_Deconstructor"; //Move the method outside the struct AASourceFile file = Util.GetAncestor<AASourceFile>(node); if (str != null) str.RemoveChild(node.Parent()); /*else enrichment.RemoveChild(node);*/ int i = file.GetDecl().IndexOf(str ?? (PDecl)enrichment); file.GetDecl().Insert(i/* + 1*/, replacer); //Add the struct as a parameter PType type; if (str != null) { ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; type = structType; } else { type = Util.MakeClone(enrichment.GetType(), finalTrans.data); } finalTrans.data.DeconstructorMap[node] = replacer; AALocalDecl structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), type), new TIdentifier("currentStruct", replacer.GetName().Line, replacer.GetName().Pos), null); replacer.GetFormals().Add(structFormal); finalTrans.data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(file, replacer)); //Call base deconstructor before each return if (str != null && str.GetBase() != null) { AStructDecl baseStruct = data.StructTypeLinks[(ANamedType) str.GetBase()]; if (data.StructDeconstructor.ContainsKey(baseStruct)) { baseStruct.Apply(this); replacer.Apply(new CallDeconstructors(baseStruct, structFormal, data)); /*AMethodDecl baseDeconstructor = data.DeconstructorMap[data.StructDeconstructor[baseStruct]]; ALocalLvalue structFormalRef = new ALocalLvalue(new TIdentifier("currentStruct")); ALvalueExp structFormalRefExp = new ALvalueExp(structFormalRef); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("baseDeconstructor"), new ArrayList() {structFormalRefExp}); AABlock block = (AABlock) replacer.GetBlock(); block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), invoke)); data.LocalLinks[structFormalRef] = structFormal; data.SimpleMethodLinks[invoke] = baseDeconstructor; data.LvalueTypes[structFormalRef] = data.ExpTypes[structFormalRefExp] = structFormal.GetType(); data.ExpTypes[invoke] = baseDeconstructor.GetReturnType();*/ } } this.structFormal = structFormal; base.CaseAMethodDecl(replacer); }
public override void CaseAConstructorDecl(AConstructorDecl node) { AStructDecl str = Util.GetAncestor<AStructDecl>(node); AEnrichmentDecl enrichment = Util.GetAncestor<AEnrichmentDecl>(node); AMethodDecl replacer = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new AVoidType(new TVoid("void")), node.GetName(), new ArrayList(), node.GetBlock()); replacer.GetName().Text += "_Constructor"; while (node.GetFormals().Count > 0) { replacer.GetFormals().Add(node.GetFormals()[0]); } //Move the method outside the struct AASourceFile file = Util.GetAncestor<AASourceFile>(node); if (str != null) str.RemoveChild(node.Parent()); else enrichment.RemoveChild(node); int i = file.GetDecl().IndexOf(str ?? (PDecl)enrichment); file.GetDecl().Insert(i/* + 1*/, replacer); //Add the struct as a parameter PType type; if (str != null) { ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; type = structType; } else { type = Util.MakeClone(enrichment.GetType(), finalTrans.data); } finalTrans.data.ConstructorMap[node] = replacer; structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), type), new TIdentifier("currentStruct", replacer.GetName().Line, replacer.GetName().Pos), null); replacer.GetFormals().Add(structFormal); finalTrans.data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(file, replacer)); //Add return stm replacer.SetReturnType(new APointerType(new TStar("*"), Util.MakeClone(type, data))); replacer.Apply(new TransformConstructorReturns(structFormal, data)); //Insert call to base constructor);); if (finalTrans.data.ConstructorBaseLinks.ContainsKey(node)) { AMethodDecl baseConstructor = finalTrans.data.ConstructorMap[finalTrans.data.ConstructorBaseLinks[node]]; ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier(baseConstructor.GetName().Text), new ArrayList()); while (node.GetBaseArgs().Count > 0) { invoke.GetArgs().Add(node.GetBaseArgs()[0]); } AThisLvalue thisLvalue1 = new AThisLvalue(new TThis("this")); ALvalueExp thisExp1 = new ALvalueExp(thisLvalue1); invoke.GetArgs().Add(thisExp1); AThisLvalue thisLvalue2 = new AThisLvalue(new TThis("this")); AAssignmentExp assignExp = new AAssignmentExp(new TAssign("="), thisLvalue2, invoke); ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; finalTrans.data.LvalueTypes[thisLvalue1] = finalTrans.data.LvalueTypes[thisLvalue2] = finalTrans.data.ExpTypes[thisExp1] = finalTrans.data.ExpTypes[assignExp] = finalTrans.data.ExpTypes[invoke] = new APointerType(new TStar("*"), structType); //finalTrans.data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); finalTrans.data.SimpleMethodLinks[invoke] = baseConstructor; ((AABlock)replacer.GetBlock()).GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), assignExp)); //Inline if base and current are two different kinds of pointer types (int/string) AStructDecl baseStruct = null; AConstructorDecl baseC = finalTrans.data.ConstructorBaseLinks[node]; foreach (KeyValuePair<AStructDecl, List<AConstructorDecl>> pair in finalTrans.data.StructConstructors) { bool found = false; foreach (AConstructorDecl decl in pair.Value) { if (baseC == decl) { found = true; break; } } if (found) { baseStruct = pair.Key; break; } } if ((str.GetIntDim() == null) != (baseStruct.GetIntDim() == null)) { //For the inilining, change the type to the type of the caller AALocalDecl lastFormal = baseConstructor.GetFormals().OfType<AALocalDecl>().Last(); lastFormal.SetRef(new TRef("ref")); APointerType oldType = (APointerType) lastFormal.GetType(); structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; APointerType newType = new APointerType(new TStar("*"), structType); lastFormal.SetType(newType); foreach ( ALocalLvalue lvalue in data.LocalLinks.Where(pair => pair.Value == lastFormal).Select(pair => pair.Key)) { data.LvalueTypes[lvalue] = newType; if (lvalue.Parent() is ALvalueExp) { data.ExpTypes[(PExp) lvalue.Parent()] = newType; if (lvalue.Parent().Parent() is APointerLvalue) data.LvalueTypes[(PLvalue) lvalue.Parent().Parent()] = newType.GetType(); } } FixInlineMethods.Inline(invoke, finalTrans); lastFormal.SetRef(null); foreach ( ALocalLvalue lvalue in data.LocalLinks.Where(pair => pair.Value == lastFormal).Select(pair => pair.Key)) { data.LvalueTypes[lvalue] = oldType; if (lvalue.Parent() is ALvalueExp) { data.ExpTypes[(PExp) lvalue.Parent()] = oldType; if (lvalue.Parent().Parent() is APointerLvalue) data.LvalueTypes[(PLvalue) lvalue.Parent().Parent()] = oldType.GetType(); } } lastFormal.SetType(oldType); } //Inline it instead, Since the pointer implementations might not be the same (int vs string) /*AMethodDecl baseConstructor = finalTrans.data.ConstructorMap[finalTrans.data.ConstructorBaseLinks[node]]; AABlock localsBlock = new AABlock(new ArrayList(), new TRBrace("}")); ABlockStm cloneBlock = new ABlockStm(new TLBrace("{"), (PBlock) baseConstructor.GetBlock().Clone()); Dictionary<AALocalDecl, PLvalue> localMap = new Dictionary<AALocalDecl, PLvalue>(); for (int argNr = 0; argNr < baseConstructor.GetFormals().Count; argNr++) { AALocalDecl formal = (AALocalDecl) baseConstructor.GetFormals()[i]; PExp arg; if (i < baseConstructor.GetFormals().Count - 1) arg = (PExp)node.GetBaseArgs()[i]; else { AThisLvalue thisLvalue = new AThisLvalue(new TThis("this")); ALvalueExp thisExp = new ALvalueExp(thisLvalue); ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; finalTrans.data.LvalueTypes[thisLvalue] = finalTrans.data.ExpTypes[thisExp] = new APointerType(new TStar("*"), structType); arg = thisExp; } if (formal.GetRef() != null || formal.GetOut() != null) { //Use same variable localMap[formal] = ((ALvalueExp) arg).GetLvalue(); } else { //Make a new variable AALocalDecl newLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data), new TIdentifier(formal.GetName().Text), Util.MakeClone(arg, data)); ALocalLvalue newLocalRef = new ALocalLvalue(new TIdentifier(newLocal.GetName().Text)); localMap[formal] = newLocalRef; data.LvalueTypes[newLocalRef] = newLocal.GetType(); data.LocalLinks[newLocalRef] = newLocal; localsBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), newLocal)); } } CloneMethod cloner = new CloneMethod(finalTrans.data, localMap, cloneBlock); baseConstructor.GetBlock().Apply(cloner); ((AABlock)cloneBlock.GetBlock()).GetStatements().Insert(0, new ABlockStm(new TLBrace("{"), localsBlock)); ((AABlock)node.GetBlock()).GetStatements().Insert(0, cloneBlock);*/ } //Fix refferences to other struct stuff); base.CaseAMethodDecl(replacer); //Add functionality to refference the current struct in a constructor //Want to do it as a pointer type, since the constructer can only be called for pointer types }
//private List<ErrorCollection.Error> multipleEntryCandidates = new List<ErrorCollection.Error>(); public override void CaseAMethodDecl(AMethodDecl node) { //Done in a previous iteration /*if (node.GetName().Text == "InitMap" && node.GetFormals().Count == 0) { if (finalTrans.multipleMainEntries) { multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), "Candidate")); } else if (finalTrans.mainEntry != null) { multipleEntryCandidates.Add(new ErrorCollection.Error(finalTrans.mainEntry.GetName(), Util.GetAncestor<AASourceFile>(finalTrans.mainEntry.GetName()), "Candidate")); multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), "Candidate")); //finalTrans.errors.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node), "Found multiple candidates for a main entry", true)); finalTrans.multipleMainEntries = true; finalTrans.mainEntry = null; } else finalTrans.mainEntry = node; }*/ AStructDecl str = Util.GetAncestor<AStructDecl>(node); if (str != null) { if (node.GetStatic() == null) structMethods.Add(node); //Move the method outside the struct str.RemoveChild(node.Parent()); AASourceFile file = (AASourceFile)str.Parent(); int i = file.GetDecl().IndexOf(str); file.GetDecl().Insert(i/* + 1*/, node); node.GetName().Text = GetUniqueStructMethodName(str.GetName().Text + "_" + node.GetName().Text); if (node.GetStatic() == null) { //Add the struct as a parameter PType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[(ANamedType) structType] = str; if (str.GetClassToken() != null) { structType = new APointerType(new TStar("*"), structType); } structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, str.GetClassToken() == null ? new TRef("ref") : null, null, null, structType, new TIdentifier("currentStruct", node.GetName().Line, node.GetName().Pos), null); node.GetFormals().Add(structFormal); data.Locals[(AABlock) node.GetBlock()].Add(structFormal); } else node.SetStatic(null); finalTrans.data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(file, node)); if (node.GetStatic() == null) OldParentStruct[node] = str; //Fix refferences to other struct stuff); base.CaseAMethodDecl(node); //Will visit later, since it's added after the struct //base.CaseAMethodDecl(node); //if (str.GetLocals().Count == 0) // str.Parent().RemoveChild(str); return; } AEnrichmentDecl enrichment = Util.GetAncestor<AEnrichmentDecl>(node); if (enrichment != null) { if (node.GetStatic() == null) structMethods.Add(node); //Move the method outside the struct enrichment.RemoveChild(node); AASourceFile file = (AASourceFile)enrichment.Parent(); int i = file.GetDecl().IndexOf(enrichment); file.GetDecl().Insert(i/* + 1*/, node); node.GetName().Text = GetUniqueStructMethodName(Util.TypeToIdentifierString(enrichment.GetType()) + "_" + node.GetName().Text); if (node.GetStatic() == null) { //Add the struct as a parameter PType structType = Util.MakeClone(enrichment.GetType(), finalTrans.data); structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, new TRef("ref"), null, null, structType, new TIdentifier("currentEnrichment", node.GetName().Line, node.GetName().Pos), null); node.GetFormals().Add(structFormal); } finalTrans.data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(file, node)); //Fix refferences to other struct stuff); base.CaseAMethodDecl(node); //Will visit later, since it's added after the struct //base.CaseAMethodDecl(node); //if (str.GetLocals().Count == 0) // str.Parent().RemoveChild(str); return; } //Build a list of overloads List<AMethodDecl> overloads = new List<AMethodDecl>(); List<string> prefixMatches = new List<string>(); foreach (SharedData.DeclItem<AMethodDecl> declItem in finalTrans.data.Methods) { if (!Util.IsSameNamespace(declItem.Decl, node)) continue; if (declItem.Decl.GetName().Text == node.GetName().Text) overloads.Add(declItem.Decl); if (declItem.Decl.GetName().Text.StartsWith(node.GetName().Text + "O")) prefixMatches.Add(declItem.Decl.GetName().Text); } foreach (AMethodDecl method in finalTrans.data.Libraries.Methods) { if (method.GetBlock() != null || method.GetNative() != null) { if (method.GetName().Text == node.GetName().Text) overloads.Add(method); if (method.GetName().Text.StartsWith(node.GetName().Text + "O")) prefixMatches.Add(method.GetName().Text); } } //Add fields foreach (SharedData.DeclItem<AFieldDecl> declItem in finalTrans.data.Fields) { if (declItem.Decl.GetName().Text.StartsWith(node.GetName().Text + "O")) prefixMatches.Add(declItem.Decl.GetName().Text); } foreach (AFieldDecl field in finalTrans.data.Libraries.Fields) { if (field.GetName().Text.StartsWith(node.GetName().Text + "O")) prefixMatches.Add(field.GetName().Text); } //Dont want to hit another method by appending O# string postfix = ""; while (true) { postfix += "O"; if (prefixMatches.Any(text => text.StartsWith(node.GetName().Text + postfix))) { continue; } break; } if (overloads.Count > 1) { int i = 0; foreach (AMethodDecl method in overloads) { if (node == finalTrans.mainEntry || (node.GetTrigger() != null && finalTrans.data.HasUnknownTrigger)) continue; i++; method.GetName().Text += postfix + i; } } if (node != finalTrans.mainEntry && (node.GetTrigger() == null || !finalTrans.data.HasUnknownTrigger)) node.GetName().Text = namespacePrefix + node.GetName().Text; base.CaseAMethodDecl(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 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); } }
public override void CaseANamedType(ANamedType node) { InANamedType(node); if (node.GetName() != null) { node.GetName().Apply(this); } OutANamedType(node); }
public static void GetTargets(string name, Token node, Node reciever, //Either null, AAName, or PExp PType returnType, //Either null, or Some type the method return type must be assignable to List<PType> argTypes, List<AMethodDecl> candidates, out bool matchArrayResize, List<AMethodDecl> implicitCandidates, List<AMethodDecl> matchingNames, out PExp baseExp, List<AMethodDecl> matchingDelegates, SharedData data, ErrorCollection errors ) { baseExp = null; matchArrayResize = false; if (reciever == null) {//A simple invoke //Look in current struct //Look in all visible namespaces //Look in library methods AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node); if (currentStruct != null) { foreach (AMethodDecl methodDecl in data.StructMethods[currentStruct]) { if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && Util.GetAncestor<AStructDecl>(methodDecl) != currentStruct) continue; if (methodDecl.GetVisibilityModifier() is AProtectedVisibilityModifier && !Util.Extends(Util.GetAncestor<AStructDecl>(methodDecl), currentStruct, data)) continue; if (methodDecl.GetStatic() == null && Util.IsStaticContext(node)) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int i = 0; i < argTypes.Count; i++) { PType argType = argTypes[i]; AALocalDecl formal = (AALocalDecl) methodDecl.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 (candidates.Count == 0) {//Set base exp if (methodDecl.GetStatic() != null) { //Calling static method baseExp = null; } else if (currentStruct.GetClassToken() != null || Util.HasAncestor<AConstructorDecl>(node) || Util.HasAncestor<ADeconstructorDecl>(node)) {//Dynamic context baseExp = new ALvalueExp(new APointerLvalue(new TStar("*"), new ALvalueExp(new AThisLvalue(new TThis("this"))))); } else {//Struct method to struct method baseExp = null; } } if (add) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } if (candidates.Count + implicitCandidates.Count == 0) { //Global methods List<IList> visibleDecls = Util.GetVisibleDecls(node, true); AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node); List<string> currentNamespace = Util.GetFullNamespace(node); foreach (IList declList in visibleDecls) { bool isSameFile = false; bool isSameNamespace = false; if (declList.Count > 0) { isSameFile = currentFile == Util.GetAncestor<AASourceFile>((PDecl) declList[0]); isSameNamespace = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace((PDecl) declList[0])); } foreach (PDecl decl in declList) { if (decl is AMethodDecl) { AMethodDecl methodDecl = (AMethodDecl) decl; if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && !isSameNamespace) continue; if (methodDecl.GetStatic() != null && !isSameFile) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int i = 0; i < argTypes.Count; i++) { PType argType = argTypes[i]; AALocalDecl formal = (AALocalDecl)methodDecl.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) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } } //Library methods foreach (AMethodDecl methodDecl in data.Libraries.Methods) { if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility //Okay, the library doesn't have any private methods. But hey. if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && currentNamespace.Count > 0) continue; if (methodDecl.GetStatic() != null) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int i = 0; i < argTypes.Count; i++) { PType argType = argTypes[i]; AALocalDecl formal = (AALocalDecl)methodDecl.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) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } } else if (reciever is AAName) {//Lookup possibilities for reciever List<List<Node>>[] targets; List<ANamespaceDecl> namespaces = new List<ANamespaceDecl>(); bool reportedError; TypeLinking.GetTargets((AAName)reciever, out targets, namespaces, data, errors, out reportedError); if (reportedError) throw new ParserException(node, "TypeChecking.GetTargets"); AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node); int iteration; for (iteration = 0; iteration < targets.Length; iteration++) { List<Node> matchingList = null; foreach (List<Node> list in targets[iteration]) { Node last = list[list.Count - 1]; PType type = null; if (last is AALocalDecl) { type = ((AALocalDecl) last).GetType(); } else if (last is APropertyDecl) { type = ((APropertyDecl) last).GetType(); } else if (last is AFieldDecl) { type = ((AFieldDecl) last).GetType(); } else if (last is TIdentifier) { type = new ANamedType(new TIdentifier("int"), null); } if (last is AStructDecl) { //Special. Static only AStructDecl structDecl = ((AStructDecl)last); foreach (AMethodDecl methodDecl in data.StructMethods[structDecl]) { if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && Util.GetAncestor<AStructDecl>(methodDecl) != currentStruct) continue; if (methodDecl.GetVisibilityModifier() is AProtectedVisibilityModifier && !Util.Extends(Util.GetAncestor<AStructDecl>(methodDecl), currentStruct, data)) continue; if (methodDecl.GetStatic() == null) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int j = 0; j < argTypes.Count; j++) { PType argType = argTypes[j]; AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j]; 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 (candidates.Count == 0) {//Set base exp //Calling static method baseExp = null; } if (add) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } else { //Find methods based on baseType if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType) type) && !(data.Enums.ContainsKey(data.StructTypeLinks[(ANamedType) type]))) { //Non static only AStructDecl structDecl = data.StructTypeLinks[(ANamedType) type]; foreach (AMethodDecl methodDecl in data.StructMethods[structDecl]) { if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && Util.GetAncestor<AStructDecl>(methodDecl) != currentStruct) continue; if (methodDecl.GetVisibilityModifier() is AProtectedVisibilityModifier && !Util.Extends(Util.GetAncestor<AStructDecl>(methodDecl), currentStruct, data)) continue; if (methodDecl.GetStatic() != null) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int j = 0; j < argTypes.Count; j++) { PType argType = argTypes[j]; AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j]; 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 (candidates.Count == 0 && implicitCandidates.Count == 0) {//Set base exp baseExp = new ALvalueExp(TypeLinking.Link((AAName) reciever, node, list, data)); } if (add) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } else if (type is ANamedType && data.DelegateTypeLinks.ContainsKey((ANamedType)type)) { if (matchingDelegates != null && name == "Invoke") { AMethodDecl delegateDecl = data.DelegateTypeLinks[(ANamedType) type]; if (delegateDecl.GetFormals().Count == argTypes.Count) { matchingNames.Add(delegateDecl); //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(delegateDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int j = 0; j < argTypes.Count; j++) { PType argType = argTypes[j]; AALocalDecl formal = (AALocalDecl)delegateDecl.GetFormals()[j]; 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; matchingDelegates.Add(delegateDecl); if (candidates.Count == 0 && implicitCandidates.Count == 0) {//Set base exp baseExp = new ALvalueExp(TypeLinking.Link((AAName)reciever, node, list, data)); } if (add) candidates.Add(delegateDecl); if (matchImplicit) implicitCandidates.Add(delegateDecl); } } } else { //Look for enrichments List<IList> visibleDecls = Util.GetVisibleDecls(node, true); AEnrichmentDecl currentEnrichment = Util.GetAncestor<AEnrichmentDecl>(node); foreach (IList declList in visibleDecls) { foreach (PDecl decl in declList) { if (decl is AEnrichmentDecl) { AEnrichmentDecl enrichment = (AEnrichmentDecl) decl; if (!Util.TypesEqual(type, enrichment.GetType(), data)) continue; foreach (PDecl enrichmentDecl in enrichment.GetDecl()) { if (enrichmentDecl is AMethodDecl) { AMethodDecl methodDecl = (AMethodDecl) enrichmentDecl; if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && enrichment != currentEnrichment) continue; if (methodDecl.GetStatic() != null) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int j = 0; j < argTypes.Count; j++) { PType argType = argTypes[j]; AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j]; 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 (candidates.Count == 0 && implicitCandidates.Count == 0) {//Set base exp baseExp = new ALvalueExp(TypeLinking.Link((AAName)reciever, node, list, data)); } if (add) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } } } } } } } if (candidates.Count + implicitCandidates.Count > 0) break; } if (iteration >= 2) {//The search continued to global variables. Look in namespaces as well AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node); List<string> currentNamespace = Util.GetFullNamespace(node); foreach (ANamespaceDecl namespaceDecl in namespaces) { bool isSameFile = Util.GetAncestor<AASourceFile>(namespaceDecl) == currentFile; bool isSameNamespace = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(namespaceDecl)); foreach (PDecl decl in namespaceDecl.GetDecl()) { if (decl is AMethodDecl) { AMethodDecl methodDecl = (AMethodDecl) decl; if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && !isSameNamespace) continue; if (methodDecl.GetStatic() != null && !isSameFile) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int i = 0; i < argTypes.Count; i++) { PType argType = argTypes[i]; AALocalDecl formal = (AALocalDecl)methodDecl.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) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } } } } else {//Get base type from exp, and find matching enrichment/struct PType type = data.ExpTypes[(PExp) reciever]; if (type is ADynamicArrayType && name == "Resize" && argTypes.Count == 1 && Assignable(argTypes[0], new ANamedType(new TIdentifier("int"), null))) { matchArrayResize = true; baseExp = (PExp) reciever; } AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node); if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)type)) { //Non static only AStructDecl structDecl = data.StructTypeLinks[(ANamedType)type]; foreach (AMethodDecl methodDecl in data.StructMethods[structDecl]) { if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && Util.GetAncestor<AStructDecl>(methodDecl) != currentStruct) continue; if (methodDecl.GetVisibilityModifier() is AProtectedVisibilityModifier && !Util.Extends(Util.GetAncestor<AStructDecl>(methodDecl), currentStruct, data)) continue; if (methodDecl.GetStatic() != null) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int j = 0; j < argTypes.Count; j++) { PType argType = argTypes[j]; AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j]; 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 (candidates.Count == 0 && implicitCandidates.Count == 0) {//Set base exp baseExp = (PExp)reciever; } if (add) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } else if (type is ANamedType && data.DelegateTypeLinks.ContainsKey((ANamedType)type)) { if (matchingDelegates != null && name == "Invoke") { AMethodDecl delegateDecl = data.DelegateTypeLinks[(ANamedType)type]; if (delegateDecl.GetFormals().Count == argTypes.Count) { matchingNames.Add(delegateDecl); //Check return type if (!(returnType != null && !(returnType is AVoidType) && !Assignable(delegateDecl.GetReturnType(), returnType))) { //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int j = 0; j < argTypes.Count; j++) { PType argType = argTypes[j]; AALocalDecl formal = (AALocalDecl) delegateDecl.GetFormals()[j]; 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) { matchingDelegates.Add(delegateDecl); if (candidates.Count == 0 && implicitCandidates.Count == 0) { //Set base exp baseExp = (PExp)reciever; } if (add) candidates.Add(delegateDecl); if (matchImplicit) implicitCandidates.Add(delegateDecl); } } } } } else { //Look for enrichments List<IList> visibleDecls = Util.GetVisibleDecls(node, true); AEnrichmentDecl currentEnrichment = Util.GetAncestor<AEnrichmentDecl>(node); foreach (IList declList in visibleDecls) { foreach (PDecl decl in declList) { if (decl is AEnrichmentDecl) { AEnrichmentDecl enrichment = (AEnrichmentDecl)decl; if (!Util.TypesEqual(type, enrichment.GetType(), data)) continue; foreach (PDecl enrichmentDecl in enrichment.GetDecl()) { if (enrichmentDecl is AMethodDecl) { AMethodDecl methodDecl = (AMethodDecl)enrichmentDecl; if (methodDecl.GetName().Text == name && methodDecl.GetFormals().Count == argTypes.Count && methodDecl.GetDelegate() == null) { matchingNames.Add(methodDecl); //Visibility if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier && enrichment != currentEnrichment) continue; if (methodDecl.GetStatic() != null) continue; //Check return type if (returnType != null && !(returnType is AVoidType) && !Assignable(methodDecl.GetReturnType(), returnType)) continue; //Check that parameters are assignable bool add = true; bool matchImplicit = false; for (int j = 0; j < argTypes.Count; j++) { PType argType = argTypes[j]; AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j]; 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 (candidates.Count == 0 && implicitCandidates.Count == 0) {//Set base exp baseExp = (PExp)reciever; } if (add) candidates.Add(methodDecl); if (matchImplicit) implicitCandidates.Add(methodDecl); } } } } } } } } int candidateCount = candidates.Count + (matchArrayResize ? 1 : 0); if (candidateCount + implicitCandidates.Count == 0 && !matchArrayResize) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); foreach (AMethodDecl matchingName in matchingNames) { subErrors.Add(new ErrorCollection.Error(matchingName.GetName(), LocRM.GetString("ErrorText124"))); } errors.Add(new ErrorCollection.Error(node, LocRM.GetString("ErrorText125"), false, subErrors.ToArray())); throw new ParserException(node, "TypeChecking.GetTargets"); } if (candidateCount > 1) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); foreach (AMethodDecl matchingName in candidates) { subErrors.Add(new ErrorCollection.Error(matchingName.GetName(), LocRM.GetString("ErrorText38"))); } if (matchArrayResize) subErrors.Add(new ErrorCollection.Error(node, LocRM.GetString("ErrorText126"))); errors.Add(new ErrorCollection.Error(node, LocRM.GetString("ErrorText127"), false, subErrors.ToArray())); throw new ParserException(node, "TypeChecking.GetTargets"); } if (candidateCount == 0 && implicitCandidates.Count > 1) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); foreach (AMethodDecl matchingName in implicitCandidates) { subErrors.Add(new ErrorCollection.Error(matchingName.GetName(), LocRM.GetString("ErrorText38"))); } errors.Add(new ErrorCollection.Error(node, LocRM.GetString("ErrorText128"), false, subErrors.ToArray())); throw new ParserException(node, "TypeChecking.GetTargets"); } }
public virtual void OutANamedType(ANamedType node) { DefaultOut(node); }
public override void OutANamedType(ANamedType node) { if (data.StructTypeLinks.ContainsKey(node) && !Util.HasAncestor<APointerType>(node)) { AStructDecl targetStr = data.StructTypeLinks[node]; AStructDecl str = Util.GetAncestor<AStructDecl>(node); AMethodDecl method = Util.GetAncestor<AMethodDecl>(node); if (str != null && method == null) { if (!StructDepandancies[str].Contains(targetStr)) StructDepandancies[str].Add(targetStr); } } base.OutANamedType(node); }
public override void InANamedType(ANamedType node) { if (!node.IsPrimitive())// !GalaxyKeywords.Primitives.words.Any(word => word == node.GetName().Text)) { AStructDecl decl = finalTrans.data.StructTypeLinks[node]; AddDepency(Util.GetAncestor<AASourceFile>(node), Util.GetAncestor<AASourceFile>(decl)); } }
public override void OutAStructFieldLvalue(AStructFieldLvalue node) { if (data.StructMethodFieldLinks.ContainsKey(node)) { AALocalDecl decl = data.StructMethodFieldLinks[node]; if (data.Enums.ContainsKey((AStructDecl) decl.Parent())) { AStructDecl str = (AStructDecl) decl.Parent(); ANamedType namedType = new ANamedType(new TIdentifier(str.GetName().Text), null); data.StructTypeLinks[namedType] = str; data.LvalueTypes[node] = namedType; } else data.LvalueTypes[node] = decl.GetType(); if (Util.IsStaticContext(node) && decl.GetStatic() == null) { errors.Add(new ErrorCollection.Error(node.GetName(), LocRM.GetString("ErrorText99"), false, new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText100")))); } } else { APropertyDecl decl = data.StructMethodPropertyLinks[node]; data.LvalueTypes[node] = decl.GetType(); CheckPropertyAccessibility(decl, node.Parent() is AAssignmentExp, node.GetName()); if (Util.IsStaticContext(node) && decl.GetStatic() == null) { errors.Add(new ErrorCollection.Error(node.GetName(), LocRM.GetString("ErrorText101"), false, new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText62")))); } } //If the lvalue is a static variable, it's okay if (data.StructMethodFieldLinks[node].GetStatic() == null && Util.GetAncestor<AMethodDecl>(node) == null && Util.GetAncestor<APropertyDecl>(node) == null) { errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText102"))); } }
public override void OutANamedType(ANamedType node) { if (!node.IsPrimitive())//!GalaxyKeywords.Primitives.words.Contains(node.GetName().Text)) node.SetName( new AAName(new List<TIdentifier>() {new TIdentifier(finalTrans.data.StructTypeLinks[node].GetName().Text)})); }
public override void OutAThisLvalue(AThisLvalue node) { AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node); AConstructorDecl constructor = Util.GetAncestor<AConstructorDecl>(node); ADeconstructorDecl deconstructor = Util.GetAncestor<ADeconstructorDecl>(node); AEnrichmentDecl enrichment = Util.GetAncestor<AEnrichmentDecl>(node); if (enrichment == null && (currentStruct == null || (currentStruct.GetClassToken() == null && constructor == null && deconstructor == null))) { errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText136"))); throw new ParserException(node.GetToken(), "TypeChecking.OutAThisLvalue"); } AMethodDecl method = Util.GetAncestor<AMethodDecl>(node); APropertyDecl property = Util.GetAncestor<APropertyDecl>(node); AALocalDecl field = Util.GetAncestor<AALocalDecl>(node); if (method != null && method.GetStatic() != null || property != null && property.GetStatic() != null || field != null && field.GetStatic() != null) { errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText137"))); throw new ParserException(node.GetToken(), "TypeChecking.OutAThisLvalue"); } if (enrichment != null) { if (constructor == null && deconstructor == null) data.LvalueTypes[node] = enrichment.GetType(); else data.LvalueTypes[node] = new APointerType(new TStar("*"), Util.MakeClone(enrichment.GetType(), data)); } else { ANamedType namedType = new ANamedType(new TIdentifier(currentStruct.GetName().Text), null); data.StructTypeLinks[namedType] = currentStruct; data.LvalueTypes[node] = new APointerType(new TStar("*"), namedType); } base.OutAThisLvalue(node); }
public override void CaseANamedType(ANamedType node) { if (SharedData.LastCreated.GenericLinks.ContainsKey(node)) ContainsGenericVar = true; }
private void MakeAssignmentRightDynamic(PLvalue leftSide, PExp rightSide, PType type, AABlock block, ref int index) { if (Util.IsBulkCopy(type)) { if (type is ANamedType) { ANamedType aType = (ANamedType)type; AStructDecl structDecl = data.StructTypeLinks[aType]; foreach (AALocalDecl localDecl in structDecl.GetLocals()) { AStructLvalue newleftSide = new AStructLvalue(new ALvalueExp(leftSide), new ADotDotType(new TDot(".")), new TIdentifier(localDecl.GetName().Text)); ABinopExp newrightSide = new ABinopExp(rightSide, new APlusBinop(new TPlus("+")), new AStringConstExp( new TStringLiteral("\"." + localDecl.GetName().Text + "\""))); data.ExpTypes[newrightSide] = data.ExpTypes[newrightSide.GetRight()] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[newleftSide.GetReceiver()] = type; data.LvalueTypes[newleftSide] = localDecl.GetType(); data.StructFieldLinks[newleftSide] = localDecl; MakeAssignmentRightDynamic(newleftSide, newrightSide, localDecl.GetType(), block, ref index); } } else {//Is array type. Can Only be a constant array type AArrayTempType aType = (AArrayTempType)type; for (int i = 0; i < int.Parse(aType.GetIntDim().Text); i++) { AArrayLvalue newleftSide = new AArrayLvalue(new TLBracket("["), new ALvalueExp(leftSide), new AIntConstExp(new TIntegerLiteral(i.ToString()))); ABinopExp newrightSide = new ABinopExp(rightSide, new APlusBinop(new TPlus("+")), new AStringConstExp( new TStringLiteral("\"[" + i + "]\""))); data.ExpTypes[newrightSide] = data.ExpTypes[newrightSide.GetRight()] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[newleftSide.GetBase()] = type; data.ExpTypes[newleftSide.GetIndex()] = new ANamedType(new TIdentifier("int"), null); data.LvalueTypes[newleftSide] = aType.GetType(); MakeAssignmentRightDynamic(newleftSide, newrightSide, aType.GetType(), block, ref index); } } } else { ANamedType aType;// = type is APointerType ? new ANamedType(new TIdentifier("string"), null) : (ANamedType)type; if (type is APointerType) { if (Util.IsIntPointer(type, ((APointerType)type).GetType(), data)) aType = new ANamedType(new TIdentifier("int"), null); else aType = new ANamedType(new TIdentifier("string"), null); } else { aType = (ANamedType) type; } string capitalType = Util.Capitalize(aType.AsIdentifierString());//Char.ToUpper(aType.GetName().Text[0]) + aType.GetName().Text.Substring(1); leftSide = Util.MakeClone(leftSide, data); rightSide = Util.MakeClone(rightSide, data); ABooleanConstExp trueConst1 = new ABooleanConstExp(new ATrueBool()); //ABooleanConstExp trueConst2 = new ABooleanConstExp(new ATrueBool()); ASimpleInvokeExp innerInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableGet" + capitalType), new ArrayList() { trueConst1, rightSide }); //ASimpleInvokeExp outerInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableSet" + capitalType), new ArrayList() { trueConst2, leftSide, innerInvoke }); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), leftSide, innerInvoke); block.GetStatements().Insert(index, new AExpStm(new TSemicolon(";"), assignment)); index++; data.ExpTypes[trueConst1] = new ANamedType(new TIdentifier("bool"), null); data.ExpTypes[innerInvoke] = aType; data.ExpTypes[assignment] = aType; data.SimpleMethodLinks[innerInvoke] = data.Libraries.Methods.First(m => m.GetName().Text == innerInvoke.GetName().Text); } }