Beispiel #1
0
/*
 * fieldset_copy
 *
 * Copy-constructor for field sets.  In the copy,
 * the nameref's must point to the entries in the
 * newly-constructed scope.
 */
static int
fieldset_copy (void *vctx, name_t *dst, void *dp,
            name_t *src, void *sp)
{
    namereflist_t *drefs = dp;
    namereflist_t *srefs = sp;
    expr_ctx_t ctx = vctx;
    scopectx_t dscope = name_scope(dst);
    namectx_t namectx = expr_namectx(ctx);
    nameref_t *ref;
    name_t *np;

    for (ref = namereflist_head(srefs); ref != 0; ref = ref->tq_next) {
        if (ref->np == 0) {
            // XXX should never happen
            continue;
        }
        strdesc_t *str = name_string(ref->np);
        np = name_search(dscope, str->ptr, str->len, 0);
        namereflist_instail(drefs, nameref_alloc(namectx, np));
    }

    return 1;

} /* fieldset_copy */
Beispiel #2
0
/*
 * macro_copydata
 *
 * Copy-constructor for macros.
 */
static int
macro_copydata (void *vctx, name_t *dst, void *dp, name_t *src, void *sp)
{
    struct macrodecl_s *srcm = sp;
    struct macrodecl_s *dstm = dp;
    nameref_t *ref;
    expr_ctx_t ctx = vctx;
    namectx_t namectx = expr_namectx(ctx);
    lexctx_t lctx = expr_lexmemctx(ctx);

    lexseq_init(&dstm->body);
    lexseq_copy(lctx, &dstm->body, &srcm->body);
    dstm->ptable = scope_copy(srcm->ptable, 0);
    namereflist_init(&dstm->plist);
    namereflist_init(&dstm->ilist);
    dstm->type = srcm->type;
    // We can't just copy the namereflists over verbatim; the copied
    // list has to reference the names in the copied name table, not
    // the original.
    for (ref = namereflist_head(&srcm->plist); ref != 0; ref = ref->tq_next) {
        name_t *np;
        if (ref->np == 0) {
            np = 0;
        } else {
            strdesc_t *namestr = name_string(ref->np);
            np = name_search(dstm->ptable, namestr->ptr, namestr->len, 0);
        }
        namereflist_instail(&dstm->plist, nameref_alloc(namectx, np));
    }
    for (ref = namereflist_head(&srcm->ilist); ref != 0; ref = ref->tq_next) {
        name_t *np;
        if (ref->np == 0) {
            np = 0;
        } else {
            strdesc_t *namestr = name_string(ref->np);
            np = name_search(dstm->ptable, namestr->ptr, namestr->len, 0);
        }
        namereflist_instail(&dstm->ilist, nameref_alloc(namectx, np));
    }

    return 1;

} /* macro_copydata */
Beispiel #3
0
/*
 * structure_copy
 *
 * Copy-constructor for a structure cell.  Handles
 * the fact that name references must point to the
 * newly-constructed scope tables, rather than the
 * originals.
 */
