Commit f1aaf1353e

Josh Wolfe <thejoshwolfe@gmail.com>
2015-12-03 20:15:07
add bool literals
1 parent 6494cf2
example/expressions/expressions.zig
@@ -4,6 +4,12 @@ extern {
     fn exit(code: i32) -> unreachable;
 }
 
+fn other_exit() -> unreachable {
+    if (true) { exit(0); }
+    // the unreachable statement is the programmer assuring the compiler that this code is impossible to execute.
+    unreachable;
+}
+
 export fn _start() -> unreachable {
     let a : i32 = 1;
     let b = 2;
@@ -19,5 +25,5 @@ export fn _start() -> unreachable {
         no_conflict
     };
     if (c == 10) { puts("OK 2"); }
-    exit(0);
+    other_exit();
 }
src/analyze.cpp
@@ -297,6 +297,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
         case NodeTypeStringLiteral:
         case NodeTypeUnreachable:
         case NodeTypeVoid:
+        case NodeTypeBoolLiteral:
         case NodeTypeSymbol:
         case NodeTypeCastExpr:
         case NodeTypePrefixOpExpr:
@@ -592,6 +593,10 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
             return_type = g->builtin_types.entry_void;
             break;
 
+        case NodeTypeBoolLiteral:
+            return_type = g->builtin_types.entry_bool;
+            break;
+
         case NodeTypeSymbol:
             {
                 Buf *symbol_name = &node->data.symbol;
@@ -766,6 +771,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
         case NodeTypeStringLiteral:
         case NodeTypeUnreachable:
         case NodeTypeVoid:
+        case NodeTypeBoolLiteral:
         case NodeTypeSymbol:
         case NodeTypeCastExpr:
         case NodeTypePrefixOpExpr:
src/codegen.cpp
@@ -487,6 +487,11 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
             return LLVMBuildUnreachable(g->builder);
         case NodeTypeVoid:
             return nullptr;
+        case NodeTypeBoolLiteral:
+            if (node->data.bool_literal)
+                return LLVMConstAllOnes(LLVMInt1Type());
+            else
+                return LLVMConstNull(LLVMInt1Type());
         case NodeTypeIfExpr:
             return gen_if_expr(g, node);
         case NodeTypeNumberLiteral:
src/parser.cpp
@@ -93,6 +93,8 @@ const char *node_type_str(NodeType node_type) {
             return "Use";
         case NodeTypeVoid:
             return "Void";
+        case NodeTypeBoolLiteral:
+            return "BoolLiteral";
         case NodeTypeIfExpr:
             return "IfExpr";
         case NodeTypeLabel:
@@ -256,6 +258,9 @@ void ast_print(AstNode *node, int indent) {
         case NodeTypeVoid:
             fprintf(stderr, "%s\n", node_type_str(node->type));
             break;
+        case NodeTypeBoolLiteral:
+            fprintf(stderr, "%s '%s'\n", node_type_str(node->type), node->data.bool_literal ? "true" : "false");
+            break;
         case NodeTypeIfExpr:
             fprintf(stderr, "%s\n", node_type_str(node->type));
             if (node->data.if_expr.condition)
@@ -457,6 +462,12 @@ static AstNode *ast_parse_type(ParseContext *pc, int token_index, int *new_token
     } else if (token->id == TokenIdKeywordVoid) {
         node->data.type.type = AstNodeTypeTypePrimitive;
         buf_init_from_str(&node->data.type.primitive_name, "void");
+    } else if (token->id == TokenIdKeywordTrue) {
+        node->data.type.type = AstNodeTypeTypePrimitive;
+        buf_init_from_str(&node->data.type.primitive_name, "true");
+    } else if (token->id == TokenIdKeywordFalse) {
+        node->data.type.type = AstNodeTypeTypePrimitive;
+        buf_init_from_str(&node->data.type.primitive_name, "false");
     } else if (token->id == TokenIdSymbol) {
         node->data.type.type = AstNodeTypeTypePrimitive;
         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
         AstNode *node = ast_create_node(pc, NodeTypeVoid, token);
         *token_index += 1;
         return node;
+    } else if (token->id == TokenIdKeywordTrue) {
+        AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
+        node->data.bool_literal = true;
+        *token_index += 1;
+        return node;
+    } else if (token->id == TokenIdKeywordFalse) {
+        AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
+        node->data.bool_literal = false;
+        *token_index += 1;
+        return node;
     } else if (token->id == TokenIdSymbol) {
         AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);
         ast_buf_from_token(pc, token, &node->data.symbol);
src/parser.hpp
@@ -40,6 +40,7 @@ enum NodeType {
     NodeTypeFnCallExpr,
     NodeTypeUse,
     NodeTypeVoid,
+    NodeTypeBoolLiteral,
     NodeTypeIfExpr,
     NodeTypeLabel,
     NodeTypeGoto,
@@ -222,6 +223,7 @@ struct AstNode {
         Buf number;
         Buf string;
         Buf symbol;
+        bool bool_literal;
     } data;
 };
 
src/tokenizer.cpp
@@ -185,6 +185,10 @@ static void end_token(Tokenize *t) {
         t->cur_tok->id = TokenIdKeywordUse;
     } else if (mem_eql_str(token_mem, token_len, "void")) {
         t->cur_tok->id = TokenIdKeywordVoid;
+    } else if (mem_eql_str(token_mem, token_len, "true")) {
+        t->cur_tok->id = TokenIdKeywordTrue;
+    } else if (mem_eql_str(token_mem, token_len, "false")) {
+        t->cur_tok->id = TokenIdKeywordFalse;
     } else if (mem_eql_str(token_mem, token_len, "if")) {
         t->cur_tok->id = TokenIdKeywordIf;
     } else if (mem_eql_str(token_mem, token_len, "else")) {
@@ -586,6 +590,8 @@ static const char * token_name(Token *token) {
         case TokenIdKeywordAs: return "As";
         case TokenIdKeywordUse: return "Use";
         case TokenIdKeywordVoid: return "Void";
+        case TokenIdKeywordTrue: return "True";
+        case TokenIdKeywordFalse: return "False";
         case TokenIdKeywordIf: return "If";
         case TokenIdKeywordElse: return "Else";
         case TokenIdKeywordGoto: return "Goto";
src/tokenizer.hpp
@@ -25,6 +25,8 @@ enum TokenId {
     TokenIdKeywordAs,
     TokenIdKeywordUse,
     TokenIdKeywordVoid,
+    TokenIdKeywordTrue,
+    TokenIdKeywordFalse,
     TokenIdKeywordIf,
     TokenIdKeywordElse,
     TokenIdKeywordGoto,
README.md
@@ -163,11 +163,13 @@ FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)
 
 PrefixOp : token(Not) | token(Dash) | token(Tilde)
 
-PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | token(Symbol) | Goto
+PrimaryExpression : token(Number) | token(String) | KeywordLiteral | GroupedExpression | token(Symbol) | Goto
 
 Goto: token(Goto) token(Symbol)
 
 GroupedExpression : token(LParen) Expression token(RParen)
+
+KeywordLiteral : token(Unreachable) | token(Void) | token(True) | token(False)
 ```
 
 ### Operator Precedence