コード例 #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();
     }
 }
コード例 #2
0
 public override void Generate(Generator generator, TypeReference returnType)
 {
     base.Generate(generator, returnType);
     expression.Prepare(generator, null);
     expression.Generate(generator);
     generator.Assembler.StoreVariable(slot);
     generator.Resolver.EnterContext();
     generator.Resolver.AddVariable(new Identifier(this, Guid.NewGuid().ToString("B")), expression.TypeReference, slot, true);
     if (!expression.TypeReference.IsDefinition && !expression.TypeReference.IsStatic)
     {
         throw new CompilerException(this, Resource.CanOnlyUseWithOnNotNullClassInstances);
     }
     generator.Resolver.SetImplicitFields(slot, expression.TypeReference);
     statement.Generate(generator, returnType);
     returns = statement.Returns();
     generator.Resolver.LeaveAndMergeContext();
 }
コード例 #3
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);
        }
コード例 #4
0
ファイル: TryStatement.cs プロジェクト: bartwe/plukc
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            //
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            PlaceholderRef fonCatchJump = null;

            if (finallyStatement != null)
            {
                fonCatchJump = new PlaceholderRef();
                generator.Assembler.ExceptionHandlerSetup(fonCatchJump);
                generator.Resolver.EnterContext();
                generator.Resolver.RegisterTryContext();
            }
            PlaceholderRef onCatchJump = null;

            if (catches.Count > 0)
            {
                onCatchJump = new PlaceholderRef();
                generator.Assembler.ExceptionHandlerSetup(onCatchJump);
            }
            generator.Resolver.EnterContext();
            generator.Resolver.RegisterTryContext();
            statement.Generate(generator, returnType);
            returns = statement.Returns();
            Resolver.Context statementContext = generator.Resolver.LeaveContextAcquire();
            if (catches.Count > 0)
            {
                generator.Assembler.ExceptionHandlerRemove();
                JumpToken noExceptionJump = generator.Assembler.CreateJumpToken();
                generator.Assembler.Jump(noExceptionJump);
                generator.Assembler.SetDestination(onCatchJump);

                JumpToken noReturnJump = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfNotMarked(noReturnJump);
                generator.Assembler.UnmarkType();
                ReturnStatement.DoReturn(this, generator);
                generator.Assembler.SetDestination(noReturnJump);

                generator.Assembler.StoreVariable(valueSlot);

                List <JumpToken> escape = new List <JumpToken>();

                foreach (Catch c in catches)
                {
                    generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, c);
                    generator.Assembler.RetrieveVariable(valueSlot);
                    JumpToken noMatch = generator.Assembler.CreateJumpToken();
                    generator.Assembler.TypeConversionDynamicNotNull(c.type.Id);
                    generator.Assembler.JumpIfUnassigned(noMatch);
                    generator.Assembler.StoreVariable(valueSlot);
                    generator.Resolver.EnterContext();
                    generator.Resolver.AddVariable(c.identifier, c.type, valueSlot, true);
                    generator.Resolver.AssignSlot(valueSlot);
                    c.statement.Generate(generator, returnType);
                    returns = returns && c.statement.Returns();
                    generator.Resolver.LeaveContext();
                    JumpToken jt = generator.Assembler.CreateJumpToken();
                    escape.Add(jt);
                    generator.Assembler.Jump(jt);
                    generator.Assembler.SetDestination(noMatch);
                }
                //unhandled, rethrow
                generator.Assembler.RetrieveVariable(valueSlot);
                generator.Assembler.ExceptionHandlerInvoke();
                foreach (JumpToken jt in escape)
                {
                    generator.Assembler.SetDestination(jt);
                }
                generator.Assembler.SetDestination(noExceptionJump);
            }
            if (finallyStatement != null)
            {
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, finallyLocation);
                generator.Resolver.LeaveContext();
                generator.Assembler.ExceptionHandlerRemove();
                generator.Assembler.Empty();
                generator.Assembler.SetDestination(fonCatchJump);
                JumpToken fnoReturnJump = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfNotMarked(fnoReturnJump);
                generator.Assembler.UnmarkType();
                generator.Assembler.StoreVariable(returnSlot);
                generator.Assembler.SetDestination(fnoReturnJump);
                generator.Assembler.StoreVariable(valueSlot);
                generator.Resolver.EnterContext();
                finallyStatement.Generate(generator, returnType);
                generator.Resolver.LeaveAndMergeContext();
                if (catches.Count == 0) // if there are no catches we can be sure the whole try part completed and so we can use the variables initialized by it.
                {
                    generator.Resolver.MergeContext(statementContext);
                }

                generator.Assembler.RetrieveVariable(returnSlot);
                JumpToken fonExceptionFinallyJump = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfUnassigned(fonExceptionFinallyJump);
                ReturnStatement.DoReturn(this, generator);
                generator.Assembler.SetDestination(fonExceptionFinallyJump);

                generator.Assembler.RetrieveVariable(valueSlot);
                JumpToken fnoException = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfUnassigned(fnoException);
                generator.Assembler.ExceptionHandlerInvoke();
                generator.Assembler.SetDestination(fnoException);
            }
            generator.Resolver.ReleaseContext(statementContext);
        }
コード例 #5
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();
        }