Example #1
0
/*-------------------------------------------------------------------------
 * Function:    ptr_bind
 *
 * Purpose:     Binds array dimensions to numeric values.
 *
 * Return:      Success:        SELF
 *
 *              Failure:        NIL
 *
 * Programmer:  Robb Matzke
 *              [email protected]
 *              Jan 13 1997
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static obj_t
ptr_bind (obj_t _self, void *mem) {

   obj_ptr_t    *self = MYCLASS(_self);
   obj_t        name=NIL, val=NIL, x=NIL;
   int          i;

   if (C_STR==self->sub->pub.cls) {
      name = obj_new (C_SYM, obj_name(self->sub));
      x = sym_vboundp (name);
      name = obj_dest (name);
      val = obj_copy (x, DEEP); /*so we can modify it*/
      x = obj_dest (x);

      /*
       * We're being tricky here.  By assigning a new value to the `sub'
       * field we're modifying all the expressions that share this cell.
       * We must insure that the correct reference count is imparted
       * to the new subtype.
       */
      for (i=1; i<self->pub.ref; i++) {
         x = obj_copy (val, SHALLOW);
         assert (x==val);
      }
      
      if (val) self->sub = val;
   }

   return obj_bind (self->sub, mem ? *((void**)mem) : NULL);
}
Example #2
0
/*-------------------------------------------------------------------------
 * Function:    sym_self_set
 *
 * Purpose:     Gives symbol `self' a new variable value and returns the
 *              previous value.  The new value is not copied.
 *
 * Return:      Success:        Previous value of variable `self'.
 *
 *              Failure:        NIL
 *
 * Programmer:  Robb Matzke
 *              [email protected]
 *              Jan 13 1997
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
obj_t
sym_self_set (obj_t newval) {

   obj_t        oldval=NIL, selfvar=NIL;

   selfvar = obj_new (C_SYM, "self");
   oldval = sym_vboundp (selfvar);
   sym_vbind (selfvar, newval);
   return oldval;
}
Example #3
0
/*-------------------------------------------------------------------------
 * Function:    sym_eval
 *
 * Purpose:     Returns the variable value of a symbol if it has one.
 *
 * Return:      Success:        Ptr to a copy of the variable value.
 *
 *              Failure:        NIL
 *
 * Programmer:  Robb Matzke
 *              [email protected]
 *              Dec  4 1996
 *
 * Modifications:
 *      Robb Matzke, 4 Feb 1997
 *      Fixed the arguments for the obj_deref() call.
 *
 *      Robb Matzke, 2000-07-03
 *      The symbol `$*' evaluates to a list of all $N files for
 *      consecutive N beginning at 1.
 *-------------------------------------------------------------------------
 */
static obj_t
sym_eval (obj_t _self)
{
    obj_t       name_1=NIL, file_1=NIL, retval=NIL;
    obj_sym_t   *self = MYCLASS(_self);

    /* If the symbol has a variable value then return it. */    
    if (MYCLASS(_self)->sym->var) {
        return obj_copy (MYCLASS(_self)->sym->var, SHALLOW);
    }

    /* The symbol `$*' evaluates to a list of the first consecutive files
     * bound to the $N symbols. */
    if (!strcmp(self->sym->name, "$*")) {
        obj_t   opands[1024], retval;
        int     nopands, i;
        
        for (nopands=0; nopands<NELMTS(opands); nopands++) {
            obj_t symbol;
            char tmp[32];
            sprintf(tmp, "$%d", nopands+1);
            symbol = obj_new(C_SYM, tmp);
            opands[nopands] = sym_vboundp(symbol);
            obj_dest(symbol);
            if (!opands[nopands] || C_FILE!=opands[nopands]->pub.cls) {
                /* We reached the last file or something isn't a file */
                obj_dest(opands[nopands]);
                break;
            }
        }
        retval = V_make_list(nopands, opands);
        for (i=0; i<nopands; i++) {
            obj_dest(opands[i]);
        }
        return retval;
    }

    /* If the symbol exists in the first data file, then return
     * that SDO. */
    name_1 = obj_new (C_SYM, "$1");
    file_1 = MYCLASS(name_1)->sym->var;
    name_1 = obj_dest (name_1);

    if (file_1 && C_FILE==file_1->pub.cls) {
        retval = obj_deref (file_1, 1, &_self);
        return retval;
    }

    /* Symbol has no value. */    
    out_errorn ("eval: variable `%s' has no value", obj_name(_self));
    return NIL;
}
Example #4
0
/*---------------------------------------------------------------------------
 * Purpose:     Return the string value of a builtin symbol.
 *
 * Return:      Copy of the string value or NULL
 *
 * Programmer:  Robb Matzke
 *              Friday, June  2, 2000
 *
 * Modifications:
 *---------------------------------------------------------------------------
 */
