Exemplo n.º 1
0
 public override void GenerateConversion(ILocation location, Generator generator, TypeReference value)
 {
     if (value is NullableTypeReference)
     {
         parent.GenerateConversion(location, generator, ((NullableTypeReference)value).Parent);
     }
     else
     {
         if (value.TypeName.Data != "void")
         {
             parent.GenerateConversion(location, generator, value);
         }
     }
 }
Exemplo n.º 2
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            condition.Generate(generator); // boolean
            boolType.GenerateConversion(this, generator, condition.TypeReference);
            JumpToken elseToken = generator.Assembler.CreateJumpToken();

            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.JumpIfFalse(elseToken);
            left.Generate(generator);
            resultType.GenerateConversion(this, generator, left.TypeReference);
            JumpToken skipElseToken = generator.Assembler.CreateJumpToken();

            generator.Assembler.Jump(skipElseToken);
            generator.Assembler.SetDestination(elseToken);
            right.Generate(generator);
            resultType.GenerateConversion(this, generator, right.TypeReference);
            generator.Assembler.SetDestination(skipElseToken);
        }
Exemplo n.º 3
0
 public override void Generate(Generator generator, TypeReference returnType)
 {
     base.Generate(generator, returnType);
     if (returnType == null)
     {
         throw new CompilerException(this, string.Format(Resource.Culture, Resource.ReturnStatementNotAllowed));
     }
     expression.Prepare(generator, returnType);
     expression.Generate(generator);
     returnType.GenerateConversion(this, generator, expression.TypeReference);
     DoReturn(this, generator);
 }
Exemplo n.º 4
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            Parameters scopeParameters = generator.Resolver.CurrentContextParameters();

            Require.Assigned(scopeParameters);
            if (scopeParameters.ParameterList.Count != this.parameters.Count)
            {
                throw new CompilerException(this, string.Format(Resource.Culture,
                                                                Resource.FunctionCallParameterCountMismatch, ParameterListString(scopeParameters.ParameterList), this.parameters.Count));
            }

            int i = 0;

            foreach (Expression parameter in this.parameters)
            {
                TypeReference tr = scopeParameters.ParameterList[i].TypeReference;
                parameter.Prepare(generator, tr);
                i++;
            }
            i = 0;
            foreach (Expression parameter in this.parameters)
            {
                TypeReference tr = scopeParameters.ParameterList[i].TypeReference;
                parameter.Generate(generator);
                tr.GenerateConversion(this, generator, parameter.TypeReference);
                i++;
                generator.Assembler.PushValue();
            }
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            //store in local slots
            List <ParameterMetadata> p = new List <ParameterMetadata>(scopeParameters.ParameterList);

            p.Reverse();
            foreach (ParameterMetadata parameter in p)
            {
                generator.Assembler.PopValue();
                generator.Assembler.StoreVariable(parameter.Slot);
            }

            bool      tryContext;
            JumpToken gotoToken = generator.Resolver.FindGoto("@recur", out tryContext);

            if ((gotoToken == null) || tryContext)
            {
                throw new CompilerException(this, string.Format(Resource.Culture, Resource.UnsupportedJumpOutOfTry));
            }
            generator.Assembler.Jump(gotoToken);
        }
Exemplo n.º 5
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            parent.Generate(generator);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            TypeReference ptr = parent.TypeReference;
            TypeReference str = returnType;

            if (str.SupportsImplicit(ptr))
            {
                returnType.GenerateConversion(this, generator, parent.TypeReference);
            }
            else
            {
                JumpToken jtNull = null;
                jtNull = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfUnassigned(jtNull);
                generator.Assembler.TypeConversionDynamicNotNull(resolvedType.Id);
                generator.Assembler.SetDestination(jtNull);
            }
        }
Exemplo n.º 6
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            left.Generate(generator);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);

            TypeReference leftType = left.TypeReference;

            if (call == null)
            {
                JumpToken skip = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfTrue(skip);
                right.Generate(generator);
                leftType.GenerateConversion(this, generator, right.TypeReference);
                generator.Assembler.SetDestination(skip);
            }
            else
            {
                call.Generate(generator);
            }
        }
