authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-12-02 16:33:06-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-12-02 16:33:06-07:00
logc89f77dd8e5005e60e8fb223c6c68b50566ac1ed
tree8512500c908ac8d95595e44af6eb9bc06bd03c06
parentffc2c9225ff78b282e06486ce5465c91186bb48d

parsing variable declaration


8 files changed, 102 insertions(+), 6 deletions(-)

README.md+3-1
...@@ -114,7 +114,7 @@ Statement : NonBlockExpression token(Semicolon) | BlockExpression...@@ -114,7 +114,7 @@ Statement : NonBlockExpression token(Semicolon) | BlockExpression
114114
115Expression : BlockExpression | NonBlockExpression115Expression : BlockExpression | NonBlockExpression
116116
117NonBlockExpression : BoolOrExpression | ReturnExpression117NonBlockExpression : ReturnExpression | VariableDeclaration | BoolOrExpression
118118
119BlockExpression : IfExpression | Block119BlockExpression : IfExpression | Block
120120
...@@ -122,6 +122,8 @@ BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndEx...@@ -122,6 +122,8 @@ BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndEx
122122
123ReturnExpression : token(Return) option(Expression)123ReturnExpression : token(Return) option(Expression)
124124
125VariableDeclaration : token(Let) token(Symbole) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
126
125IfExpression : token(If) Expression Block option(Else | ElseIf)127IfExpression : token(If) Expression Block option(Else | ElseIf)
126128
127ElseIf : token(Else) IfExpression129ElseIf : token(Else) IfExpression
example/expressions/expressions.zig created+14
...@@ -0,0 +1,14 @@
1#link("c")
2extern {
3 fn puts(s: *const u8) -> i32;
4 fn exit(code: i32) -> unreachable;
5}
6
7export fn _start() -> unreachable {
8 let a : i32 = 1;
9 let b = 2;
10 let c : i32;
11 // let d; // compile error
12 puts("Hello, world!");
13 exit(a + b);
14}
src/analyze.cpp+10
...@@ -277,6 +277,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,...@@ -277,6 +277,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
277 case NodeTypeType:277 case NodeTypeType:
278 case NodeTypeFnDecl:278 case NodeTypeFnDecl:
279 case NodeTypeReturnExpr:279 case NodeTypeReturnExpr:
280 case NodeTypeVariableDeclaration:
280 case NodeTypeRoot:281 case NodeTypeRoot:
281 case NodeTypeBlock:282 case NodeTypeBlock:
282 case NodeTypeBinOpExpr:283 case NodeTypeBinOpExpr:
...@@ -373,6 +374,14 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -373,6 +374,14 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
373 break;374 break;
374 }375 }
375376
377 case NodeTypeVariableDeclaration:
378 {
379 zig_panic("TODO: analyze variable declaration");
380
381 return_type = g->builtin_types.entry_void;
382 break;
383 }
384
376 case NodeTypeBinOpExpr:385 case NodeTypeBinOpExpr:
377 {386 {
378 switch (node->data.bin_op_expr.bin_op) {387 switch (node->data.bin_op_expr.bin_op) {
...@@ -630,6 +639,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,...@@ -630,6 +639,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
630 case NodeTypeType:639 case NodeTypeType:
631 case NodeTypeFnDecl:640 case NodeTypeFnDecl:
632 case NodeTypeReturnExpr:641 case NodeTypeReturnExpr:
642 case NodeTypeVariableDeclaration:
633 case NodeTypeRoot:643 case NodeTypeRoot:
634 case NodeTypeBlock:644 case NodeTypeBlock:
635 case NodeTypeBinOpExpr:645 case NodeTypeBinOpExpr:
src/codegen.cpp+2
...@@ -477,6 +477,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -477,6 +477,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
477 return gen_bin_op_expr(g, node);477 return gen_bin_op_expr(g, node);
478 case NodeTypeReturnExpr:478 case NodeTypeReturnExpr:
479 return gen_return_expr(g, node);479 return gen_return_expr(g, node);
480 case NodeTypeVariableDeclaration:
481 zig_panic("TODO: variable declaration code gen");
480 case NodeTypeCastExpr:482 case NodeTypeCastExpr:
481 return gen_cast_expr(g, node);483 return gen_cast_expr(g, node);
482 case NodeTypePrefixOpExpr:484 case NodeTypePrefixOpExpr:
src/parser.cpp+60-5
...@@ -75,6 +75,8 @@ const char *node_type_str(NodeType node_type) {...@@ -75,6 +75,8 @@ const char *node_type_str(NodeType node_type) {
75 return "Directive";75 return "Directive";
76 case NodeTypeReturnExpr:76 case NodeTypeReturnExpr:
77 return "ReturnExpr";77 return "ReturnExpr";
78 case NodeTypeVariableDeclaration:
79 return "VariableDeclaration";
78 case NodeTypeCastExpr:80 case NodeTypeCastExpr:
79 return "CastExpr";81 return "CastExpr";
80 case NodeTypeNumberLiteral:82 case NodeTypeNumberLiteral:
...@@ -178,6 +180,16 @@ void ast_print(AstNode *node, int indent) {...@@ -178,6 +180,16 @@ void ast_print(AstNode *node, int indent) {
178 if (node->data.return_expr.expr)180 if (node->data.return_expr.expr)
179 ast_print(node->data.return_expr.expr, indent + 2);181 ast_print(node->data.return_expr.expr, indent + 2);
180 break;182 break;
183 case NodeTypeVariableDeclaration:
184 {
185 Buf *name_buf = &node->data.variable_declaration.symbol;
186 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf));
187 if (node->data.variable_declaration.type)
188 ast_print(node->data.variable_declaration.type, indent + 2);
189 if (node->data.variable_declaration.expr)
190 ast_print(node->data.variable_declaration.expr, indent + 2);
191 break;
192 }
181 case NodeTypeExternBlock:193 case NodeTypeExternBlock:
182 {194 {
183 fprintf(stderr, "%s\n", node_type_str(node->type));195 fprintf(stderr, "%s\n", node_type_str(node->type));
...@@ -1042,6 +1054,45 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m...@@ -1042,6 +1054,45 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m
1042 }1054 }
1043}1055}
10441056
1057/*
1058VariableDeclaration : token(Let) token(Symbole) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
1059*/
1060static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory) {
1061 Token *let_tok = &pc->tokens->at(*token_index);
1062 if (let_tok->id == TokenIdKeywordLet) {
1063 *token_index += 1;
1064 AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, let_tok);
1065
1066 Token *name_token = &pc->tokens->at(*token_index);
1067 *token_index += 1;
1068 ast_expect_token(pc, name_token, TokenIdSymbol);
1069 ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol);
1070
1071 Token *eq_or_colon = &pc->tokens->at(*token_index);
1072 *token_index += 1;
1073 if (eq_or_colon->id == TokenIdEq) {
1074 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1075 return node;
1076 } else if (eq_or_colon->id == TokenIdColon) {
1077 node->data.variable_declaration.type = ast_parse_type(pc, *token_index, token_index);
1078
1079 Token *eq_token = &pc->tokens->at(*token_index);
1080 if (eq_token->id == TokenIdEq) {
1081 *token_index += 1;
1082
1083 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1084 }
1085 return node;
1086 } else {
1087 ast_invalid_token_error(pc, eq_or_colon);
1088 }
1089 } else if (mandatory) {
1090 ast_invalid_token_error(pc, let_tok);
1091 } else {
1092 return nullptr;
1093 }
1094}
1095
1045/*1096/*
1046BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression1097BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression
1047*/1098*/
...@@ -1086,19 +1137,23 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, int *token_index, bool ma...@@ -1086,19 +1137,23 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, int *token_index, bool ma
1086}1137}
10871138
1088/*1139/*
1089NonBlockExpression : BoolOrExpression | ReturnExpression1140NonBlockExpression : ReturnExpression | VariableDeclaration | BoolOrExpression
1090*/1141*/
1091static AstNode *ast_parse_non_block_expr(ParseContext *pc, int *token_index, bool mandatory) {1142static AstNode *ast_parse_non_block_expr(ParseContext *pc, int *token_index, bool mandatory) {
1092 Token *token = &pc->tokens->at(*token_index);1143 Token *token = &pc->tokens->at(*token_index);
10931144
1094 AstNode *bool_or_expr = ast_parse_bool_or_expr(pc, token_index, false);
1095 if (bool_or_expr)
1096 return bool_or_expr;
1097
1098 AstNode *return_expr = ast_parse_return_expr(pc, token_index, false);1145 AstNode *return_expr = ast_parse_return_expr(pc, token_index, false);
1099 if (return_expr)1146 if (return_expr)
1100 return return_expr;1147 return return_expr;
11011148
1149 AstNode *variable_declaration_expr = ast_parse_variable_declaration_expr(pc, token_index, false);
1150 if (variable_declaration_expr)
1151 return variable_declaration_expr;
1152
1153 AstNode *bool_or_expr = ast_parse_bool_or_expr(pc, token_index, false);
1154 if (bool_or_expr)
1155 return bool_or_expr;
1156
1102 if (mandatory)1157 if (mandatory)
1103 ast_invalid_token_error(pc, token);1158 ast_invalid_token_error(pc, token);
11041159
src/parser.hpp+9
...@@ -29,6 +29,7 @@ enum NodeType {...@@ -29,6 +29,7 @@ enum NodeType {
29 NodeTypeExternBlock,29 NodeTypeExternBlock,
30 NodeTypeDirective,30 NodeTypeDirective,
31 NodeTypeReturnExpr,31 NodeTypeReturnExpr,
32 NodeTypeVariableDeclaration,
32 NodeTypeBinOpExpr,33 NodeTypeBinOpExpr,
33 NodeTypeCastExpr,34 NodeTypeCastExpr,
34 NodeTypeNumberLiteral,35 NodeTypeNumberLiteral,
...@@ -95,6 +96,13 @@ struct AstNodeReturnExpr {...@@ -95,6 +96,13 @@ struct AstNodeReturnExpr {
95 AstNode *expr;96 AstNode *expr;
96};97};
9798
99struct AstNodeVariableDeclaration {
100 Buf symbol;
101 // one or both of type and expr will be non null
102 AstNode *type;
103 AstNode *expr;
104};
105
98enum BinOpType {106enum BinOpType {
99 BinOpTypeInvalid,107 BinOpTypeInvalid,
100 // TODO: include assignment?108 // TODO: include assignment?
...@@ -190,6 +198,7 @@ struct AstNode {...@@ -190,6 +198,7 @@ struct AstNode {
190 AstNodeParamDecl param_decl;198 AstNodeParamDecl param_decl;
191 AstNodeBlock block;199 AstNodeBlock block;
192 AstNodeReturnExpr return_expr;200 AstNodeReturnExpr return_expr;
201 AstNodeVariableDeclaration variable_declaration;
193 AstNodeBinOpExpr bin_op_expr;202 AstNodeBinOpExpr bin_op_expr;
194 AstNodeExternBlock extern_block;203 AstNodeExternBlock extern_block;
195 AstNodeDirective directive;204 AstNodeDirective directive;
src/tokenizer.cpp+3
...@@ -165,6 +165,8 @@ static void end_token(Tokenize *t) {...@@ -165,6 +165,8 @@ static void end_token(Tokenize *t) {
165 t->cur_tok->id = TokenIdKeywordFn;165 t->cur_tok->id = TokenIdKeywordFn;
166 } else if (mem_eql_str(token_mem, token_len, "return")) {166 } else if (mem_eql_str(token_mem, token_len, "return")) {
167 t->cur_tok->id = TokenIdKeywordReturn;167 t->cur_tok->id = TokenIdKeywordReturn;
168 } else if (mem_eql_str(token_mem, token_len, "let")) {
169 t->cur_tok->id = TokenIdKeywordLet;
168 } else if (mem_eql_str(token_mem, token_len, "mut")) {170 } else if (mem_eql_str(token_mem, token_len, "mut")) {
169 t->cur_tok->id = TokenIdKeywordMut;171 t->cur_tok->id = TokenIdKeywordMut;
170 } else if (mem_eql_str(token_mem, token_len, "const")) {172 } else if (mem_eql_str(token_mem, token_len, "const")) {
...@@ -574,6 +576,7 @@ static const char * token_name(Token *token) {...@@ -574,6 +576,7 @@ static const char * token_name(Token *token) {
574 case TokenIdKeywordConst: return "Const";576 case TokenIdKeywordConst: return "Const";
575 case TokenIdKeywordMut: return "Mut";577 case TokenIdKeywordMut: return "Mut";
576 case TokenIdKeywordReturn: return "Return";578 case TokenIdKeywordReturn: return "Return";
579 case TokenIdKeywordLet: return "Let";
577 case TokenIdKeywordExtern: return "Extern";580 case TokenIdKeywordExtern: return "Extern";
578 case TokenIdKeywordUnreachable: return "Unreachable";581 case TokenIdKeywordUnreachable: return "Unreachable";
579 case TokenIdKeywordPub: return "Pub";582 case TokenIdKeywordPub: return "Pub";
src/tokenizer.hpp+1
...@@ -15,6 +15,7 @@ enum TokenId {...@@ -15,6 +15,7 @@ enum TokenId {
15 TokenIdSymbol,15 TokenIdSymbol,
16 TokenIdKeywordFn,16 TokenIdKeywordFn,
17 TokenIdKeywordReturn,17 TokenIdKeywordReturn,
18 TokenIdKeywordLet,
18 TokenIdKeywordMut,19 TokenIdKeywordMut,
19 TokenIdKeywordConst,20 TokenIdKeywordConst,
20 TokenIdKeywordExtern,21 TokenIdKeywordExtern,