char *
sym_bi_gets(const char *name)
{
    char        fullname[1024], *retval;
    obj_t       var, val;

    /* Add built-in prefix */
    if (*name!='$') {
        fullname[0] = '$';
        strcpy(fullname+1, name);
        name = fullname;
    }

    var = obj_new(C_SYM, name);
    val = sym_vboundp(var);
    var = obj_dest(var);

    retval = safe_strdup(obj_name(val));
    obj_dest(val);
    return retval;
}
Example #5
0
/*---------------------------------------------------------------------------
 * Purpose:     Returns the integer value of a built-in symbol. If the
 *              symbol is set to something not an integer then return 1.
 *
 * Programmer:  Robb Matzke
 *              Thursday, June  1, 2000
 *
 * Modifications:
 *---------------------------------------------------------------------------
 */
int
sym_bi_true(const char *name)
{
    char        fullname[1024];
    int         retval;
    obj_t       var_name, val;

    /* Add built-in prefix */
    if (*name!='$') {
        fullname[0] = '$';
        strcpy(fullname+1, name);
        name = fullname;
    }

    /* Get value */
    var_name = obj_new(C_SYM, name);
    val = sym_vboundp(var_name);
    var_name = obj_dest(var_name);
    if (num_isint(val)) retval = num_int(val);
    else retval = val ? 1 : 0;
    val = obj_dest (val);
    return retval;
}
Example #6
0
/*-------------------------------------------------------------------------
 * Function:    lex_token
 *
 * Purpose:     Figures out what token is next on the input stream.  If
 *              skipnl is non-zero then the new-line token is skipped.
 *
 * Return:      Success:        Token number, optional lexeme returned
 *                              through the LEXEME argument.
 *
 *              Failure:        TOK_INVALID
 *
 * Programmer:  Robb Matzke
 *              [email protected]
 *              Dec  4 1996
 *
 * Modifications:
 *
 *      Robb Matzke, 3 Feb 1997
 *      Cleaned up error messages.
 *
 *      Robb Matzke, 7 Feb 1997
 *      Added the `=' token.
 *
 *      Robb Matzke, 7 Feb 1997
 *      The `*' and `?'characters are now legal as part of a symbol name
 *      so we can give those pattern matching characters to the `ls'
 *      command.
 *
 *      Robb Matzke, 12 Mar 1997
 *      Since we don't have mathematical expressions yet, a numeric
 *      constant is allowed to begin with a `-'.
 *
 *      Robb Matzke, 2000-06-06
 *      Symbol names may include `-'. Something that starts with a `-' is
 *      only a number if it's followed by a digit.
 *
 *      Mark C. Miller, Mon Nov  9 18:08:05 PST 2009
 *      Added logic to support parsing of '#nnnnnn' dataset names,
 *      but only when in '/.silo' dir.
 *-------------------------------------------------------------------------
 */
