예제 #1
1
static struct block *cast_expression(struct block *block)
{
    struct typetree *type;
    struct token tok;
    struct symbol *sym;

    /* This rule needs two lookahead; to see beyond the initial parenthesis if
     * it is actually a cast or an expression. */
    if (peek().token == '(') {
        tok = peekn(2);
        switch (tok.token) {
        case IDENTIFIER:
            sym = sym_lookup(&ns_ident, tok.strval);
            if (!sym || sym->symtype != SYM_TYPEDEF)
                break;
        case FIRST(type_name):
            consume('(');
            type = declaration_specifiers(NULL);
            if (peek().token != ')') {
                type = declarator(type, NULL);
            }
            consume(')');
            block = cast_expression(block);
            block->expr = eval_cast(block, block->expr, type);
            return block;
        default:
            break;
        }
    }

    return unary_expression(block);
}
Expression *ExpressionBuilder::unary_expression()
{
    switch (next()) {
    case '+':
        return createUnaryExpression('+', unary_expression());
    case '-':
        return createUnaryExpression('-',  unary_expression());
    case '!':
        return createUnaryExpression('!',  unary_expression());
    case '~':
        return createUnaryExpression('~', unary_expression());
    case Token_defined:
    {
        int identifierIndex  = 0;
        if (test(Token_identifier)) {
            identifierIndex = i - 1;
        } else if (test('(')) {
            if (test(Token_identifier))
                identifierIndex = i -1;
            test(')');
        }
        return createMacroReference(MacroReference::DefinedRef, createTokenList(identifierIndex));
    }
    default:
        prev();
        return primary_expression();
    }
}
예제 #3
0
/**
乘除类表达式
<multiplicative_expression>::=<unary_expression>
                            {<TK_STAR><unary_expression>
                            |<TK_DIVIDE><unary_expression>
                            |<TK_MOD><unary_expression>}
*/
void multiplicative_expression(){
    unary_expression();
    while(TK_STAR == token || TK_DIVIDE == token || TK_MOD == token){
        get_token();
        unary_expression();
    }
}
예제 #4
0
파일: parse.c 프로젝트: charliesome/slash
static sl_node_base_t*
mul_expression(sl_parse_state_t* ps)
{
    sl_node_base_t* left = unary_expression(ps);
    sl_node_base_t* right;
    sl_token_t* tok;
    while(peek_token(ps)->type == SL_TOK_TIMES || peek_token(ps)->type == SL_TOK_DIVIDE ||
            peek_token(ps)->type == SL_TOK_MOD) {
        tok = next_token(ps);
        right = unary_expression(ps);
        left = sl_make_send_node(ps, left, sl_intern2(ps->vm, tok->str), 1, &right);
    }
    return left;
}
예제 #5
0
파일: parser.c 프로젝트: palmerc/lab
int assignment_expression(void) {
	if( conditional_expression() ) {
	} else if( unary_expression() ) {
		assignment_operator();
		assignment_expression();
	}
}
예제 #6
0
파일: parse.c 프로젝트: charliesome/slash
static sl_node_base_t*
unary_expression(sl_parse_state_t* ps)
{
    sl_node_base_t* expr;
    sl_token_t* tok;
    switch(peek_token(ps)->type) {
        case SL_TOK_MINUS:
            tok = next_token(ps);
            expr = unary_expression(ps);
            return sl_make_send_node(ps, expr, sl_intern(ps->vm, "negate"), 0, NULL);
        case SL_TOK_TILDE:
            tok = next_token(ps);
            expr = unary_expression(ps);
            return sl_make_send_node(ps, expr, sl_intern2(ps->vm, tok->str), 0, NULL);
        case SL_TOK_NOT:
            next_token(ps);
            expr = unary_expression(ps);
            return sl_make_unary_node(ps, expr, SL_NODE_NOT);
        case SL_TOK_RETURN:
            tok = next_token(ps);
            if(!(ps->scope->flags & SL_PF_CAN_RETURN)) {
                error(ps, sl_make_cstring(ps->vm, "Can't return outside of a method or lambda"), tok);
            }
            switch(peek_token(ps)->type) {
                case SL_TOK_SEMICOLON:
                case SL_TOK_CLOSE_BRACE:
                case SL_TOK_CLOSE_TAG:
                /* in these case we want to allow for postfix control structures: */
                case SL_TOK_IF:
                case SL_TOK_UNLESS:
                    return sl_make_unary_node(ps, sl_make_immediate_node(ps, ps->vm->lib.nil), SL_NODE_RETURN);
                default:
                    return sl_make_unary_node(ps, low_precedence_logical_expression(ps), SL_NODE_RETURN);
            }
            break;
        case SL_TOK_THROW:
            next_token(ps);
            return sl_make_unary_node(ps, low_precedence_logical_expression(ps), SL_NODE_THROW);
        case SL_TOK_USE:
            return use_expression(ps);
        default:
            return power_expression(ps);
    }
}
예제 #7
0
// Parse a unary expression.
//
//    unary-expression:
//      postfix-expression
//      '!' unary-expression
//      '-' unary-expression
//      '+' unary-expression
//      '~' unary-expression
//
Expr&
Parser::unary_expression()
{
  if (Token tok = match_if(tk::bang_tok)) {
    Expr& e = unary_expression();
    return on_logical_not_expression(tok, e);
  } else if (Token tok = match_if(tk::minus_tok)) {
    Expr& e = unary_expression();
    return on_neg_expression(tok, e);
  } else if (Token tok = match_if(tk::plus_tok)) {
    Expr& e = unary_expression();
    return on_pos_expression(tok, e);
  } else if (Token tok = match_if(tk::caret_tok)) {
    Expr& e = unary_expression();
    return on_compl_expression(tok, e);
  } else {
    return postfix_expression();
  }
}
예제 #8
0
int PP_Expression::unary_expression()
{
    switch (next()) {
    case PP_PLUS:
        return unary_expression();
    case PP_MINUS:
        return -unary_expression();
    case PP_NOT:
        return !unary_expression();
    case PP_TILDE:
        return ~unary_expression();
    case PP_MOC_TRUE:
        return 1;
    case PP_MOC_FALSE:
        return 0;
    default:
        prev();
        return primary_expression();
    }
}
예제 #9
0
파일: parser.c 프로젝트: palmerc/lab
int cast_expression(void) {
	if ( unary_expression() ) {
	} else if ( lookaheadT.type == LPAREN ) {
		match(LPAREN);
		type_name();
		match(RPAREN);
		cast_expression();
	} else {
		abort();
	}
}
예제 #10
0
struct Symbol* cast_expression(struct CastExpression* node)
{
    struct Symbol* symbol = 0;
    if (node->type == 0)
        return unary_expression(node->unaryExpression, &symbol);
    int specifier = 0, stars = 0;
    typename2specifier(node->typeName, &specifier, &stars);
    symbol = cast_expression(node->castExpression);
    symbol = load_symbol(symbol);
    symbol = cast_symbol(symbol, specifier, stars);
    return cast_expression(node->castExpression);
}
예제 #11
0
// Parse a multiplicative expression.
//
//    multiplicative-expression:
//      unary-expression:
//      multiplicative-expression '*' unary-expression
//      multiplicative-expression '/' unary-expression
//      multiplicative-expression '%' unary-expression
Expr&
Parser::multiplicative_expression()
{
  Expr* e1 = &unary_expression();
  while (true) {
    // Use a switch?
    if (Token tok = match_if(tk::star_tok)) {
      Expr& e2 = unary_expression();
      e1 = &on_mul_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::slash_tok)) {
      Expr& e2 = unary_expression();
      e1 = &on_div_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::percent_tok)) {
      Expr& e2 = unary_expression();
      e1 = &on_rem_expression(tok, *e1, e2);
    } else {
      break;
    }
  }
  return *e1;
}
예제 #12
0
/**
一元表达式
<unary_expression>::=<postfix_expression>
                    |<TK_AND><unary_expression>
                    |<TK_STAE><unary_expression>
                    |<TK_PLUS><unary_expression>
                    |<TK_MINUS><unary_expression>
                    |<sizeof_expression>

*/
void unary_expression(){
    switch(token){
        case TK_AND:case TK_STAR:case TK_PLUS:case TK_MINUS:
            get_token();
            unary_expression();
            break;
        case KW_SIZEOF:
            sizeof_expression();
            break;
        default:
            postfix_expression();
            break;
    }
}
Expression *ExpressionBuilder::multiplicative_expression()
{
    Expression *value = unary_expression();
    switch (next()) {
    case '*':
        return createBinaryExpression('*', value, multiplicative_expression());
    case '%':
        return createBinaryExpression('%', value, multiplicative_expression());
    case '/':
        return createBinaryExpression('/', value, multiplicative_expression());
    default:
        prev();
        return value;
    };
}
예제 #14
0
파일: parser.c 프로젝트: palmerc/lab
int unary_expression(void) {
	if( postfix_expression() ) {
	} else if( lookaheadT.type == INC_OP ) {	
		match(INC_OP);
		unary_expression();
	} else if( lookaheadT.type == DEC_OP ) {
		match(DEC_OP);
		unary_expression();
	} else if( unary_operator() ) {
		cast_expression();
	} else if( lookaheadT.type == SIZEOF ) {
		match(SIZEOF);
		if( unary_expression() ) {
		} else if( lookaheadT.type == LPAREN ) {
			match(LPAREN);
			type_name();
			match(RPAREN);
		} else {
			abort();
		}
	} else {
		abort();
	}
}
예제 #15
0
// Parse an additive expression.
//
//    additive-expression:
//      multiplicative-expression:
//      additive-expression '+' multiplicative-expression
//      additive-expression '-' multiplicative-expression
Expr&
Parser::additive_expression()
{
  Expr* e1 = &multiplicative_expression();
  while (true) {
    if (Token tok = match_if(tk::plus_tok)) {
      Expr& e2 = multiplicative_expression();
      e1 = &on_add_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::minus_tok)) {
      Expr& e2 = unary_expression();
      e1 = &on_sub_expression(tok, *e1, e2);
    } else {
      break;
    }
  }
  return *e1;
}
예제 #16
0
int PP_Expression::multiplicative_expression()
{
    int value = unary_expression();
    switch (next()) {
    case PP_STAR:
        return value * multiplicative_expression();
    case PP_PERCENT:
    {
        int remainder = multiplicative_expression();
        return remainder ? value % remainder : 0;
    }
    case PP_SLASH:
    {
        int div = multiplicative_expression();
        return div ? value / div : 0;
    }
    default:
        prev();
        return value;
    };
}
예제 #17
0
struct Symbol* unary_expression(struct UnaryExpression* node, struct Symbol** orig_symbol)
{
    int len;
    struct Symbol *symbol, *symbol1 = NULL;
    switch (node->type) {
        case 0:
            return postfix_expression(node->postfixExpression, orig_symbol);
        case 1:
        case 2:
            symbol = load_symbol(unary_expression(node->unaryExpression, orig_symbol));
            test_changeable(*orig_symbol);
            if (node->type == 2)
                symbol1 = test_calculable(symbol, '-');
            else
                symbol1 = test_calculable(symbol, '+');
            if (symbol1)
                return symbol1;
            ADDSTRING("  ");
            symbol1 = new_symbol("", symbol->storage, symbol->qualifier, symbol->specifier, symbol->stars - 1, 0, symbol->length);
            code_gen_symbol('%', symbol1);
            ADDSTRING(" = ");
            if ((symbol->specifier & (3 << 6)) > 0)
            {
                ADDSTRING("f");
            }
            if (node->type == 1)
            {
                ADDSTRING("add ");
            }
            else
            {
                ADDSTRING("sub ");
            }
            code_gen_type_specifier(symbol->specifier,1,symbol->length, symbol->stars);
            ADDSTRING(" ");
            code_gen_symbol('%', symbol);
            ADDSTRING(", ");
            if ((symbol->specifier & (3 << 6)) > 0)
            {
                ADDSTRING("1.000000e+00\n");
            }
            else
            {
                ADDSTRING("1\n");
            }
            ADDSTRING("  store ");
            code_gen_type_specifier(symbol->specifier,0,symbol->length, symbol->stars);
            ADDSTRING(" ");
            code_gen_symbol('%', symbol1);
            ADDSTRING(", ");
            code_gen_type_specifier(symbol->specifier,0,symbol->length, symbol->stars);
            ADDSTRING("* ");
            code_gen_symbol('%', *orig_symbol);
            ADDSTRING(", align ");
            int l = len_gen_type_specifier(symbol->specifier);
            sprintf(buf, "%d", l);
            ADDSTRING(buf);
            ADDSTRING("\n");
            *orig_symbol = 0;
            break;
            
        case 3:
            symbol = cast_expression(node->castExpression);
            switch (node->unaryOperator) {
                case 1:
                    test_pointable(symbol);
                    symbol = symbol->reference;
                    *orig_symbol = 0;
                    symbol1 = new_symbol("", symbol->storage, 2, symbol->specifier, symbol->stars + 1, 0, symbol->length);
                    ADDSTRING("  ");
                    code_gen_symbol('%', symbol1);
                    ADDSTRING(" = getelementptr inbounds ");
                    code_gen_type_specifier(symbol->specifier, 0, symbol->length, symbol1->stars);
                    ADDSTRING(" ");
                    code_gen_symbol('%', symbol);
                    ADDSTRING(", ");
                    ADDSTRING(PTR_LEN_TYPE);
                    ADDSTRING(" 0\n");
                    break;
                case 2:
                    test_referenceable(symbol);
                    symbol = load_symbol(symbol);
                    symbol1 = new_symbol("", symbol->storage, 0, symbol->specifier, symbol->stars - 1, 0, symbol->length);
                    *orig_symbol = symbol1;
                    if (symbol1->stars == 0)
                        symbol1->specifier = 32;
                    symbol1->reference = symbol;
                    ADDSTRING("  ");
                    code_gen_symbol('%', symbol1);
                    ADDSTRING(" = load ");
                    code_gen_type_specifier(symbol->specifier, 0, symbol->length, symbol->stars);
                    ADDSTRING(" ");
                    code_gen_symbol('%', symbol);
                    ADDSTRING(" ");
                    code_gen_symbol('%', symbol);
                    ADDSTRING(", align 8\n");
                    break;
                case 3:
                    test_regular(symbol);
                    symbol1 = symbol;
                    *orig_symbol = 0;
                    break;
                case 4:
                    test_regular(symbol);
                    symbol = load_symbol(symbol);
                    symbol1 = test_calculable(symbol, 'n');
                    if (symbol1)
                    {
                        return symbol1;
                    }
                    symbol1 = new_symbol("", symbol->storage, 2, symbol->specifier, symbol->stars, 0, 0);
                    *orig_symbol = symbol;
                    ADDSTRING("  ");
                    code_gen_symbol('%', symbol1);
                    if ((symbol->specifier & (3 << 6)) != 0)
                    {
                        ADDSTRING(" = f");
                    }
                    else
                    {
                        ADDSTRING(" = ");
                    }
                    ADDSTRING("sub ");
                    code_gen_type_specifier(symbol->specifier,1, symbol->length, symbol->stars);
                    ADDSTRING(" ");
                    if ((symbol->specifier & (3 << 6)) != 0)
                    {
                        ADDSTRING("0.000000e+00");
                    }
                    else
                    {
                        ADDSTRING("0");
                    }
                    ADDSTRING(", ");
                    code_gen_symbol('%', symbol);
                    ADDSTRING("\n");
                    *orig_symbol = 0;
                    break;
                case 5:
                    test_integer(symbol);
                    symbol = load_symbol(symbol);
                    symbol1 = test_calculable(symbol, '~');
                    if (symbol1)
                    {
                        return symbol1;
                    }
                    *orig_symbol = 0;
                    symbol = cast_symbol(symbol, 16, 0);
                    symbol1 = new_symbol("", symbol->storage, symbol->qualifier, symbol->specifier, symbol->stars, 0, symbol->length);
                    ADDSTRING("  ");
                    code_gen_symbol('%', symbol1);
                    ADDSTRING(" = xor ");
                    code_gen_type_specifier(symbol->specifier,0, symbol->length, symbol->stars);
                    ADDSTRING(" ");
                    code_gen_symbol('%', symbol);
                    ADDSTRING(", -1");
                    ADDSTRING("\n");
                    break;
                case 6:
                    *orig_symbol = 0;
                    symbol1 = test_calculable(symbol, '!');
                    symbol = load_symbol(symbol);
                    if (symbol1)
                    {
                        return symbol1;
                    }
                    symbol1 = new_symbol("0", 0, 2, 16, 0, 2, 0);
                    symbol1 = equality_symbol(symbol, symbol1, 2, 1);
                    break;
                default:
                    break;
            }
            break;
            
        case 4:
            *orig_symbol = 0;
            symbol = unary_expression(node->unaryExpression, orig_symbol);
            if (symbol->stars > (symbol->length > 0))
                len = PTR_LENGTH;
            else
            {
                len = len_gen_type_specifier(symbol->specifier);
                if (symbol->length)
                    len *= symbol->length;
            }
            sprintf(buf, "%d", len);
            symbol1 = new_symbol(buf, 0, 2, 4, 0, 2, 0);
            break;
            
        case 5:
            *orig_symbol = 0;
            len = len_gen_type_name(node->typeName);
            sprintf(buf, "%d", len);
            symbol1 = new_symbol(buf, 0, 2, 4, 0, 2, 0);
            break;
            
        default:
            break;
    }
    return symbol1;
}
예제 #18
0
struct Symbol* assignment_expression(struct AssignmentExpression* node)
{
    if (node->type == 0)
        return conditional_expression(node->conditionalExpression);
    // to do
    struct Symbol* orig_symbol;
    struct Symbol* symbol2 = load_symbol(assignment_expression(node->assignmentExpression));
    struct Symbol* symbol1 = unary_expression(node->unaryExpression, &orig_symbol);
    struct Symbol* symbol3 = 0;
    int specifier = symbol1->specifier;

