/// <summary> /// Create an automatic .Equal() method /// </summary> /// <param name="type">Type node</param> private void GenerateAutoComparator(TypeNode type) { var node = new MethodNode("equal", new SignatureNode("bool"), false); // define parameter var parameters = new HashList<ParameterNode>(); var param = new ParameterNode("_obj", new SignatureNode(type.Name), 0); parameters.Add(param.Name, param); // generate series of comparisons foreach(var curr in type.Fields) { // // if(@<name> != _obj.<name>) return false; // node.Body.Statements.Add( Expr.If( Expr.Compare( Expr.IdentifierGet(curr, true), Lexer.LexemType.NotEqual, Expr.IdentifierGet(curr, Expr.IdentifierGet("_obj")) ), Expr.Return( Expr.Bool(true) ) ) ); } // return true node.Body.Statements.Add( Expr.Return( Expr.Bool(true) ) ); node.SetParameters(parameters); node.Owner = type; AddMethod(type, node); }
/// <summary> /// Create an automatic constructor to set all fields /// </summary> /// <param name="type">Type node</param> private void GenerateAutoCtor(TypeNode type) { var node = new MethodNode(".ctor", new SignatureNode("void"), false); var parameters = new HashList<ParameterNode>(); int idx = 0; foreach(var curr in type.Fields) { var param = new ParameterNode("_" + curr, type.Fields[curr].Type, idx); parameters.Add("_" + curr, param); idx++; var assignNode = new IdentifierSetNode(curr, true); assignNode.Expression = new IdentifierGetNode("_" + curr); node.Body.Statements.Add(assignNode); } node.SetParameters(parameters); node.Owner = type; AddMethod(type, node); }
/// <summary> /// Import a method from any assembly into Mirelle registry /// </summary> /// <param name="baseType">Actual type</param> /// <param name="baseName">Method name within actual type</param> /// <param name="owner">Owner type name within Mirelle</param> /// <param name="name">Method name within mirelle</param> /// <param name="type">Type</param> /// <param name="isStatic">Static flag</param> /// <param name="parameters">Parameter list</param> /// <returns></returns> public MethodNode ImportMethod(Type baseType, string baseName, string owner, string name, string type, bool isStatic = false, params string[] parameters) { var ownerType = FindType(owner); if (ownerType == null) throw new CompilerException(String.Format(Resources.errTypeNotFound, owner)); // find method in the base type and import it var types = new Type[parameters.Length]; var idx = 0; foreach (var curr in parameters) { types[idx] = ResolveBasicType(curr); idx++; } MethodReference importedMethod; if(baseName == ".ctor") importedMethod = AssemblyImport(baseType.GetConstructor(types)); else importedMethod = AssemblyImport(baseType.GetMethod(baseName, types)); var typeNode = new SignatureNode(type); ResolveType(typeNode); var method = new MethodNode(name, typeNode, isStatic, true, importedMethod); // parameters var sb = new StringBuilder(name); idx = 0; foreach (var curr in parameters) { // declared as extension method ? // first parameter is the invoker itself, remove it from parameters list if (!importedMethod.HasThis && !isStatic && idx == 0) { idx++; continue; } var signNode = new SignatureNode(curr); sb.Append(" "); sb.Append(curr); var param = new ParameterNode("p" + idx.ToString(), signNode, idx); method.Parameters.Add(param.Name, param); idx++; } method.Signature = sb.ToString(); // check if an identical method hasn't already been declared if (ownerType.Methods.Contains(method.Signature)) throw new CompilerException(String.Format(Resources.errMethodRedefinition, method.Name, owner)); // register method in the owner type AddMethod(ownerType, method); method.Owner = ownerType; return method; }