Exemplo n.º 1
0
Arquivo: parser.c Projeto: palmerc/lab
int postfix_expression(void) {
	if ( primary_expression() ) {
	} else if( postfix_expression() ) {
		if( lookaheadT.type == LBRACKET ) {
			match(LBRACKET);
			expression();
			match(RBRACKET);
		} else if( lookaheadT.type == LPAREN ) {
			match(LPAREN);
			if( argument_expression_list() ) {
			}
			match(RPAREN);
		} else if( lookaheadT.type == PERIOD ) {
			match(PERIOD);
			match(ID);
		} else if( lookaheadT.type == PTR_OP ) {	
			match(PTR_OP);
			match(ID);
		} else if( lookaheadT.type == INC_OP ) {
			match(INC_OP);
		} else if( lookaheadT.type == DEC_OP ) {	
			match(DEC_OP);
		} else {
			abort();
		}
	} else {
		abort();
	}
}
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();
    }
}
Exemplo n.º 3
0
static sl_node_base_t*
call_expression(sl_parse_state_t* ps)
{
    sl_node_base_t* left = primary_expression(ps);
    sl_node_base_t** nodes;
    size_t node_len;
    size_t node_cap;
    sl_token_t* tok;
    if(left->type == SL_NODE_VAR && peek_token(ps)->type == SL_TOK_OPEN_PAREN) {
        left = send_with_args_expression(ps, sl_make_self_node(ps),
            sl_intern2(ps->vm, sl_make_ptr((sl_object_t*)((sl_node_var_t*)left)->name)));
    }
    while(1) {
        tok = peek_token(ps);
        switch(tok->type) {
            case SL_TOK_DOT:
                next_token(ps);
                left = send_expression(ps, left);
                break;
            case SL_TOK_COLON:
                next_token(ps);
                left = sl_make_bind_method_node(ps, left, def_expression_method_name(ps));
                break;
            case SL_TOK_PAAMAYIM_NEKUDOTAYIM:
                next_token(ps);
                tok = expect_token(ps, SL_TOK_CONSTANT);
                left = sl_make_const_node(ps, left,
                    sl_intern2(ps->vm,
                        sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)));
                break;
            case SL_TOK_OPEN_BRACKET:
                next_token(ps);
                node_cap = 1;
                node_len = 0;
                nodes = sl_alloc(ps->vm->arena, sizeof(SLVAL) * node_cap);
                while(peek_token(ps)->type != SL_TOK_CLOSE_BRACKET) {
                    if(node_len >= node_cap) {
                        node_cap *= 2;
                        nodes = sl_realloc(ps->vm->arena, nodes, sizeof(SLVAL) * node_cap);
                    }
                    nodes[node_len++] = expression(ps);
                    if(peek_token(ps)->type != SL_TOK_CLOSE_BRACKET) {
                        expect_token(ps, SL_TOK_COMMA);
                    }
                }
                expect_token(ps, SL_TOK_CLOSE_BRACKET);
                left = sl_make_send_node(ps, left, sl_intern(ps->vm, "[]"), node_len, nodes);
                break;
            default:
                return left;
        }
    }
}
Exemplo n.º 4
0
// Parse a postfix-expression.
//
//    postfix-expression:
//      primary-expression
//      postfix-expression '.' id
//      postfix-expression '(' [expression-list] ')'
//      postfix-expression '[' expression ']'
//
// TODO: Add lots of stuff here.
Expr&
Parser::postfix_expression()
{
  Expr* e = &primary_expression();
  while (true) {
    if (lookahead() == tk::dot_tok)
      e = &dot_expression(*e);
    else if (lookahead() == tk::lparen_tok)
      e = &call_expression(*e);
    else if (lookahead() == tk::lbracket_tok)
      e = &subscript_expression(*e);
    else
      break;
  }
  return *e;
}
Exemplo n.º 5
0
static sl_node_base_t*
try_expression(sl_parse_state_t* ps)
{
    sl_node_base_t *body, *lval = NULL, *catch_body = NULL;
    sl_token_t* tok;
    expect_token(ps, SL_TOK_TRY);
    body = body_expression(ps);
    expect_token(ps, SL_TOK_CATCH);
    tok = peek_token(ps);
    if(tok->type != SL_TOK_OPEN_BRACE) {
        lval = primary_expression(ps);
        if(!sl_node_is_lval(lval)) {
            unexpected(ps, tok);
        }
    }
    catch_body = body_expression(ps);
    return sl_make_try_node(ps, body, lval, catch_body);
}
Exemplo n.º 6
0
/**
后缀表达式
<postfix_expression>::=<primary_expression>
                      {<TK_OPENPA><expression><TK_CLOSEPA>
                      |<TK_OPENPA><TK_CLOSEPA>
                      |<TK_OPENPA><arguement_expression_list><TK_CLOSEPA>
                      |<TK_DOT><IDENTIFIER>
                      |<TK_POINTSTO><IDENTIFIER>}
*/
void postfix_expression(){
    primary_expression();
    while(1){
        if(TK_DOT == token || TK_POINTSTO == token){
            get_token();
            token |= SC_MEMBER;
            get_token();
        }else if(TK_OPENBR == token){
            get_token();
            expression();
            skip(TK_CLOSEBR);
			get_token();
        }else if(TK_OPENPA == token){
            argument_expression_list();
        }else
            break;
    }
}
Exemplo n.º 7
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();
    }
}
Exemplo n.º 8
0
static sl_node_base_t*
def_expression(sl_parse_state_t* ps)
{
    SLID name;
    sl_node_base_t* on = NULL;
    sl_node_base_t* body;
    sl_token_t* tok;
    size_t req_arg_count = 0, req_arg_cap = 2;
    sl_string_t** req_args = sl_alloc(ps->vm->arena, sizeof(sl_string_t*) * req_arg_cap);
    size_t opt_arg_count = 0, opt_arg_cap = 2;
    sl_node_opt_arg_t* opt_args = sl_alloc(ps->vm->arena, sizeof(sl_node_opt_arg_t) * opt_arg_cap);
    sl_parse_scope_t scope;
    expect_token(ps, SL_TOK_DEF);
    switch(peek_token(ps)->type) {
        case SL_TOK_IDENTIFIER:
            if(peek_token_n(ps, 2)->type == SL_TOK_DOT) {
                on = sl_make_var_node(ps, SL_NODE_VAR, next_token(ps)->str);
                next_token(ps);
                name = def_expression_method_name(ps);
            } else {
                on = NULL;
                name = def_expression_method_name(ps);
            }
            break;
        case SL_TOK_SELF:
        case SL_TOK_IVAR:
        case SL_TOK_CVAR:
        case SL_TOK_CONSTANT:
            on = primary_expression(ps);
            expect_token(ps, SL_TOK_DOT);
            name = def_expression_method_name(ps);
            break;
        default:
            name = def_expression_method_name(ps);
    }
    if(peek_token(ps)->type == SL_TOK_EQUALS) {
        next_token(ps);
        name = sl_intern2(ps->vm,
            sl_string_concat(ps->vm, sl_id_to_string(ps->vm, name), sl_make_cstring(ps->vm, "=")));
    }
    int at_opt_args = 0;
    if(peek_token(ps)->type != SL_TOK_OPEN_BRACE) {
        expect_token(ps, SL_TOK_OPEN_PAREN);
        if(peek_token(ps)->type == SL_TOK_SELF) {
            error(ps, sl_make_cstring(ps->vm, "not a chance"), peek_token(ps));
        }
        while(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) {
            tok = expect_token(ps, SL_TOK_IDENTIFIER);
            if(peek_token(ps)->type == SL_TOK_EQUALS) {
                at_opt_args = 1;
            }
            if(at_opt_args) {
                expect_token(ps, SL_TOK_EQUALS);
                if(opt_arg_count >= opt_arg_cap) {
                    opt_arg_cap *= 2;
                    opt_args = sl_realloc(ps->vm->arena, opt_args, sizeof(sl_node_opt_arg_t) * opt_arg_cap);
                }
                opt_args[opt_arg_count].name = (sl_string_t*)sl_get_ptr(
                    sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
                opt_args[opt_arg_count++].default_value = expression(ps);
            } else {
                if(req_arg_count >= req_arg_cap) {
                    req_arg_cap *= 2;
                    req_args = sl_realloc(ps->vm->arena, req_args, sizeof(sl_string_t*) * req_arg_cap);
                }
                req_args[req_arg_count++] = (sl_string_t*)sl_get_ptr(
                    sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
            }
            if(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) {
                expect_token(ps, SL_TOK_COMMA);
            }
        }
        expect_token(ps, SL_TOK_CLOSE_PAREN);
    }
    scope.prev = ps->scope;
    scope.flags = SL_PF_CAN_RETURN;
    ps->scope = &scope;
    body = body_expression(ps);
    ps->scope = scope.prev;
    ps->scope->flags |= SL_PF_SCOPE_CLOSURE;
    return sl_make_def_node(ps, name, on, req_arg_count, req_args, opt_arg_count, opt_args, body);
}
Exemplo n.º 9
0
static struct block *postfix_expression(struct block *block)
{
    struct var root;

    block = primary_expression(block);
    root = block->expr;

    while (1) {
        const struct member *field;
        const struct typetree *type;
        struct var expr, copy, *arg;
        struct token tok;
        int i, j;

        switch ((tok = peek()).token) {
        case '[':
            do {
                /* Evaluate a[b] = *(a + b). The semantics of pointer arithmetic
                 * takes care of multiplying b with the correct width. */
                consume('[');
                block = expression(block);
                root = eval_expr(block, IR_OP_ADD, root, block->expr);
                root = eval_deref(block, root);
                consume(']');
            } while (peek().token == '[');
            break;
        case '(':
            type = root.type;
            if (is_pointer(root.type) && is_function(root.type->next))
                type = type_deref(root.type);
            else if (!is_function(root.type)) {
                error("Expression must have type pointer to function, was %t.",
                    root.type);
                exit(1);
            }
            consume('(');
            arg = calloc(nmembers(type), sizeof(*arg));
            for (i = 0; i < nmembers(type); ++i) {
                if (peek().token == ')') {
                    error("Too few arguments, expected %d but got %d.",
                        nmembers(type), i);
                    exit(1);
                }
                block = assignment_expression(block);
                arg[i] = block->expr;
                /* todo: type check here. */
                if (i < nmembers(type) - 1) {
                    consume(',');
                }
            }
            while (is_vararg(type) && peek().token != ')') {
                consume(',');
                arg = realloc(arg, (i + 1) * sizeof(*arg));
                block = assignment_expression(block);
                arg[i] = block->expr;
                i++;
            }
            consume(')');
            for (j = 0; j < i; ++j)
                param(block, arg[j]);
            free(arg);
            root = eval_call(block, root);
            break;
        case '.':
            consume('.');
            tok = consume(IDENTIFIER);
            field = find_type_member(root.type, tok.strval);
            if (!field) {
                error("Invalid field access, no member named '%s'.",
                    tok.strval);
                exit(1);
            }
            root.type = field->type;
            root.offset += field->offset;
            break;
        case ARROW:
            consume(ARROW);
            tok = consume(IDENTIFIER);
            if (is_pointer(root.type) && is_struct_or_union(root.type->next)) {
                field = find_type_member(type_deref(root.type), tok.strval);
                if (!field) {
                    error("Invalid field access, no member named '%s'.",
                        tok.strval);
                    exit(1);
                }

                /* Make it look like a pointer to the field type, then perform
                 * normal dereferencing. */
                root.type = type_init(T_POINTER, field->type);
                root = eval_deref(block, root);
                root.offset = field->offset;
            } else {
                error("Invalid field access.");
                exit(1);
            }
            break;
        case INCREMENT:
            consume(INCREMENT);
            copy = create_var(root.type);
            eval_assign(block, copy, root);
            expr = eval_expr(block, IR_OP_ADD, root, var_int(1));
            eval_assign(block, root, expr);
            root = copy;
            break;
        case DECREMENT:
            consume(DECREMENT);
            copy = create_var(root.type);
            eval_assign(block, copy, root);
            expr = eval_expr(block, IR_OP_SUB, root, var_int(1));
            eval_assign(block, root, expr);
            root = copy;
            break;
        default:
            block->expr = root;
            return block;
        }
    }
}
Exemplo n.º 10
0
struct Symbol* postfix_expression(struct PostfixExpression* node, struct Symbol** orig_symbol)
{
    struct Symbol* symbol, *ref, *newSymbol = 0, *symbol1;
    switch (node->type) {
        case 0:
            return primary_expression(node->primaryExpression, orig_symbol);
        case 1:
            symbol = load_symbol(postfix_expression(node->postfixExpression, orig_symbol));
            test_referenceable(symbol);
            ref = load_symbol(expression_func(node->expression));
            *orig_symbol = new_symbol("", symbol->storage, 0, symbol->specifier, symbol->stars - 1, 0, 0);
            if (symbol->stars == 1)
                (*orig_symbol)->specifier = 32;
            ADDSTRING("  ");
            code_gen_symbol('%', *orig_symbol);
            ADDSTRING(" = getelementptr inbounds ");
            code_gen_type_specifier(symbol->specifier, 0, symbol->length, symbol->stars);
            ADDSTRING(" ");
            if (symbol->depth == 0)
                code_gen_symbol('@', symbol);
            else
                code_gen_symbol('%', symbol);
            if (symbol->length)
                ADDSTRING(", i32 0");
            ADDSTRING(", ");
            test_integer(ref);
            code_gen_type_specifier(ref->specifier, 0, 0, 0);
            ADDSTRING(" ");
            code_gen_symbol('%', ref);
            ADDSTRING("\n");
            ADDSTRING("  ");
            newSymbol = new_symbol("", 0, 2, symbol->specifier, symbol->stars - 1, 0, 0);
            newSymbol->reference = *orig_symbol;
            code_gen_symbol('%', newSymbol);
            ADDSTRING(" = load ");
            code_gen_type_specifier(symbol->specifier, 0, (*orig_symbol)->length, symbol->stars);
            ADDSTRING(" ");
            code_gen_symbol('%', *orig_symbol);
            ADDSTRING(", align ");
            if (newSymbol->stars)
            {
                if (PTR_LENGTH == 8)
                {
                    ADDSTRING("8\n");
                }
                else
                {
                    ADDSTRING("4\n");
                }
            }
            else
            {
                int len = len_gen_type_specifier(newSymbol->specifier);
                sprintf(buf, "%d\n", len);
                ADDSTRING(buf);
            }
            return newSymbol;
        case 2:
        case 3:
            symbol = postfix_expression(node->postfixExpression, orig_symbol);
            test_functionable(symbol);
            if (node->type == 3)
            {
                argument_expression_list(node->argumentExpressionList, symbol->parameterlist);
            }
            if (!(symbol->specifier & 0x02)) {
                newSymbol = new_symbol("", symbol->storage, 2, symbol->specifier, symbol->stars, 0, symbol->length);
                ADDSTRING("  ");
                code_gen_symbol('%', newSymbol);
                ADDSTRING(" = call ");
            } else {
                ADDSTRING("  call ");
                newSymbol = symbol;
            }
            if (strcmp(symbol->name, "free") != 0)
            {
                code_gen_type_specifier(symbol->specifier, 0, symbol->length, symbol->stars);
                ADDSTRING(" ");
                if (strcmp(symbol->name, "printf") == 0 || strcmp(symbol->name, "scanf") == 0)
                {
                    ADDSTRING("(i8*, ...)* ");
                }
                code_gen_symbol('@', symbol);
            }
            else
            {
                ADDSTRING("i32 (");
                code_gen_type_specifier(symbol_arg[0]->specifier, 0, 0, symbol_arg[0]->stars);
                ADDSTRING(", ...)* bitcast (i32 (...)* @free to i32 (");
                code_gen_type_specifier(symbol_arg[0]->specifier, 0, 0, symbol_arg[0]->stars);
                ADDSTRING(", ...)*)");
            }
            ADDSTRING("(");
            if (node->type == 3)
            {
                pop_arg();
            }
            ADDSTRING(")\n");
            *orig_symbol = newSymbol;
            return newSymbol;
        case 4:
        case 5:
            // to do: struct
            return 0;
        case 6:
        case 7:
            symbol = load_symbol(postfix_expression(node->postfixExpression, orig_symbol));
            test_changeable(*orig_symbol);
            symbol1 = new_symbol("", symbol->storage, 2, symbol->specifier, symbol->stars, 0, symbol->length);
            ADDSTRING("  ");
            code_gen_symbol('%', symbol1);
            ADDSTRING(" = ");
            if ((symbol->specifier & (3 << 6)) > 0)
            {
                ADDSTRING("f");
            }
            if (node->type == 6)
            {
                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");
            return symbol;
        default:
            return 0;
    }
}