Exemplo n.º 7
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            expression.Prepare(generator, null); // boolean
            expression.Generate(generator);      // boolean
            boolType.GenerateConversion(this, generator, expression.TypeReference);
            JumpToken elseToken = generator.Assembler.CreateJumpToken();

            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.JumpIfFalse(elseToken);
            generator.Resolver.EnterContext();
            if (statement.IsEmptyBlock())
            {
                throw new CompilerException(statement, string.Format(Resource.Culture, Resource.IfBranchIsEmpty));
            }
            statement.Generate(generator, returnType);
            Resolver.Context trueContext = generator.Resolver.LeaveContextAcquire();
            if (elseStatement != null)
            {
                if (elseStatement.IsEmptyBlock())
                {
                    throw new CompilerException(elseStatement, string.Format(Resource.Culture, Resource.IfBranchIsEmpty));
                }
                JumpToken skipElseToken = generator.Assembler.CreateJumpToken();
                generator.Assembler.Jump(skipElseToken);
                generator.Assembler.SetDestination(elseToken);
                generator.Resolver.EnterContext();
                elseStatement.Generate(generator, returnType);
                returns = statement.Returns() && elseStatement.Returns();
                Resolver.Context falseContext = generator.Resolver.LeaveContextAcquire();
                generator.Resolver.IntersectContexts(trueContext, falseContext);
                generator.Resolver.ReleaseContext(falseContext);
                generator.Assembler.SetDestination(skipElseToken);
            }
            else
            {
                generator.Assembler.SetDestination(elseToken);
            }
            generator.Resolver.ReleaseContext(trueContext);
        }
Exemplo n.º 8
0
 public override void Generate(Generator generator, TypeReference returnType)
 {
     base.Generate(generator, returnType);
     generator.Resolver.EnterContext();
     expression.Prepare(generator, typeRef);
     if (typeName == null)
     {
         typeRef = expression.TypeReference;
     }
     if (!disposable.Supports(typeRef))
     {
         throw new CompilerException(this, Resource.CanOnlyUseScopeOnNotNullDisposable);
     }
     expression.Generate(generator);
     typeRef.GenerateConversion(this, generator, expression.TypeReference);
     generator.Resolver.AddVariable(name, typeRef, slot, true);
     generator.Resolver.AssignSlot(slot);
     generator.Assembler.StoreVariable(slot);
     statement.Generate(generator, returnType);
     returns = statement.Returns();
     generator.Resolver.LeaveAndMergeContext();
 }
Exemplo n.º 9
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            parent.Generate(generator);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            TypeReference ptr       = parent.TypeReference;
            bool          allowNull = ptr.IsNullable && !typeReference.IsNullable;

            if (!allowNull)
            {
                generator.Assembler.CrashIfNull();
            }
            TypeReference str = typeReference;

            if (str.SupportsImplicit(ptr))
            {
                typeReference.GenerateConversion(this, generator, parent.TypeReference);
            }
            else
            {
                JumpToken jtNull = null;
                if (allowNull)
                {
                    jtNull = generator.Assembler.CreateJumpToken();
                    generator.Assembler.JumpIfUnassigned(jtNull);
                }
                generator.Assembler.TypeConversionDynamicNotNull(str.Id);
                JumpToken jtOk = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfAssigned(jtOk);
                throwCastException.Generate(generator, null);
                generator.Assembler.SetDestination(jtOk);
                if (allowNull)
                {
                    generator.Assembler.SetDestination(jtNull);
                }
            }
        }
Exemplo n.º 10
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);
            }
        }
