Ejemplo n.º 1
0
static uclptr_t STRING_create (const void* sample_data)
{
	if (sizeof(char*) <= sizeof(cell_t))
	{
		uclptr_t storage_index = cell_alloc();
		if (storage_index != NIL)
		{
			int length = strlen(sample_data) + 1;
			//char **storage_cell_ptr = (char**)&uclmem[storage_index];
			char **storage_cell_ptr = (char**)&CONTAINER(storage_index);
			MANAGED(storage_index) = 1;
			*storage_cell_ptr = (char*)malloc(length);
			memset (*storage_cell_ptr, 0, length);
			strcpy (*storage_cell_ptr, sample_data);
			return storage_index;
		}
	}
	else /* физический указатель очень велик и не помещается даже на место целой ячейки */
	{
		int length = strlen(sample_data) + 1;
		char *src = (char*)malloc(length);
		strcpy (src, sample_data);
		return chop (&src, sizeof(void*));
	}
	return NIL;
}
Ejemplo n.º 2
0
static void
cell(struct tbl_node *tbl, struct tbl_row *rp,
		int ln, const char *p, int *pos)
{
	int		 i;
	enum tbl_cellt	 c;

	/* Handle leading vertical lines */

	while (p[*pos] == ' ' || p[*pos] == '\t' || p[*pos] == '|') {
		if (p[*pos] == '|') {
			if (rp->vert < 2)
				rp->vert++;
			else
				mandoc_msg(MANDOCERR_TBLLAYOUT_VERT,
				    tbl->parse, ln, *pos, NULL);
		}
		(*pos)++;
	}

again:
	while (p[*pos] == ' ' || p[*pos] == '\t')
		(*pos)++;

	if (p[*pos] == '.' || p[*pos] == '\0')
		return;

	/* Parse the column position (`c', `l', `r', ...). */

	for (i = 0; i < KEYS_MAX; i++)
		if (tolower((unsigned char)p[*pos]) == keys[i].name)
			break;

	if (i == KEYS_MAX) {
		mandoc_vmsg(MANDOCERR_TBLLAYOUT_CHAR, tbl->parse,
		    ln, *pos, "%c", p[*pos]);
		(*pos)++;
		goto again;
	}
	c = keys[i].key;

	/* Special cases of spanners. */

	if (c == TBL_CELL_SPAN) {
		if (rp->last == NULL)
			mandoc_msg(MANDOCERR_TBLLAYOUT_SPAN,
			    tbl->parse, ln, *pos, NULL);
		else if (rp->last->pos == TBL_CELL_HORIZ ||
		    rp->last->pos == TBL_CELL_DHORIZ)
			c = rp->last->pos;
	} else if (c == TBL_CELL_DOWN && rp == tbl->first_row)
		mandoc_msg(MANDOCERR_TBLLAYOUT_DOWN,
		    tbl->parse, ln, *pos, NULL);

	(*pos)++;

	/* Allocate cell then parse its modifiers. */

	mods(tbl, cell_alloc(tbl, rp, c), ln, p, pos);
}
Ejemplo n.º 3
0
Archivo: interp.c Proyecto: sbstp/zeta
/**
Evaluate a function call
*/
value_t eval_call(
    clos_t* callee,
    array_t* arg_exprs,
    clos_t* caller,
    value_t* caller_locals
)
{
    ast_fun_t* fptr = callee->fun;
    assert (fptr != NULL);

    if (arg_exprs->len != fptr->param_decls->len)
    {
        printf("argument count mismatch\n");
        exit(-1);
    }

    // Allocate space for the local variables
    value_t* callee_locals = alloca(
        sizeof(value_t) * fptr->local_decls->len
    );

    // Allocate mutable cells for the escaping variables
    for (size_t i = 0; i < fptr->esc_locals->len; ++i)
    {
        ast_decl_t* decl = array_get(fptr->esc_locals, i).word.decl;
        assert (decl->esc);
        assert (decl->idx < fptr->local_decls->len);
        callee_locals[decl->idx] = value_from_obj((heapptr_t)cell_alloc());
    }

    // Evaluate the argument values
    for (size_t i = 0; i < arg_exprs->len; ++i)
    {
        //printf("evaluating arg %ld\n", i);

        heapptr_t param_decl = array_get_ptr(fptr->param_decls, i);

        // Evaluate the parameter value
        value_t arg_val = eval_expr(
            array_get_ptr(arg_exprs, i),
            caller,
            caller_locals
        );

        // Assign the value to the parameter
        eval_assign(
            param_decl,
            arg_val,
            callee,
            callee_locals
        );
    }

    // Evaluate the unit function body in the local frame
    return eval_expr(fptr->body_expr, callee, callee_locals);
}
Ejemplo n.º 4
0
static int
cell(struct tbl_node *tbl, struct tbl_row *rp, 
		int ln, const char *p, int *pos)
{
	int		 i;
	enum tbl_cellt	 c;

	/* Parse the column position (`r', `R', `|', ...). */

	for (i = 0; i < KEYS_MAX; i++)
		if (tolower((unsigned char)p[*pos]) == keys[i].name)
			break;

	if (KEYS_MAX == i) {
		TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
		return(0);
	}

	c = keys[i].key;

	/*
	 * If a span cell is found first, raise a warning and abort the
	 * parse.  FIXME: recover from this somehow?
	 */

	if (NULL == rp->first && TBL_CELL_SPAN == c) {
		TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
		return(0);
	}

	(*pos)++;

	/* Extra check for the double-vertical. */

	if (TBL_CELL_VERT == c && '|' == p[*pos]) {
		(*pos)++;
		c = TBL_CELL_DVERT;
	} 
	
	/* Disallow adjacent spacers. */

	if (rp->last && (TBL_CELL_VERT == c || TBL_CELL_DVERT == c) &&
			(TBL_CELL_VERT == rp->last->pos || 
			 TBL_CELL_DVERT == rp->last->pos)) {
		TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos - 1);
		return(0);
	}

	/* Allocate cell then parse its modifiers. */

	return(mods(tbl, cell_alloc(tbl, rp, c), ln, p, pos));
}
Ejemplo n.º 5
0
static uclptr_t INTEGER32_create (const void* sample_data)
/* Теперь надо посмотреть, влезает ли 32-битное число в поле CDR.
 * Если не влезает, оно будет храниться в отдельной ячейке (сделаем смелое предположение о том, что туда-то уж оно влезет). */
{
	if (sizeof(int32_t) != sizeof(uclptr_t)) /* определяется на этапе компиляции */
	{
		uclptr_t storage_index = cell_alloc(); /* возьмём ещё одну ячейку */
		//int32_t **storage_cell_ptr = (int32_t**)&uclmem[storage_index]; /* представим, что это указатель на int */
		int32_t **storage_cell_ptr = (int32_t**)&CONTAINER(storage_index); /* представим, что это указатель на int */
		MANAGED(storage_index) = 1;
		*storage_cell_ptr = (int32_t*)sample_data; /* положим его туда */
		return storage_index; /* вернём индекс ячейки хранения */
	}
	else return (uint32_t)((intptr_t)sample_data);
}
Ejemplo n.º 6
0
static uclptr_t VECTOR_create (const void* sample_data) /* параметр - uint32_t, количество выделяемых ячеек. */
/* Эта функция только создаёт пустой вектор, его наполнение - забота совершенно другой конструкции.
 * */
{
	uint32_t i, n = (uintptr_t)sample_data;
	uint32_t size = (n * sizeof(uclptr_t));	/* смело! А вдруг упрёмся в ограничение? */
	ucl_vector_t *vector;
	uclptr_t storage_index;

	if (sizeof(void*) <= sizeof(cell_t)) /* если указатель на кучу влезает целиком в поле container, то используем эту схему хранения */
	{
		storage_index = cell_alloc();
		if (storage_index != NIL)
		{
			ucl_vector_t **storage_cell_ptr = (ucl_vector_t**)&CONTAINER(storage_index);
			//GC(storage_index) = GC_TRANSIENT;
			MANAGED(storage_index) = 1;
			*storage_cell_ptr = (ucl_vector_t*)malloc(sizeof(ucl_vector_t)); /* выделяем память под дескриптор ветора */
			vector = *storage_cell_ptr;
		}
		else
		{
			printf ("Panic stop: no free memory left!\n");
			exit(-1);
		}
	}
	else /* если физический указатель очень велик и не помещается даже на место целой ячейки, тогда используем другую схему хранения - чоппер! */
	{
		vector = (ucl_vector_t*)malloc(sizeof(ucl_vector_t));
		storage_index = chop (&vector, sizeof(ucl_vector_t*));
	}
	vector->length = n;
	vector->ptr = (uclptr_t*)malloc(size);
	for (i=0; i < vector->length; i++)
	{
		vector->ptr[i] = NIL;
	}
	return storage_index;
}
Ejemplo n.º 7
0
void
tbl_layout(struct tbl_node *tbl, int ln, const char *p, int pos)
{
	struct tbl_row	*rp;

	rp = NULL;
	for (;;) {
		/* Skip whitespace before and after each cell. */

		while (p[pos] == ' ' || p[pos] == '\t')
			pos++;

		switch (p[pos]) {
		case ',':  /* Next row on this input line. */
			pos++;
			rp = NULL;
			continue;
		case '\0':  /* Next row on next input line. */
			return;
		case '.':  /* End of layout. */
			pos++;
			tbl->part = TBL_PART_DATA;

			/*
			 * When the layout is completely empty,
			 * default to one left-justified column.
			 */

			if (tbl->first_row == NULL) {
				tbl->first_row = tbl->last_row =
				    mandoc_calloc(1, sizeof(*rp));
			}
			if (tbl->first_row->first == NULL) {
				mandoc_msg(MANDOCERR_TBLLAYOUT_NONE,
				    tbl->parse, ln, pos, NULL);
				cell_alloc(tbl, tbl->first_row,
				    TBL_CELL_LEFT);
				return;
			}

			/*
			 * Search for the widest line
			 * along the left and right margins.
			 */

			for (rp = tbl->first_row; rp; rp = rp->next) {
				if (tbl->opts.lvert < rp->vert)
					tbl->opts.lvert = rp->vert;
				if (rp->last != NULL &&
				    rp->last->col + 1 == tbl->opts.cols &&
				    tbl->opts.rvert < rp->last->vert)
					tbl->opts.rvert = rp->last->vert;

				/* If the last line is empty, drop it. */

				if (rp->next != NULL &&
				    rp->next->first == NULL) {
					free(rp->next);
					rp->next = NULL;
					tbl->last_row = rp;
				}
			}
			return;
		default:  /* Cell. */
			break;
		}

		/*
		 * If the last line had at least one cell,
		 * start a new one; otherwise, continue it.
		 */

		if (rp == NULL) {
			if (tbl->last_row == NULL ||
			    tbl->last_row->first != NULL) {
				rp = mandoc_calloc(1, sizeof(*rp));
				if (tbl->last_row)
					tbl->last_row->next = rp;
				else
					tbl->first_row = rp;
				tbl->last_row = rp;
			} else
				rp = tbl->last_row;
		}
		cell(tbl, rp, ln, p, &pos);
	}
}
Ejemplo n.º 8
0
static int
cell(struct tbl_node *tbl, struct tbl_row *rp, 
		int ln, const char *p, int *pos)
{
	int		 vert, i;
	enum tbl_cellt	 c;

	/* Handle vertical lines. */

	for (vert = 0; '|' == p[*pos]; ++*pos)
		vert++;
	while (' ' == p[*pos])
		(*pos)++;

	/* Parse the column position (`c', `l', `r', ...). */

	for (i = 0; i < KEYS_MAX; i++)
		if (tolower((unsigned char)p[*pos]) == keys[i].name)
			break;

	if (KEYS_MAX == i) {
		mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, 
				ln, *pos, NULL);
		return(0);
	}

	c = keys[i].key;

	/*
	 * If a span cell is found first, raise a warning and abort the
	 * parse.  If a span cell is found and the last layout element
	 * isn't a "normal" layout, bail.
	 *
	 * FIXME: recover from this somehow?
	 */

	if (TBL_CELL_SPAN == c) {
		if (NULL == rp->first) {
			mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
					ln, *pos, NULL);
			return(0);
		} else if (rp->last)
			switch (rp->last->pos) {
			case (TBL_CELL_HORIZ):
			case (TBL_CELL_DHORIZ):
				mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
						ln, *pos, NULL);
				return(0);
			default:
				break;
			}
	}

	/*
	 * If a vertical spanner is found, we may not be in the first
	 * row.
	 */

	if (TBL_CELL_DOWN == c && rp == tbl->first_row) {
		mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, ln, *pos, NULL);
		return(0);
	}

	(*pos)++;

	/* Disallow adjacent spacers. */

	if (vert > 2) {
		mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, ln, *pos - 1, NULL);
		return(0);
	}

	/* Allocate cell then parse its modifiers. */

	return(mods(tbl, cell_alloc(tbl, rp, c, vert), ln, p, pos));
}