static int
structure_copy (void *vctx, name_t *dst, void *dp,
                name_t *src, void *sp)
{
    expr_ctx_t ctx = vctx;
    lexctx_t lctx = expr_lexmemctx(ctx);
    strudef_t *dstru = dp;
    strudef_t *sstru = sp;
    namectx_t namectx = expr_namectx(ctx);
    nameref_t *ref;
    name_t *np;

    dstru->acctbl = scope_copy(sstru->acctbl, 0);
    dstru->allotbl = scope_copy(sstru->allotbl, 0);
    for (ref = namereflist_head(&sstru->accformals); ref != 0;
         ref = ref->tq_next) {
        if (ref->np == 0) {
            np = 0;
        } else {
            strdesc_t *str = name_string(ref->np);
            np = name_search(dstru->acctbl, str->ptr, str->len, 0);
        }
        namereflist_instail(&dstru->accformals, nameref_alloc(namectx, np));
    }
    for (ref = namereflist_head(&sstru->alloformals); ref != 0;
         ref = ref->tq_next) {
        if (ref->np == 0) {
            np = 0;
        } else {
            strdesc_t *str = name_string(ref->np);
            np = name_search(dstru->allotbl, str->ptr, str->len, 0);
        }
        namereflist_instail(&dstru->alloformals, nameref_alloc(namectx, np));
    }
    lexseq_copy(lctx, &dstru->accbody, &sstru->accbody);
    lexseq_copy(lctx, &dstru->allobody, &sstru->allobody);

    return 1;

} /* structure_copy */
Beispiel #4
0
static void		cut_env(t_all *all, char ***env_dup)
{
	char	*name;
	int		ret;

	ret = 0;
	name = get_name(all->ch_arg[2]);
	ret = name_search(ft_strdup(name), all);
	if (ret != -1)
	{
		write_value(env_dup, ret);
		ft_strdel(&name);
	}
}
Beispiel #5
0
/*
 * macro_expand
 *
 * Expands a macro.
 */
