mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 19:23:08 +00:00
add undefined literal
This commit is contained in:
parent
523e3b86af
commit
0e51c16ef5
@ -135,6 +135,7 @@ enum NodeType {
|
|||||||
NodeTypeUse,
|
NodeTypeUse,
|
||||||
NodeTypeBoolLiteral,
|
NodeTypeBoolLiteral,
|
||||||
NodeTypeNullLiteral,
|
NodeTypeNullLiteral,
|
||||||
|
NodeTypeUndefinedLiteral,
|
||||||
NodeTypeIfBoolExpr,
|
NodeTypeIfBoolExpr,
|
||||||
NodeTypeIfVarExpr,
|
NodeTypeIfVarExpr,
|
||||||
NodeTypeWhileExpr,
|
NodeTypeWhileExpr,
|
||||||
@ -609,6 +610,12 @@ struct AstNodeNullLiteral {
|
|||||||
Expr resolved_expr;
|
Expr resolved_expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstNodeUndefinedLiteral {
|
||||||
|
// populated by semantic analyzer
|
||||||
|
StructValExprCodeGen resolved_struct_val_expr;
|
||||||
|
Expr resolved_expr;
|
||||||
|
};
|
||||||
|
|
||||||
struct AstNodeSymbolExpr {
|
struct AstNodeSymbolExpr {
|
||||||
Buf symbol;
|
Buf symbol;
|
||||||
|
|
||||||
@ -692,6 +699,7 @@ struct AstNode {
|
|||||||
AstNodeContainerInitExpr container_init_expr;
|
AstNodeContainerInitExpr container_init_expr;
|
||||||
AstNodeStructValueField struct_val_field;
|
AstNodeStructValueField struct_val_field;
|
||||||
AstNodeNullLiteral null_literal;
|
AstNodeNullLiteral null_literal;
|
||||||
|
AstNodeUndefinedLiteral undefined_literal;
|
||||||
AstNodeSymbolExpr symbol_expr;
|
AstNodeSymbolExpr symbol_expr;
|
||||||
AstNodeBoolLiteral bool_literal;
|
AstNodeBoolLiteral bool_literal;
|
||||||
AstNodeBreakExpr break_expr;
|
AstNodeBreakExpr break_expr;
|
||||||
|
|||||||
@ -55,6 +55,7 @@ static AstNode *first_executing_node(AstNode *node) {
|
|||||||
case NodeTypeUse:
|
case NodeTypeUse:
|
||||||
case NodeTypeBoolLiteral:
|
case NodeTypeBoolLiteral:
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
case NodeTypeIfBoolExpr:
|
case NodeTypeIfBoolExpr:
|
||||||
case NodeTypeIfVarExpr:
|
case NodeTypeIfVarExpr:
|
||||||
case NodeTypeLabel:
|
case NodeTypeLabel:
|
||||||
@ -1006,6 +1007,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
|
|||||||
case NodeTypeCharLiteral:
|
case NodeTypeCharLiteral:
|
||||||
case NodeTypeBoolLiteral:
|
case NodeTypeBoolLiteral:
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
case NodeTypeSymbol:
|
case NodeTypeSymbol:
|
||||||
case NodeTypePrefixOpExpr:
|
case NodeTypePrefixOpExpr:
|
||||||
case NodeTypeIfBoolExpr:
|
case NodeTypeIfBoolExpr:
|
||||||
@ -1079,7 +1081,9 @@ static bool type_has_codegen_value(TypeTableEntryId id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void add_global_const_expr(CodeGen *g, Expr *expr) {
|
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);
|
g->global_const_list.append(expr);
|
||||||
expr->has_global_const = true;
|
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);
|
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,
|
static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import,
|
||||||
BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
|
BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
|
||||||
{
|
{
|
||||||
@ -3634,11 +3652,12 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
|
|||||||
case NodeTypeBoolLiteral:
|
case NodeTypeBoolLiteral:
|
||||||
return_type = resolve_expr_const_val_as_bool(g, node, node->data.bool_literal.value);
|
return_type = resolve_expr_const_val_as_bool(g, node, node->data.bool_literal.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
return_type = analyze_null_literal_expr(g, import, context, expected_type, node);
|
return_type = analyze_null_literal_expr(g, import, context, expected_type, node);
|
||||||
break;
|
break;
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
|
return_type = analyze_undefined_literal_expr(g, import, context, expected_type, node);
|
||||||
|
break;
|
||||||
case NodeTypeSymbol:
|
case NodeTypeSymbol:
|
||||||
return_type = analyze_symbol_expr(g, import, context, expected_type, node);
|
return_type = analyze_symbol_expr(g, import, context, expected_type, node);
|
||||||
break;
|
break;
|
||||||
@ -3804,6 +3823,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
|
|||||||
case NodeTypeCharLiteral:
|
case NodeTypeCharLiteral:
|
||||||
case NodeTypeBoolLiteral:
|
case NodeTypeBoolLiteral:
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
case NodeTypeSymbol:
|
case NodeTypeSymbol:
|
||||||
case NodeTypePrefixOpExpr:
|
case NodeTypePrefixOpExpr:
|
||||||
case NodeTypeIfBoolExpr:
|
case NodeTypeIfBoolExpr:
|
||||||
@ -3837,6 +3857,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
|
|||||||
case NodeTypeCharLiteral:
|
case NodeTypeCharLiteral:
|
||||||
case NodeTypeBoolLiteral:
|
case NodeTypeBoolLiteral:
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
case NodeTypeGoto:
|
case NodeTypeGoto:
|
||||||
case NodeTypeBreak:
|
case NodeTypeBreak:
|
||||||
case NodeTypeContinue:
|
case NodeTypeContinue:
|
||||||
@ -4155,6 +4176,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
|
|||||||
case NodeTypeCharLiteral:
|
case NodeTypeCharLiteral:
|
||||||
case NodeTypeBoolLiteral:
|
case NodeTypeBoolLiteral:
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
case NodeTypeSymbol:
|
case NodeTypeSymbol:
|
||||||
case NodeTypePrefixOpExpr:
|
case NodeTypePrefixOpExpr:
|
||||||
case NodeTypeIfBoolExpr:
|
case NodeTypeIfBoolExpr:
|
||||||
@ -4364,6 +4386,8 @@ Expr *get_resolved_expr(AstNode *node) {
|
|||||||
return &node->data.bool_literal.resolved_expr;
|
return &node->data.bool_literal.resolved_expr;
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
return &node->data.null_literal.resolved_expr;
|
return &node->data.null_literal.resolved_expr;
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
|
return &node->data.undefined_literal.resolved_expr;
|
||||||
case NodeTypeGoto:
|
case NodeTypeGoto:
|
||||||
return &node->data.goto_expr.resolved_expr;
|
return &node->data.goto_expr.resolved_expr;
|
||||||
case NodeTypeBreak:
|
case NodeTypeBreak:
|
||||||
@ -4438,6 +4462,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
|
|||||||
case NodeTypeUse:
|
case NodeTypeUse:
|
||||||
case NodeTypeBoolLiteral:
|
case NodeTypeBoolLiteral:
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
case NodeTypeLabel:
|
case NodeTypeLabel:
|
||||||
case NodeTypeGoto:
|
case NodeTypeGoto:
|
||||||
case NodeTypeBreak:
|
case NodeTypeBreak:
|
||||||
|
|||||||
@ -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, "");
|
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) {
|
static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
|
||||||
assert(node->type == NodeTypeContainerInitExpr);
|
assert(node->type == NodeTypeContainerInitExpr);
|
||||||
|
|
||||||
@ -1963,7 +1947,11 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
|
|||||||
case NodeTypeFieldAccessExpr:
|
case NodeTypeFieldAccessExpr:
|
||||||
return gen_field_access_expr(g, node, false);
|
return gen_field_access_expr(g, node, false);
|
||||||
case NodeTypeNullLiteral:
|
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:
|
case NodeTypeIfBoolExpr:
|
||||||
return gen_if_bool_expr(g, node);
|
return gen_if_bool_expr(g, node);
|
||||||
case NodeTypeIfVarExpr:
|
case NodeTypeIfVarExpr:
|
||||||
|
|||||||
@ -129,6 +129,8 @@ const char *node_type_str(NodeType node_type) {
|
|||||||
return "BoolLiteral";
|
return "BoolLiteral";
|
||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
return "NullLiteral";
|
return "NullLiteral";
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
|
return "UndefinedLiteral";
|
||||||
case NodeTypeIfBoolExpr:
|
case NodeTypeIfBoolExpr:
|
||||||
return "IfBoolExpr";
|
return "IfBoolExpr";
|
||||||
case NodeTypeIfVarExpr:
|
case NodeTypeIfVarExpr:
|
||||||
@ -412,6 +414,9 @@ void ast_print(AstNode *node, int indent) {
|
|||||||
case NodeTypeContinue:
|
case NodeTypeContinue:
|
||||||
fprintf(stderr, "%s\n", node_type_str(node->type));
|
fprintf(stderr, "%s\n", node_type_str(node->type));
|
||||||
break;
|
break;
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
|
fprintf(stderr, "%s\n", node_type_str(node->type));
|
||||||
|
break;
|
||||||
case NodeTypeAsmExpr:
|
case NodeTypeAsmExpr:
|
||||||
fprintf(stderr, "%s\n", node_type_str(node->type));
|
fprintf(stderr, "%s\n", node_type_str(node->type));
|
||||||
break;
|
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")
|
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) {
|
static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
|
||||||
Token *token = &pc->tokens->at(*token_index);
|
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);
|
AstNode *node = ast_create_node(pc, NodeTypeContinue, token);
|
||||||
*token_index += 1;
|
*token_index += 1;
|
||||||
return node;
|
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) {
|
} else if (token->id == TokenIdAtSign) {
|
||||||
*token_index += 1;
|
*token_index += 1;
|
||||||
Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
|
Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
|
||||||
@ -3202,6 +3211,9 @@ void normalize_parent_ptrs(AstNode *node) {
|
|||||||
case NodeTypeNullLiteral:
|
case NodeTypeNullLiteral:
|
||||||
// none
|
// none
|
||||||
break;
|
break;
|
||||||
|
case NodeTypeUndefinedLiteral:
|
||||||
|
// none
|
||||||
|
break;
|
||||||
case NodeTypeIfBoolExpr:
|
case NodeTypeIfBoolExpr:
|
||||||
set_field(&node->data.if_bool_expr.condition);
|
set_field(&node->data.if_bool_expr.condition);
|
||||||
set_field(&node->data.if_bool_expr.then_block);
|
set_field(&node->data.if_bool_expr.then_block);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user