void parse_expression(void) {
  Token t;
  parse_term();
  for(;;) {
    t = get_token();
    if (t.type != T_ADD &&
        t.type != T_SUB &&
        t.type != T_OR &&
        t.type != T_AND &&
        t.type != T_XOR) {
      unget_token();
      break;
    }
    parse_term();
    Opcode op = OP_ADD;
    if (t.type == T_ADD) {
      op = OP_ADD;
    } else if (t.type == T_SUB) {
      op = OP_SUB;
    } else if (t.type == T_OR) {
      op = OP_OR;
    } else if (t.type == T_AND) {
      op = T_AND;
    } else if (t.type == T_XOR) {
      op = T_XOR;
    }
    vm_add_opcode(op);
  }
}
Example #2
0
double
parse_expression()
{
    double v1;
    double v2;
    Token token;

    v1 = parse_term();
    for (;;) {
        my_get_token(&token);
        if (token.kind != ADD_OPERATOR_TOKEN 
            && token.kind != SUB_OPERATOR_TOKEN) {
            unget_token(&token);
            break;
        }
        v2 = parse_term();
        if (token.kind == ADD_OPERATOR_TOKEN) {
            v1 += v2;
        } else if (token.kind == SUB_OPERATOR_TOKEN) {
            v1 -= v2;
        } else {
            unget_token(&token);
        }
    }
    return v1;
}
/******************************************************************************
    rest_expr := + term rest_expr
                 - term rest_expr
                 (nil)
 *****************************************************************************/
