public override void DeclarationStatement(TreeNode node, Qualifier qualifier, string identifier) { Type localType = ((UserLocal)node.Entry.ReflectionObject).LocalType; LocalBuilder lb = ig.DeclareLocal(localType); node.Entry.ReflectionObject = lb; }
/// <summary> /// Changes a qualifier to an array type qualifier. /// When the qualifier already is an array it adds another dimension to the array. /// </summary> /// <returns>The array type qualifier</returns> public Qualifier MakeArrayType() { Qualifier q = new Qualifier(this); q[Count - 1] += "[]"; return(q); }
public override void BeginCatch(TreeNode node, TreeNode node2, Qualifier qual, string p) { LocalBuilder l = (LocalBuilder)node2.Entry.ReflectionObject; ig.BeginCatchBlock(l.LocalType); ig.Emit(OpCodes.Stloc, l); }
public override void BeginMethod(TreeNode node, List <string> modifiers, Qualifier return_, string name, List <Parameter> parameters) { metb = (MethodBuilder)node.Entry.ReflectionObject; ig = metb.GetILGenerator(); ig.DeclareLocal(typeof(object)); ig.Emit(OpCodes.Nop); }
/// <summary> /// Transforms a type qualifier to a Qualifier object. /// </summary> /// <param name="name">The identifier of the type</param> /// <returns>The full qualifier</returns> public Qualifier TypeQualifier(string name) { Qualifier ids = new Qualifier(); ids.Add(name); return(ids); }
public override void BeginFor(TreeNode node, TreeNode node2, Qualifier qual, string p) { ig.Emit(OpCodes.Callvirt, typeof(IEnumerable).GetMethod("GetEnumerator")); Label forEnd = ig.DefineLabel(); forEndLabels.Push(forEnd); Label forLabel = ig.DefineLabel(); forStartLabels.Push(forLabel); ig.MarkLabel(forLabel); ig.Emit(OpCodes.Dup); ig.Emit(OpCodes.Callvirt, typeof(IEnumerator).GetMethod("MoveNext")); ig.Emit(OpCodes.Brfalse, forEnd); ig.Emit(OpCodes.Dup); ig.Emit(OpCodes.Callvirt, typeof(IEnumerator).GetMethod("get_Current")); LocalBuilder l = (LocalBuilder)node2.Entry.ReflectionObject; if (l.LocalType.IsValueType) { ig.Emit(OpCodes.Unbox, l.LocalType); ig.Emit(OpCodes.Ldobj, l.LocalType); } else { ig.Emit(OpCodes.Castclass, l.LocalType); } ig.Emit(OpCodes.Stloc, l); }
public override void VariableUsed(TreeNode node, Qualifier qual) { if (node.Parent.Type != VnvdTreeWalker.BECOMES || node.ChildIndex == node.Parent.ChildCount - 1) { if (node.Entry.ReflectionObject is LocalBuilder) { LocalBuilder lb = (LocalBuilder)node.Entry.ReflectionObject; if (lb.LocalType.IsPrimitive && ((TreeNode)node.Parent).EntryType == EntryType.Method) { ig.Emit(OpCodes.Ldloca, lb); } else { ig.Emit(OpCodes.Ldloc, lb); } } else if (node.Entry.ReflectionObject is ParameterInfo) { ParameterInfo lb = (ParameterInfo)node.Entry.ReflectionObject; if (lb.ParameterType.IsPrimitive && ((TreeNode)node.Parent).EntryType == EntryType.Method) { ig.Emit(OpCodes.Ldarga, (short)lb.Position); } else { ig.Emit(OpCodes.Ldarg, (short)lb.Position); } } else if (node.Entry.ReflectionObject is UserLocal) { Type t = ((UserLocal)node.Entry.ReflectionObject).LocalType; if (node.Value == null) { // doe niets, array acces hier } else if (t.Equals(typeof(Int32))) { this.LiteralNumber(node); } else if (t.Equals(typeof(Double))) { this.LiteralFloat(node); } else if (t.Equals(typeof(String))) { this.LiteralString(node); } else if (t.Equals(typeof(Char))) { this.LiteralCharacter(node); } else if (t.Equals(typeof(Boolean))) { this.LiteralBoolean(node); } } CheckStack(node, true); } }
/// <summary> /// Changes an array type qualifier to an element type qualifier. /// </summary> /// <returns>The element type qualifier</returns> public Qualifier ToArrayElementQual() { if (IsArray) { Qualifier ret = new Qualifier(this); ret[Count - 1] = ret[Count - 1].Substring(0, ret[Count - 1].Length - 2); return(ret); } else { return(this); } }
public override void CastExpression(TreeNode node, Qualifier qual) { Type dest = (Type)node.Entry.ReflectionObject; Type src = ((TreeNode)node.GetChild(1)).ReturnType; if (src is UserType) { src = (Type)((UserType)src).Entry.ReflectionObject; } if (src.IsValueType && dest == typeof(object)) { ig.Emit(OpCodes.Box, src); } else if (src == typeof(object) && dest.IsValueType) { ig.Emit(OpCodes.Unbox, dest); ig.Emit(OpCodes.Ldobj, dest); } else if (src.IsPrimitive && dest.IsPrimitive) { if (dest == typeof(int) || dest == typeof(char)) { ig.Emit(OpCodes.Conv_I4); } else if (dest == typeof(byte)) { ig.Emit(OpCodes.Conv_I1); } else if (dest == typeof(double)) { ig.Emit(OpCodes.Conv_R8); } } else { ig.Emit(OpCodes.Castclass, dest); } }
/// <summary> /// Transforms a FQUALIFIER tree node into a full qualifier object. /// </summary> /// <param name="fullQualifier">The AST node</param> /// <returns>The full qualifier</returns> public static Qualifier GetFullQualifier(ITree fullQualifier) { Qualifier ids = new Qualifier(); if (fullQualifier == null) { return(ids); } for (int i = 0; i < fullQualifier.ChildCount - 1; i++) { ids.Add(fullQualifier.GetChild(i).Text); } if (fullQualifier.GetChild(fullQualifier.ChildCount - 1).Text.Equals("ARRAY")) { ids[ids.Count - 1] = ids[ids.Count - 1] + "[]"; } else { ids.Add(fullQualifier.GetChild(fullQualifier.ChildCount - 1).Text); } return(ids); }
/// <summary> /// TreeWalker method for a class declaration expression (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="modifiers">The modifiers used on the class</param> /// <param name="qualifier">The full qualifier of the class</param> /// <param name="extendation">The classes that are extended by this class</param> /// <param name="implementation">The classes that are implemented by this class</param> public abstract void Class(TreeNode node, List <string> modifiers, Qualifier qualifier, List <Qualifier> extendation, List <Qualifier> implementation);
/// <summary> /// TreeWalker method for an instanceof expression (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qual">The qualifier to try to cast to</param> public abstract void IsTypeExpression(TreeNode node, Qualifier qual);
/// <summary> /// TreeWalker method for the begin of a for loop expression (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="node2">The node of the local used by the for loop</param> /// <param name="qual">The qualifier of the type used by the for loop</param> /// <param name="p">The identifier of the type used by the for loop</param> public abstract void BeginFor(TreeNode node, TreeNode node2, Qualifier qual, string p);
/// <summary> /// TreeWalker method for a method declaration (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="modifiers">The modifiers used on the method</param> /// <param name="qualifier">The full qualifier of the type of the method</param> /// <param name="identifier">The identifier of the method</param> /// <param name="parameters">The parameters of the method</param> public abstract void Method(TreeNode node, List <string> modifiers, Qualifier qualifier, string identifier, List <Parameter> parameters);
/// <summary> /// TreeWalker method for a constant field declaration (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="modifiers">The modifiers used on the field</param> /// <param name="qualifier">The type of the field</param> /// <param name="identifier">The name of the field</param> public abstract void ConstField(TreeNode node, List <string> modifiers, Qualifier qualifier, string identifier);
/// <summary> /// Now walk the previously defined types and check each extends and implements /// </summary> public void WalkClassExtendation() { CheckerException exc = new CheckerException(); reorderedTypes = new List <TreeNode>(types); for (int i = 0; i < types.Count; i++) { TreeNode n = types[i]; currentType = (UserType)n.Entry.ReflectionObject; searchPath = (List <string>)((TreeNode)n.Parent.Parent).Entry.ReflectionObject; searchPath.Add(currentType.Namespace); Qualifier extends; List <Qualifier> implements; if (n.GetChild(2) != null) { if (n.GetChild(2).Type == VnvdTreeWalker.EXTENDS) { extends = AbstractHelper.GetFullQualifier(n.GetChild(2).GetChild(0)); if (n.GetChild(3) != null && n.GetChild(3).Type == VnvdTreeWalker.IMPLEMENTS) { implements = AbstractHelper.GetImplements(n.GetChild(3)); } else { implements = new List <Qualifier>(); } } else if (n.GetChild(2).Type == VnvdTreeWalker.IMPLEMENTS) { implements = AbstractHelper.GetImplements(n.GetChild(2)); extends = new Qualifier() { "System", "Object" }; } else { extends = new Qualifier() { "System", "Object" }; implements = new List <Qualifier>(); } } else { extends = new Qualifier() { "System", "Object" }; implements = new List <Qualifier>(); } try { IdEntry ext = this.GetTypeIdEntry(extends.ToString()); Type extType = (Type)ext.ReflectionObject; if (currentType.IsInterface && ext.ReflectionObject != typeof(object) && !((Type)ext.ReflectionObject).IsInterface) { throw new CheckerException(n, "An interface can only extend another interface, not a class: " + ((Type)ext.ReflectionObject).FullName); } if (!currentType.IsInterface && !extType.IsClass) { throw new CheckerException(n, "Cannot extend interface or value type " + extType.FullName); } if (extType.IsSubclassOf(currentType)) { throw new CheckerException(n, "Circular extendation detected at " + extType.FullName + " and " + currentType.FullName); } if (extType.IsSealed) { throw new CheckerException(n, "Cannot extend types marked as sealed: " + extType.FullName); } if (currentType.IsInterface && ext.ReflectionObject != typeof(object)) { implements.Add(extends); } else if (!currentType.IsInterface && !currentType.IsEnum) { currentType.SetBaseType(ext); } for (int j = i + 1; j < reorderedTypes.Count; j++) { if (reorderedTypes[j].Entry.ReflectionObject == ext.ReflectionObject) { TreeNode temp = reorderedTypes[j]; reorderedTypes.Remove(temp); reorderedTypes.Insert(i, temp); } } } catch (CheckerException ex) { exc.AddError(n, ex.GetLastError().Second); } try { foreach (var implement in implements) { IdEntry imple = this.GetTypeIdEntry(implement.ToString()); Type t = (Type)imple.ReflectionObject; if (!t.IsInterface) { throw new CheckerException(n, "Cannot implement a class or value type " + t.FullName); } currentType.AddInterface(imple); } } catch (CheckerException ex) { exc.AddError(n, ex.GetLastError().Second); } this.searchPath.Remove(currentType.Namespace); } if (exc.ErrorCount > 0) { throw exc; } }
/// <summary> /// TreeWalker method for the begin of a interface declaration (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="modifiers">The modifiers used on the interface</param> /// <param name="qualifier">The qualifier of the interface</param> /// <param name="extends">The classes extended by the interface</param> public abstract void BeginInterface(TreeNode node, List <string> modifiers, Qualifier qualifier, List <Qualifier> extends);
/// <summary> /// TreeWalker method for the begin of a class declaration (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="modifiers">The modifiers used on the class</param> /// <param name="qualifier">The qualifier of the class</param> /// <param name="extends">The classes extended by this class</param> /// <param name="implements">The interfaces implemented by this class</param> public abstract void BeginClass(TreeNode node, List <string> modifiers, Qualifier qualifier, List <Qualifier> extends, List <Qualifier> implements);
/// <summary> /// TreeWalker method for a variable usage expression (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qual">The full qualifier of the variable used</param> public abstract void VariableUsed(TreeNode node, Qualifier qual);
/// <summary> /// TreeWalker method for an object creation expression (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qualifier">The full qualifier of the class the object is an instance off</param> public abstract void ObjectCreation(TreeNode node, Qualifier qualifier);
/// <summary> /// TreeWalker method for the begin of a namespace declaration (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qualifier">The full qualifier of the namespace</param> public abstract void BeginNamespace(TreeNode node, Qualifier qualifier);
/// <summary> /// Transforms a type qualifier to a Qualifier object. /// </summary> /// <param name="name">The full qualifier</param> /// <returns>The full qualifier</returns> public Qualifier TypeQualifier(Qualifier list) { return(list); }
/// <summary> /// TreeWalker method for an import statement (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qualifier">The qualifier to import</param> public abstract void Import(TreeNode node, Qualifier qualifier);
/// <summary> /// TreeWalker method for a constant declaration (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qual">The full qualifier of the type of the constant</param> /// <param name="p">The identifier of the constant</param> public abstract void ConstantDeclaration(TreeNode node, Qualifier qual, string p);
/// <summary> /// TreeWalker method for a declaration statement (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qualifier">The full qualifier of the type</param> /// <param name="identifier">The identifier of the variable</param> public abstract void DeclarationStatement(TreeNode node, Qualifier qualifier, string identifier);
/// <summary> /// TreeWalker method for an abstract method declaration (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="modifiers">The modifiers used on the abstract method</param> /// <param name="returns">The qualifier of the type returned by the abstract method</param> /// <param name="p">The identifier of the abstract method</param> /// <param name="parameters">The parameters of the abstract method</param> public abstract void AbstractMethod(TreeNode node, List <string> modifiers, Qualifier returns, string p, List <Parameter> parameters);
/// <summary> /// TreeWalker method for a cast as expression (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qual">The qualifier of the type to cast to</param> public abstract void CastAsExpression(TreeNode node, Qualifier qual);
/// <summary> /// TreeWalker method for an interface method declaration (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qualifier">The full qualifier of the type of the method</param> /// <param name="identifier">The identifier of the method</param> /// <param name="parameters">The parameters of the method</param> public abstract void InterfaceMethod(TreeNode node, Qualifier qualifier, string identifier, List <Parameter> parameters);
/// <summary> /// Manually walk the node and define all classes and interfaces found /// </summary> /// <param name="node">The parent node where to start searching for classes and interfaces</param> public void WalkClasses(TreeNode node) { CheckerException exc = new CheckerException(); node.Entry = new IdEntry(); List <String> using_ = new List <String>(); node.Entry.ReflectionObject = using_; // manually traverse the AST so we can first define all classes before references to them are made foreach (TreeNode n in node.Children) { if (n.Type == VnvdTreeWalker.USING) { using_.Add(AbstractHelper.GetFullQualifier(n.GetChild(0)).ToString()); } else if (n.Type == VnvdTreeWalker.NAMESPACE) { Qualifier q = AbstractHelper.GetFullQualifier(n.GetChild(0)); string ns = q.ToString(); foreach (TreeNode n2 in n.Children) { try { if (n2.Type == VnvdTreeWalker.CLASS) { n2.EntryType = EntryType.Class; n2.Entry = new IdEntry(); UserType t = DefineClass(ns, AbstractHelper.GetFullQualifier(n2.GetChild(1)).ToString(), AbstractHelper.GetModifiers(n2.GetChild(0))); n2.Entry.ReflectionObject = t; t.Entry = n2.Entry; if (IsAlreadyDefined(t.Name, t.Namespace)) { throw new CheckerException(n2, "A type with the same name '" + t.FullName + "' already exists"); } userTypes.Add(t); types.Add(n2); } else if (n2.Type == VnvdTreeWalker.INTERFACE) { n2.EntryType = EntryType.Interface; n2.Entry = new IdEntry(); UserType t = DefineInterface(ns, AbstractHelper.GetFullQualifier(n2.GetChild(1)).ToString(), AbstractHelper.GetModifiers(n2.GetChild(0))); n2.Entry.ReflectionObject = t; t.Entry = n2.Entry; if (IsAlreadyDefined(t.Name, t.Namespace)) { throw new CheckerException(n2, "A type with the same name '" + t.FullName + "' already exists"); } userTypes.Add(t); types.Insert(0, n2); } else if (n2.Type == VnvdTreeWalker.ENUM) { n2.EntryType = EntryType.Enum; n2.Entry = new IdEntry(); UserType t = DefineEnum(ns, AbstractHelper.GetFullQualifier(n2.GetChild(1)).ToString(), AbstractHelper.GetModifiers(n2.GetChild(0))); n2.Entry.ReflectionObject = t; t.Entry = n2.Entry; if (IsAlreadyDefined(t.Name, t.Namespace)) { throw new CheckerException(n2, "A type with the same name '" + t.FullName + "' already exists"); } userTypes.Add(t); types.Insert(0, n2); } } catch (CheckerException ex) { exc.AddError(n2, ex.GetLastError().Second); } } } } lib.CustomTypes = userTypes.ToArray(); if (exc.ErrorCount > 0) { throw exc; } }
/// <summary> /// TreeWalker method for the begin of a catch block (see grammar). /// </summary> /// <param name="node">The AST node</param> /// <param name="qual">The qualifier of the type of the local used to store the exception</param> /// <param name="p">The identifier of the local used to store the exception</param> public abstract void EndCatch(TreeNode node, Qualifier qual, string p);