/[svn]/linuxsampler/trunk/src/scriptvm/common.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/common.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2879 by schoenebeck, Tue Apr 19 14:07:53 2016 UTC revision 2948 by schoenebeck, Fri Jul 15 15:29:04 2016 UTC
# Line 160  namespace LinuxSampler { Line 160  namespace LinuxSampler {
160           * @see exprType()           * @see exprType()
161           */           */
162          VMIntArrayExpr* asIntArray() const;          VMIntArrayExpr* asIntArray() const;
163    
164            /**
165             * Returns true in case this expression can be considered to be a
166             * constant expression. A constant expression will retain the same
167             * value throughout the entire life time of a script and the
168             * expression's constant value may be evaluated already at script
169             * parse time, which may result in performance benefits during script
170             * runtime.
171             */
172            virtual bool isConstExpr() const = 0;
173    
174            bool isModifyable() const;
175      };      };
176    
177      /** @brief Virtual machine integer expression      /** @brief Virtual machine integer expression
# Line 366  namespace LinuxSampler { Line 378  namespace LinuxSampler {
378          virtual ExprType_t argType(int iArg) const = 0;          virtual ExprType_t argType(int iArg) const = 0;
379    
380          /**          /**
381           * This function is called by the parser to check whether arguments           * This method is called by the parser to check whether arguments
382           * passed in scripts to this function are accepted by this function. If           * passed in scripts to this function are accepted by this function. If
383           * a script calls this function with an argument's data type not           * a script calls this function with an argument's data type not
384           * accepted by this function, the parser will throw a parser error. On           * accepted by this function, the parser will throw a parser error. On
# Line 384  namespace LinuxSampler { Line 396  namespace LinuxSampler {
396          virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0;          virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0;
397    
398          /**          /**
399             * This method is called by the parser to check whether some arguments
400             * (and if yes which ones) passed to this script function will be
401             * modified by this script function. Most script functions simply use
402             * their arguments as inputs, that is they only read the argument's
403             * values. However some script function may also use passed
404             * argument(s) as output variables. In this case the function
405             * implementation must return @c true for the respective argument
406             * index here.
407             *
408             * @param iArg - index of the function argument in question
409             *               (must be between 0 .. maxAllowedArgs() - 1)
410             */
411            virtual bool modifiesArg(int iArg) const = 0;
412    
413            /**
414           * Implements the actual function execution. This exec() method is           * Implements the actual function execution. This exec() method is
415           * called by the VM whenever this function implementation shall be           * called by the VM whenever this function implementation shall be
416           * executed at script runtime. This method blocks until the function           * executed at script runtime. This method blocks until the function
# Line 423  namespace LinuxSampler { Line 450  namespace LinuxSampler {
450      struct VMRelPtr {      struct VMRelPtr {
451          void** base; ///< Base pointer.          void** base; ///< Base pointer.
452          int offset;  ///< Offset (in bytes) relative to base pointer.          int offset;  ///< Offset (in bytes) relative to base pointer.
453            bool readonly; ///< Whether the pointed data may be modified or just be read.
454      };      };
455    
456      /** @brief Pointer to built-in VM integer variable (of C/C++ type int).      /** @brief Pointer to built-in VM integer variable (of C/C++ type int).
# Line 450  namespace LinuxSampler { Line 478  namespace LinuxSampler {
478          VMIntRelPtr() {          VMIntRelPtr() {
479              base   = NULL;              base   = NULL;
480              offset = 0;              offset = 0;
481                readonly = false;
482          }          }
483          VMIntRelPtr(const VMRelPtr& data) {          VMIntRelPtr(const VMRelPtr& data) {
484              base   = data.base;              base   = data.base;
485              offset = data.offset;              offset = data.offset;
486                readonly = false;
487          }          }
488          virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; }          virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; }
489          virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; }          virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; }
# Line 536  namespace LinuxSampler { Line 566  namespace LinuxSampler {
566      #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \      #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \
567          (VMRelPtr) {                                     \          (VMRelPtr) {                                     \
568              (void**) &basePtr,                           \              (void**) &basePtr,                           \
569              offsetof(T_struct, T_member)                 \              offsetof(T_struct, T_member),                \
570                false                                        \
571          }                                                \          }                                                \
572      )                                                    \      )                                                    \
573    
574        /**
575         * Same as DECLARE_VMINT(), but this one defines the VMIntRelPtr and
576         * VMInt8RelPtr structures to be of read-only type. That means the script
577         * parser will abort any script at parser time if the script is trying to
578         * modify such a read-only built-in variable.
579         *
580         * @b NOTE: this is only intended for built-in read-only variables that
581         * may change during runtime! If your built-in variable's data is rather
582         * already available at parser time and won't change during runtime, then
583         * you should rather register a built-in constant in your VM class instead!
584         *
585         * @see ScriptVM::builtInConstIntVariables()
586         */
587        #define DECLARE_VMINT_READONLY(basePtr, T_struct, T_member) ( \
588            (VMRelPtr) {                                          \
589                (void**) &basePtr,                                \
590                offsetof(T_struct, T_member),                     \
591                true                                              \
592            }                                                     \
593        )                                                         \
594    
595      /** @brief Built-in VM 8 bit integer array variable.      /** @brief Built-in VM 8 bit integer array variable.
596       *       *
597       * Used for defining built-in integer array script variables (8 bit per       * Used for defining built-in integer array script variables (8 bit per
# Line 553  namespace LinuxSampler { Line 605  namespace LinuxSampler {
605          VMInt8Array() : data(NULL), size(0) {}          VMInt8Array() : data(NULL), size(0) {}
606      };      };
607    
608        /** @brief Virtual machine script variable.
609         *
610         * Common interface for all variables accessed in scripts.
611         */
612        class VMVariable : virtual public VMExpr {
613        public:
614            /**
615             * Whether a script may modify the content of this variable by
616             * assigning a new value to it.
617             *
618             * @see isConstExpr(), assign()
619             */
620            virtual bool isAssignable() const = 0;
621    
622            /**
623             * In case this variable is assignable, this method will be called to
624             * perform the value assignment to this variable with @a expr
625             * reflecting the new value to be assigned.
626             *
627             * @param expr - new value to be assigned to this variable
628             */
629            virtual void assignExpr(VMExpr* expr) = 0;
630        };
631        
632        /** @brief Dynamically executed variable (abstract base class).
633         *
634         * Interface for the implementation of a dynamically generated content of
635         * a built-in script variable. Most built-in variables are simply pointers
636         * to some native location in memory. So when a script reads them, the
637         * memory location is simply read to get the value of the variable. A
638         * dynamic variable however is not simply a memory location. For each access
639         * to a dynamic variable some native code is executed to actually generate
640         * and provide the content (value) of this type of variable.
641         */
642        class VMDynVar : public VMVariable {
643        public:
644            /**
645             * Returns true in case this dynamic variable can be considered to be a
646             * constant expression. A constant expression will retain the same value
647             * throughout the entire life time of a script and the expression's
648             * constant value may be evaluated already at script parse time, which
649             * may result in performance benefits during script runtime.
650             *
651             * However due to the "dynamic" behavior of dynamic variables, almost
652             * all dynamic variables are probably not constant expressions. That's
653             * why this method returns @c false by default. If you are really sure
654             * that your dynamic variable implementation can be considered a
655             * constant expression then you may override this method and return
656             * @c true instead. Note that when you return @c true here, your
657             * dynamic variable will really just be executed once; and exectly
658             * already when the script is loaded!
659             *
660             * As an example you may implement a "constant" built-in dynamic
661             * variable that checks for a certain operating system feature and
662             * returns the result of that OS feature check as content (value) of
663             * this dynamic variable. Since the respective OS feature might become
664             * available/unavailable after OS updates, software migration, etc. the
665             * OS feature check should at least be performed once each time the
666             * application is launched. And since the OS feature check might take a
667             * certain amount of execution time, it might make sense to only
668             * perform the check if the respective variable name is actually
669             * referenced at all in the script to be loaded. Note that the dynamic
670             * variable will still be evaluated again though if the script is
671             * loaded again. So it is up to you to probably cache the result in the
672             * implementation of your dynamic variable.
673             *
674             * On doubt, please rather consider to use a constant built-in script
675             * variable instead of implementing a "constant" dynamic variable, due
676             * to the runtime overhead a dynamic variable may cause.
677             *
678             * @see isAssignable()
679             */
680            bool isConstExpr() const OVERRIDE { return false; }
681    
682            /**
683             * In case this dynamic variable is assignable, the new value (content)
684             * to be assigned to this dynamic variable.
685             *
686             * By default this method does nothing. Override and implement this
687             * method in your subclass in case your dynamic variable allows to
688             * assign a new value by script.
689             *
690             * @param expr - new value to be assigned to this variable
691             */
692            void assignExpr(VMExpr* expr) OVERRIDE {}
693        };
694    
695        /** @brief Dynamically executed variable (of integer data type).
696         *
697         * This is the base class for all built-in integer script variables whose
698         * variable content needs to be provided dynamically by executable native
699         * code on each script variable access.
700         */
701        class VMDynIntVar : virtual public VMDynVar, virtual public VMIntExpr {
702        public:
703        };
704    
705        /** @brief Dynamically executed variable (of string data type).
706         *
707         * This is the base class for all built-in string script variables whose
708         * variable content needs to be provided dynamically by executable native
709         * code on each script variable access.
710         */
711        class VMDynStringVar : virtual public VMDynVar, virtual public VMStringExpr {
712        public:
713        };
714    
715      /** @brief Provider for built-in script functions and variables.      /** @brief Provider for built-in script functions and variables.
716       *       *
717       * Abstract base class defining the high-level interface for all classes       * Abstract base class defining the high-level interface for all classes
# Line 587  namespace LinuxSampler { Line 746  namespace LinuxSampler {
746           * variables, which never change their value at runtime.           * variables, which never change their value at runtime.
747           */           */
748          virtual std::map<String,int> builtInConstIntVariables() = 0;          virtual std::map<String,int> builtInConstIntVariables() = 0;
749    
750            /**
751             * Returns a variable name indexed map of all built-in dynamic variables,
752             * which are not simply data stores, rather each one of them executes
753             * natively to provide or alter the respective script variable data.
754             */
755            virtual std::map<String,VMDynVar*> builtInDynamicVariables() = 0;
756      };      };
757    
758      /** @brief Execution state of a virtual machine.      /** @brief Execution state of a virtual machine.
# Line 667  namespace LinuxSampler { Line 833  namespace LinuxSampler {
833       */       */
834      struct ParserIssue {      struct ParserIssue {
835          String txt; ///< Human readable explanation text of the parser issue.          String txt; ///< Human readable explanation text of the parser issue.
836          int line; ///< Line number within the script where this issue was encountered.          int firstLine; ///< The first line number within the script where this issue was encountered (indexed with 1 being the very first line).
837            int lastLine; ///< The last line number within the script where this issue was encountered.
838            int firstColumn; ///< The first column within the script where this issue was encountered (indexed with 1 being the very first column).
839            int lastColumn; ///< The last column within the script where this issue was encountered.
840          ParserIssueType_t type; ///< Whether this issue is either a parser error or just a parser warning.          ParserIssueType_t type; ///< Whether this issue is either a parser error or just a parser warning.
841    
842          /**          /**
# Line 676  namespace LinuxSampler { Line 845  namespace LinuxSampler {
845          inline void dump() {          inline void dump() {
846              switch (type) {              switch (type) {
847                  case PARSER_ERROR:                  case PARSER_ERROR:
848                      printf("[ERROR] line %d: %s\n", line, txt.c_str());                      printf("[ERROR] line %d, column %d: %s\n", firstLine, firstColumn, txt.c_str());
849                      break;                      break;
850                  case PARSER_WARNING:                  case PARSER_WARNING:
851                      printf("[Warning] line %d: %s\n", line, txt.c_str());                      printf("[Warning] line %d, column %d: %s\n", firstLine, firstColumn, txt.c_str());
852                      break;                      break;
853              }              }
854          }          }
# Line 767  namespace LinuxSampler { Line 936  namespace LinuxSampler {
936          virtual VMEventHandler* eventHandlerByName(const String& name) = 0;          virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
937      };      };
938    
939        class SourceToken;
940    
941        /** @brief Recognized token of a script's source code.
942         *
943         * Represents one recognized token of a script's source code, for example
944         * a keyword, variable name, etc. and it provides further informations about
945         * that particular token, i.e. the precise location (line and column) of the
946         * token within the original script's source code.
947         *
948         * This class is not actually used by the sampler itself. It is rather
949         * provided for external script editor applications. Primary purpose of
950         * this class is syntax highlighting for external script editors.
951         */
952        class VMSourceToken {
953        public:
954            VMSourceToken();
955            VMSourceToken(SourceToken* ct);
956            VMSourceToken(const VMSourceToken& other);
957            virtual ~VMSourceToken();
958    
959            // original text of this token as it is in the script's source code
960            String text() const;
961    
962            // position of token in script
963            int firstLine() const; ///< First line this source token is located at in script source code (indexed with 0 being the very first line).
964            int firstColumn() const; ///< Last line this source token is located at in script source code.
965    
966            // base types
967            bool isEOF() const;
968            bool isNewLine() const;
969            bool isKeyword() const;
970            bool isVariableName() const;
971            bool isIdentifier() const;
972            bool isNumberLiteral() const;
973            bool isStringLiteral() const;
974            bool isComment() const;
975            bool isPreprocessor() const;
976            bool isOther() const;
977    
978            // extended types
979            bool isIntegerVariable() const;
980            bool isStringVariable() const;
981            bool isArrayVariable() const;
982            bool isEventHandlerName() const;
983    
984            VMSourceToken& operator=(const VMSourceToken& other);
985    
986        private:
987            SourceToken* m_token;
988        };
989    
990  } // namespace LinuxSampler  } // namespace LinuxSampler
991    
992  #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H  #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

Legend:
Removed from v.2879  
changed lines
  Added in v.2948

  ViewVC Help
Powered by ViewVC