Ejemplo n.º 1
0
        public override void Emit(ILRunner pRunner)
        {
            foreach (var v in Values)
            {
                v.Emit(pRunner);
            }
            if (Values.Count > 1)
            {
                SmallType[] types = new SmallType[Values.Count];
                for (int i = 0; i < Values.Count; i++)
                {
                    types[i] = Values[i].Type;
                }
                var t = SmallType.CreateTupleOf(types).ToSystemType();

                Type[] systemTypes = new Type[types.Length];
                for (int i = 0; i < types.Length; i++)
                {
                    systemTypes[i] = types[i].ToSystemType();
                }
                var c = t.GetConstructor(systemTypes);
                pRunner.Emitter.Emit(OpCodes.Newobj, c);
            }

            pRunner.Emitter.Emit(OpCodes.Ret);
        }
Ejemplo n.º 2
0
        public override void Visit(MethodSyntax pNode)
        {
            //Create any generic type parameters to the function
            Dictionary <string, SmallType> typeArgs = new Dictionary <string, SmallType>();

            foreach (var t in pNode.TypeHints)
            {
                typeArgs.Add(t, SmallType.CreateGenericParameter(t));
            }

            //
            //Create types for method
            //

            //Infer parameter types now that structs have been defined
            foreach (var p in pNode.Parameters)
            {
                var st = SmallType.FromString(p.Namespace, p.Value);
                if (p.TypeParameters.Count > 0)
                {
                    SmallType[] types = new SmallType[p.TypeParameters.Count];
                    for (int i = 0; i < types.Length; i++)
                    {
                        //If the type parameter is one on the method definition, use that type
                        if (typeArgs.ContainsKey(p.TypeParameters[i]))
                        {
                            types[i] = typeArgs[p.TypeParameters[i]];
                        }
                        else
                        {
                            types[i] = SmallType.FromString("", p.TypeParameters[i]);
                        }
                    }

                    if (!p.Type.IsVariant)
                    {
                        st = st.MakeGenericType(types);
                    }
                    else
                    {
                        //vnt types are transformed to the actual type parameter
                        if (p.TypeParameters.Count > 1)
                        {
                            SmallType[] typeParameters = new SmallType[p.TypeParameters.Count];
                            for (int i = 0; i < typeParameters.Length; i++)
                            {
                                typeParameters[i] = SmallType.CreateGenericParameter(p.TypeParameters[i]);
                            }
                            st = SmallType.CreateTupleOf(typeParameters);
                        }
                        else
                        {
                            st = SmallType.CreateGenericParameter(p.TypeParameters[0]);
                        }
                    }
                }
                p.SetType(st);
            }

            foreach (var r in pNode.ReturnValues)
            {
                //If the type parameter is one on the method definition, use that type
                if (typeArgs.ContainsKey(r.Value))
                {
                    r.SetType(SmallType.CreateGenericParameter(r.Value));
                }
                else
                {
                    r.SetType(SmallType.FromString(r.Namespace, r.Value));
                }
            }

            //
            //Create method definition
            //

            //Create parameters
            MethodDefinition.Parameter[] parameters = new MethodDefinition.Parameter[pNode.Parameters.Count];
            for (int i = 0; i < pNode.Parameters.Count; i++)
            {
                parameters[i] = new MethodDefinition.Parameter(pNode.Parameters[i]);
            }

            //Create return types
            SmallType[] returnTypes = new SmallType[pNode.ReturnValues.Count];
            for (int i = 0; i < pNode.ReturnValues.Count; i++)
            {
                returnTypes[i] = pNode.ReturnValues[i].Type;
            }

            var d = MetadataCache.AddMethod(pNode.Name, parameters, returnTypes, typeArgs.Values.ToList());

            if (pNode.Annotations.Count > 0)
            {
                //Process any standard annotations
                //run
                //export
                //external info
                foreach (var a in pNode.Annotations)
                {
                    if (a.Value.Equals("run", StringComparison.OrdinalIgnoreCase))
                    {
                        if (_mainFound)
                        {
                            Compiler.ReportError(CompilerErrorType.DuplicateRun, pNode);
                        }
                        else
                        {
                            d.IsMain = true;
                        }

                        if (pNode.Parameters.Count > 0 || pNode.ReturnValues.Count > 0)
                        {
                            Compiler.ReportError(CompilerErrorType.InvalidRun, pNode);
                        }
                        _mainFound = true;
                    }
                    else if (a.Value.Equals("export", StringComparison.OrdinalIgnoreCase))
                    {
                        d.SetScope(Scope.Public);
                    }
                    else if (pNode.External)
                    {
                        var s = a.Value.Split(';');
                        if (s.Length != 3)
                        {
                            Compiler.ReportError(CompilerErrorType.InvalidExternalAnnotation, pNode);
                        }

                        d.SetExternInfo(s[0], s[1], s[2]);
                    }
                }

                if (d.ExternMethod != null && d.Scope == Scope.Public)
                {
                    Compiler.ReportError(CompilerErrorType.ExportExternal, pNode, pNode.Name);
                }
            }
            pNode.SetDefinition(d);
        }