예제 #1
0
USING_NAMESPACE_ACADO

// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// SIMPLE AUXILIARY FUNCTION:
Expression symmetricDoubleProduct( const Expression& expr, const Expression& arg ) {

    uint dim = arg.getNumCols();
    uint dim2 = arg.getNumRows();

    IntermediateState inter_res = zeros<double>(dim2,dim);
    for( uint i = 0; i < dim; i++ ) {
        for( uint k1 = 0; k1 < dim2; k1++ ) {
            for( uint k2 = 0; k2 <= k1; k2++ ) {
                inter_res(k1,i) += expr(k1,k2)*arg(k2,i);
            }
            for( uint k2 = k1+1; k2 < dim2; k2++ ) {
                inter_res(k1,i) += expr(k2,k1)*arg(k2,i);
            }
        }
    }

    Expression new_expr( "", dim, dim );
    for( uint i = 0; i < dim; i++ ) {
        for( uint j = 0; j <= i; j++ ) {
            Expression new_tmp = 0;
            for( uint k1 = 0; k1 < dim2; k1++ ) {
                new_tmp = new_tmp+arg(k1,i)*inter_res(k1,j);
            }
            new_expr(i,j) = new_tmp;
            new_expr(j,i) = new_tmp;
        }
    }
    return new_expr;
}
예제 #2
0
파일: eval.c 프로젝트: S010/misc
struct expr    *
cdr(struct expr * e, struct context * ctx)
{
	struct list    *nl;
	struct expr    *a, *re;

	if (!e)
		return empty_list();

	if (list_len(e) < 2) {
		free_expr(e);
		return empty_list();
	}
	a = eval(e->v.list->next->v, ctx);
	if (a->t != LLIST || a->v.list == NULL) {
		full_free_expr(a);
		free_expr(e);
		return empty_list();
	}
	nl = list_dup(a->v.list->next);
	if (!nl) {
		re = empty_list();
	} else {
		re = new_expr(LLIST);
		re->v.list = nl;
	}
	full_free_expr(a);
	free_expr(e);
	return re;
}
예제 #3
0
파일: eval.c 프로젝트: S010/misc
struct expr    *
cons(struct expr * e, struct context * ctx)
{
	struct expr    *ne, *a, *b, *re;
	struct list    *l;

	if (!e || list_len(e) < 3) {
		dbgprintf("invalid cons expr\n");
		free_expr(e);
		return empty_list();
	}
	a = eval(e->v.list->next->v, ctx);
	b = eval(e->v.list->next->next->v, ctx);

	if (b->t != LLIST) {
		full_free_expr(a);
		re = empty_list();
	} else {
		re = new_expr(LLIST);
		list_add(re, a);
		for (l = b->v.list; l != NULL; l = l->next)
			list_add(re, exprs_dup(l->v));
		free_list(l);
	}
	full_free_expr(b);
	free_expr(e);
	return re;
}
예제 #4
0
파일: parse_gnu.c 프로젝트: boostsup/minix3
static expression_t *gnu_get_oplist(asm86_t * a, int *pn, int deref)
/* Get a comma (or colon for jmpf and callf) separated list of instruction
 * operands.
 */
{
	expression_t *e, *o1, *o2;
	token_t *t;
	int sreg;

	if ((e= gnu_get_operand(a, pn, deref)) == nil) return nil;

	t = get_token(*pn);
	
	if (t->symbol == ':' && IS_REGSEG(sreg = isregister(e->name))) {
		a->seg = segreg2seg(sreg);
		del_expr(e);
		(*pn)++;
		e = gnu_get_oplist(a, pn, deref);
	}
	else if (t->symbol == ',' || t->symbol == ':') {
		o1= e;
		(*pn)++;
		if ((o2= gnu_get_oplist(a, pn, deref)) == nil) {
			del_expr(o1);
			return nil;
		}
		e= new_expr();
		e->operator= ',';
		e->left= o2;
		e->right= o1;
	}
	return e;
}
예제 #5
0
파일: tinyexpr.c 프로젝트: cguebert/Panda
static te_expr *base(state *s) {
    /* <base>      =    <constant> | <variable> | <function> <power> | "(" <expr> ")" */
    te_expr *ret;

    switch (s->type) {
        case TOK_NUMBER:
            ret = new_expr(0, 0);
            ret->value = s->value;
            next_token(s);
            break;

        case TOK_VARIABLE:
            ret = new_expr(0, 0);
            ret->bound = s->var;
            next_token(s);
            break;

        case TOK_FUNCTION1:
            ret = new_expr(0, 0);
            ret->f1 = s->f1;
            next_token(s);
            ret->left = power(s);
            break;

        case TOK_OPEN:
            next_token(s);
            ret = expr(s);
            if (s->type != TOK_CLOSE) {
                s->type = TOK_ERROR;
            } else {
                next_token(s);
            }
            break;

        default:
            ret = new_expr(0, 0);
            s->type = TOK_ERROR;
            ret->value = NAN;
            break;
    }

    return ret;
}
예제 #6
0
파일: eval.c 프로젝트: S010/misc
struct expr    *
atom_t(void)
{
	struct expr    *e;

	e = new_expr(LATOM);
	e->v.atom = new_atom("t");

	return e;
}
예제 #7
0
exprt concatenate_array_id(
		const exprt &array, const mp_integer &index,
		const typet &type)
{
  std::string a, identifier;
  a = array.get_string(ID_identifier);
  identifier=a+"["+integer2string(index)+"]";
  symbol_exprt new_expr(identifier, type);

  return new_expr;
}
예제 #8
0
파일: tinyexpr.c 프로젝트: cguebert/Panda
static te_expr *term(state *s) {
    /* <term>      =    <factor> {("*" | "/" | "%") <factor>} */
    te_expr *ret = factor(s);

    while (s->type == TOK_FUNCTION2 && (s->f2 == mul || s->f2 == divide || s->f2 == fmod)) {
        te_fun2 t = s->f2;
        next_token(s);
        ret = new_expr(ret, factor(s));
        ret->f2 = t;
    }

    return ret;
}
예제 #9
0
파일: tinyexpr.c 프로젝트: cguebert/Panda
static te_expr *expr(state *s) {
    /* <expr>      =    <term> {("+" | "-") <term>} */
    te_expr *ret = term(s);

    while (s->type == TOK_FUNCTION2 && (s->f2 == add || s->f2 == sub)) {
        te_fun2 t = s->f2;
        next_token(s);
        ret = new_expr(ret, term(s));
        ret->f2 = t;
    }

    return ret;
}
예제 #10
0
파일: tinyexpr.c 프로젝트: cguebert/Panda
static te_expr *factor(state *s) {
    /* <factor>    =    <power> {"^" <power>} */
    te_expr *ret = power(s);

    while (s->type == TOK_FUNCTION2 && (s->f2 == pow)) {
        te_fun2 t = s->f2;
        next_token(s);
        ret = new_expr(ret, power(s));
        ret->f2 = t;
    }

    return ret;
}
예제 #11
0
void goto_symext::replace_nondet(exprt &expr)
{
  if(expr.id()==ID_side_effect &&
     expr.get(ID_statement)==ID_nondet)
  {
    exprt new_expr(ID_nondet_symbol, expr.type());
    new_expr.set(ID_identifier, "symex::nondet"+std::to_string(nondet_count++));
    new_expr.add_source_location()=expr.source_location();
    expr.swap(new_expr);
  }
  else
    Forall_operands(it, expr)
      replace_nondet(*it);
}
예제 #12
0
파일: eval.c 프로젝트: S010/misc
struct expr    *
defun(struct expr * e, struct context * ctx)
{
	struct expr    *pe, *pl;
	struct list    *l;

	if (!e || list_len(e) < 4) {
		free_expr(e);
		return empty_list();
	}
	if (!e->v.list->next || !e->v.list->next->v || e->v.list->next->v->t != LATOM || !e->v.list->next->v->v.atom || !e->v.list->next->v->v.atom->v) {
		free_expr(e);
		return empty_list();
	}
	if (!e->v.list->next->next || !is_valid_p_expr(e->v.list->next->next->v)) {
		free_expr(e);
		return empty_list();
	}
	if (!e->v.list->next->next->next || !e->v.list->next->next->next->v) {
		free_expr(e);
		return empty_list();
	}
	pl = new_expr(LLIST);
	pl->v.list = new_list();
	pl->v.list->v = new_expr(LATOM);
	pl->v.list->v->v.atom = new_atom("lambda");
	pl->v.list->next = new_list();
	pl->v.list->next->v = exprs_dup(e->v.list->next->next->v);
	pl->v.list->next->next = new_list();
	pl->v.list->next->next->v = exprs_dup(e->v.list->next->next->next->v);

	pe = add_to_context(ctx, strdup(e->v.list->next->v->v.atom->v), pl);
	full_free_expr(pe);
	free_expr(e);

	return empty_list();
}
예제 #13
0
exprt concatenate_array_id(
		const exprt &array, const exprt &index,
		const typet &type)
{
  std::string a, idx, identifier;
  a = array.get_string(ID_identifier);

  if (index.id()==ID_typecast)
    idx = index.op0().get_string(ID_value);
  else
    idx = index.get_string(ID_value);

  mp_integer i=string2integer(idx);
  identifier=a+"["+integer2string(i)+"]";
  symbol_exprt new_expr(identifier, type);

  return new_expr;
}
예제 #14
0
파일: tinyexpr.c 프로젝트: cguebert/Panda
static te_expr *power(state *s) {
    /* <power>     =    {("-" | "+")} <base> */
    int sign = 1;
    while (s->type == TOK_FUNCTION2 && (s->f2 == add || s->f2 == sub)) {
        if (s->f2 == sub) sign = -sign;
        next_token(s);
    }

    te_expr *ret;

    if (sign == 1) {
        ret = base(s);
    } else {
        ret = new_expr(base(s), 0);
        ret->f1 = negate;
    }

    return ret;
}
예제 #15
0
파일: eval.c 프로젝트: S010/misc
struct expr    *
list(struct expr * e, struct context * ctx)
{
	struct expr    *pe, *re;
	const struct list *l;
	int             i;

	if (!e)
		return empty_list();

	if (list_len(e) < 2) {
		free_expr(e);
		return empty_list();
	}
	re = new_expr(LLIST);
	for (i = 1; (l = get_list_el(e, i)) != NULL; ++i) {
		pe = eval(l->v, ctx);
		list_add(re, pe);
	}
	free_expr(e);
	return re;
}
예제 #16
0
static expression_t *ack_get_oplist(int *pn, int deref)
/* Get a comma (or colon for jmpf and callf) separated list of instruction
 * operands.
 */
{
	expression_t *e, *o1, *o2;
	token_t *t;

	if ((e= ack_get_operand(pn, deref)) == nil) return nil;

	if ((t= get_token(*pn))->symbol == ',' || t->symbol == ':') {
		o1= e;
		(*pn)++;
		if ((o2= ack_get_oplist(pn, deref)) == nil) {
			del_expr(o1);
			return nil;
		}
		e= new_expr();
		e->operator= ',';
		e->left= o1;
		e->right= o2;
	}
	return e;
}
예제 #17
0
파일: eval.c 프로젝트: S010/misc
struct expr    *
empty_list(void)
{
	return new_expr(LLIST);
}
예제 #18
0
파일: parse_gnu.c 프로젝트: boostsup/minix3
asm86_t *gnu_get_instruction(void)
{
	asm86_t *a= nil;
	expression_t *e;
	token_t *t;

	while ((t= get_token(0))->symbol == ';' || t->symbol == '/') {
		zap();		/* if a comment started by a '/' */
		skip_token(1);
	}

	if (t->type == T_EOF) return nil;

	if (t->type == T_COMMENT || t->type == T_C_PREPROCESSOR) {

		a = new_asm86();
		if (t->type == T_COMMENT)
			a->opcode = COMMENT;
		else
			a->opcode = C_PREPROCESSOR;

		a->raw_string = malloc(t->len + 1);
		if (!a->raw_string)
			return NULL;

		strcpy(a->raw_string, t->name);
		skip_token(1);
		return a;
	}

	if (t->symbol == '#') {
		/* Preprocessor line and file change. */

		if ((t= get_token(1))->type != T_WORD || !isanumber(t->name)
			|| get_token(2)->type != T_STRING
		) {
			parse_err(1, t, "file not preprocessed?\n");
			zap();
		} else {
			set_file(get_token(2)->name,
				strtol(get_token(1)->name, nil, 0) - 1);

			/* GNU CPP adds extra cruft, simply zap the line. */
			zap();
		}
		a= gnu_get_instruction();
	} else
	if (t->type == T_WORD && get_token(1)->symbol == ':') {
		/* A label definition. */

		a= new_asm86();
		a->line= t->line;
		a->opcode= DOT_LABEL;
		a->optype= PSEUDO;
		a->args= e= new_expr();
		e->operator= ':';
		e->name= copystr(t->name);
		syms_add(t->name);
		skip_token(2);
	} else
	if (t->type == T_WORD && get_token(1)->symbol == '=') {
		int n= 2;

		if ((e= gnu_get_C_expression(&n)) == nil) {
			zap();
			a= gnu_get_instruction();
		} else
		if (get_token(n)->type != T_COMMENT && get_token(n)->symbol != ';') {
			parse_err(1, t, "garbage after assignment\n");
			zap();
			a= gnu_get_instruction();
		} else {
			a= new_asm86();
			if (get_token(n)->type == T_COMMENT) {
				token_t *c = get_token(n);

				a->raw_string = malloc(c->len + 1);
				if (!a->raw_string)
					return NULL;

				strcpy(a->raw_string, c->name);
			}
			a->line= t->line;
			a->opcode= DOT_EQU;
			a->optype= PSEUDO;
			a->args= new_expr();
			a->args->operator= '=';
			a->args->name= copystr(t->name);
			syms_add(t->name);
			a->args->middle= e;
			skip_token(n+1);
		}
	} else
	if (t->type == T_WORD) {
		if ((a= gnu_get_statement()) == nil) {
			zap();
			a= gnu_get_instruction();
		}
	} else {
		parse_err(1, t, "syntax error\n");
		zap();
		a= gnu_get_instruction();
	}
	return a;
}
예제 #19
0
파일: cjit_read.c 프로젝트: pcpa/lightning
token_t
primary(void)
{
    expr_t	*expr;
    entry_t	*entry;
    token_t	 token;
    int		 ch, lineno, column;

    if (ahead) {
        token = ahead->token;
        push_expr(ahead);
        ahead = NULL;
        return (token);
    }
    ch = skipws();
    lineno = parser.lineno;
    column = parser.column - 1;
    switch (ch) {
    case EOF:
        token = tok_eof;
        break;
    case '(':
        token = tok_oparen;
        break;
    case ')':
        token = tok_cparen;
        break;
    case '[':
        token = tok_obrack;
        break;
    case ']':
        token = tok_cbrack;
        break;
    case '{':
        token = tok_obrace;
        break;
    case '}':
        token = tok_cbrace;
        break;
    case ';':
        token = tok_semicollon;
        break;
    case ':':
        token = tok_collon;
        break;
    case ',':
        token = tok_comma;
        break;
    case '.':
        if ((ch = getch()) != '.') {
            ungetch(ch);
            token = tok_dot;
        }
        else if (getch() != '.')		error(NULL, "error near '..'");
        else				token = tok_ellipsis;
        break;
    case '=':
        if ((ch = getch()) == '=')		token = tok_eq;
        else {
            ungetch(ch);
            token = tok_set;
        }
        break;
    case '&':
        if ((ch = getch()) == '&')		token = tok_andand;
        else if (ch == '=')			token = tok_andset;
        else {
            ungetch(ch);
            token = tok_and;
        }
        break;
    case '|':
        if ((ch = getch()) == '|')		token = tok_oror;
        else if (ch == '=')			token = tok_orset;
        else {
            ungetch(ch);
            token = tok_or;
        }
        break;
    case '^':
        if ((ch = getch()) == '=')		token = tok_xorset;
        else {
            ungetch(ch);
            token = tok_xor;
        }
        break;
    case '<':
        if ((ch = getch()) == '=')		token = tok_le;
        else if (ch == '<') {
            if ((ch = getch()) == '=')	token = tok_lshset;
            else {
                ungetch(ch);
                token = tok_lsh;
            }
        }
        else {
            ungetch(ch);
            token = tok_lt;
        }
        break;
    case '>':
        if ((ch = getch()) == '=')		token = tok_ge;
        else if (ch == '>') {
            if ((ch = getch()) == '=')	token = tok_rshset;
            else {
                ungetch(ch);
                token = tok_rsh;
            }
        }
        else {
            ungetch(ch);
            token = tok_gt;
        }
        break;
    case '+':
        if ((ch = getch()) == '+')		token = tok_inc;
        else if (ch == '=')			token = tok_addset;
        else {
            ungetch(ch);
            token = tok_add;
        }
        break;
    case '-':
        if ((ch = getch()) == '-')		token = tok_dec;
        else if (ch == '=')			token = tok_subset;
        else if (ch == '>')			token = tok_arrow;
        else {
            ungetch(ch);
            token = tok_sub;
        }
        break;
    case '*':
        if ((ch = getch()) == '=')		token = tok_mulset;
        else {
            ungetch(ch);
            token = tok_mul;
        }
        break;
    case '/':
        if ((ch = getch()) == '=')		token = tok_divset;
        else {
            ungetch(ch);
            token = tok_div;
        }
        break;
    case '%':
        if ((ch = getch()) == '=')		token = tok_remset;
        else {
            ungetch(ch);
            token = tok_rem;
        }
        break;
    case '!':
        if ((ch = getch()) == '=')		token = tok_ne;
        else {
            ungetch(ch);
            token = tok_not;
        }
        break;
    case '~':
        token = tok_com;
        break;
    case '?':
        token = tok_question;
        break;
    case 'a' ... 'z':
    case 'A' ... 'Z':
    case '_':
        token = identifier(ch);
        break;
    case '0' ... '9':
        token = number(ch);
        break;
    case '"':
        token = string();
        break;
    case '\'':
        token = character();
        break;
    default:
        error(NULL, "syntax error");
    }

    parser.token = token;
    expr = new_expr(token, lineno, column);
    if (token == tok_string) {
        if ((entry = get_hash(strings, parser.string)) == NULL) {
            entry = (entry_t *)xmalloc(sizeof(entry_t));
            entry->name.string = xstrdup(parser.string);
            entry->value = entry->name.string;
            put_hash(strings, entry);
        }
        expr->data._unary.cp = entry->value;
    }
    else
        expr->data._unary = parser.value;
    push_expr(expr);

    return (token);
}
예제 #20
0
static expression_t *ack_get_C_expression(int *pn)
/* Read a "C-like" expression.  Note that we don't worry about precedence,
 * the expression is printed later like it is read.  If the target language
 * does not have all the operators (like ~) then this has to be repaired by
 * changing the source file.  (No problem, you still have one source file
 * to maintain, not two.)
 */
{
	expression_t *e, *a1, *a2;
	token_t *t;

	if ((t= get_token(*pn))->symbol == '[') {
		/* [ expr ]: grouping. */
		(*pn)++;
		if ((a1= ack_get_C_expression(pn)) == nil) return nil;
		if (get_token(*pn)->symbol != ']') {
			parse_err(1, t, "missing ]\n");
			del_expr(a1);
			return nil;
		}
		(*pn)++;
		e= new_expr();
		e->operator= '[';
		e->middle= a1;
	} else
	if (t->type == T_WORD || t->type == T_STRING) {
		/* Label, number, or string. */
		e= new_expr();
		e->operator= t->type == T_WORD ? 'W' : 'S';
		e->name= allocate(nil, (t->len+1) * sizeof(e->name[0]));
		memcpy(e->name, t->name, t->len+1);
		e->len= t->len;
		(*pn)++;
	} else
	if (t->symbol == '+' || t->symbol == '-' || t->symbol == '~') {
		/* Unary operator. */
		(*pn)++;
		if ((a1= ack_get_C_expression(pn)) == nil) return nil;
		e= new_expr();
		e->operator= t->symbol;
		e->middle= a1;
	} else {
		parse_err(1, t, "expression syntax error\n");
		return nil;
	}

	switch ((t= get_token(*pn))->symbol) {
	case '+':
	case '-':
	case '*':
	case '/':
	case '%':
	case '&':
	case '|':
	case '^':
	case S_LEFTSHIFT:
	case S_RIGHTSHIFT:
		(*pn)++;
		a1= e;
		if ((a2= ack_get_C_expression(pn)) == nil) {
			del_expr(a1);
			return nil;
		}
		e= new_expr();
		e->operator= t->symbol;
		e->left= a1;
		e->right= a2;
	}
	return e;
}
예제 #21
0
asm86_t *ack_get_instruction(void)
{
	asm86_t *a= nil;
	expression_t *e;
	token_t *t;

	while ((t= get_token(0))->symbol == ';')
		skip_token(1);

	if (t->type == T_EOF) return nil;

	if (t->symbol == '#') {
		/* Preprocessor line and file change. */

		if ((t= get_token(1))->type != T_WORD || !isanumber(t->name)
			|| get_token(2)->type != T_STRING
		) {
			parse_err(1, t, "file not preprocessed?\n");
			zap();
		} else {
			set_file(get_token(2)->name,
				strtol(get_token(1)->name, nil, 0) - 1);

			/* GNU CPP adds extra cruft, simply zap the line. */
			zap();
		}
		a= ack_get_instruction();
	} else
	if (t->type == T_WORD && get_token(1)->symbol == ':') {
		/* A label definition. */
		a= new_asm86();
		a->line= t->line;
		a->opcode= DOT_LABEL;
		a->optype= PSEUDO;
		a->args= e= new_expr();
		e->operator= ':';
		e->name= copystr(t->name);
		skip_token(2);
	} else
	if (t->type == T_WORD && get_token(1)->symbol == '=') {
		int n= 2;

		if ((e= ack_get_C_expression(&n)) == nil) {
			zap();
			a= ack_get_instruction();
		} else
		if (get_token(n)->symbol != ';') {
			parse_err(1, t, "garbage after assignment\n");
			zap();
			a= ack_get_instruction();
		} else {
			a= new_asm86();
			a->line= t->line;
			a->opcode= DOT_EQU;
			a->optype= PSEUDO;
			a->args= new_expr();
			a->args->operator= '=';
			a->args->name= copystr(t->name);
			a->args->middle= e;
			skip_token(n+1);
		}
	} else
	if (t->type == T_WORD) {
		if ((a= ack_get_statement()) == nil) {
			zap();
			a= ack_get_instruction();
		}
	} else {
		parse_err(1, t, "syntax error\n");
		zap();
		a= ack_get_instruction();
	}
	return a;
}
예제 #22
0
static expression_t *ack_get_operand(int *pn, int deref)
/* Get something like: (memory), offset(base)(index*scale), or simpler. */
{
	expression_t *e, *offset, *base, *index;
	token_t *t;
	int c;

	/* Is it (memory)? */
	if (get_token(*pn)->symbol == '('
		&& ((t= get_token(*pn + 1))->type != T_WORD
			|| !isregister(t->name))
	) {
		/* A memory dereference. */
		(*pn)++;
		if ((offset= ack_get_C_expression(pn)) == nil) return nil;
		if (get_token(*pn)->symbol != ')') {
			parse_err(1, t, "operand syntax error\n");
			del_expr(offset);
			return nil;
		}
		(*pn)++;
		e= new_expr();
		e->operator= '(';
		e->middle= offset;
		return e;
	}

	/* #constant? */
	if (dialect == NCC && deref
			&& ((c= get_token(*pn)->symbol) == '#' || c == '*')) {
		/* NCC: mov ax,#constant  ->  ACK: mov ax,constant */
		(*pn)++;
		return ack_get_C_expression(pn);
	}

	/* @address? */
	if (dialect == NCC && get_token(*pn)->symbol == '@') {
		/* NCC: jmp @address  ->  ACK: jmp (address) */
		(*pn)++;
		if ((offset= ack_get_operand(pn, deref)) == nil) return nil;
		e= new_expr();
		e->operator= '(';
		e->middle= offset;
		return e;
	}

	/* Offset? */
	if (get_token(*pn)->symbol != '(') {
		/* There is an offset. */
		if ((offset= ack_get_C_expression(pn)) == nil) return nil;
	} else {
		/* No offset. */
		offset= nil;
	}

	/* (base)? */
	if (get_token(*pn)->symbol == '('
		&& (t= get_token(*pn + 1))->type == T_WORD
		&& isregister(t->name)
		&& get_token(*pn + 2)->symbol == ')'
	) {
		/* A base register expression. */
		base= new_expr();
		base->operator= 'B';
		base->name= copystr(t->name);
		(*pn)+= 3;
	} else {
		/* No base register expression. */
		base= nil;
	}

	/* (index*scale)? */
	if (get_token(*pn)->symbol == '(') {
		/* An index most likely. */
		token_t *m= nil;

		if (!(		/* This must be true: */
			(t= get_token(*pn + 1))->type == T_WORD
			&& isregister(t->name)
			&& (get_token(*pn + 2)->symbol == ')' || (
				get_token(*pn + 2)->symbol == '*'
				&& (m= get_token(*pn + 3))->type == T_WORD
				&& strchr("1248", m->name[0]) != nil
				&& m->name[1] == 0
				&& get_token(*pn + 4)->symbol == ')'
			))
		)) {
			/* Alas it isn't */
			parse_err(1, t, "operand syntax error\n");
			del_expr(offset);
			del_expr(base);
			return nil;
		}
		/* Found an index. */
		index= new_expr();
		index->operator= m == nil ? '1' : m->name[0];
		index->name= copystr(t->name);
		(*pn)+= (m == nil ? 3 : 5);
	} else {
		/* No index. */
		index= nil;
	}

	if (dialect == NCC && deref && base == nil && index == nil
		&& !(offset != nil && offset->operator == 'W'
					&& isregister(offset->name))
	) {
		/* NCC: mov ax,thing  ->  ACK mov ax,(thing) */
		e= new_expr();
		e->operator= '(';
		e->middle= offset;
		return e;
	}

	if (base == nil && index == nil) {
		/* Return a lone offset as is. */
		e= offset;
	} else {
		e= new_expr();
		e->operator= 'O';
		e->left= offset;
		e->middle= base;
		e->right= index;
	}
	return e;
}
예제 #23
0
static te_expr *base(state *s) {
    /* <base>      =    <constant> | <variable> | <function-0> {"(" ")"} | <function-1> <power> | <function-X> "(" <expr> {"," <expr>} ")" | "(" <list> ")" */
    te_expr *ret;
    int arity;

    switch (TYPE_MASK(s->type)) {
        case TOK_NUMBER:
            ret = new_expr(TE_CONSTANT, 0);
            ret->value = s->value;
            next_token(s);
            break;

        case TOK_VARIABLE:
            ret = new_expr(TE_VARIABLE, 0);
            ret->bound = s->bound;
            next_token(s);
            break;

        case TE_FUNCTION0:
        case TE_CLOSURE0:
            ret = new_expr(s->type, 0);
            ret->function = s->function;
            if (IS_CLOSURE(s->type)) ret->parameters[0] = s->context;
            next_token(s);
            if (s->type == TOK_OPEN) {
                next_token(s);
                if (s->type != TOK_CLOSE) {
                    s->type = TOK_ERROR;
                } else {
                    next_token(s);
                }
            }
            break;

        case TE_FUNCTION1:
        case TE_CLOSURE1:
            ret = new_expr(s->type, 0);
            ret->function = s->function;
            if (IS_CLOSURE(s->type)) ret->parameters[1] = s->context;
            next_token(s);
            ret->parameters[0] = power(s);
            break;

        case TE_FUNCTION2: case TE_FUNCTION3: case TE_FUNCTION4:
        case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7:
        case TE_CLOSURE2: case TE_CLOSURE3: case TE_CLOSURE4:
        case TE_CLOSURE5: case TE_CLOSURE6: case TE_CLOSURE7:
            arity = ARITY(s->type);

            ret = new_expr(s->type, 0);
            ret->function = s->function;
            if (IS_CLOSURE(s->type)) ret->parameters[arity] = s->context;
            next_token(s);

            if (s->type != TOK_OPEN) {
                s->type = TOK_ERROR;
            } else {
                int i;
                for(i = 0; i < arity; i++) {
                    next_token(s);
                    ret->parameters[i] = expr(s);
                    if(s->type != TOK_SEP) {
                        break;
                    }
                }
                if(s->type != TOK_CLOSE || i != arity - 1) {
                    s->type = TOK_ERROR;
                } else {
                    next_token(s);
                }
            }

            break;

        case TOK_OPEN:
            next_token(s);
            ret = list(s);
            if (s->type != TOK_CLOSE) {
                s->type = TOK_ERROR;
            } else {
                next_token(s);
            }
            break;

        default:
            ret = new_expr(0, 0);
            s->type = TOK_ERROR;
            ret->value = NAN;
            break;
    }

    return ret;
}
예제 #24
0
파일: parse_gnu.c 프로젝트: boostsup/minix3
static expression_t *gnu_get_operand(asm86_t * a, int *pn, int deref)
/* Get something like: $immed, memory, offset(%base,%index,scale), or simpler. */
{
	expression_t *e, *offset, *base, *index;
	token_t *t;
	int c;

	if (get_token(*pn)->symbol == '$') {
		/* An immediate value. */
		(*pn)++;
		return gnu_get_C_expression(pn);
	}

	if (get_token(*pn)->symbol == '*') {
		(*pn)++;
		deref = 1;
#if 0
		if ((offset= gnu_get_operand(a, pn, deref)) == nil) return nil;
#if 0
		e= new_expr();
		e->operator= '(';
		e->middle= offset;
		return e;
#endif
		return offset;
#endif
	}

	if ((get_token(*pn)->symbol == '%')
		&& (t= get_token(*pn + 1))->type == T_WORD
		&& isregister(t->name)
	) {
		/* A register operand. */
		(*pn)+= 2;
		e= new_expr();
		e->operator= 'W';
		e->name= copystr(t->name);
		return e;
	}

	/* Offset? */
	if (get_token(*pn)->symbol != '('
				|| get_token(*pn + 1)->symbol != '%') {
		/* There is an offset. */
		if ((offset= gnu_get_C_expression(pn)) == nil) return nil;
	} else {
		/* No offset. */
		offset= nil;
	}

	/* (%base,%index,scale) ? */
	base= index= nil;
	if (get_token(*pn)->symbol == '(') {
		(*pn)++;

		/* %base ? */
		if (get_token(*pn)->symbol == '%'
			&& (t= get_token(*pn + 1))->type == T_WORD
			&& isregister(t->name)
		) {
			/* A base register expression. */
			base= new_expr();
			base->operator= 'B';
			base->name= copystr(t->name);
			(*pn)+= 2;
		}

		if (get_token(*pn)->symbol == ',') (*pn)++;

		/* %index ? */
		if (get_token(*pn)->symbol == '%'
			&& (t= get_token(*pn + 1))->type == T_WORD
			&& isregister(t->name)
		) {
			/* A index register expression. */
			index= new_expr();
			index->operator= '1';		/* for now */
			index->name= copystr(t->name);
			(*pn)+= 2;
		}

		if (get_token(*pn)->symbol == ',') (*pn)++;

		/* scale ? */
		if ((base != nil || index != nil)
			&& (t= get_token(*pn))->type == T_WORD
			&& strchr("1248", t->name[0]) != nil
			&& t->name[1] == 0
		) {		
			if (index == nil) {
				/* Base is really an index register. */
				index= base;
				base= nil;
			}
			index->operator= t->name[0];
			(*pn)++;
		}

		if (get_token(*pn)->symbol == ')') {
			/* Ending paren. */
			(*pn)++;
		} else {
			/* Alas. */
			parse_err(1, t, "operand syntax error\n");
			del_expr(offset);
			del_expr(base);
			del_expr(index);
			return nil;
		}
	}

	if (base == nil && index == nil) {
		if (deref) {
			/* Return a lone offset as (offset). */
			e= new_expr();
			e->operator= '(';
			e->middle= offset;
		} else {
			/* Return a lone offset as is. */
			e= offset;
		}
	} else {
		e= new_expr();
		e->operator= 'O';
		e->left= offset;

		e->middle= base;
		e->right= index;
	}
	return e;
}