authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-12-03 12:15:07-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-12-03 12:15:07-07:00
logf1aaf1353e12aa39bd6f89588852a1c70e8424b3
tree38d2f72517dc257ef4f8eb09ff4ae84be0819201
parent6494cf208e8045c58e8ab79fb76e360cec077263

add bool literals


8 files changed, 52 insertions(+), 2 deletions(-)

README.md+3-1
......@@ -163,11 +163,13 @@ FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)
163163
164164PrefixOp : token(Not) | token(Dash) | token(Tilde)
165165
166PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | token(Symbol) | Goto
166PrimaryExpression : token(Number) | token(String) | KeywordLiteral | GroupedExpression | token(Symbol) | Goto
167167
168168Goto: token(Goto) token(Symbol)
169169
170170GroupedExpression : token(LParen) Expression token(RParen)
171
172KeywordLiteral : token(Unreachable) | token(Void) | token(True) | token(False)
171173```
172174
173175### Operator Precedence
example/expressions/expressions.zig+7-1
......@@ -4,6 +4,12 @@ extern {
44 fn exit(code: i32) -> unreachable;
55}
66
7fn other_exit() -> unreachable {
8 if (true) { exit(0); }
9 // the unreachable statement is the programmer assuring the compiler that this code is impossible to execute.
10 unreachable;
11}
12
713export fn _start() -> unreachable {
814 let a : i32 = 1;
915 let b = 2;
......@@ -19,5 +25,5 @@ export fn _start() -> unreachable {
1925 no_conflict
2026 };
2127 if (c == 10) { puts("OK 2"); }
22 exit(0);
28 other_exit();
2329}
src/analyze.cpp+6
......@@ -297,6 +297,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
297297 case NodeTypeStringLiteral:
298298 case NodeTypeUnreachable:
299299 case NodeTypeVoid:
300 case NodeTypeBoolLiteral:
300301 case NodeTypeSymbol:
301302 case NodeTypeCastExpr:
302303 case NodeTypePrefixOpExpr:
......@@ -592,6 +593,10 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
592593 return_type = g->builtin_types.entry_void;
593594 break;
594595
596 case NodeTypeBoolLiteral:
597 return_type = g->builtin_types.entry_bool;
598 break;
599
595600 case NodeTypeSymbol:
596601 {
597602 Buf *symbol_name = &node->data.symbol;
......@@ -766,6 +771,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
766771 case NodeTypeStringLiteral:
767772 case NodeTypeUnreachable:
768773 case NodeTypeVoid:
774 case NodeTypeBoolLiteral:
769775 case NodeTypeSymbol:
770776 case NodeTypeCastExpr:
771777 case NodeTypePrefixOpExpr:
src/codegen.cpp+5
......@@ -487,6 +487,11 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
487487 return LLVMBuildUnreachable(g->builder);
488488 case NodeTypeVoid:
489489 return nullptr;
490 case NodeTypeBoolLiteral:
491 if (node->data.bool_literal)
492 return LLVMConstAllOnes(LLVMInt1Type());
493 else
494 return LLVMConstNull(LLVMInt1Type());
490495 case NodeTypeIfExpr:
491496 return gen_if_expr(g, node);
492497 case NodeTypeNumberLiteral:
src/parser.cpp+21
......@@ -93,6 +93,8 @@ const char *node_type_str(NodeType node_type) {
9393 return "Use";
9494 case NodeTypeVoid:
9595 return "Void";
96 case NodeTypeBoolLiteral:
97 return "BoolLiteral";
9698 case NodeTypeIfExpr:
9799 return "IfExpr";
98100 case NodeTypeLabel:
......@@ -256,6 +258,9 @@ void ast_print(AstNode *node, int indent) {
256258 case NodeTypeVoid:
257259 fprintf(stderr, "%s\n", node_type_str(node->type));
258260 break;
261 case NodeTypeBoolLiteral:
262 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), node->data.bool_literal ? "true" : "false");
263 break;
259264 case NodeTypeIfExpr:
260265 fprintf(stderr, "%s\n", node_type_str(node->type));
261266 if (node->data.if_expr.condition)
......@@ -457,6 +462,12 @@ static AstNode *ast_parse_type(ParseContext *pc, int token_index, int *new_token
457462 } else if (token->id == TokenIdKeywordVoid) {
458463 node->data.type.type = AstNodeTypeTypePrimitive;
459464 buf_init_from_str(&node->data.type.primitive_name, "void");
465 } else if (token->id == TokenIdKeywordTrue) {
466 node->data.type.type = AstNodeTypeTypePrimitive;
467 buf_init_from_str(&node->data.type.primitive_name, "true");
468 } else if (token->id == TokenIdKeywordFalse) {
469 node->data.type.type = AstNodeTypeTypePrimitive;
470 buf_init_from_str(&node->data.type.primitive_name, "false");
460471 } else if (token->id == TokenIdSymbol) {
461472 node->data.type.type = AstNodeTypeTypePrimitive;
462473 ast_buf_from_token(pc, token, &node->data.type.primitive_name);
......@@ -614,6 +625,16 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
614625 AstNode *node = ast_create_node(pc, NodeTypeVoid, token);
615626 *token_index += 1;
616627 return node;
628 } else if (token->id == TokenIdKeywordTrue) {
629 AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
630 node->data.bool_literal = true;
631 *token_index += 1;
632 return node;
633 } else if (token->id == TokenIdKeywordFalse) {
634 AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
635 node->data.bool_literal = false;
636 *token_index += 1;
637 return node;
617638 } else if (token->id == TokenIdSymbol) {
618639 AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);
619640 ast_buf_from_token(pc, token, &node->data.symbol);
src/parser.hpp+2
......@@ -40,6 +40,7 @@ enum NodeType {
4040 NodeTypeFnCallExpr,
4141 NodeTypeUse,
4242 NodeTypeVoid,
43 NodeTypeBoolLiteral,
4344 NodeTypeIfExpr,
4445 NodeTypeLabel,
4546 NodeTypeGoto,
......@@ -222,6 +223,7 @@ struct AstNode {
222223 Buf number;
223224 Buf string;
224225 Buf symbol;
226 bool bool_literal;
225227 } data;
226228};
227229
src/tokenizer.cpp+6
......@@ -185,6 +185,10 @@ static void end_token(Tokenize *t) {
185185 t->cur_tok->id = TokenIdKeywordUse;
186186 } else if (mem_eql_str(token_mem, token_len, "void")) {
187187 t->cur_tok->id = TokenIdKeywordVoid;
188 } else if (mem_eql_str(token_mem, token_len, "true")) {
189 t->cur_tok->id = TokenIdKeywordTrue;
190 } else if (mem_eql_str(token_mem, token_len, "false")) {
191 t->cur_tok->id = TokenIdKeywordFalse;
188192 } else if (mem_eql_str(token_mem, token_len, "if")) {
189193 t->cur_tok->id = TokenIdKeywordIf;
190194 } else if (mem_eql_str(token_mem, token_len, "else")) {
......@@ -586,6 +590,8 @@ static const char * token_name(Token *token) {
586590 case TokenIdKeywordAs: return "As";
587591 case TokenIdKeywordUse: return "Use";
588592 case TokenIdKeywordVoid: return "Void";
593 case TokenIdKeywordTrue: return "True";
594 case TokenIdKeywordFalse: return "False";
589595 case TokenIdKeywordIf: return "If";
590596 case TokenIdKeywordElse: return "Else";
591597 case TokenIdKeywordGoto: return "Goto";
src/tokenizer.hpp+2
......@@ -25,6 +25,8 @@ enum TokenId {
2525 TokenIdKeywordAs,
2626 TokenIdKeywordUse,
2727 TokenIdKeywordVoid,
28 TokenIdKeywordTrue,
29 TokenIdKeywordFalse,
2830 TokenIdKeywordIf,
2931 TokenIdKeywordElse,
3032 TokenIdKeywordGoto,