    test_changeable(orig_symbol);
    if (node->assignmentOperator > 1)
    {
        switch (node->assignmentOperator) {
            case 2:
                symbol3 = multiplicative_symbol(symbol1, symbol2, 1);
                break;
            case 3:
                symbol3 = multiplicative_symbol(symbol1, symbol2, 2);
                break;
            case 4:
                symbol3 = multiplicative_symbol(symbol1, symbol2, 3);
                break;
            case 5:
                symbol3 = additive_symbol(symbol1, symbol2, 1);
                break;
            case 6:
                symbol3 = additive_symbol(symbol1, symbol2, 2);
                break;
            case 7:
                symbol3 = shift_symbol(symbol1, symbol2, 1);
                break;
            case 8:
                symbol3 = shift_symbol(symbol1, symbol2, 2);
                break;
            case 9:
                symbol3 = and_symbol(symbol1, symbol2, 1);
                break;
            case 10:
                symbol3 = exclusive_or_symbol(symbol1, symbol2, 1);
                break;
            case 11:
                symbol3 = inclusive_or_symbol(symbol1, symbol2, 1);
                break;
            default:
                break;
        }
    }
    else
        symbol3 = symbol2;
    
    symbol3 = cast_symbol(symbol3, orig_symbol->specifier, orig_symbol->stars);
    ADDSTRING("  store ");
    code_gen_type_specifier(symbol1->specifier,0,symbol1->length,symbol1->stars);
    ADDSTRING(" ");
    code_gen_symbol('%', symbol3);
    ADDSTRING(", ");
    code_gen_type_specifier(orig_symbol->specifier,0,orig_symbol->length,orig_symbol->stars);
    ADDSTRING("* ");
    code_gen_symbol('%',orig_symbol);
    ADDSTRING(", align ");
    int l = len_gen_type_specifier(specifier);
    sprintf(buf, "%d", l);
    ADDSTRING(buf);
    ADDSTRING("\n");
    return symbol3;
}
예제 #19
0
static struct block *unary_expression(struct block *block)
{
    struct var value;