void
parse_rest_expr( val_t* val ) 
{
    printtab();
    dprintf("parse_rest_expr()\n");
    level++;
    if ( match_char( '+' ) ) {
        val_t val2;
        parse_term( &val2 );
        val->d.fval += val2.d.fval;
        parse_rest_expr( val );
    } else if ( match_char( '-' ) ) {
        val_t val2;
        parse_term( &val2 );
        val->d.fval /= val2.d.fval;
        parse_rest_expr( val );
    } else if ( match_eof() ) {

    } else {

    }

    level--;

    return;
}
Example #4
0
static AVEvalExpr * parse_subexpr(Parser *p) {
    AVEvalExpr * e = parse_term(p);
    while(*p->s == '+' || *p->s == '-') {
        e= new_eval_expr(e_add, 1, e, parse_term(p));
    };

    return e;
}
Example #5
0
/*-------------------------------------------------------------------------
 * Function:    parse_range
 *
 * Purpose:     Tries to parse a range expression of the form `I1:I2'
 *              where I1 and I2 are integer constants.
 *
 * Return:      Success:        A range object.
 *
 *              Failure:        &ErrorCell
 *
 * Programmer:  Robb Matzke
 *              [email protected]
 *              Jan  3 1997
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static obj_t
parse_range (lex_t *f, int skipnl) {

   obj_t        lt=NIL, rt=NIL, retval=NIL;
   int          lo, hi;

   lt = parse_term (f, skipnl);
   if (&ErrorCell==lt) return &ErrorCell;

   if (TOK_COLON==lex_token (f, NULL, skipnl)) {
      lex_consume (f);
      rt = parse_term (f, skipnl);
      if (&ErrorCell==rt) {
         obj_dest (rt);
         return &ErrorCell;
      }

      /*
       * Both arguments must be integer constants.
       */
      if (!num_isint(lt)) {
         out_error ("Range: left limit is not an integer constant: ", lt);
         obj_dest (lt);
         obj_dest (rt);
         return &ErrorCell;
      }
      if (!num_isint(rt)) {
         out_error ("Range: right limit is not an integer constant: ", rt);
         obj_dest (lt);
         obj_dest (rt);
         return &ErrorCell;
      }

      /*
       * The constants must be in a reasonable order.
       */
      lo = num_int (lt);
      hi = num_int (rt);
      if (hi<lo) {
         out_errorn ("Range: inverted range %d:%d changed to %d:%d",
                     lo, hi, hi, lo);
         lo = num_int (rt);
         hi = num_int (lt);
      }

      /*
       * Create the range object.
       */
      lt = obj_dest (lt);
      rt = obj_dest (rt);
      retval = obj_new (C_RANGE, lo, hi);
   } else {
      retval = lt;
   }
   return retval;
}
Example #6
0
expr *parse_expr()
{
  expr *l = parse_term();
  char c = getchar();
  while (c != '\n' && (c == '+' || c == '-')) {
    expr *r = parse_term();
    l = binop(c, l, r);
    c = getchar();
  }
  ungetc(c, stdin);
  return l;
}
Example #7
0
static RegExp *
parse_diff(void)
{
    RegExp *e, *f;
    e = parse_term();
    while (curtok == '\\') {
	get_next_token(); /* \ */
	f = parse_term();
	e = mkDiff(e, f);
	if(!e)
	    Scanner_fatal(in, "can only difference char sets");
    }
    return e;
}
Example #8
0
File: parse.c Project: jkdewar/rook
/*----------------------------------------------------------------------*/
static ast_expression_t *parse_signed_term(parse_state_t *p) {
    ast_expression_t *term;

    /* TODO:jkd handle unary op */
    term = parse_term(p);
    return term;
}
Example #9
0
static struct tdb_event_filter *parse_filter(const tdb *db,
                                             const char *filter_expression,
                                             int verbose)
{
    char *dup = strdup(filter_expression);
    char *expr = dup;
    char *ctx = NULL;
    char *token = NULL;

    struct tdb_event_filter *filter = tdb_event_filter_new();

    if (!dup || !filter)
        DIE("Out of memory.");

    while ((token = strtok_r(expr, " \n\t", &ctx))){
        int is_negative = 0;

        if (*token == '&'){
            if (verbose)
                fprintf(stderr, "AND\n");
            tdb_event_filter_new_clause(filter);
        }else{
            tdb_item item = parse_term(db, token, &is_negative, dup, verbose);
            tdb_event_filter_add_term(filter, item, is_negative);
        }

        expr = NULL;
    }

    free(dup);
    return filter;
}
Example #10
0
File: parse.c Project: jkdewar/rook
/*----------------------------------------------------------------------*/
static ast_expression_t *parse_sum_op(parse_state_t *p, ast_expression_t *left) {
    token_t* token;

    token = peek_token(p);
    if (token == NULL) {
        return NULL;
    } else if (token->type == TK_PLUS || token->type == TK_MINUS) {
        ast_expression_t *right;
        ast_expression_t *bin_op;
        ast_expression_t *sum_op;

        next_token(p);
        right = parse_term(p);

        bin_op = ALLOC(sizeof(ast_expression_t));
        BZERO(bin_op);
        bin_op->tag = AST_EXPRESSION_BIN_OP;
        bin_op->u.bin_op.left = left;
        bin_op->u.bin_op.right = right;
        bin_op->u.bin_op.operation = token->type;

        sum_op = parse_sum_op(p, bin_op);
        return sum_op != NULL ? sum_op : bin_op;
    } else {
        return NULL;
    }
}
Example #11
0
void parse_expression(){
  char t;
  parse_term();
  for(;;){
    t = get_token();
    if(t != '+' && t != '-'){
      e_index--; // トークンを押し戻す
      break;
    }
    parse_term();
    if(t == '+'){
      printf("OP_ADD\n");
    }else if(t == '-'){
      printf("OP_SUB\n");
    }
  }
}
Example #12
0
std::string SimplifyParser::simplify (const std::string & expression)
{
    // simplify terms like APP APP S K K
    begin(expression);
    SimplifyTerm term = parse_term();
    end();
    return term.route;
}
Example #13
0
File: v7.c Project: di3online/v7
//  expression  =   term { add_op term } |
//                  expression "?" expression ":" expression
//                  expression logical_op expression
//                  variable "=" expression
//  add_op      =   "+" | "-"
static enum v7_err parse_expression(struct v7 *v7) {
#ifdef V7_DEBUG
  const char *stmt_str = v7->cursor;
#endif
  int op;

  v7->cur_obj = &v7->scopes[v7->current_scope];
  TRY(parse_term(v7));

  while (*v7->cursor == '-' || *v7->cursor == '+') {
    int ch = *v7->cursor;
    TRY(match(v7, ch));
    TRY(parse_term(v7));
    TRY(do_arithmetic_op(v7, ch));
  }

  if ((op = is_logical_op(v7->cursor)) > OP_XX) {
    v7->cursor += op == OP_LT || op == OP_GT ? 1 : 2;
    skip_whitespaces_and_comments(v7);
    TRY(parse_expression(v7));
    TRY(do_logical_op(v7, op));
  }

