예제 #1
0
        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);
        }
예제 #2
0
        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;
        }