    switch (peek().token) {
    case '&':
        consume('&');
        block = cast_expression(block);
        block->expr = eval_addr(block, block->expr);
        break;
    case '*':
        consume('*');
        block = cast_expression(block);
        block->expr = eval_deref(block, block->expr);
        break;
    case '!':
        consume('!');
        block = cast_expression(block);
        block->expr = eval_expr(block, IR_OP_EQ, var_int(0), block->expr);
        break;
    case '~':
        consume('~');
        block = cast_expression(block);
        block->expr = eval_expr(block, IR_NOT, block->expr);
        break;
    case '+':
        consume('+');
        block = cast_expression(block);
        block->expr.lvalue = 0;
        break;
    case '-':
        consume('-');
        block = cast_expression(block);
        block->expr = eval_expr(block, IR_OP_SUB, var_int(0), block->expr);
        break;
    case SIZEOF: {
        struct typetree *type;
        struct block *head = cfg_block_init(), *tail;
        consume(SIZEOF);
        if (peek().token == '(') {
            switch (peekn(2).token) {
            case FIRST(type_name):
                consume('(');
                type = declaration_specifiers(NULL);
                if (peek().token != ')') {
                    type = declarator(type, NULL);
                }
                consume(')');
                break;
            default:
                tail = unary_expression(head);
                type = (struct typetree *) tail->expr.type;
                break;
            }
        } else {
            tail = unary_expression(head);
            type = (struct typetree *) tail->expr.type;
        }
        if (is_function(type)) {
            error("Cannot apply 'sizeof' to function type.");
        }
        if (!size_of(type)) {
            error("Cannot apply 'sizeof' to incomplete type.");
        }
        block->expr = var_int(size_of(type));
        break;
    }
    case INCREMENT:
        consume(INCREMENT);
        block = unary_expression(block);
        value = block->expr;
        block->expr = eval_expr(block, IR_OP_ADD, value, var_int(1));
        block->expr = eval_assign(block, value, block->expr);
        break;
    case DECREMENT:
        consume(DECREMENT);
        block = unary_expression(block);
        value = block->expr;
        block->expr = eval_expr(block, IR_OP_SUB, value, var_int(1));
        block->expr = eval_assign(block, value, block->expr);
        break;
    default:
        block = postfix_expression(block);
        break;
    }

    return block;
}