aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2015-12-24 15:09:35 -0700
committerAndrew Kelley <superjoe30@gmail.com>2015-12-24 15:09:47 -0700
commit5ceaae288c4f80fe5ce1449cd9d2efe0e541d629 (patch)
tree7cf0b1b188c9f9ca8df0d4f379b47a6348adf6fd /src
parentffc593b8082eb0fa83b1a3d1b63c840379911cd5 (diff)
downloadzig-5ceaae288c4f80fe5ce1449cd9d2efe0e541d629.tar.gz
zig-5ceaae288c4f80fe5ce1449cd9d2efe0e541d629.zip
add break expression
Diffstat (limited to 'src')
-rw-r--r--src/analyze.cpp13
-rw-r--r--src/analyze.hpp1
-rw-r--r--src/codegen.cpp12
-rw-r--r--src/parser.cpp11
-rw-r--r--src/parser.hpp1
5 files changed, 37 insertions, 1 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index bd9eaa7f2d..a5e1255126 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -48,6 +48,7 @@ static AstNode *first_executing_node(AstNode *node) {
case NodeTypeIfExpr:
case NodeTypeLabel:
case NodeTypeGoto:
+ case NodeTypeBreak:
case NodeTypeAsmExpr:
case NodeTypeFieldAccessExpr:
case NodeTypeStructDecl:
@@ -530,6 +531,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
case NodeTypeWhileExpr:
case NodeTypeLabel:
case NodeTypeGoto:
+ case NodeTypeBreak:
case NodeTypeAsmExpr:
case NodeTypeFieldAccessExpr:
case NodeTypeStructField:
@@ -598,6 +600,7 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) {
case NodeTypeWhileExpr:
case NodeTypeLabel:
case NodeTypeGoto:
+ case NodeTypeBreak:
case NodeTypeAsmExpr:
case NodeTypeFieldAccessExpr:
case NodeTypeStructField:
@@ -1360,6 +1363,12 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import,
return g->builtin_types.entry_void;
}
+static TypeTableEntry *analyze_break_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+ TypeTableEntry *expected_type, AstNode *node)
+{
+ return g->builtin_types.entry_unreachable;
+}
+
static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context,
TypeTableEntry *expected_type, AstNode *node)
{
@@ -1439,6 +1448,9 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
return_type = g->builtin_types.entry_unreachable;
break;
}
+ case NodeTypeBreak:
+ return_type = analyze_break_expr(g, import, context, expected_type, node);
+ break;
case NodeTypeAsmExpr:
{
node->data.asm_expr.return_count = 0;
@@ -1792,6 +1804,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
case NodeTypeWhileExpr:
case NodeTypeLabel:
case NodeTypeGoto:
+ case NodeTypeBreak:
case NodeTypeAsmExpr:
case NodeTypeFieldAccessExpr:
case NodeTypeStructField:
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 66f5c2eeed..fae6f0b81f 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -196,6 +196,7 @@ struct CodeGen {
FnTableEntry *cur_fn;
LLVMBasicBlockRef cur_basic_block;
BlockContext *cur_block_context;
+ LLVMBasicBlockRef cur_break_block;
bool c_stdint_used;
AstNode *root_export_decl;
int version_major;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 2c0ed2efed..d4870e002b 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1024,13 +1024,23 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) {
LLVMBuildCondBr(g->builder, cond_val, body_block, end_block);
LLVMPositionBuilderAtEnd(g->builder, body_block);
+ g->cur_break_block = end_block;
gen_expr(g, node->data.while_expr.body);
+ g->cur_break_block = nullptr;
LLVMBuildBr(g->builder, cond_block);
LLVMPositionBuilderAtEnd(g->builder, end_block);
return nullptr;
}
+static LLVMValueRef gen_break(CodeGen *g, AstNode *node) {
+ assert(node->type == NodeTypeBreak);
+ assert(g->cur_break_block);
+
+ add_debug_source_node(g, node);
+ return LLVMBuildBr(g->builder, g->cur_break_block);
+}
+
static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
switch (node->type) {
case NodeTypeBinOpExpr:
@@ -1160,6 +1170,8 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
case NodeTypeGoto:
add_debug_source_node(g, node);
return LLVMBuildBr(g->builder, node->codegen_node->data.label_entry->basic_block);
+ case NodeTypeBreak:
+ return gen_break(g, node);
case NodeTypeLabel:
{
LabelTableEntry *label_entry = node->codegen_node->data.label_entry;
diff --git a/src/parser.cpp b/src/parser.cpp
index 5a5486e713..ff6a2dd573 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -122,6 +122,8 @@ const char *node_type_str(NodeType node_type) {
return "Label";
case NodeTypeGoto:
return "Goto";
+ case NodeTypeBreak:
+ return "Break";
case NodeTypeAsmExpr:
return "AsmExpr";
case NodeTypeFieldAccessExpr:
@@ -336,6 +338,9 @@ void ast_print(AstNode *node, int indent) {
case NodeTypeGoto:
fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.go_to.name));
break;
+ case NodeTypeBreak:
+ fprintf(stderr, "%s\n", node_type_str(node->type));
+ break;
case NodeTypeAsmExpr:
fprintf(stderr, "%s\n", node_type_str(node->type));
break;
@@ -1102,7 +1107,7 @@ static AstNode *ast_parse_struct_val_expr(ParseContext *pc, int *token_index) {
}
/*
-PrimaryExpression : token(Number) | token(String) | KeywordLiteral | GroupedExpression | Goto | BlockExpression | token(Symbol) | StructValueExpression
+PrimaryExpression : token(Number) | token(String) | KeywordLiteral | GroupedExpression | Goto | Break | BlockExpression | token(Symbol) | StructValueExpression
*/
static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
@@ -1156,6 +1161,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
ast_buf_from_token(pc, dest_symbol, &node->data.go_to.name);
return node;
+ } else if (token->id == TokenIdKeywordBreak) {
+ AstNode *node = ast_create_node(pc, NodeTypeBreak, token);
+ *token_index += 1;
+ return node;
}
AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false);
diff --git a/src/parser.hpp b/src/parser.hpp
index af24b29131..309337bbfa 100644
--- a/src/parser.hpp
+++ b/src/parser.hpp
@@ -48,6 +48,7 @@ enum NodeType {
NodeTypeWhileExpr,
NodeTypeLabel,
NodeTypeGoto,
+ NodeTypeBreak,
NodeTypeAsmExpr,
NodeTypeStructDecl,
NodeTypeStructField,