Commit 0e51c16ef5

Andrew Kelley <superjoe30@gmail.com>
2016-01-23 06:42:02
add undefined literal
1 parent 523e3b8
src/all_types.hpp
@@ -135,6 +135,7 @@ enum NodeType {
     NodeTypeUse,
     NodeTypeBoolLiteral,
     NodeTypeNullLiteral,
+    NodeTypeUndefinedLiteral,
     NodeTypeIfBoolExpr,
     NodeTypeIfVarExpr,
     NodeTypeWhileExpr,
@@ -609,6 +610,12 @@ struct AstNodeNullLiteral {
     Expr resolved_expr;
 };
 
+struct AstNodeUndefinedLiteral {
+    // populated by semantic analyzer
+    StructValExprCodeGen resolved_struct_val_expr;
+    Expr resolved_expr;
+};
+
 struct AstNodeSymbolExpr {
     Buf symbol;
 
@@ -692,6 +699,7 @@ struct AstNode {
         AstNodeContainerInitExpr container_init_expr;
         AstNodeStructValueField struct_val_field;
         AstNodeNullLiteral null_literal;
+        AstNodeUndefinedLiteral undefined_literal;
         AstNodeSymbolExpr symbol_expr;
         AstNodeBoolLiteral bool_literal;
         AstNodeBreakExpr break_expr;
src/analyze.cpp
@@ -55,6 +55,7 @@ static AstNode *first_executing_node(AstNode *node) {
         case NodeTypeUse:
         case NodeTypeBoolLiteral:
         case NodeTypeNullLiteral:
+        case NodeTypeUndefinedLiteral:
         case NodeTypeIfBoolExpr:
         case NodeTypeIfVarExpr:
         case NodeTypeLabel:
@@ -1006,6 +1007,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
         case NodeTypeCharLiteral:
         case NodeTypeBoolLiteral:
         case NodeTypeNullLiteral:
+        case NodeTypeUndefinedLiteral:
         case NodeTypeSymbol:
         case NodeTypePrefixOpExpr:
         case NodeTypeIfBoolExpr:
@@ -1079,7 +1081,9 @@ static bool type_has_codegen_value(TypeTableEntryId id) {
 }
 
 static void add_global_const_expr(CodeGen *g, Expr *expr) {
-    if (expr->const_val.ok && type_has_codegen_value(expr->type_entry->id) && !expr->has_global_const) {
+    if (expr->const_val.ok &&
+        type_has_codegen_value(expr->type_entry->id) && !expr->has_global_const)
+    {
         g->global_const_list.append(expr);
         expr->has_global_const = true;
     }
@@ -2470,6 +2474,20 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i
     return resolve_expr_const_val_as_null(g, node, expected_type);
 }
 
+static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+        TypeTableEntry *expected_type, AstNode *node)
+{
+    Expr *expr = get_resolved_expr(node);
+    ConstExprValue *const_val = &expr->const_val;
+
+    const_val->ok = true;
+
+    zig_panic("TODO");
+
+    return expected_type;
+}
+
+
 static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import,
         BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
 {
@@ -3634,11 +3652,12 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
         case NodeTypeBoolLiteral:
             return_type = resolve_expr_const_val_as_bool(g, node, node->data.bool_literal.value);
             break;
-
         case NodeTypeNullLiteral:
             return_type = analyze_null_literal_expr(g, import, context, expected_type, node);
             break;
-
+        case NodeTypeUndefinedLiteral:
+            return_type = analyze_undefined_literal_expr(g, import, context, expected_type, node);
+            break;
         case NodeTypeSymbol:
             return_type = analyze_symbol_expr(g, import, context, expected_type, node);
             break;
@@ -3804,6 +3823,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
         case NodeTypeCharLiteral:
         case NodeTypeBoolLiteral:
         case NodeTypeNullLiteral:
+        case NodeTypeUndefinedLiteral:
         case NodeTypeSymbol:
         case NodeTypePrefixOpExpr:
         case NodeTypeIfBoolExpr:
@@ -3837,6 +3857,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
         case NodeTypeCharLiteral:
         case NodeTypeBoolLiteral:
         case NodeTypeNullLiteral:
+        case NodeTypeUndefinedLiteral:
         case NodeTypeGoto:
         case NodeTypeBreak:
         case NodeTypeContinue:
@@ -4155,6 +4176,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
         case NodeTypeCharLiteral:
         case NodeTypeBoolLiteral:
         case NodeTypeNullLiteral:
+        case NodeTypeUndefinedLiteral:
         case NodeTypeSymbol:
         case NodeTypePrefixOpExpr:
         case NodeTypeIfBoolExpr:
@@ -4364,6 +4386,8 @@ Expr *get_resolved_expr(AstNode *node) {
             return &node->data.bool_literal.resolved_expr;
         case NodeTypeNullLiteral:
             return &node->data.null_literal.resolved_expr;
+        case NodeTypeUndefinedLiteral:
+            return &node->data.undefined_literal.resolved_expr;
         case NodeTypeGoto:
             return &node->data.goto_expr.resolved_expr;
         case NodeTypeBreak:
@@ -4438,6 +4462,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
         case NodeTypeUse:
         case NodeTypeBoolLiteral:
         case NodeTypeNullLiteral:
+        case NodeTypeUndefinedLiteral:
         case NodeTypeLabel:
         case NodeTypeGoto:
         case NodeTypeBreak:
src/codegen.cpp
@@ -1486,22 +1486,6 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) {
     return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, "");
 }
 
-static LLVMValueRef gen_null_literal(CodeGen *g, AstNode *node) {
-    assert(node->type == NodeTypeNullLiteral);
-
-    TypeTableEntry *type_entry = get_expr_type(node);
-    assert(type_entry->id == TypeTableEntryIdMaybe);
-
-    LLVMValueRef tmp_struct_ptr = node->data.null_literal.resolved_struct_val_expr.ptr;
-
-    add_debug_source_node(g, node);
-    LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, "");
-    LLVMValueRef null_value = LLVMConstNull(LLVMInt1Type());
-    LLVMBuildStore(g->builder, null_value, field_ptr);
-
-    return tmp_struct_ptr;
-}
-
 static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
     assert(node->type == NodeTypeContainerInitExpr);
 
@@ -1963,7 +1947,11 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
         case NodeTypeFieldAccessExpr:
             return gen_field_access_expr(g, node, false);
         case NodeTypeNullLiteral:
-            return gen_null_literal(g, node);
+            // caught by constant expression eval codegen
+            zig_unreachable();
+        case NodeTypeUndefinedLiteral:
+            // caught by constant expression eval codegen
+            zig_unreachable();
         case NodeTypeIfBoolExpr:
             return gen_if_bool_expr(g, node);
         case NodeTypeIfVarExpr:
src/parser.cpp
@@ -129,6 +129,8 @@ const char *node_type_str(NodeType node_type) {
             return "BoolLiteral";
         case NodeTypeNullLiteral:
             return "NullLiteral";
+        case NodeTypeUndefinedLiteral:
+            return "UndefinedLiteral";
         case NodeTypeIfBoolExpr:
             return "IfBoolExpr";
         case NodeTypeIfVarExpr:
@@ -412,6 +414,9 @@ void ast_print(AstNode *node, int indent) {
         case NodeTypeContinue:
             fprintf(stderr, "%s\n", node_type_str(node->type));
             break;
+        case NodeTypeUndefinedLiteral:
+            fprintf(stderr, "%s\n", node_type_str(node->type));
+            break;
         case NodeTypeAsmExpr:
             fprintf(stderr, "%s\n", node_type_str(node->type));
             break;
@@ -1368,7 +1373,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand
 
 /*
 PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol")
-KeywordLiteral : token(True) | token(False) | token(Null) | token(Break) | token(Continue)
+KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined"
 */
 static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
     Token *token = &pc->tokens->at(*token_index);
@@ -1410,6 +1415,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
         AstNode *node = ast_create_node(pc, NodeTypeContinue, token);
         *token_index += 1;
         return node;
+    } else if (token->id == TokenIdKeywordUndefined) {
+        AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token);
+        *token_index += 1;
+        return node;
     } else if (token->id == TokenIdAtSign) {
         *token_index += 1;
         Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
@@ -3202,6 +3211,9 @@ void normalize_parent_ptrs(AstNode *node) {
         case NodeTypeNullLiteral:
             // none
             break;
+        case NodeTypeUndefinedLiteral:
+            // none
+            break;
         case NodeTypeIfBoolExpr:
             set_field(&node->data.if_bool_expr.condition);
             set_field(&node->data.if_bool_expr.then_block);