public StorageModifierNode(string modifier, SourcePosition position) : base(position, modifier, LexTokenType.Keyword) { this.Modifier = modifier switch { _ => throw new ArgumentException() }; } }
public static bool IsLegal(this StorageModifier modifier) { if (modifier == (StorageModifier.Virtual | StorageModifier.Override)) { return(false); } else { return(true); } }
public void AddStorageModifier(StorageModifier modifier) => this.m_storageType |= modifier;
/// <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()); } }
// 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()); } }
/// <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)); }