Forráskód Böngészése

Change label syntax for `for` and `match` from #label name to name:

Ginger Bill 8 éve
szülő
commit
d3f63e5903
3 módosított fájl, 60 hozzáadás és 102 törlés
  1. 5 5
      core/fmt.odin
  2. 1 1
      core/os_x.odin
  3. 54 96
      src/parser.c

+ 5 - 5
core/fmt.odin

@@ -561,10 +561,10 @@ _write_int :: proc(fi: ^FmtInfo, u: u64, base: int, is_signed: bool, bit_size: i
 	}
 
 	buf: [256]byte;
-	flags: strconv.Int_Flag;
-	if fi.hash   { flags |= strconv.Int_Flag.PREFIX; }
-	if fi.plus   { flags |= strconv.Int_Flag.PLUS; }
-	if fi.space  { flags |= strconv.Int_Flag.SPACE; }
+	flags: strconv.IntFlag;
+	if fi.hash   { flags |= strconv.IntFlag.PREFIX; }
+	if fi.plus   { flags |= strconv.IntFlag.PLUS; }
+	if fi.space  { flags |= strconv.IntFlag.SPACE; }
 	s := strconv.append_bits(buf[0..<0], u, base, is_signed, bit_size, digits, flags);
 
 	prev_zero := fi.zero;
