public void Generate(Generator generator) { generator.AllocateAssembler(); functionPointer = generator.Assembler.Region.BaseLocation; Assembler a = generator.Assembler; int thisidx = a.AddParameter(); // this; int typeidx = a.AddParameter(); // type generator.Symbols.Source(a.Region.CurrentLocation, definition); a.StartFunction(); //TODO: a binary searchtree would be fun foreach (KeyValuePair <int, DefinitionTypeReference> titrkvp in definition.GetSupportedTypesMap()) { a.RetrieveVariable(typeidx); a.PushValue(); a.SetOnlyValue(titrkvp.Value.Id); a.IntegerEquals(); JumpToken noMatch = a.CreateJumpToken(); a.JumpIfFalse(noMatch); a.RetrieveVariable(thisidx); a.SetTypePart(definition.RuntimeStruct); if (titrkvp.Key != -1) { a.TypeConversionNotNull(titrkvp.Key); } a.StopFunction(); a.SetDestination(noMatch); } a.Empty(); a.StopFunction(); generator.Symbols.Source(a.Region.CurrentLocation, definition, SourceMark.EndSequence); generator.Symbols.WriteData(a.Region.BaseLocation, a.Region.Length, "dcf:" + definition.Name.Data); }
void GenerateLambda(Generator generator) { Assembler oldAssembler = generator.Assembler; offset = oldAssembler.SlotCount(); generator.AllocateAssembler(); Assembler inner = generator.Assembler; generator.Assembler = new LambdaAssembler(this, generator.Assembler); generator.Resolver.EnterContextParentReadOnly(); closureSlot = offset; localSlots.Add(closureSlot, inner.AddParameter()); // closure, or nothing if no fields Parameters p = new Parameters(); for (int i = 0; i < parameters.Count; ++i) { int s = inner.AddParameter(); int ex = offset + localSlots.Count; localSlots.Add(ex, s); generator.Resolver.AddVariable(parameters[i], parameterTypes[i], ex, true); generator.Resolver.AssignSlot(ex); generator.Resolver.RetrieveSlot(this, ex, false); // todo: make warning: treat function arguments as used ParameterMetadata pm = p.AddParameter(parameters[i], parameterTypes[i], parameters[i]); pm.Bind(ex); } generator.Resolver.SetContextParameters(p); statement.Prepare(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.StartFunction(); JumpToken returnToken = generator.Assembler.CreateJumpToken(); generator.Resolver.RegisterGoto("@return", returnToken); JumpToken recurToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(recurToken); generator.Resolver.RegisterGoto("@recur", recurToken); statement.Generate(generator, returnType); generator.Assembler.SetDestination(returnToken); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "lambda:"); functionPointer = generator.Assembler.Region.BaseLocation; generator.Resolver.LeaveContext(); generator.Assembler = oldAssembler; }