  // Parse assignment
  if (*v7->cursor == '=') {
    //printf("=> cur_obj: %p\n", cur_obj);
    TRY(parse_assignment(v7, v7->cur_obj));
  }

  // Parse ternary operator
  if (*v7->cursor == '?') {
    int condition_true = v7_is_true(v7_top(v7)[-1]);
    int old_no_exec = v7->no_exec;

    TRY(match(v7, '?'));
    v7->no_exec = old_no_exec || !condition_true;
    TRY(parse_expression(v7));
    TRY(match(v7, ':'));
    v7->no_exec = old_no_exec || condition_true;
    TRY(parse_expression(v7));
    v7->no_exec = old_no_exec;
  }

  return V7_OK;
}
Example #14
0
void parse_paramListFollow(unode_str_t* param) {
    symbol_t* var;
    e_data_t func_param_type;
    switch(next_token.type) {
        case TT_COMMA:
            match(TT_COMMA);
            parse_term();
            if (param)
                func_param_type = param->item.type;
            else
                error("Bad function call parameters types/count", ERROR_TYPE_COMPAT);
            //var_init(); //TODO: ???
            switch (curr_token.type) {
                case TT_LIT_INT:
                    func_call_add_param(INT_DT);
                    if (func_param_type == INT_DT)
                        generate_param_push_int(curr_token.int_val);
                    else
                        generate_param_push_double((double)curr_token.int_val);
                    break;
                case TT_LIT_DOUBLE:
                    func_call_add_param(DOUBLE_DT);
                    if (func_param_type == DOUBLE_DT)
                        generate_param_push_double(curr_token.double_val);
                    else
                        generate_param_push_int((int)curr_token.double_val);
                    break;
                case TT_LIT_STRING:
                    func_call_add_param(STRING_DT);
                    generate_param_push_string(curr_token.str);
                    break;
                case TT_IDENTIFICATOR:
                    var = var_table_find(curr_token.str);
                    if (var == NULL) {
                        error("Reference to undefined variable", ERROR_SEM);
                    } else if (var->def != true) {
                        error("Trying to use uninitialized variable", ERROR_UNDEF);
                    } else {
                        func_call_add_param(var->type);
                        if (var->type == DOUBLE_DT && func_param_type == INT_DT)
                            generate_param_conv_push(var->addr, true, false);
                        else if (var->type == INT_DT && func_param_type == DOUBLE_DT)
                            generate_param_conv_push(var->addr, false, true);
                        else
                            generate_param_push(var->addr);
                    }
                    break;
                default:
                    ;
            }
            ++param_count;
            parse_paramListFollow(param->prev);
            break;
        default:
            return;
    }
}
Example #15
0
struct node *parse_arithmetic(struct compiler *compiler)
{
    struct node *result = parse_term(compiler);

    while (lexer_current(compiler) == T_ADD || lexer_current(compiler) == T_SUB)
    {
        struct node *node = alloc_node(compiler, N_BINARY_OP);

        node->op = lexer_current(compiler);
        node->left = result;

        lexer_next(compiler);

        node->right = parse_term(compiler);
        result = node;
    }

