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); } } }
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); }
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); }
public IdentifierSyntax(string pValue) : base(0) { Value = pValue; _type = SmallType.FromString("", pValue); TypeParameters = new List <string>(); }
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); }