Example #1
0
        public override void Visit(StructSyntax pNode)
        {
            var s = SmallType.FromString("", pNode.Prefix);

            //Determine types of all fields
            foreach (var f in pNode.Fields)
            {
                if (s.FieldExists(f.Value))
                {
                    Compiler.ReportError(CompilerErrorType.StructDuplicateMember, pNode, f.Value, pNode.Name);
                }
                else
                {
                    var fld = SmallType.FromString(f.Namespace, f.Value);
                    s.AddField(f.Value, f.TypeParameters, fld);
                }
            }

            SmallType.RegisterType(s, null);

            //Process standard annotations
            //export
            foreach (var a in pNode.Annotations)
            {
                if (a.Value.Equals("export", StringComparison.OrdinalIgnoreCase))
                {
                    s.Exported = true;
                }
            }
            pNode.SetType(s);
        }
        public override void Emit(ILRunner pRunner)
        {
            MethodDefinition def = MetadataCache.GetMethod(this);

            foreach (var a in Arguments)
            {
                a.Emit(pRunner);
            }

            if (def.Name == "ToString")
            {
                Type[] types = new Type[Arguments.Count];
                for (int i = 0; i < Arguments.Count; i++)
                {
                    types[i] = Arguments[i].Type.ToSystemType();
                }
                var m = InstanceType.GetMethod(Value, types);
                pRunner.Emitter.Emit(OpCodes.Callvirt, m);
            }
            else
            {
                if (TypeParameters.Count == 0)
                {
                    pRunner.Emitter.Emit(OpCodes.Call, def.CallSite);
                }
                else
                {
                    Type[] types = new Type[TypeParameters.Count];
                    for (int i = 0; i < TypeParameters.Count; i++)
                    {
                        types[i] = SmallType.FromString("", TypeParameters[i]).ToSystemType();
                        if (types[i] == null)
                        {
                            var t = pRunner.CurrentMethod.TypeHints;
                            for (int j = 0; j < t.Count; j++)
                            {
                                if (TypeParameters[i].Equals(t[j].Name, StringComparison.OrdinalIgnoreCase))
                                {
                                    types[i] = t[j].ToSystemType();
                                }
                            }
                        }
                    }
                    var cs = def.CallSite.MakeGenericMethod(types);
                    pRunner.Emitter.Emit(OpCodes.Call, cs);
                }
            }

            if (def.ReturnTypes.Length > 0)
            {
                //TODO Should move to some sort of visitor? This will fail eventually if I allow struct functions
                if (Parent.GetType() == typeof(BlockSyntax) || !string.IsNullOrEmpty(Namespace) && Parent.Parent.GetType() == typeof(BlockSyntax))
                {
                    pRunner.Emitter.Emit(OpCodes.Pop);
                }
            }
        }
Example #3
0
        public override void Visit(CastSyntax pNode)
        {
            //Infer parameter types now that structs have been defined
            pNode.Parameter.SetType(SmallType.FromString(pNode.Parameter.Namespace, pNode.Parameter.Value));
            pNode.ReturnValue.SetType(SmallType.FromString(pNode.ReturnValue.Namespace, pNode.ReturnValue.Value));

            var d = MetadataCache.AddCast(pNode.Parameter.Type, pNode.Parameter.Value, pNode.ReturnValue.Type);

            d.SetScope(Scope.Public);
            pNode.SetDefinition(d);
        }
Example #4
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);
        }
Example #5
0
 public IdentifierSyntax(string pValue) : base(0)
 {
     Value          = pValue;
     _type          = SmallType.FromString("", pValue);
     TypeParameters = new List <string>();
 }
Example #6
0
        public override SyntaxNode Visit(IdentifierSyntax pNode)
        {
            var m = GetValue <MemberAccessContext>("MemberContext", null);

            if (m != null && MetadataCache.ImportedNamespaces().Contains(pNode.Value))
            {
                m.Namespace = pNode.Value;
                return(SyntaxFactory.NamespaceIdentifier(pNode.Value));
            }

            if (m == null || m.Member == null)
            {
                if (GetValue("InDeclaration", false))
                {
                    if (MetadataCache.LocalExistsInThisScope(pNode.Value))
                    {
                        Compiler.ReportError(CompilerErrorType.DuplicateLocal, pNode.Parent, pNode.Value);
                    }
                    else
                    {
                        var space = m == null ? "" : m.Namespace;
                        var t     = SmallType.FromString(space, pNode.Value);
                        if (pNode.TypeParameters.Count > 0)
                        {
                            SmallType[] typeArgs = new SmallType[pNode.TypeParameters.Count];
                            for (int i = 0; i < typeArgs.Length; i++)
                            {
                                typeArgs[i] = SmallType.FromString("", pNode.TypeParameters[i]);
                            }
                            t = t.MakeGenericType(typeArgs);
                        }

                        pNode.Local = MetadataCache.DefineLocal(pNode, t);
                    }
                }
                else
                {
                    var t = GetValue <SmallType>("StructType", null);
                    if (t != null)
                    {
                        var field = t.GetField(pNode.Value);
                        if (field == null)
                        {
                            Compiler.ReportError(CompilerErrorType.StructInvalidMember, pNode, t.Name, pNode.Value);
                        }
                        pNode.Local = MetadataCache.DefineField(pNode, field.Type, t);
                    }
                    else
                    {
                        if (!MetadataCache.LocalExists(pNode.Value))
                        {
                            Compiler.ReportError(CompilerErrorType.LocalNotDefined, pNode.Parent, pNode.Value);
                        }
                        else
                        {
                            pNode.Local = MetadataCache.GetLocal(pNode.Value);
                        }
                    }
                }
                if (m != null)
                {
                    m.Member = pNode.Local;
                }

                if (!pNode.Type.IsTupleType && pNode.Type.IsValueType && GetValue("LoadObject", false))
                {
                    pNode.LoadAddress = true;
                }

                return(base.Visit(pNode));
            }

            var mi = SyntaxFactory.MemberIdentifier(m.Member, pNode.Value);

            if (m.Member.Type != SmallType.Undefined)
            {
                if (!m.Member.Type.FieldExists(pNode.Value))
                {
                    Compiler.ReportError(CompilerErrorType.StructInvalidMember, pNode.Parent, m.Member.Value, pNode.Value);
                }
                else
                {
                    var f = m.Member.Type.GetField(pNode.Value);
                    mi.Local = LocalDefinition.Create(mi, pNode.Value, f.Type);
                    m.Member = mi.Local;
                }
            }

            if (!mi.Type.IsTupleType && mi.Type.IsValueType && !GetValue("LoadObject", false))
            {
                mi.LoadAddress = true;
            }

            return(mi);
        }