Exemplo n.º 11
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            if (statement.IsEmptyStatement())
            {
                throw new CompilerException(statement, string.Format(Resource.Culture, Resource.LoopStatementHasNoBody));
            }

            generator.Resolver.EnterContext();

            expression.Prepare(generator, null);
            expression.Generate(generator); // Iterator<slot> ?
            // create the field, and the hidden enumerator
            if (enumeratorType == null)
            {
                enumeratorType = expression.TypeReference;
            }
            else
            {
                enumeratorType.GenerateConversion(expression, generator, expression.TypeReference);
            }
            generator.Resolver.AddVariable(enumeratorName, enumeratorType, enumeratorSlot, true);
            generator.Resolver.AssignSlot(enumeratorSlot);
            // get the enumerator from the expression
            generator.Assembler.StoreVariable(enumeratorSlot);
            // start of the loop
            JumpToken loopToken = generator.Assembler.CreateJumpToken();

            generator.Assembler.SetDestination(loopToken);
            // move the enumerator and check if something is available
            move.Prepare(generator, null);
            move.Generate(generator);
            boolType.GenerateConversion(this, generator, move.TypeReference);
            JumpToken skipToken = generator.Assembler.CreateJumpToken();

            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.JumpIfFalse(skipToken);
            // something is available so put it in the field
            current.Prepare(generator, null);
            current.Generate(generator);
            if (type == null)
            {
                type = current.TypeReference;
            }
            if (name != null)
            {
                generator.Resolver.AddVariable(name, type, slot, true);
                type.GenerateConversion(this, generator, current.TypeReference);
                generator.Resolver.AssignSlot(slot);
                generator.Assembler.StoreVariable(slot);
            }
            // for body
            generator.Resolver.EnterContext();
            generator.Resolver.RegisterGoto("@continue", loopToken);
            generator.Resolver.RegisterGoto("@break", skipToken);
            statement.Generate(generator, returnType);
            generator.Resolver.LeaveContext();
            generator.Assembler.Jump(loopToken);
            generator.Assembler.SetDestination(skipToken);
            generator.Resolver.LeaveContext();
        }
Exemplo n.º 12
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            if (target == null)
            {
                int slot = generator.Resolver.ResolveSlotOffset(name);
                value.Generate(generator);
                type.GenerateConversion(this, generator, value.TypeReference);
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
                generator.Resolver.WriteSlot(this, slot);
                generator.Assembler.StoreVariable(slot);
            }
            else
            {
                target.Generate(generator);

                TypeReference thisType = target.TypeReference;

                bool staticRef = thisType is StaticTypeReference;

                Definition thisDefinition;
                if (staticRef)
                {
                    thisDefinition = ((StaticTypeReference)thisType).Parent.Definition;
                }
                else
                {
                    thisDefinition = ((DefinitionTypeReference)thisType).Definition;
                }

                if (thisDefinition.HasField(name, staticRef))
                {
                    Field field = thisDefinition.GetField(name, staticRef);
                    if (!field.GetModifiers.Static)
                    {
                        generator.Assembler.PushValue();
                        int fieldOffset = thisDefinition.GetFieldOffset(this, name, generator.Resolver.CurrentDefinition, true);
                        if (target is IIncompleteSlotAssignment)
                        {
                            if (((IIncompleteSlotAssignment)target).IsIncompleteSlot())
                            {
                                generator.Resolver.AssignField(field);
                            }
                        }
                        value.Generate(generator);
                        type.GenerateConversion(value, generator, value.TypeReference);
                        generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
                        TypeReference slot = field.TypeReference;
                        if (slot.IsNullable)
                        {
                            slot = ((NullableTypeReference)slot).Parent;
                        }
                        DefinitionTypeReference dtr = slot as DefinitionTypeReference;
                        if ((dtr != null) && (!dtr.Definition.GarbageCollectable))
                        {
                            generator.Assembler.StoreInFieldOfSlotNoTouch(fieldOffset);
                        }
                        else
                        {
                            generator.Assembler.StoreInFieldOfSlot(generator.Toucher, fieldOffset);
                        }
                    }
                    else
                    {
                        generator.Assembler.PushValue();
                        if (target is IIncompleteSlotAssignment)
                        {
                            if (((IIncompleteSlotAssignment)target).IsIncompleteSlot())
                            {
                                generator.Resolver.AssignField(field);
                            }
                        }
                        value.Generate(generator);
                        type.GenerateConversion(value, generator, value.TypeReference);
                        generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
                        generator.Assembler.Store(field.StaticSlot);
                    }
                }
                else
                {
                    int propertySlot = thisDefinition.GetSetPropertyOffset(this, name, generator.Resolver.CurrentDefinition);
                    generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
                    generator.Assembler.FetchMethod(propertySlot);
                    generator.Assembler.PushValue();
                    value.Generate(generator);
                    type.GenerateConversion(value, generator, value.TypeReference);
                    generator.Assembler.PushValue();
                    Placeholder retSite = generator.Assembler.CallFromStack(1);
                    generator.AddCallTraceEntry(retSite, this, generator.Resolver.CurrentDefinition.Name.DataModifierLess, generator.Resolver.CurrentFieldName);
                }
            }
        }