Пример #1
0
 /// <summary>
 /// Add a method to the type
 /// </summary>
 /// <param name="type">Type node</param>
 /// <param name="method">Method node</param>
 public void AddMethod(TypeNode type, MethodNode method)
 {
     if (type.Methods.Contains(method.Name))
     type.Methods[method.Name].Add(method);
       else
     type.Methods.Add(method.Name, new List<MethodNode> { method });
 }
Пример #2
0
        /// <summary>
        /// Create an automatic ToString() method
        /// </summary>
        /// <param name="type">Type node</param>
        private void GenerateToString(TypeNode type)
        {
            var node = new MethodNode("ToString", new SignatureNode("string"), false);
              node.Virtual = true;

              node.Body.Statements.Add(Expr.Return(Expr.String(type.Name)));

              node.Owner = type;
              AddMethod(type, node);
        }
Пример #3
0
        /// <summary>
        /// Create a to_a static method for the enum.
        /// </summary>
        /// <param name="owner">Owner type</param>
        private void GenerateEnumToArray(TypeNode owner)
        {
            // exclude .ctor, to_s, to_a and ToString
              var count = owner.Methods.Count - 4;
              var to_a = FindMethod(owner.Name, "to_a");

              // return arr
              to_a.Body = Expr.CodeBlock(

            // var arr = new [null as <enum>] * count
            Expr.Var(
              "names",
              Expr.Multiply(
            Expr.Array(
              Expr.String()
            ),
            Expr.Int(count)
              )
            ),

            // previous content
            to_a.Body,

            Expr.Var(
              "arr",
              Expr.Multiply(
            Expr.Array(
              Expr.As(
                Expr.Null(),
                owner.Name
              )
            ),
            Expr.Int(count)
              )
            ),

            // for idx in 0..(count-1) do
            Expr.For(
              "idx",
              Expr.Range(
            Expr.Int(0),
            Expr.Int(count-1)
              ),
              // arr[idx] = new <enum> idx, names[idx]
              Expr.ArraySet(
            Expr.IdentifierGet("arr"),
            Expr.IdentifierGet("idx"),
            Expr.New(
              owner.Name,
              Expr.IdentifierGet("idx"),
              Expr.ArrayGet(
                Expr.IdentifierGet("names"),
                Expr.IdentifierGet("idx")
              )
            )
              )
            ),

            // return arr
            Expr.Return(
              Expr.IdentifierGet("arr")
            )
              );
        }