@@ -1089,7 +1089,7 @@ sbprintf :: proc(b: ^StringBuffer, fmt: string, args: ..any) -> string {
 		// Process a "verb"
 		i++;
 
-		#label prefix_loop
+	prefix_loop:
 		for ; i < end; i++ {
 			match fmt[i] {
 			case '+':

+ 1 - 1
core/os_x.odin

@@ -41,7 +41,7 @@ RTLD_FIRST    :: 0x100;
 
 args: [dynamic]string;
 
-FileTime :: struct #ordered {
+_FileTime :: struct #ordered {
 	seconds: i64,
 	nanoseconds: i64
 }

+ 54 - 96
src/parser.c

@@ -106,6 +106,13 @@ typedef enum FieldFlag {
 	FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_immutable,
 } FieldListTag;
 
+typedef enum StmtAllowFlag {
+	StmtAllowFlag_None  = 0,
+	StmtAllowFlag_In    = 1<<0,
+	StmtAllowFlag_Label = 1<<1,
+} StmtAllowFlag;
+
+
 
 AstNodeArray make_ast_node_array(AstFile *f) {
 	AstNodeArray a;
@@ -1594,6 +1601,14 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
 	}
 
 	switch (s->kind) {
+	case AstNode_IfStmt:
+	case AstNode_WhenStmt:
+	case AstNode_ForStmt:
+	case AstNode_RangeStmt:
+	case AstNode_MatchStmt:
+	case AstNode_TypeMatchStmt:
+		return true;
+
 	case AstNode_HelperType:
 		return is_semicolon_optional_for_node(f, s->HelperType.type);
 
@@ -1912,9 +1927,10 @@ void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, Str
 	}
 }
 
+
 AstNodeArray parse_lhs_expr_list(AstFile *f);
 AstNodeArray parse_rhs_expr_list(AstFile *f);
-AstNode *    parse_simple_stmt  (AstFile *f, bool in_stmt_ok);
+AstNode *    parse_simple_stmt  (AstFile *f, StmtAllowFlag flags);
 AstNode *    parse_type         (AstFile *f);
 
 AstNode *convert_stmt_to_expr(AstFile *f, AstNode *statement, String kind) {
@@ -1932,73 +1948,6 @@ AstNode *convert_stmt_to_expr(AstFile *f, AstNode *statement, String kind) {
 
 
 
-// AstNode *parse_block_expr(AstFile *f) {
-// 	AstNodeArray stmts = {0};
-// 	Token open, close;
-// 	open = expect_token(f, Token_OpenBrace);
-// 	f->expr_level++;
-// 	stmts = parse_stmt_list(f);
-// 	f->expr_level--;
-// 	close = expect_token(f, Token_CloseBrace);
-// 	return ast_block_expr(f, stmts, open, close);
-// }
-
-// AstNode *parse_if_expr(AstFile *f) {
-// 	if (f->curr_proc == NULL) {
-// 		syntax_error(f->curr_token, "You cannot use an if expression in the file scope");
-// 		return ast_bad_stmt(f, f->curr_token, f->curr_token);
-// 	}
-
-// 	Token token = expect_token(f, Token_if);
-// 	AstNode *init = NULL;
-// 	AstNode *cond = NULL;
-// 	AstNode *body = NULL;
-// 	AstNode *else_expr = NULL;
-
-// 	isize prev_level = f->expr_level;
-// 	f->expr_level = -1;
-
-// 	if (allow_token(f, Token_Semicolon)) {
-// 		cond = parse_expr(f, false);
-// 	} else {
-// 		init = parse_simple_stmt(f, false);
-// 		if (allow_token(f, Token_Semicolon)) {
-// 			cond = parse_expr(f, false);
-// 		} else {
-// 			cond = convert_stmt_to_expr(f, init, str_lit("boolean expression"));
-// 			init = NULL;
-// 		}
-// 	}
-
-// 	f->expr_level = prev_level;
-
-// 	if (cond == NULL) {
-// 		syntax_error(f->curr_token, "Expected condition for if statement");
-// 	}
-
-// 	body = parse_block_expr(f);
-
-// 	if (allow_token(f, Token_else)) {
-// 		switch (f->curr_token.kind) {
-// 		case Token_if:
-// 			else_expr = parse_if_expr(f);
-// 			break;
-// 		case Token_OpenBrace:
-// 			else_expr = parse_block_expr(f);
-// 			break;
-// 		default:
-// 			syntax_error(f->curr_token, "Expected if expression block statement");
-// 			else_expr = ast_bad_expr(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
-// 			break;
-// 		}
-// 	} else {
-// 		syntax_error(f->curr_token, "An if expression must have an else clause");
-// 		return ast_bad_stmt(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
-// 	}
-
-// 	return ast_if_expr(f, token, init, cond, body, else_expr);
-// }
-
 AstNode *parse_operand(AstFile *f, bool lhs) {
 	AstNode *operand = NULL; // Operand
 	switch (f->curr_token.kind) {
@@ -2556,7 +2505,7 @@ AstNode *parse_value_decl(AstFile *f, AstNodeArray lhs) {
 
 
 
-AstNode *parse_simple_stmt(AstFile *f, bool in_stmt_ok) {
+AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) {
 	AstNodeArray lhs = parse_lhs_expr_list(f);
 	Token token = f->curr_token;
 	switch (token.kind) {
@@ -2590,7 +2539,7 @@ AstNode *parse_simple_stmt(AstFile *f, bool in_stmt_ok) {
 	} break;
 
 	case Token_in:
-		if (in_stmt_ok) {
+		if (flags&StmtAllowFlag_In) {
 			allow_token(f, Token_in);
 			bool prev_allow_range = f->allow_range;
 			f->allow_range = true;
@@ -2606,6 +2555,31 @@ AstNode *parse_simple_stmt(AstFile *f, bool in_stmt_ok) {
 		break;
 
 	case Token_Colon:
+		if ((flags&StmtAllowFlag_Label) && lhs.count == 1) {
+			TokenKind next = look_ahead_token_kind(f, 1);
+			switch (next) {
+			case Token_for:
+			case Token_match: {
+				next_token(f);
+				AstNode *name = lhs.e[0];
+				AstNode *label = ast_label_decl(f, ast_node_token(name), name);
+				AstNode *stmt = parse_stmt(f);
+			#define _SET_LABEL(Kind_, label_) case GB_JOIN2(AstNode_, Kind_): (stmt->Kind_).label = label_; break
+				switch (stmt->kind) {
+				_SET_LABEL(ForStmt, label);
+				_SET_LABEL(RangeStmt, label);
+				_SET_LABEL(MatchStmt, label);
+				_SET_LABEL(TypeMatchStmt, label);
+				default:
+					syntax_error(token, "Labels can only be applied to a loop or match statement");
+					break;
+				}
+			#undef _SET_LABEL
+				return stmt;
+			} break;
+			}
+		}
+
 		return parse_value_decl(f, lhs);
 	}
 
@@ -2614,6 +2588,8 @@ AstNode *parse_simple_stmt(AstFile *f, bool in_stmt_ok) {
 		return ast_bad_stmt(f, token, f->curr_token);
 	}
 
+
+
 	switch (token.kind) {
 	case Token_Inc:
 	case Token_Dec:
@@ -3207,7 +3183,7 @@ AstNode *parse_if_stmt(AstFile *f) {
 	if (allow_token(f, Token_Semicolon)) {
 		cond = parse_expr(f, false);
 	} else {
-		init = parse_simple_stmt(f, false);
+		init = parse_simple_stmt(f, StmtAllowFlag_None);
 		if (allow_token(f, Token_Semicolon)) {
 			cond = parse_expr(f, false);
 		} else {
@@ -3343,7 +3319,7 @@ AstNode *parse_for_stmt(AstFile *f) {
 		isize prev_level = f->expr_level;
 		f->expr_level = -1;
 		if (f->curr_token.kind != Token_Semicolon) {
-			cond = parse_simple_stmt(f, true);
+			cond = parse_simple_stmt(f, StmtAllowFlag_In);
 			if (cond->kind == AstNode_AssignStmt && cond->AssignStmt.op.kind == Token_in) {
 				is_range = true;
 			}
@@ -3354,11 +3330,11 @@ AstNode *parse_for_stmt(AstFile *f) {
 			init = cond;
 			cond = NULL;
 			if (f->curr_token.kind != Token_Semicolon) {
-				cond = parse_simple_stmt(f, false);
+				cond = parse_simple_stmt(f, StmtAllowFlag_None);
 			}
 			expect_semicolon(f, cond);
 			if (f->curr_token.kind != Token_OpenBrace) {
-				post = parse_simple_stmt(f, false);
+				post = parse_simple_stmt(f, StmtAllowFlag_None);
 			}
 		}
 
@@ -3432,7 +3408,7 @@ AstNode *parse_match_stmt(AstFile *f) {
 		isize prev_level = f->expr_level;
 		f->expr_level = -1;
 
-		tag = parse_simple_stmt(f, true);
+		tag = parse_simple_stmt(f, StmtAllowFlag_In);
 		if (tag->kind == AstNode_AssignStmt && tag->AssignStmt.op.kind == Token_in) {
 			is_type_match = true;
 		} else {
@@ -3440,7 +3416,7 @@ AstNode *parse_match_stmt(AstFile *f) {
 				init = tag;
 				tag = NULL;
 				if (f->curr_token.kind != Token_OpenBrace) {
-					tag = parse_simple_stmt(f, false);
+					tag = parse_simple_stmt(f, StmtAllowFlag_None);
 				}
 			}
 		}
@@ -3536,7 +3512,7 @@ AstNode *parse_stmt(AstFile *f) {
 	case Token_Xor:
 	case Token_Not:
 	case Token_And:
-		s = parse_simple_stmt(f, false);
+		s = parse_simple_stmt(f, StmtAllowFlag_Label);
 		expect_semicolon(f, s);
 		return s;
 
@@ -3648,25 +3624,7 @@ AstNode *parse_stmt(AstFile *f) {
 		Token name = expect_token(f, Token_Ident);
 		String tag = name.string;
 
-		if (str_eq(tag, str_lit("label"))) {
-			AstNode *name  = parse_ident(f);
-			AstNode *label = ast_label_decl(f, token, name);
-			AstNode *stmt  = parse_stmt(f);
-
-		#define _SET_LABEL(Kind_, label_) case GB_JOIN2(AstNode_, Kind_): (stmt->Kind_).label = label_; break
-			switch (stmt->kind) {
-			_SET_LABEL(ForStmt, label);
-			_SET_LABEL(RangeStmt, label);
-			_SET_LABEL(MatchStmt, label);
-			_SET_LABEL(TypeMatchStmt, label);
-			default:
-				syntax_error(token, "#label cannot only be applied to a loop or match statement");
-				break;
-			}
-		#undef _SET_LABEL
-
-			return stmt;
-		} else if (str_eq(tag, str_lit("import"))) {
+		if (str_eq(tag, str_lit("import"))) {
 			AstNode *cond = NULL;
 			Token import_name = {0};