int
lex_token(lex_t *f, char **lexeme, int skipnl)
{
    int          c, at, quote, inDotSiloDir=0;
    static const char *symcharsA = "_$/*?";
    static const char *symcharsB = "_$/*?#";
    const char *symchars = symcharsA;

    /* Return the current token if appropriate. */    
    if (f->tok && (!skipnl || TOK_EOL!=f->tok)) {
        if (lexeme) *lexeme = f->lexeme;
        return f->tok;
    }

    /* Skip leading space. */    
    f->prompt = skipnl ? LEX_PROMPT2 : LEX_PROMPT;
    while (EOF!=(c=lex_getc(f)) && '\n'!=c && isspace(c)) /*void*/;

    /* handle special case of leading '#' and see if we're in .silo dir */
    if ('#'==c) {
        obj_t   f1, val;
        DBfile *file;
        char cwd[1024];

        f1 = obj_new (C_SYM, "$1");
        val = sym_vboundp (f1);
        f1 = obj_dest (f1);
        if (NULL!=(file=file_file(val)) && 
            DBGetDir(file, cwd)>=0 &&
            !strncmp(cwd,"/.silo",6)) {
            inDotSiloDir = 1;
            symchars = symcharsB;
        }
    }

    /* Store the next token. */    
    if (EOF==c) {
        f->lexeme[0] = '\0';
        f->tok = EOF;

    } else if ('\n'==c) {
        if (skipnl) {
            f->tok = lex_token(f, NULL, true);
        } else {
            f->lexeme[0] = '\n';
            f->lexeme[1] = '\0';
            f->tok = TOK_EOL;
        }

    } else if ('#'==c && !inDotSiloDir) {
        while (EOF!=(c=lex_getc(f)) && '\n'!=c) /*void*/;
        lex_ungetc(f, c);
        return lex_token(f, lexeme, skipnl);

    } else if ('>'==c) {
        c = lex_getc(f);
        if ('>'==c) {
            strcpy(f->lexeme, ">>");
            f->tok = TOK_RTRT;
        } else {
            lex_ungetc(f, c);
            strcpy(f->lexeme, ">");
            f->tok = TOK_RT;
        }

    } else if (strchr("|.()[]{}:,=", c)) {
        f->lexeme[0] = c;
        f->lexeme[1] = '\0';
        f->tok = c;

    } else if (isalpha(c) || strchr(symchars,c)) {
        /* A symbol. */        
        f->lexeme[0] = c;
        f->lexeme[1] = '\0';
        at = 1;
        while (EOF!=(c=lex_getc(f)) &&
               (isalpha(c) || isdigit(c) || strchr(symchars, c))) {
            if (at+1<sizeof(f->lexeme)) {
                f->lexeme[at++] = c;
                f->lexeme[at] = '\0';
            }
        }
        lex_ungetc(f, c);
        f->tok = TOK_SYM;
      
    } else if ('-'==c) {
        /* Could be a number or a symbol */
        f->lexeme[0] = c;
        f->lexeme[1] = '\0';
        if (EOF!=(c=lex_getc(f)) && ('.'==c || isdigit(c))) {
            f->lexeme[1] = c;
            f->lexeme[2] = '\0';
            at = 2;
            while (EOF!=(c=lex_getc(f)) &&
                   (isdigit(c) || strchr("+-.eE", c))) {
                if (at+1<sizeof(f->lexeme)) {
                    f->lexeme[at++] = c;
                    f->lexeme[at] = '\0';
                }
            }
            lex_ungetc(f, c);
            f->tok = TOK_NUM;
        } else {
            at=1;
            while (EOF!=c &&
                   (isalpha(c) || isdigit(c) || strchr("_$/*?-", c))) {
                if (at+1<sizeof(f->lexeme)) {
                    f->lexeme[at++] = c;
                    f->lexeme[at] = '\0';
                }
                c = lex_getc(f);
            }
            lex_ungetc(f, c);
            f->tok = TOK_SYM;
        }
       
    } else if ('-'==c || isdigit(c)) {
        /* A number */        
        f->lexeme[0] = c;
        f->lexeme[1] = '\0';
        at = 1;
        while (EOF!=(c=lex_getc(f)) &&
               (isdigit(c) || strchr("+-.eE", c))) {
            if (at+1<sizeof(f->lexeme)) {
                f->lexeme[at++] = c;
                f->lexeme[at] = '\0';
            }
        }
        lex_ungetc(f, c);
        f->tok = TOK_NUM;

    } else if ('"'==c || '\''==c) {
        /* A string */        
        quote = c;
        at = 0;
        f->lexeme[0] = '\0';
        while (EOF!=(c=lex_getc(f)) && quote!=c && '\n'!=c) {
            if ('\\'==c) {
                switch ((c=lex_getc(f))) {
                case 'b':
                    c = '\b';
                    break;
                case 'n':
                    c = '\n';
                    break;
                case 'r':
                    c = '\r';
                    break;
                case 't':
                    c = '\t';
                    break;
                case EOF:
                    c = '\\';
                    break;
                default:
                    if (c>='0' && c<='7') {
                        int c2 = lex_getc(f);
                        if (c2>='0' && c2<='7') {
                            int c3 = lex_getc(f);
                            if (c3>='0' && c3<='7') {
                                c = ((c-'0')*8+c2-'0')*8+c3-'0';
                            } else {
                                lex_ungetc(f, c3);
                                c = (c-'0')*8+c2-'0';
                            }
                        } else {
                            lex_ungetc(f, c2);
                            c -= '0';
                        }
                    }
                    break;
                }
            }
            if (at+1<sizeof(f->lexeme)) {
                f->lexeme[at++] = c;
                f->lexeme[at] = '\0';
            }
        }
        if ('\n'==c) {
            out_errorn("linefeed inside string constant (truncated at EOL)");
            lex_ungetc(f, c);
        } else if (c<0) {
            out_errorn("EOF inside string constant (truncated at EOF)");
        }
        f->tok = TOK_STR;

    } else {
        /* Invalid character.  Don't print an error message since a
         * syntax error will result in the parser anyway. */
        f->lexeme[0] = c;
        f->lexeme[1] = '\0';
        f->tok = TOK_INVALID;
    }

    if (lexeme) *lexeme = f->lexeme;
    return f->tok;
}