Beispiel #1
0
 public override void Generate(Generator generator)
 {
     if (getStatement != null)
     {
         generator.Resolver.EnterContext();
         generator.Resolver.SetContextParameters(getParameters);
         generator.Resolver.CurrentFieldName = name.Data + ":get";
         generator.AllocateAssembler();
         getParameters.Generate(generator);
         ParameterMetadata thisParam = getParameters.Find("this");
         generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);
         getStatement.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);
         getStatement.Generate(generator, type);
         if (!getStatement.Returns())
         {
             throw new CompilerException(getStatement, string.Format(Resource.Culture, Resource.NotAllCodePathsReturnAValue));
         }
         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, "getter:" + ParentDefinition.Name.Data + "." + name.Data);
         getStatementPointer = generator.Assembler.Region.BaseLocation;
         generator.Resolver.LeaveContext();
     }
     if (setStatement != null)
     {
         generator.Resolver.EnterContext();
         generator.Resolver.SetContextParameters(setParameters);
         generator.Resolver.CurrentFieldName = name.Data + ":set";
         generator.AllocateAssembler();
         setParameters.Generate(generator);
         ParameterMetadata thisParam = setParameters.Find("this");
         generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);
         setStatement.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);
         setStatement.Generate(generator, null);
         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, "setter:" + ParentDefinition.Name.Data + "." + name.Data);
         setStatementPointer = generator.Assembler.Region.BaseLocation;
         generator.Resolver.LeaveContext();
     }
 }
Beispiel #2
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);
        }
Beispiel #3
0
        public override void Generate(Generator generator)
        {
            rootConstructorNode.GenerateFunction(generator);
            generator.Resolver.EnterContext();
            generator.Resolver.CurrentFieldName = ConstructorName();
            generator.AllocateAssembler();
            parametersMetadata.Generate(generator);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.StartFunction();
            generator.Assembler.CallAllocator(generator.Allocator, ParentDefinition.InstanceSize, ParentDefinition.RuntimeStruct);
            int thisslot = generator.Resolver.ResolveSlotOffset(new Identifier(this, "this"));

            generator.Resolver.IncompleteSlot(thisslot, false);
            generator.Assembler.StoreVariable(thisslot);

            generator.Assembler.SetTypePart(rootConstructorNode.RuntimeStruct);
            generator.Assembler.PushValue();
            foreach (ParameterMetadata p in parametersMetadata.ParameterList)
            {
                generator.Assembler.RetrieveVariable(p.Slot);
                generator.Assembler.PushValue();
            }
            Placeholder retSite = generator.Assembler.CallFromStack(parametersMetadata.ParameterList.Count);

            generator.AddCallTraceEntry(retSite, this, generator.Resolver.CurrentDefinition.Name.DataModifierLess, generator.Resolver.CurrentFieldName);

            generator.Resolver.LeaveContext();
            generator.Assembler.RetrieveVariable(thisslot);

            generator.Assembler.StopFunction();
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence);
            generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "constructor:" + ParentDefinition.TypeReference.TypeName.Data + ".constructor");
            functionPointer = generator.Assembler.Region.BaseLocation;

            castFunction = new CallableCastFunction(this);
            castFunction.Generate(generator);
            if (ParentDefinition.GarbageCollectable)
            {
                runtimeStruct.WriteNumber(1);
            }
            else
            {
                runtimeStruct.WriteNumber(0);
            }
            runtimeStruct.WritePlaceholder(castFunction.FunctionPointer);
            runtimeStruct.WriteNumber(0);
            runtimeStruct.WriteNumber(0);
            runtimeStruct.WritePlaceholder(functionPointer);
            runtimeStruct.WritePlaceholder(ParentDefinition.RuntimeStruct);
            generator.Symbols.WriteData(runtimeStruct.BaseLocation, runtimeStruct.Length, "ms:" + ParentDefinition.TypeReference.TypeName.Data + ".constructor");
        }
Beispiel #4
0
        public void Generate(Generator generator)
        {
            generator.AllocateAssembler();
            functionPointer = generator.Assembler.Region.BaseLocation;
            Assembler a = generator.Assembler;

            generator.Symbols.Source(a.Region.BaseLocation, location);
            a.StartFunction();
            //TODO: implementation ?
            a.Empty();
            // the current type supports nothing, not even its own type...
            a.StopFunction();
            generator.Symbols.Source(a.Region.CurrentLocation, location, SourceMark.EndSequence);
            generator.Symbols.WriteData(a.Region.BaseLocation, a.Region.Length, "ccf");
        }
Beispiel #5
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;
        }
Beispiel #6
0
            public void GenerateFunction(Generator generator)
            {
                Require.False(generated);
                generated = true;
                if (redirect != null)
                {
                    redirect.node.GenerateFunction(generator);
                }
                else
                {
                    foreach (ConstructorNodeInvocation i in inherit)
                    {
                        i.node.GenerateFunction(generator);
                    }
                }

                generator.Resolver.EnterContext();
                generator.Resolver.EnterFakeContext(definition);

                StringBuilder sb = new StringBuilder();

                //sb.Append(parentDefinition.TypeReference.TypeName.Data);
                sb.Append("this");
                //sb.Append(definition.TypeReference.TypeName.Data);
                parameters.PrettyPrint(sb);
                string name = sb.ToString();

                generator.Resolver.CurrentFieldName = name;

                generator.AllocateAssembler();
                parameters.Generate(generator);

                ParameterMetadata thisParam = parameters.Find("this");

                generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);

                int thisslot = generator.Resolver.ResolveSlotOffset(new Identifier(location, "this"));

                generator.Resolver.IncompleteSlot(thisslot, false);

                statement.Prepare(generator);
                if (redirect == null)
                {
                    definition.PrepareInitializer(generator);
                }

                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, location);
                generator.Assembler.StartFunction();
                if (redirect != null)
                {
                    redirect.Call(generator);
                }
                else
                {
                    foreach (ConstructorNodeInvocation i in inherit)
                    {
                        i.Call(generator);
                    }
                    definition.GenerateInitializer(generator);
                }
                statement.Generate(generator, null);

                int slot = generator.Resolver.ResolveSlotOffset(new Identifier(location, "this"));

                generator.Resolver.RetrieveSlot(location, slot, false);

                foreach (Field field in definition.Fields)
                {
                    if (generator.Resolver.IsFieldAssigned(field))
                    {
                        assignedFields.Add(field);
                    }
                }

                generator.Resolver.LeaveFakeContext();
                generator.Resolver.LeaveContext();
                generator.Assembler.StopFunction();
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, location, SourceMark.EndSequence);
                generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "constructor:" + parentDefinition.TypeReference.TypeName.Data + "." + name);
                functionPointer = generator.Assembler.Region.BaseLocation;
            }
Beispiel #7
0
        public Placeholder Generate(Generator generator, Identifier primaryContextName, Identifier methodName, TypeReference returnType, Parameters parametersMetadata)
        {
            if (string.IsNullOrEmpty(xml))
            {
                generator.AllocateAssembler();
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName);
                generator.Assembler.CallNative(generator.Importer.FetchImport(primaryContextName.Namespace, primaryContextName.Data, methodName.Data), 0, false, true);
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName, SourceMark.EndSequence);
                generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "extern:" + primaryContextName.Data + "." + methodName.Data);
                return(generator.Assembler.Region.BaseLocation);
            }
            else
            {
                generator.AllocateAssembler();
                parametersMetadata.Generate(generator);
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName);
                generator.Assembler.StartFunction();

                if (parametersMetadata.ParameterList.Count != parameters.Count)
                {
                    throw new ExternException(this, "Parameter count mismatch.");
                }

                string word = "int32";
                if (Program.Linux_x86_64 || Program.Windows_x86_64)
                {
                    word = "int64";
                }

                generator.Assembler.SetupNativeReturnSpace();

                for (int i = parameters.Count - 1; i >= 0; --i)
                {
                    string type = parameters[i];
                    if (type == word)
                    {
                        generator.Assembler.RetrieveVariable(parametersMetadata.ParameterList[i].Slot);
                        generator.Assembler.PushValuePart();
                    }
                    else
                    {
                        throw new ExternException(this, "Unsupported type.");
                    }
                }

                if (string.IsNullOrEmpty(library))
                {
                    throw new ExternException(this, "No library specified");
                }
                if (string.IsNullOrEmpty(entrypoint))
                {
                    throw new ExternException(this, "No entrypoint specified");
                }
                generator.Assembler.CallNative(generator.Importer.FetchImportAsPointer(library, entrypoint), parameters.Count, false, false);

                if (returns == word)
                {
                    generator.Assembler.SetTypePart(intType.RuntimeStruct);
                    returnType.GenerateConversion(this, generator, intType);
                }
                else
                if (returns == "void")
                {
                    voidType.GenerateConversion(this, generator, returnType);
                    generator.Assembler.Empty();
                }
                else
                {
                    throw new ExternException(this, "Unsupported return type.");
                }

                generator.Assembler.StopFunction();
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName, SourceMark.EndSequence);
                generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "extern:" + primaryContextName.Data + "." + methodName.Data);
                return(generator.Assembler.Region.BaseLocation);
            }
        }