    return result;
}
Example #16
0
File: parser.c Project: gnar/zombo
/* +, - */
static ASTNode *parse_clause(Parser *p) /* better name? */
{
	ASTNode *expr = parse_term(p);

loop:
	switch (peek_id(p))
	{
		case TOK_PLUS:
			accept(p); ignore_eols(p);
			expr = ast_create_2(AST_ADD, expr, parse_term(p));
			goto loop;

		case TOK_MINUS:
			accept(p); ignore_eols(p);
			expr = ast_create_2(AST_SUB, expr, parse_term(p));
			goto loop;
	}

	return expr;
}
Example #17
0
instruction_ptr Parser::parse_expression()
{
    int start_line = current_lexeme().line();
    
    instruction_ptr left = parse_term();
    
    if (!left)
        return instruction_ptr();
    
    while (match_current_lexeme_simple_arithmetic())
    {
        Lexeme lexeme = current_lexeme();
        
        next_lexeme();
        
        instruction_ptr right = parse_term();
        
        if (!right)
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        switch (lexeme.type())
        {
            case kAddition:
                left = instruction_ptr(new ArithmeticOperationInstruction(start_line, kAdd, left, right));
                break;
            case kSubtraction:
                left = instruction_ptr(new ArithmeticOperationInstruction(start_line, kSub, left, right));
                break;
            default:
            {
                report_current_syntax_error();
                return instruction_ptr();
            }
        }
    }
    
    return left;
}
Example #18
0
Cmd* Parser::parse_pre_unary()
{
  Cmd* cmd = tokenizer.peek();
  if (tokenizer.consume(TOKEN_MINUS))
  {
    return new(cmd) CmdNegate( parse_pre_unary() );
  }
  else
  {
    return parse_term();
  }
}
Example #19
0
int parse_expression(CALC_ELEMENT ** e)
{
	CALC_ELEMENT *t1 = NULL, *t2 = NULL;
	PARSE_SYMBOL s;
	if (parse_term(&t1) != 0)
		return -1;
	/* we have one here, which is nice... */
	s = get_symbol();
	while ((s == PARSE_ADD) || (s == PARSE_SUB)) {
		accept(s);
		if (parse_term(&t2) != 0) {
			free_calc_element(t1);
			return -1;
		}
		if (s == PARSE_ADD)
			t1 = create_bin_op('+', t1, t2);
		else
			t1 = create_bin_op('-', t1, t2);
		t2 = NULL;
		s = get_symbol();
	}
	*e = t1;
	return 0;
}
Example #20
0
void parse_coutStmt() {
    switch(next_token.type) {
        case TT_KW_COUT:
            match(TT_KW_COUT);
            match(TT_OP_STREAM_OUT);
            parse_term();
            symbol_t* var;
            if (curr_token.type == TT_IDENTIFICATOR) {
                var = var_table_find(curr_token.str);
                if (var == NULL) {
                    error("Reference to undefined variable", ERROR_SEM);
                } else if (var->def != true) {
                    error("Trying to use uninitialized variable", ERROR_UNDEF);
                }
                switch(var->type) {
                    case INT_DT:
                        generate_cout_int(var->addr);
                        break;
                    case DOUBLE_DT:
                        generate_cout_double(var->addr);
                        break;
                    case STRING_DT:
                        generate_cout_string(var->addr);
                        break;
                    default:
                        ;
                }
            }
            switch(curr_token.type) {
                case TT_LIT_INT:
                    generate_cout_int_lit(curr_token.int_val);
                    break;
                case TT_LIT_DOUBLE:
                    generate_cout_double_lit(curr_token.double_val);
                    break;
                case TT_LIT_STRING:
                    generate_cout_string_lit(curr_token.str);
                    break;
                default:
                    ;
            }
            parse_coutStmtFollow();
            break;
        default:
            error("Syntactic error: Failed to parse the program", ERROR_SYN);
    }
}
/******************************************************************************
    expr := term rest_expr
 *****************************************************************************/
void
parse_expr(val_t* val)
{
    printtab();
    dprintf("parse_expr()\n");
    
    level++;
    if ( match_variable( val ) ) {
        parse_rest_var( val );
    } else {
        parse_term( val );
        parse_rest_expr( val );
    }

    level--;

    return;
}
Example #22
0
struct expression *parse_exp()
{
    struct expression *term = parse_term();
    if (is_empty_expression(term))
        return NULL;

    if (current_token == NULL) return NULL;

    switch (current_token->type) {
    case OpAnd:
        advanceToken();
        struct expression *exp =
            new_op_expression(AndExp, term, parse_exp());
        if (is_right_child_empty(exp)) {
            destroy_expression(exp);
            return NULL;
        }
        return exp;
    default:
        return term;
    }
}
Example #23
0
struct expression *parse_term()
{
    struct expression *term;

    if (current_token == NULL) return NULL;

