Пример #1
0
     public StorageModifierNode(string modifier, SourcePosition position) : base(position, modifier, LexTokenType.Keyword)
     {
         this.Modifier = modifier switch
         {
             _ => throw new ArgumentException()
         };
     }
 }
Пример #2
0
 public static bool IsLegal(this StorageModifier modifier)
 {
     if (modifier == (StorageModifier.Virtual | StorageModifier.Override))
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
Пример #3
0
 public void AddStorageModifier(StorageModifier modifier) => this.m_storageType |= modifier;
Пример #4
0
 /// <summary>
 /// Make the right sort of opcodestore-ish opcode for what storage
 /// mode we're in.
 /// </summary>
 /// <param name="kind">which sort of storage is this</param>
 /// <param name="lazyGlobal">true if store should make a lazyglobal,
 /// false if it should not.  NOTE that it should always be true when
 /// doing DECLARE operations and only vary when doing SET operations.</param>
 /// <returns>the new opcode you should add</returns>
 private Opcode CreateAppropriateStoreCode(StorageModifier kind, bool lazyGlobal)
 {
     switch (kind)
     {
         case StorageModifier.LOCAL:
             return new OpcodeStoreLocal();
         case StorageModifier.GLOBAL:
             return new OpcodeStoreGlobal();
         default:
             if (lazyGlobal)
                 return AddOpcode(new OpcodeStore());
             else
                 return AddOpcode(new OpcodeStoreExist());
     }
 }
Пример #5
0
        // This is no longer called directly from parse because it now is called from
        // VisitDeclareStatement, which reads the storage modifier keywords and
        // passes them on to here.
        private void VisitLockStatement(ParseNode node, StorageModifier whereToStore)
        {
            NodeStartHousekeeping(node);
            string lockIdentifier = node.Nodes[1].Token.Text;
            int expressionHash = ConcatenateNodes(node.Nodes[3]).GetHashCode();
            UserFunction lockObject = context.UserFunctions.GetUserFunction(
                lockIdentifier,
                whereToStore == StorageModifier.GLOBAL ? (Int16)0 : GetContainingScopeId(node),
                node);

            string functionLabel = lockObject.GetUserFunctionLabel(expressionHash);
            // lock variable
            AddOpcode(new OpcodePush(lockObject.ScopelessPointerIdentifier));
            AddOpcode(new OpcodePushDelegateRelocateLater(null,true), functionLabel);
            AddOpcode(CreateAppropriateStoreCode(whereToStore, allowLazyGlobal));

            if (lockObject.IsSystemLock())
            {
                // add update trigger
                string triggerIdentifier = "lock-" + lockObject.ScopelessIdentifier;
                if (context.Triggers.Contains(triggerIdentifier))
                {
                    Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier);
                    AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel());
                    AddOpcode(new OpcodeAddTrigger());
                }

                // enable this FlyByWire parameter
                AddOpcode(new OpcodePush(new KOSArgMarkerType()));
                AddOpcode(new OpcodePush(lockIdentifier));
                AddOpcode(new OpcodePush(true));
                AddOpcode(new OpcodeCall("toggleflybywire()"));
                // add a pop to clear out the dummy return value from toggleflybywire()
                AddOpcode(new OpcodePop());
            }
        }
Пример #6
0
        /// <summary>
        /// Process a single parameter from the parameter list for a
        /// function or program.  i.e. if encountering the statement
        /// "DECLARE PARAMETER AA, BB, CC is 0." , then this method needs to be
        /// called 3 times, once for AA, once for BB, and once for "CC is 0":
        /// </summary>
        /// <param name="whereToStore">is it local or global or lazyglobal</param>
        /// <param name="identifierNode">Parse node holding the identifier of the param</param>
        /// <param name="expressionNode">Parse node holding the expression to initialize to if
        /// this is a defaultable parameter.  If it is not a defaultable parameter, pass null here</param>
        private void VisitDeclareOneParameter(StorageModifier whereToStore, ParseNode identifierNode, ParseNode expressionNode)
        {
            if (expressionNode != null)
            {
                // This tests each defaultable parameter to see if it's at arg bottom.
                // The test must be repeated for each parameter rather than optimizing by
                // falling through to all subsequent defaulter expressions for the rest of
                // the parameters once the first one finds arg bottom.
                // This is because kerboscript does not require the declare parameters to
                // be contiguous statements so there may be code in between them you're
                // not supposed to skip over.

                AddOpcode(new OpcodeTestArgBottom());
                OpcodeBranchIfFalse branchSkippingInit = new OpcodeBranchIfFalse();
                AddOpcode(branchSkippingInit);

                VisitNode(expressionNode); // evals init expression on the top of the stack where the arg would have been

                branchSkippingInit.DestinationLabel = GetNextLabel(false);
            }
            VisitNode(identifierNode);
            AddOpcode(new OpcodeSwap());
            AddOpcode(CreateAppropriateStoreCode(whereToStore, true));
        }