Ginger Bill 8 роки тому
батько
коміт
60b6538a7a
5 змінених файлів з 128 додано та 118 видалено
  1. 1 1
      core/_preload.odin
  2. 1 1
      core/utf8.odin
  3. 3 3
      core/win32.odin
  4. 118 113
      src/parser.c
  5. 5 0
      src/tokenizer.c

+ 1 - 1
core/_preload.odin

@@ -13,7 +13,7 @@
 // IMPORTANT NOTE(bill): Do not change the order of any of this data
 // The compiler relies upon this _exact_ order
 Type_Info :: union {
-	Member :: type struct #ordered {
+	Member :: struct #ordered {
 		name:      string;     // can be empty if tuple
 		type_info: ^Type_Info
 		offset:    int;        // offsets are not used in tuples

+ 1 - 1
core/utf8.odin

@@ -46,7 +46,7 @@ encode_rune :: proc(r_: rune) -> ([4]byte, int) {
 	r := r_
 	buf: [4]byte
 	i := r as u32
-	mask: byte : 0x3f
+	mask :: 0x3f as byte
 	if i <= 1<<7-1 {
 		buf[0] = r as byte
 		return buf, 1

+ 3 - 3
core/win32.odin

@@ -110,8 +110,8 @@ WIN32_FILE_ATTRIBUTE_DATA :: struct #ordered {
 }
 
 GET_FILEEX_INFO_LEVELS :: type i32
-GetFileExInfoStandard : GET_FILEEX_INFO_LEVELS : 0
-GetFileExMaxInfoLevel : GET_FILEEX_INFO_LEVELS : 1
+GetFileExInfoStandard :: 0 as GET_FILEEX_INFO_LEVELS
+GetFileExMaxInfoLevel :: 1 as GET_FILEEX_INFO_LEVELS
 
 GetLastError     :: proc() -> i32                           #foreign #dll_import
 ExitProcess      :: proc(exit_code: u32)                    #foreign #dll_import
@@ -232,7 +232,7 @@ RGBQUAD :: struct #ordered {
 
 BI_RGB         :: 0
 DIB_RGB_COLORS :: 0x00
-SRCCOPY        : u32 : 0x00cc0020
+SRCCOPY        :: 0x00cc0020 as u32
 
 StretchDIBits :: proc(hdc: HDC,
                       x_dst, y_dst, width_dst, height_dst: i32,

+ 118 - 113
src/parser.c

@@ -102,9 +102,11 @@ AstNodeArray make_ast_node_array(AstFile *f) {
 		AstNode *expr; \
 	}) \
 	AST_NODE_KIND(ProcLit, "procedure literal", struct { \
-		AstNode *type; \
-		AstNode *body; \
-		u64 tags;      \
+		AstNode *type;         \
+		AstNode *body;         \
+		u64      tags;         \
+		String   foreign_name; \
+		String   link_name;    \
 	}) \
 	AST_NODE_KIND(CompoundLit, "compound literal", struct { \
 		AstNode *type; \
@@ -245,7 +247,7 @@ AST_NODE_KIND(_DeclBegin,      "", i32) \
 			u64      tags;         \
 			String   foreign_name; \
 			String   link_name;    \
-			AstNode *note;          \
+			AstNode *note;         \
 	}) \
 	AST_NODE_KIND(TypeDecl,   "type declaration",   struct { \
 		Token token; \
@@ -277,6 +279,7 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
 		Token token;          \
 		AstNodeArray params;  \
 		AstNodeArray results; \
+		u64          tags;    \
 	}) \
 	AST_NODE_KIND(PointerType, "pointer type", struct { \
 		Token token; \
@@ -683,11 +686,13 @@ AstNode *make_ellipsis(AstFile *f, Token token, AstNode *expr) {
 }
 
 
-AstNode *make_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags) {
+AstNode *make_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags, String foreign_name, String link_name) {
 	AstNode *result = make_node(f, AstNode_ProcLit);
 	result->ProcLit.type = type;
 	result->ProcLit.body = body;
 	result->ProcLit.tags = tags;
+	result->ProcLit.foreign_name = foreign_name;
+	result->ProcLit.link_name = link_name;
 	return result;
 }
 
@@ -912,11 +917,12 @@ AstNode *make_parameter(AstFile *f, AstNodeArray names, AstNode *type, bool is_u
 	return result;
 }
 
-AstNode *make_proc_type(AstFile *f, Token token, AstNodeArray params, AstNodeArray results) {
+AstNode *make_proc_type(AstFile *f, Token token, AstNodeArray params, AstNodeArray results, u64 tags) {
 	AstNode *result = make_node(f, AstNode_ProcType);
 	result->ProcType.token = token;
 	result->ProcType.params = params;
 	result->ProcType.results = results;
+	result->ProcType.tags = tags;
 	return result;
 }
 
@@ -1300,7 +1306,7 @@ AstNode *parse_value(AstFile *f) {
 	return value;
 }
 
-AstNode *parse_identifier_or_type(AstFile *f, u32 flags);
+AstNode *parse_identifier_or_type(AstFile *f);
 
 
 void check_proc_add_tag(AstFile *f, AstNode *tag_expr, u64 *tags, ProcTag tag, String tag_name) {
@@ -1544,14 +1550,17 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
 			body = parse_body(f);
 			f->expr_level--;
 
-			type = make_proc_lit(f, type, body, tags);
+			type = make_proc_lit(f, type, body, tags, foreign_name, link_name);
+		} else if (type != NULL && type->kind == AstNode_ProcType) {
+			type->ProcType.tags = tags;
 		}
+
 		f->curr_proc = curr_proc;
 		return type;
 	}
 
 	default: {
-		AstNode *type = parse_identifier_or_type(f, 0);
+		AstNode *type = parse_identifier_or_type(f);
 		if (type != NULL) {
 			// NOTE(bill): Sanity check as identifiers should be handled already
 			GB_ASSERT_MSG(type->kind != AstNode_Ident, "Type Cannot be identifier");
@@ -1832,7 +1841,22 @@ AstNodeArray parse_rhs_expr_list(AstFile *f) {
 	return parse_expr_list(f, false);
 }
 
-AstNode *parse_decl(AstFile *f, AstNodeArray names);
+void parse_check_name_list_for_reserves(AstFile *f, AstNodeArray names) {
+	for_array(i, names) {
+		AstNode *name = names.e[i];
+		if (name->kind == AstNode_Ident) {
+			String n = name->Ident.string;
+			// NOTE(bill): Check for reserved identifiers
+			if (str_eq(n, str_lit("context"))) {
+				syntax_error_node(name, "`context` is a reserved identifier");
+				break;
+			}
+		}
+	}
+}
+
+AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name);
+
 
 AstNode *parse_simple_stmt(AstFile *f) {
 	isize lhs_count = 0, rhs_count = 0;
@@ -1870,8 +1894,83 @@ AstNode *parse_simple_stmt(AstFile *f) {
 		return make_assign_stmt(f, token, lhs, rhs);
 	} break;
 
-	case Token_Colon: // Declare
-		return parse_decl(f, lhs);
+	case Token_Colon: { // Declare
+		AstNodeArray names = lhs;
+		parse_check_name_list_for_reserves(f, names);
+
+		Token colon = expect_token(f, Token_Colon);
+		AstNode *type = parse_identifier_or_type(f);
+		AstNodeArray values = {0};
+
+		if (allow_token(f, Token_Eq)) {
+			values = parse_rhs_expr_list(f);
+			if (values.count > names.count) {
+				syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
+			} else if (values.count == 0) {
+				syntax_error(f->curr_token, "Expected an expression for this declaration");
+			}
+			if (type == NULL && values.count == 0) {
+				syntax_error(f->curr_token, "Missing variable type or initialization");
+				return make_bad_decl(f, f->curr_token, f->curr_token);
+			}
+		}
+
+		if (values.e == NULL) {
+			values = make_ast_node_array(f);
+		}
+
+		return make_var_decl(f, names, type, values);
+	} break;
+
+	case Token_ColonColon: {
+		AstNodeArray names = lhs;
+		parse_check_name_list_for_reserves(f, names);
+
+		Token colon_colon = expect_token(f, Token_ColonColon);
+
+		if (f->curr_token.kind == Token_type ||
+		    f->curr_token.kind == Token_struct ||
+		    f->curr_token.kind == Token_enum ||
+		    f->curr_token.kind == Token_union ||
+		    f->curr_token.kind == Token_raw_union) {
+			Token token = f->curr_token;
+			if (token.kind == Token_type) {
+				next_token(f);
+			}
+			if (names.count != 1) {
+				syntax_error_node(names.e[0], "You can only declare one type at a time");
+				return make_bad_decl(f, names.e[0]->Ident, token);
+			}
+
+			return make_type_decl(f, token, names.e[0], parse_type(f));
+		} else if (f->curr_token.kind == Token_proc) {
+		    // NOTE(bill): Procedure declarations
+			Token proc_token = f->curr_token;
+			AstNode *name = names.e[0];
+			if (names.count != 1) {
+				syntax_error(proc_token, "You can only declare one procedure at a time");
+				return make_bad_decl(f, name->Ident, proc_token);
+			}
+
+			return parse_proc_decl(f, proc_token, name);
+		}
+
+		AstNodeArray values = parse_rhs_expr_list(f);
+		if (values.count > names.count) {
+			syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
+		} else if (values.count < names.count) {
+			syntax_error(f->curr_token, "All constant declarations must be defined");
+		} else if (values.count == 0) {
+			syntax_error(f->curr_token, "Expected an expression for this declaration");
+		}
+
+		if (values.count == 0 && names.count > 0) {
+			syntax_error(f->curr_token, "Missing constant value");
+			return make_bad_decl(f, f->curr_token, f->curr_token);
+		}
+
+		return make_const_decl(f, names, NULL, values);
+	} break;
 	}
 
 	if (lhs_count > 1) {
@@ -1936,7 +2035,7 @@ AstNodeArray parse_identfier_list(AstFile *f) {
 
 
 AstNode *parse_type_attempt(AstFile *f) {
-	AstNode *type = parse_identifier_or_type(f, 0);
+	AstNode *type = parse_identifier_or_type(f);
 	if (type != NULL) {
 		// TODO(bill): Handle?
 	}
@@ -1963,7 +2062,7 @@ AstNode *parse_proc_type(AstFile *f) {
 
 	Token proc_token = parse_proc_signature(f, &params, &results);
 
-	return make_proc_type(f, proc_token, params, results);
+	return make_proc_type(f, proc_token, params, results, 0);
 }
 
 
@@ -2087,7 +2186,7 @@ AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool using_allo
 	return decls;
 }
 
-AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
+AstNode *parse_identifier_or_type(AstFile *f) {
 	switch (f->curr_token.kind) {
 	case Token_Ident: {
 		AstNode *e = parse_identifier(f);
@@ -2104,6 +2203,10 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
 		return e;
 	}
 
+	case Token_type:
+		expect_token(f, Token_type);
+		return parse_identifier_or_type(f);
+
 	case Token_Pointer: {
 		Token token = expect_token(f, Token_Pointer);
 		AstNode *elem = parse_type(f);
@@ -2342,104 +2445,6 @@ AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) {
 	return make_proc_decl(f, name, proc_type, body, tags, foreign_name, link_name);
 }
 
-AstNode *parse_decl(AstFile *f, AstNodeArray names) {
-	AstNodeArray values = {0};
-	AstNode *type = NULL;
-
-	for_array(i, names) {
-		AstNode *name = names.e[i];
-		if (name->kind == AstNode_Ident) {
-			String n = name->Ident.string;
-			// NOTE(bill): Check for reserved identifiers
-			if (str_eq(n, str_lit("context"))) {
-				syntax_error_node(name, "`context` is a reserved identifier");
-				break;
-			}
-		}
-	}
-
-	if (allow_token(f, Token_Colon)) {
-		if (!allow_token(f, Token_type)) {
-			type = parse_identifier_or_type(f, 0);
-		}
-	} else if (f->curr_token.kind != Token_Eq && f->curr_token.kind != Token_Semicolon) {
-		syntax_error(f->curr_token, "Expected type separator `:` or `=`");
-	}
-
-	bool is_mutable = true;
-
-	if (f->curr_token.kind == Token_Eq || f->curr_token.kind == Token_Colon) {
-		if (f->curr_token.kind == Token_Colon) {
-			is_mutable = false;
-		}
-		next_token(f);
-
-		if (f->curr_token.kind == Token_type ||
-		    f->curr_token.kind == Token_struct ||
-		    f->curr_token.kind == Token_enum ||
-		    f->curr_token.kind == Token_union ||
-		    f->curr_token.kind == Token_raw_union) {
-			Token token = f->curr_token;
-			if (token.kind == Token_type) {
-				next_token(f);
-			}
-			if (names.count != 1) {
-				syntax_error_node(names.e[0], "You can only declare one type at a time");
-				return make_bad_decl(f, names.e[0]->Ident, token);
-			}
-
-			if (type != NULL) {
-				syntax_error(f->prev_token, "Expected either `type` or nothing between : and :");
-				// NOTE(bill): Do not fail though
-			}
-
-			return make_type_decl(f, token, names.e[0], parse_type(f));
-		} else if (f->curr_token.kind == Token_proc && is_mutable == false) {
-		    // NOTE(bill): Procedure declarations
-			Token proc_token = f->curr_token;
-			AstNode *name = names.e[0];
-			if (names.count != 1) {
-				syntax_error(proc_token, "You can only declare one procedure at a time");
-				return make_bad_decl(f, name->Ident, proc_token);
-			}
-
-			return parse_proc_decl(f, proc_token, name);
-
-		} else {
-			values = parse_rhs_expr_list(f);
-			if (values.count > names.count) {
-				syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
-			} else if (values.count < names.count && !is_mutable) {
-				syntax_error(f->curr_token, "All constant declarations must be defined");
-			} else if (values.count == 0) {
-				syntax_error(f->curr_token, "Expected an expression for this declaration");
-			}
-		}
-	}
-
-	if (is_mutable) {
-		if (type == NULL && values.count == 0) {
-			syntax_error(f->curr_token, "Missing variable type or initialization");
-			return make_bad_decl(f, f->curr_token, f->curr_token);
-		}
-	} else {
-		if (type == NULL && values.count == 0 && names.count > 0) {
-			syntax_error(f->curr_token, "Missing constant value");
-			return make_bad_decl(f, f->curr_token, f->curr_token);
-		}
-	}
-
-	if (values.e == NULL) {
-		values = make_ast_node_array(f);
-	}
-
-	if (is_mutable) {
-		return make_var_decl(f, names, type, values);
-	}
-	return make_const_decl(f, names, type, values);
-}
-
-
 AstNode *parse_if_stmt(AstFile *f) {
 	if (f->curr_proc == NULL) {
 		syntax_error(f->curr_token, "You cannot use an if statement in the file scope");

+ 5 - 0
src/tokenizer.c

@@ -74,6 +74,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
 	TOKEN_KIND(Token_OpenBrace, "{"), \
 	TOKEN_KIND(Token_CloseBrace, "}"), \
 	TOKEN_KIND(Token_Colon, ":"), \
+	TOKEN_KIND(Token_ColonColon, "::"), \
 	TOKEN_KIND(Token_Semicolon, ";"), \
 	TOKEN_KIND(Token_Period, "."), \
 	TOKEN_KIND(Token_Comma, ","), \
@@ -871,6 +872,10 @@ Token tokenizer_get_token(Tokenizer *t) {
 			break;
 		case ':':
 			token.kind = Token_Colon;
+			if (t->curr_rune == ':') {
+				advance_to_next_rune(t);
+				token.kind = Token_ColonColon;
+			}
 			break;
 		case '(':
 			token.kind = Token_OpenParen;