Beispiel #8
0
        public override void Generate(Generator generator)
        {
            Require.False(generated);
            Require.True(prepared);
            generated    = true;
            castFunction = new CallableCastFunction(this);
            castFunction.Generate(generator);

            generator.Resolver.EnterContext();
            generator.Resolver.SetContextParameters(parametersMetadata);
            generator.Resolver.CurrentFieldName = name.Data + "()";

            if (modifiers.Extern)
            {
                string className = ParentDefinition.Name.PrimaryName.Data;
                if (className == "pluk.base.Array")
                {
                    string s = ParentDefinition.Name.Data;
                    if (s == "pluk.base.Array<pluk.base.Int>")
                    {
                        className = "pluk.base.Array..pluk.base.Int";
                    }
                    else if (s == "pluk.base.Array<pluk.base.Bool>")
                    {
                        className = "pluk.base.Array..pluk.base.Bool";
                    }
                    else if (s == "pluk.base.Array<pluk.base.Byte>")
                    {
                        className = "pluk.base.Array..pluk.base.Byte";
                    }
                }
                string fieldName = name.Data;
                if (modifiers.ExternMetadata == null)
                {
                    string namespaceName = ParentDefinition.Name.PrimaryName.Namespace;
                    generator.AllocateAssembler();
                    parametersMetadata.Generate(generator);
                    ParameterMetadata thisParam = parametersMetadata.Find("this");
                    generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);

                    generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
                    generator.Assembler.StartFunction();
                    generator.Assembler.SetupNativeReturnSpace();
                    int count = parametersMetadata.NativeArgumentCount();
                    generator.Assembler.SetupNativeStackFrameArgument(count);
                    parametersMetadata.WriteNative(generator.Assembler);
                    generator.Assembler.CallNative(generator.Importer.FetchImport(namespaceName, className, fieldName), count * 2, true, false);
                    generator.Assembler.StopFunction();
                    generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence);
                    generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "method-externed:" + ParentDefinition.Name.Data + "." + name.Data);
                    functionPointer = generator.Assembler.Region.BaseLocation;
                }
                else
                {
                    functionPointer = modifiers.ExternMetadata.Generate(generator, ParentDefinition.Name.PrimaryName, name, returnType, parametersMetadata);
                }
            }
            else
            {
                generator.AllocateAssembler();
                parametersMetadata.Generate(generator);
                ParameterMetadata thisParam = parametersMetadata.Find("this");
                if (modifiers.Static)
                {
                    Require.True(thisParam.TypeReference.IsStatic);
                }
                generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);
                statementMetadata.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);
                statementMetadata.Generate(generator, returnType);
                if (modifiers.Abstract)
                {
                    generator.Assembler.Empty();
                    generator.Assembler.CrashIfNull();
                }
                else
                if ((returnType != null) && (!returnType.IsVoid) && (!statementMetadata.Returns()))
                {
                    throw new CompilerException(statementMetadata, string.Format(Resource.Culture, Resource.NotAllCodePathsReturnAValue));
                }
                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, "method:" + ParentDefinition.Name.Data + "." + name.Data);
                functionPointer = generator.Assembler.Region.BaseLocation;
            }

            generator.Resolver.LeaveContext();
        }