    switch (current_token->type) {
    case Var:
        term = new_var_expression(current_token->u.var_id);
        advanceToken();
        return term;
    case LeftParen:
        advanceToken();
        term = parse_prop();
        if (is_empty_expression(term)) {
            return NULL;
        }
        switch (current_token->type) {
        case RightParen:
            advanceToken();
            return term;
        default:
            return NULL;
        }
    case OpNot:
        advanceToken();
        term = new_op_expression(NotExp, parse_term(), NULL);
        if (is_left_child_empty(term)) {
            destroy_expression(term);
            return NULL;
        }
        return term;
    default:
        return NULL;
    }
}
Example #24
0
Data* parse_aexpr(char** p)
{
	Data* ret = NULL;
	while(parse_ws(p),**p)
	{
		int sign ;
		sign = parse_sign(p);
		if( !ret || sign )
		{
			Data* term = parse_term(p);
			if( term->type == TYPE_ERROR )
			{
				dispose(ret);
				return term;    /*Throw the error*/
			}
			else if( !ret )      /* First term */
			{
				if( sign != 0 && term->type == TYPE_STRING )   
						  /* There are one or more negitive/positive sign before A string*/
						  /* e.g. : +"illegal"*/
				{
					dispose(term);
					dispose(ret);						
					return Raise(SYNTAX); /*raise a syntax error*/
				}
				else ret = term;
				if( sign < 0 )
				{/*only INTEGER and REAL */
					if( term->type == TYPE_INTEGER )
						term->storage.Integer = -term->storage.Integer;
					else
						term->storage.Real = -term->storage.Real;
				}
			}
			else if( term->type == TYPE_STRING )
			{
				ret = temp_var(ret);
				if( sign > 0 )  /* AC + STRING */
				{
					if( ret->type != TYPE_STRING )
					{
						/* non-string + string is illegal */
						dispose(term);
						dispose(ret);
						return Raise(TYPE_MISMATCH);
					}
					/* do strcat */
					char* A = ret->storage.String;
					char* B = term->storage.String;
					int  lA = strlen(A);
					int  lB = strlen(B);
					char* temp = (char*)malloc( lA + lB + 1);
					strcpy( temp , A );
					strcpy( temp + lA , B );
					ret->storage.String = temp;
					if( A != init_value[TYPE_STRING].String )
						free(A);   /*dispose old string*/
					dispose(term);     /*dispose this term*/
				}
				else
				{
					/* AC - string is illegal */
					dispose(term);
					dispose(ret);
					return Raise(TYPE_MISMATCH);
				}
			}
			else if( term->type == TYPE_INTEGER )
			{
				ret = temp_var(ret);
				/*AC + INTEGER*/
				if( ret->type == TYPE_STRING )
				{/*Type Mismatch*/
					dispose(ret);
					dispose(term);
					return Raise(TYPE_MISMATCH);
				}
				else if( ret->type == TYPE_INTEGER )
				{/*Integer + Integer*/
					ret->storage.Integer += sign * term->storage.Integer;
					dispose(term);
				}
				else if( ret->type == TYPE_REAL )
				{/*Real + Integer*/
					ret->storage.Real += sign * term->storage.Integer;
					dispose(term);					
				}
			} 
			else if( term->type == TYPE_REAL )
			{

				double org;
				ret = temp_var(ret);
				/*AC + REAL */
				if( ret->type == TYPE_STRING )
				{/*Type Mismatch*/
					dispose(ret);
					dispose(term);
					return Raise(TYPE_MISMATCH);
				}


				if( ret->type == TYPE_REAL )
					org = ret->storage.Real;
				else
					org = ret->storage.Integer;
				ret->type = TYPE_REAL;
				ret->storage.Real = org + sign * term->storage.Real;
				dispose(term);
			}
		}
		else
			break; 
	}
	if( ret == NULL )
		ret=Raise(SYNTAX);
	return ret;
}
Example #25
0
static int parse_term(units *v, int scale_indicator,
		      int parenthesised, int rigid)
{
  int negative = 0;
  for (;;)
    if (parenthesised && tok.space())
      tok.next();
    else if (tok.ch() == '+')
      tok.next();
    else if (tok.ch() == '-') {
      tok.next();
      negative = !negative;
    }
    else
      break;
  unsigned char c = tok.ch();
  switch (c) {
  case '|':
    // | is not restricted to the outermost level
    // tbl uses this
    tok.next();
    if (!parse_term(v, scale_indicator, parenthesised, rigid))
      return 0;
    int tem;
    tem = (scale_indicator == 'v'
	   ? curdiv->get_vertical_position().to_units()
	   : curenv->get_input_line_position().to_units());
    if (tem >= 0) {
      if (*v < INT_MIN + tem) {
	error("numeric overflow");
	return 0;
      }
    }
    else {
      if (*v > INT_MAX + tem) {
	error("numeric overflow");
	return 0;
      }
    }
    *v -= tem;
    if (negative) {
      if (*v == INT_MIN) {
	error("numeric overflow");
	return 0;
      }
      *v = -*v;
    }
    return 1;
  case '(':
    tok.next();
    c = tok.ch();
    if (c == ')') {
      if (rigid)
	return 0;
      warning(WARN_SYNTAX, "empty parentheses");
      tok.next();
      *v = 0;
      return 1;
    }
    else if (c != 0 && strchr(SCALE_INDICATOR_CHARS, c) != 0) {
      tok.next();
      if (tok.ch() == ';') {
	tok.next();
	scale_indicator = c;
      }
      else {
	error("expected `;' after scale-indicator (got %1)",
	      tok.description());
	return 0;
      }
    }
    else if (c == ';') {
      scale_indicator = 0;
      tok.next();
    }
    if (!parse_expr(v, scale_indicator, 1, rigid))
      return 0;
    tok.skip();
    if (tok.ch() != ')') {
      if (rigid)
	return 0;
      warning(WARN_SYNTAX, "missing `)' (got %1)", tok.description());
    }
    else
      tok.next();
    if (negative) {
      if (*v == INT_MIN) {
	error("numeric overflow");
	return 0;
      }
      *v = -*v;
    }
    return 1;
  case '.':
    *v = 0;
    break;
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
    *v = 0;
    do {
      if (*v > INT_MAX/10) {
	error("numeric overflow");
	return 0;
      }
      *v *= 10;
      if (*v > INT_MAX - (int(c) - '0')) {
	error("numeric overflow");
	return 0;
      }
      *v += c - '0';
      tok.next();
      c = tok.ch();
    } while (csdigit(c));
    break;
  case '/':
  case '*':
  case '%':
  case ':':
  case '&':
  case '>':
  case '<':
  case '=':
    warning(WARN_SYNTAX, "empty left operand");
    *v = 0;
    return rigid ? 0 : 1;
  default:
    warning(WARN_NUMBER, "numeric expression expected (got %1)",
	    tok.description());
    return 0;
  }
  int divisor = 1;
  if (tok.ch() == '.') {
    tok.next();
    for (;;) {
      c = tok.ch();
      if (!csdigit(c))
	break;
      // we may multiply the divisor by 254 later on
      if (divisor <= INT_MAX/2540 && *v <= (INT_MAX - 9)/10) {
	*v *= 10;
	*v += c - '0';
	divisor *= 10;
      }
      tok.next();
    }
  }
  int si = scale_indicator;
  int do_next = 0;
  if ((c = tok.ch()) != 0 && strchr(SCALE_INDICATOR_CHARS, c) != 0) {
    switch (scale_indicator) {
    case 'z':
      if (c != 'u' && c != 'z') {
	warning(WARN_SCALE,
		"only `z' and `u' scale indicators valid in this context");
	break;
      }
      si = c;
      break;
    case 0:
      warning(WARN_SCALE, "scale indicator invalid in this context");
      break;
    case 'u':
      si = c;
      break;
    default:
      if (c == 'z') {
	warning(WARN_SCALE, "`z' scale indicator invalid in this context");
	break;
      }
      si = c;
      break;
    }
    // Don't do tok.next() here because the next token might be \s, which
    // would affect the interpretation of m.
    do_next = 1;
  }
  switch (si) {
  case 'i':
    *v = scale(*v, units_per_inch, divisor);
    break;
  case 'c':
    *v = scale(*v, units_per_inch*100, divisor*254);
    break;
  case 0:
  case 'u':
    if (divisor != 1)
      *v /= divisor;
    break;
  case 'f':
    *v = scale(*v, 65536, divisor);
    break;
  case 'p':
    *v = scale(*v, units_per_inch, divisor*72);
    break;
  case 'P':
    *v = scale(*v, units_per_inch, divisor*6);
    break;
  case 'm':
    {
      // Convert to hunits so that with -Tascii `m' behaves as in nroff.
      hunits em = curenv->get_size();
      *v = scale(*v, em.is_zero() ? hresolution : em.to_units(), divisor);
    }
    break;
  case 'M':
    {
      hunits em = curenv->get_size();
      *v = scale(*v, em.is_zero() ? hresolution : em.to_units(), divisor*100);
    }
    break;
  case 'n':
    {
      // Convert to hunits so that with -Tascii `n' behaves as in nroff.
      hunits en = curenv->get_size()/2;
      *v = scale(*v, en.is_zero() ? hresolution : en.to_units(), divisor);
    }
    break;
  case 'v':
    *v = scale(*v, curenv->get_vertical_spacing().to_units(), divisor);
    break;
  case 's':
    while (divisor > INT_MAX/(sizescale*72)) {
      divisor /= 10;
      *v /= 10;
    }
    *v = scale(*v, units_per_inch, divisor*sizescale*72);
    break;
  case 'z':
    *v = scale(*v, sizescale, divisor);
    break;
  default:
    assert(0);
  }
  if (do_next)
    tok.next();
  if (negative) {
    if (*v == INT_MIN) {
      error("numeric overflow");
      return 0;
    }
    *v = -*v;
  }
  return 1;
}
Example #26
0
static int parse_expr(units *v, int scale_indicator,
		      int parenthesised, int rigid)
{
  int result = parse_term(v, scale_indicator, parenthesised, rigid);
  while (result) {
    if (parenthesised)
      tok.skip();
    int op = tok.ch();
    switch (op) {
    case '+':
    case '-':
    case '/':
    case '*':
    case '%':
    case ':':
    case '&':
      tok.next();
      break;
    case '>':
      tok.next();
      if (tok.ch() == '=') {
	tok.next();
	op = OP_GEQ;
      }
      else if (tok.ch() == '?') {
	tok.next();
	op = OP_MAX;
      }
      break;
    case '<':
      tok.next();
      if (tok.ch() == '=') {
	tok.next();
	op = OP_LEQ;
      }
      else if (tok.ch() == '?') {
	tok.next();
	op = OP_MIN;
      }
      break;
    case '=':
      tok.next();
      if (tok.ch() == '=')
	tok.next();
      break;
    default:
      return result;
    }
    units v2;
    if (!parse_term(&v2, scale_indicator, parenthesised, rigid))
      return 0;
    int overflow = 0;
    switch (op) {
    case '<':
      *v = *v < v2;
      break;
    case '>':
      *v = *v > v2;
      break;
    case OP_LEQ:
      *v = *v <= v2;
      break;
    case OP_GEQ:
      *v = *v >= v2;
      break;
    case OP_MIN:
      if (*v > v2)
	*v = v2;
      break;
    case OP_MAX:
      if (*v < v2)
	*v = v2;
      break;
    case '=':
      *v = *v == v2;
      break;
    case '&':
      *v = *v > 0 && v2 > 0;
      break;
    case ':':
      *v = *v > 0 || v2 > 0;
      break;
    case '+':
      if (v2 < 0) {
	if (*v < INT_MIN - v2)
	  overflow = 1;
      }
      else if (v2 > 0) {
	if (*v > INT_MAX - v2)
	  overflow = 1;
      }
      if (overflow) {
	error("addition overflow");
	return 0;
      }
      *v += v2;
      break;
    case '-':
      if (v2 < 0) {
	if (*v > INT_MAX + v2)
	  overflow = 1;
      }
      else if (v2 > 0) {
	if (*v < INT_MIN + v2)
	  overflow = 1;
      }
      if (overflow) {
	error("subtraction overflow");
	return 0;
      }
      *v -= v2;
      break;
    case '*':
      if (v2 < 0) {
	if (*v > 0) {
	  if ((unsigned)*v > -(unsigned)INT_MIN / -(unsigned)v2)
	    overflow = 1;
	}
	else if (-(unsigned)*v > INT_MAX / -(unsigned)v2)
	  overflow = 1;
      }
      else if (v2 > 0) {
	if (*v > 0) {
	  if (*v > INT_MAX / v2)
	    overflow = 1;
	}
	else if (-(unsigned)*v > -(unsigned)INT_MIN / v2)
	  overflow = 1;
      }
      if (overflow) {
	error("multiplication overflow");
	return 0;
      }
      *v *= v2;
      break;
    case '/':
      if (v2 == 0) {
	error("division by zero");
	return 0;
      }
      *v /= v2;
      break;
    case '%':
      if (v2 == 0) {
	error("modulus by zero");
	return 0;
      }
      *v %= v2;
      break;
    default:
      assert(0);
    }
  }
  return result;
}