#include "../parser.h" #include "ast.h" #include "../symtab/symtab.h" /** * 0 false * 1 true */ int peek_decl(tok_buf_t* tokbuf) { flush_peek_tok(tokbuf); switch (peek_tok_type(tokbuf)) { case TOKEN_STATIC: case TOKEN_EXTERN: case TOKEN_REGISTER: case TOKEN_TYPEDEF: error("not impliment"); break; default: flush_peek_tok(tokbuf); } switch (peek_tok_type(tokbuf)) { case TOKEN_VOID: case TOKEN_CHAR: case TOKEN_SHORT: case TOKEN_INT: case TOKEN_LONG: case TOKEN_FLOAT: case TOKEN_DOUBLE: // FIXME Ptr return 1; default: flush_peek_tok(tokbuf); } return 0; } ast_node_t* parse_decl_val(parser_t* parser) { tok_buf_t* tokbuf = &parser->tokbuf; tok_type_t ttype; flush_peek_tok(tokbuf); ast_node_t* node; ast_node_t* type_node = parse_type(parser); flush_peek_tok(tokbuf); ast_node_t* name_node = new_ast_ident_node(peek_tok(tokbuf)); node = new_ast_node(); node->decl_val.type = type_node; node->decl_val.name = name_node; node->type = NT_DECL_VAR; symtab_add_symbol(parser->symtab, name_node->syms.tok.val.str, node, 0); ttype = peek_tok_type(tokbuf); if (ttype == TOKEN_ASSIGN) { node->decl_val.expr_stmt = parse_stmt(parser); if (node->decl_val.expr_stmt->type != NT_STMT_EXPR) { error("parser_decl_val want stmt_expr"); } } else if (ttype == TOKEN_SEMICOLON) { pop_tok(tokbuf); expect_pop_tok(tokbuf, TOKEN_SEMICOLON); } else { error("parser_decl_val syntax error"); } return node; } ast_node_t* parse_decl(parser_t* parser) { tok_buf_t* tokbuf = &parser->tokbuf; flush_peek_tok(tokbuf); tok_type_t ttype; ast_node_t* node; if (peek_decl(tokbuf) == 0) { error("syntax error expect decl_val TYPE"); } if (peek_tok_type(tokbuf) != TOKEN_IDENT) { error("syntax error expect decl_val IDENT"); } ttype = peek_tok_type(tokbuf); switch (ttype) { case TOKEN_L_PAREN: // ( return NULL; break; case TOKEN_ASSIGN: case TOKEN_SEMICOLON: node = parse_decl_val(parser); break; default: error("syntax error expect decl_val ASSIGN or SEMICOLON"); return NULL; } return node; }