Пример #4
0
        /// <summary>
        /// Create a default constructor without parameters
        /// </summary>
        /// <param name="type">Type node</param>
        private void GenerateDefaultCtor(TypeNode type)
        {
            var node = new MethodNode(".ctor", new SignatureNode("void"), false);
              node.Body.Statements.Add(Expr.Return());

              node.SetParameters();
              node.Owner = type;
              AddMethod(type, node);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
 /// <summary>
 /// Create type instance constructor
 /// </summary>
 /// <param name="owner">Owner type node</param>
 /// <param name="parameters">List of parameters</param>
 /// <returns></returns>
 public MethodNode CreateCtor(TypeNode owner, HashList<ParameterNode> parameters = null, bool prepare = false)
 {
     return CreateMethod(owner, ".ctor", new SignatureNode("void"), parameters, false, prepare);
 }
Пример #8
0
        /// <summary>
        /// Create a type node
        /// </summary>
        /// <param name="name">Type name</param>
        /// <param name="parent">Parent name</param>
        /// <returns></returns>
        public TypeNode CreateType(string name, string parent)
        {
            // check if type already exists
              if (RootNode.Types.Contains(name))
            throw new CompilerException(String.Format(Resources.errTypeRedefinition, name));

              // check if type's parent does not exist
              if (!RootNode.Types.Contains(parent))
            throw new CompilerException(String.Format(Resources.errTypeParentNotFound, name, parent));

              // check if the parent type has a default constructor
              try
              {
            FindMethod(parent, ".ctor");
            throw new CompilerException(String.Format(Resources.errTypeParentDefaultCtor, parent));
              }
              catch { }

              // add type to the assembly and Mirelle registry
              var attribs = TypeAttributes.AnsiClass | TypeAttributes.Public | TypeAttributes.AutoClass;
              var nativeType = new TypeDefinition("MirelleCompiled", name, attribs, RootNode.Types[parent].Type);
              Assembly.MainModule.Types.Add(nativeType);
              var type = new TypeNode(name, parent, false, nativeType);
              RootNode.Types.Add(name, type);
              return type;
        }
Пример #9
0
        /// <summary>
        /// Create a type node
        /// </summary>
        /// <param name="name">Type name</param>
        /// <returns></returns>
        public TypeNode CreateType(string name)
        {
            // check if type already exists
              if (RootNode.Types.Contains(name))
            throw new CompilerException(String.Format(Resources.errTypeRedefinition, name));

              // add type to the assembly
              var attribs = TypeAttributes.AnsiClass | TypeAttributes.Public | TypeAttributes.AutoClass;
              var nativeType = new TypeDefinition("MirelleCompiled", name, attribs, Assembly.MainModule.TypeSystem.Object);
              nativeType.Interfaces.Add(MirelleTypeInterface);
              Assembly.MainModule.Types.Add(nativeType);

              var type = new TypeNode(name, "", false, nativeType);
              RootNode.Types.Add(name, type);
              return type;
        }
Пример #10
0
 /// <summary>
 /// Create type static constructor
 /// </summary>
 /// <param name="owner">Owner type node</param>
 /// <returns></returns>
 public MethodNode CreateStaticCtor(TypeNode owner, bool prepare = false)
 {
     return CreateMethod(owner, ".cctor", new SignatureNode("void"), null, true, prepare);
 }
Пример #11
0
        /// <summary>
        /// Create a method in a type
        /// </summary>
        /// <param name="owner">Owner type node</param>
        /// <param name="name">Method name</param>
        /// <param name="type">Method return value type signature</param>
        /// <param name="parameters">Method parameters list</param>
        /// <param name="isStatic">Static flag</param>
        /// <returns></returns>
        public MethodNode CreateMethod(TypeNode owner, string name, SignatureNode type, HashList<ParameterNode> parameters = null, bool isStatic = false, bool prepare = false)
        {
            // cannot add methods to built-in types
              if (owner.BuiltIn)
            throw new CompilerException(String.Format(Resources.errExtendBuiltInType, owner.Name));

              // create method in assembly and in Mirelle Registry
              var method = new MethodNode(name, type, isStatic);

              method.SetParameters(parameters);

              // check if an identical method hasn't already been declared
              if (owner.Methods.Contains(method.Name))
              {
            if(owner.Methods[method.Name].Exists(curr => curr.Signature == method.Signature))
              throw new CompilerException(String.Format(Resources.errMethodRedefinition, method.Name, owner.Name));
              }

              // register method in the parent type
              AddMethod(owner, method);
              method.Owner = owner;

              if (prepare)
            PrepareMethod(method);

              return method;
        }
Пример #12
0
 /// <summary>
 /// Create field initializer
 /// </summary>
 /// <param name="parent">Owner type node</param>
 /// <returns></returns>
 public MethodNode CreateInitializer(TypeNode owner, bool prepare = false)
 {
     return CreateMethod(owner, ".init", new SignatureNode("void"), null, false, prepare);
 }
Пример #13
0
        /// <summary>
        /// Create a field in a type
        /// </summary>
        /// <param name="owner">Owner type node</param>
        /// <param name="name">Field name</param>
        /// <param name="type">Field type signature</param>
        /// <param name="isStatic">Static flag</param>
        /// <returns></returns>
        public FieldNode CreateField(TypeNode owner, string name, SignatureNode type, bool isStatic = false)
        {
            // cut the atmark
              if(name[0] == '@')
            name = name.SafeSubstring(1, name.Length - 1);

              // cannot add fields to built-in types
              if (owner.BuiltIn)
            throw new CompilerException(String.Format(Resources.errExtendBuiltInType, owner.Name));

              // check if such a field has already been registered
              if (owner.Fields.Contains(name))
            throw new CompilerException(String.Format(Resources.errFieldRedefinition, name, owner.Name));

              // create field in Mirelle registry
              var field = new FieldNode(name, type, isStatic);
              owner.Fields.Add(name, field);
              field.Owner = owner;
              return field;
        }
Пример #14
0
        /// <summary>
        /// Create a new value in the enumerable type
        /// </summary>
        /// <param name="owner">Owner type</param>
        /// <param name="name">Value name</param>
        public void CreateEnumValue(TypeNode owner, string name)
        {
            // get the identifier
              // .ctor and to_s  are not counted
              // while to_a will be added later
              var value = owner.Methods.Count - 3;

              // check for redefinition
              if(owner.Methods.Contains(name))
            throw new CompilerException(String.Format(Resources.errEnumRedefinition, name, owner.Name));

              // create the method
              var method = CreateMethod(owner, name, new SignatureNode(owner.Name), null, true);

              // create a new instance with a separate identifier
              method.Body = Expr.CodeBlock(
            Expr.Return(
              Expr.New(
            owner.Name,
            Expr.Int(value),
            Expr.String(name)
              )
            )
              );

              // save corresponding info to to_a
              var to_a = FindMethod(owner.Name, "to_a");
              to_a.Body.Statements.Add(
            Expr.ArraySet(
              Expr.IdentifierGet("names"),
              Expr.Int(value),
              Expr.String(name)
            )
              );
        }
Пример #15
0
        /// <summary>
        /// Import a type from any assembly into Mirelle Registry
        /// </summary>
        /// <param name="name">Type name</param>
        /// <param name="actualType">Type reference</param>
        /// <param name="parent">Parent type name (must be already imported)</param>
        /// <returns></returns>
        public TypeNode ImportType(Type actualType, string name, string parent = "")
        {
            // type has already been defined?
              if (RootNode.Types.Contains(name))
            throw new CompilerException(String.Format(Resources.errTypeRedefinition, name));

              FindType(parent);

              // add type to the assembly and Mirelle registry
              var importedType = AssemblyImport(actualType);
              var type = new TypeNode(name, parent, true, importedType);
              RootNode.Types.Add(name, type);
              return type;
        }