static int
macro_expand (macroctx_t mctx, name_t *macroname, lexseq_t *result)
{
    struct macrodecl_s *macro = name_extraspace(macroname);
    expr_ctx_t ctx = mctx->ectx;
    parse_ctx_t pctx = expr_parse_ctx(ctx);
    lexctx_t lctx = parser_lexmemctx(pctx);
    expansion_t *curexp = expansion_alloc(mctx);
    expansion_t *prev_exp;
    lextype_t lt;
    lexeme_t *lex;
    lexseq_t extras;
    name_t *np;
    scopectx_t expscope;
    int which;
    int nactuals;
    punctclass_t pcl;
    lextype_t psep;
    lextype_t terms[3];
    static strdesc_t comma = STRDEF(",");

    if (macro == 0 || curexp == 0) {
        expr_signal(ctx, STC__INTCMPERR, "macro_expand");
        return 1;
    }
    memset(curexp, 0, sizeof(struct expansion_s));

    // We save the punctuation class here, since it will get
    // munged by the parsing of the macro parameters.
    parser_punctclass_get(pctx, &pcl, &psep);

    prev_exp = 0;
    if (macro->type == MACRO_COND) {
        for (prev_exp = mctx->curexp; prev_exp != 0 && prev_exp->curmacro != macroname;
             prev_exp = prev_exp->next);
    }

    nactuals = 0;
    lexseq_init(&extras);

    // Simple macros with no formal arguments get no processing
    // of parameter lists whatsoever.
    if (macro->type == MACRO_SIMPLE && namereflist_length(&macro->plist) == 0) {
        expscope = 0;
        which = 3;
    } else {
        // For keyword macros, prime the scope with the declared
        // formals, so we can inherit the default values.
        if (macro->type == MACRO_KWD) {
            expscope = scope_copy(macro->ptable, 0);
        } else {
            expscope = scope_begin(scope_namectx(parser_scope_get(pctx)), 0);
        }

        lt = parser_next(pctx, QL_NORMAL, &lex);
        if (macro->type == MACRO_KWD) {
            if (lt != LEXTYPE_DELIM_LPAR) {
                expr_signal(ctx, STC__DELIMEXP, "(");
                parser_insert(pctx, lex);
                return 1;
            }
            which = 0;
            lexeme_free(lctx, lex);
        } else {
            for (which = 0; lt != openers[which] && which < 3; which++);
            if (which >= 3 && namereflist_length(&macro->plist) > 0) {
                expr_signal(ctx, STC__DELIMEXP, "(");
                parser_insert(pctx, lex);
                return 1;
            }
            if (which >= 3) {
                parser_insert(pctx, lex);
            } else {
                lexeme_free(lctx, lex);
            }
        }
    }

    // If we had a match on an opener, process
    // the actual parameters.
    if (which < 3) {

        nameref_t *formal;
        lexseq_t val;

        terms[0] = LEXTYPE_DELIM_COMMA;
        terms[1] = closers[which];

        formal = namereflist_head(&macro->plist);

        while (1) {
            // Keyword macro actuals are of the form name=value
            // For positionals, grab the next formal-parameter name,
            // or set np to NULL to add the actual to %REMAINING.
            if (macro->type == MACRO_KWD) {
                lt = parser_next(pctx, QL_NAME, &lex);
                if (lexeme_boundtype(lex) != LEXTYPE_NAME) {
                    expr_signal(ctx, STC__NAMEEXP);
                    lexeme_free(lctx, lex);
                    break;
                }
                np = name_search(macro->ptable, lex->text.ptr, lex->text.len, 0);
                if (np == 0) {
                    expr_signal(ctx, STC__INTCMPERR, "macro_expand[2]");
                }
                lexeme_free(lctx, lex);
                if (!parser_expect(pctx, QL_NORMAL, LEXTYPE_OP_ASSIGN, 0, 1)) {
                    expr_signal(ctx, STC__OPEREXP, "=");
                    break;
                }
            } else if (nactuals < namereflist_length(&macro->plist)) {
                np = formal->np;
                formal = formal->tq_next;
            } else {
                np = 0;
            }
            lexseq_init(&val);
            // Now parse the actual-parameter, which can be an expression
            if (!parse_lexeme_seq(pctx, 0, QL_NAME, terms, 2, &val, &lt)) {
                lexseq_free(lctx, &val);
                break;
            }

            // If we are recursively expanding a conditional macro and
            // there are no parameters, we're done - no expansion.
            if (prev_exp != 0 && lexseq_length(&val) == 0 && nactuals == 0) {
                scope_end(expscope);
                free(curexp);
                return 1;
            }

            if (np == 0) {
                if (lexseq_length(&extras) > 0) {
                    lexseq_instail(&extras,
                                   lexeme_create(lctx, LEXTYPE_DELIM_COMMA, &comma));
                }
                lexseq_append(&extras, &val);
            } else {
                name_t *actual;
                // Associate the actual with the formal.  For keyword
                // macros, the scope_copy() above sets a special "no check"
                // flag that allows each name to be redeclared once.
                // name_declare() clears this flag, so we can catch genuine
                // redeclarations.
                actual = macparam_special(expscope, name_string(np), &val);
                if (actual == 0) {
                    expr_signal(ctx, STC__INTCMPERR, "macro_expand[3]");
                }
                lexseq_free(lctx, &val);
            }

            nactuals += 1;

            if (lt == closers[which]) {
                break;
            }

            if (lt != LEXTYPE_DELIM_COMMA) {
                expr_signal(ctx, STC__DELIMEXP, ",");
                break;
            }

        } /* while (1) */

        if (lt != closers[which]) {
            expr_signal(ctx, STC__DELIMEXP, "closer");
            lexseq_free(lctx, &extras);
            scope_end(expscope);
            return 1;
        }

        if (nactuals < namereflist_length(&macro->plist)) {
            name_t *anp;
            while (formal != 0) {
                anp = macparam_special(expscope, name_string(formal->np), 0);
                if (anp == 0) {
                    expr_signal(ctx, STC__INTCMPERR, "macro_expand[4]");
                }
                formal = formal->tq_next;
            }
        }

    } /* if which < 3 */

    // The macro actual parameters are now processed; hook
    // the scope into the current hierarchy, restore the punctuation
    // class to what it was before we parsed the actuals, and
    // generate the expansion sequence.

    parser_punctclass_set(pctx, pcl, psep);

    curexp->count = (prev_exp == 0 ? 0 : prev_exp->count);
    curexp->expscope = expscope;
    curexp->curmacro = macroname;
    curexp->next = mctx->curexp;
    curexp->nactuals = nactuals;
    lexseq_append(&curexp->remaining, &extras);
    mctx->curexp = curexp;

    return prepare_body(mctx, curexp, result);

} /* macro_expand */