⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cslang.txt

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 TXT
📖 第 1 页 / 共 5 页
字号:
           static SLang_Intrin_Var_Type Intrin_Vars [] =           {              MAKE_VARIABLE("I_Variable", &I, SLANG_INT_TYPE, 0),              MAKE_VARIABLE("S_Variable", &S_Ptr, SLANG_STRING_TYPE, 1),              SLANG_END_TABLE           };  may be added via           if (-1 == SLadd_intrin_var_table (Intrin_Vars, NULL))             exit (EXIT_FAILURE);  It should be rather obvious that the arguments to the MAKE_VARIABLE  macro correspond to the parameters of the SLadd_intrinsic_variable  function.  Finally, variables may be added to a specific namespace via the  SLns_add_intrin_var_table and SLns_add_intrinsic_variable functions.  3.5.  Aggregate Data Objects  An aggregate data object is an object that can contain more than one  data value.  The S-Lang interpreter supports several such objects:  arrays, structure, and associative arrays.  In the following sections,  information about interacting with these objects is given.  3.5.1.  Arrays  An intrinsic function may interact with an array in several different  ways.  For example, an intrinsic may create an array and return it.  The basic functions for manipulating arrays include:          SLang_create_array          SLang_pop_array_of_type          SLang_push_array          SLang_free_array          SLang_get_array_element          SLang_set_array_element  The use of these functions will be illustrated via a few simple exam-  ples.  The first example shows how to create an return an array of strings to  the interpreter.  In particular, the names of the four seasons of the  year will be returned:           void months_of_the_year (void)           {              static char *seasons[4] =                {                   "Spring", "Summer", "Autumn", "Winter"                };              SLang_Array_Type *at;              int i, four;              four = 4;              at = SLang_create_array (SLANG_STRING_TYPE, 0, NULL, &four, 1);              if (at == NULL)                return;              /* Now set the elements of the array */              for (i = 0; i < 4; i++)                {                  if (-1 == SLang_set_array_element (at, &i, &seasons[i]))                    {                       SLang_free_array (at);                       return;                    }                }             (void) SLang_push_array (at, 0);             SLang_free_array (at);           }  This example illustrates several points.  First of all, the SLang_cre-  ate_array function was used to create a 1 dimensional array of 4  strings.  Since this function could fail, its return value was  checked.  Then the SLang_set_array_element function was used to set  the elements of the newly created array.  Note that the address con-  taining the value of the array element was passed and not the value of  the array element itself.  That is,      SLang_set_array_element (at, &i, seasons[i])  was not used.  The return value from this function was also checked  because it too could also fail.  Finally, the array was pushed onto  the interpreter's stack and then it was freed.  It is important to  understand why it was freed.  This is because arrays are reference-  counted.  When the array was created, it was returned with a reference  count of 1.  When it was pushed, the reference count was bumped up to  2.  Then since it was nolonger needed by the function,  SLang_free_array was called to decrement the reference count back to  1.  For convenience, the second argument to SLang_push_array deter-  mines whether or not it is to also free the array.  So, instead of the  two function calls:          (void) SLang_push_array (at, 0);          SLang_free_array (at);  it is preferable to combine them as          (void) SLang_push_array (at, 1);  The second example returns a diagonal array of a specified size to the  stack.  A diagonal array is a 2-d array with all elements zero except  for those along the diagonal, which have a value of one:          void make_diagonal_array (int n)          {             SLang_Array_Type *at;             int dims[2];             int i, one;             dims[0] = dims[1] = n;             at = SLang_create_array (SLANG_INT_TYPE, 0, NULL, dims, 2);             if (at == NULL)               return;             one = 1;             for (i = 0; i < n; i++)               {                  dims[0] = dims[1] = i;                  if (-1 == SLang_set_array_element (at, dims, &one))                    {                       SLang_free_array (at);                       return;                    }               }             (void) SLang_push_array (at, 1);          }  In this example, only the diagonal elements of the array were set.  This is bacause when the array was created, all its elements were set  to zero.  Now consider an example that acts upon an existing array.  In  particular, consider one that computes the trace of a 2-d matrix,  i.e., the sum of the diagonal elements:          double compute_trace (void)          {             SLang_Array_Type *at;             double trace;             int dims[2];             if (-1 == SLang_pop_array_of_type (&at, SLANG_DOUBLE_TYPE))               return 0.0;             /* We want a 2-d square matrix.  If the matrix is 1-d and has only one                element, then return that element. */             trace = 0.0;             if (((at->num_dims == 1) && (at->dims[0] == 1))                 || ((at->num_dims == 2) && (at->dims[0] == at->dims[1])))               {                  double dtrace;                  int n = at->dims[0];                  for (i = 0; i < n; i++)                    {                       dims[0] = dims[1] = i;                       (void) SLang_get_array_element (at, &dims, &dtrace);                       trace += dtrace;                    }               }            else SLang_verror (SL_TYPE_MISMATCH, "Expecting a square matrix");            SLang_free_array (at);            return trace;          }  In this example, SLang_pop_array_of_type was used to pop an array of  doubles from the stack.  This function will make implicit typecasts in  order to return an array of the requested type.  3.5.2.  Structures  For the purposes of this section, we shall differentiate structures  according to whether or not they correspond to an application defined  C structure.  Those that do are called intrinsic structures, and those  do not are called S-Lang interpreter structures.  3.5.2.1.  Interpreter Structures  The following simple example shows one method that may be used to  create and return a structure with a string and integer field to the  interpreter's stack:      int push_struct_example (char *string_value, int int_value)      {         char *field_names[2];         unsigned char field_types[2];         VOID_STAR field_values[2];         field_names[0] = "string_field";         field_types[0] = SLANG_STRING_TYPE;         field_values[0] = &string_value;         field_names[1] = "int_field";         field_types[1] = SLANG_INT_TYPE;         field_values[1] = &int_value;         if (-1 == SLstruct_create_struct (2, field_names,                                              field_types, field_values))           return -1;         return 0;      }  Here, SLstruct_create_struct is used to push a structure with the  specified field names and values onto the interpreter's stack.  A simpler mechanism exists provided that one has already defined a C  structure with a description of how the structure is laid out.  For  example, consider a C structure defined by           typedef struct           {              char *s;              int i;           }           SI_Type;  Its layout may be specified via a table of SLang_CStruct_Field_Type  entries:           SLang_CStruct_Field_Type SI_Type_Layout [] =           {             MAKE_CSTRUCT_FIELD(SI_Type, s, "string_field", SLANG_STRING_TYPE, 0),             MAKE_CSTRUCT_FIELD(SI_Type, i, "int_field", SLANG_INT_TYPE, 0),             SLANG_END_CSTRUCT_TABLE           };  Here, MAKE_CSTRUCT_FIELD is a macro taking 5 arguments:           MAKE_CSTRUCT_FIELD(C-structure-type,                              C-field-name,                              slang-field-name,                              slang-data-type,                              is-read-only)  The first argument is the structure type, the second is the name of a  field of the structure, the third is a string that specifies the name  of the corresponding field of the S-Lang structure, the fourth argu-  ment specifies the field's type, and the last argument specifies  whether or not the field should be regarded as read-only.  Once the layout of the structure has been specified, pushing a S-Lang  version of the structure is trival:           int push_struct_example (char *string_value, int int_value)           {              SI_Type si;              si.s = string_value;              si.i = int_value;              return SLang_push_cstruct ((VOID_STAR)&si, SI_Type_Layout);           }  This mechanism of structure creation also permits a S-Lang structure  to be passed to an intrinsic function through the use of the  SLang_pop_cstruct routine, e.g.,            void print_si_struct (void)            {               SI_Type si;               if (-1 == SLang_pop_cstruct ((VOID_STAR)&si, SI_Type_Layout))                 return;               printf ("si.i=%d", si.i);               printf ("si.s=%s", si.s);               SLang_free_cstruct ((VOID_STAR)&si, SI_Type_Layout);            }  Assuming print_si_struct exists as an intrinsic function, the S-Lang  code            variable s = struct {string_field, int_field};            s.string_field = "hello";            s.int_field = 20;            print_si_struct (s);  would result in the display of            si.i=20;            si.s=hello  Note that the SLang_free_cstruct function was called after the con-  tents of si were nolonger needed.  This was necessary because  SLang_pop_cstruct allocated memory to set the char *s field of si.  Calling SLang_free_cstruct frees up such memory.  Now consider the following:           typedef struct           {              pid_t pid;              gid_t group;           }           X_t;  How should the layout of this structure be defined?  One might be  tempted to use:           SLang_CStruct_Field_Type X_t_Layout [] =           {             MAKE_CSTRUCT_FIELD(X_t, pid, "pid", SLANG_INT_TYPE, 0),             MAKE_CSTRUCT_FIELD(X_t, group, "group", SLANG_INT_TYPE, 0),             SLANG_END_CSTRUCT_TABLE           };  However, this assumes pid_t and gid_t have been typedefed as ints.  But what if gid_t is a short?  In such a case, using             MAKE_CSTRUCT_FIELD(X_t, group, "group", SLANG_SHORT_TYPE, 0),  would be the appropriate entry for the group field.  Of course, one  has no way of knowing how gid_t is declared on other systems.  For  this reason, it is preferable to use the MAKE_CSTRUCT_INT_FIELD macro  in cases involving integer valued fields, e.g.,           SLang_CStruct_Field_Type X_t_Layout [] =           {             MAKE_CSTRUCT_INT_FIELD(X_t, pid, "pid", 0),             MAKE_CSTRUCT_INT_FIELD(X_t, group, "group", 0),             SLANG_END_CSTRUCT_TABLE           };  Before leaving this section, it is important to mention that access to  character array fields is not permitted via this interface.  That is,  a structure such as            typedef struct            {               char name[32];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -