| author | |
| committer | |
| log | 37b13bf1512d8eed7308a2194c1935d91a33796c |
| tree | 42b6d1d4b6ddd16c7f69c4bdd15677a720609cf3 |
| parent | e50ced44a2cf6268c19df901ad56b367d8d802fe |
10 files changed, 57 insertions(+), 34 deletions(-)
doc/langref.md+1-1| ... | ... | @@ -151,7 +151,7 @@ GroupedExpression = "(" Expression ")" |
| 151 | 151 | |
| 152 | 152 | KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this" |
| 153 | 153 | |
| 154 | ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}" | |
| 154 | ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}" | |
| 155 | 155 | |
| 156 | 156 | ``` |
| 157 | 157 |
src/all_types.hpp+4| ... | ... | @@ -598,6 +598,7 @@ struct AstNodeContainerDecl { |
| 598 | 598 | ContainerKind kind; |
| 599 | 599 | ZigList<AstNode *> fields; |
| 600 | 600 | ZigList<AstNode *> decls; |
| 601 | bool is_extern; | |
| 601 | 602 | }; |
| 602 | 603 | |
| 603 | 604 | struct AstNodeStructField { |
| ... | ... | @@ -801,6 +802,7 @@ struct TypeStructField { |
| 801 | 802 | }; |
| 802 | 803 | struct TypeTableEntryStruct { |
| 803 | 804 | AstNode *decl_node; |
| 805 | bool is_extern; | |
| 804 | 806 | bool is_packed; |
| 805 | 807 | uint32_t src_field_count; |
| 806 | 808 | uint32_t gen_field_count; |
| ... | ... | @@ -827,6 +829,7 @@ struct TypeTableEntryError { |
| 827 | 829 | |
| 828 | 830 | struct TypeTableEntryEnum { |
| 829 | 831 | AstNode *decl_node; |
| 832 | bool is_extern; | |
| 830 | 833 | uint32_t src_field_count; |
| 831 | 834 | uint32_t gen_field_count; |
| 832 | 835 | TypeEnumField *fields; |
| ... | ... | @@ -845,6 +848,7 @@ struct TypeTableEntryEnum { |
| 845 | 848 | |
| 846 | 849 | struct TypeTableEntryUnion { |
| 847 | 850 | AstNode *decl_node; |
| 851 | bool is_extern; | |
| 848 | 852 | uint32_t src_field_count; |
| 849 | 853 | uint32_t gen_field_count; |
| 850 | 854 | TypeStructField *fields; |
src/analyze.cpp+3| ... | ... | @@ -838,12 +838,15 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKi |
| 838 | 838 | switch (kind) { |
| 839 | 839 | case ContainerKindStruct: |
| 840 | 840 | entry->data.structure.decl_node = decl_node; |
| 841 | entry->data.structure.is_extern = decl_node->data.container_decl.is_extern; | |
| 841 | 842 | break; |
| 842 | 843 | case ContainerKindEnum: |
| 843 | 844 | entry->data.enumeration.decl_node = decl_node; |
| 845 | entry->data.enumeration.is_extern = decl_node->data.container_decl.is_extern; | |
| 844 | 846 | break; |
| 845 | 847 | case ContainerKindUnion: |
| 846 | 848 | entry->data.unionation.decl_node = decl_node; |
| 849 | entry->data.unionation.is_extern = decl_node->data.container_decl.is_extern; | |
| 847 | 850 | break; |
| 848 | 851 | } |
| 849 | 852 |
src/ir.cpp+3| ... | ... | @@ -8007,6 +8007,9 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru |
| 8007 | 8007 | TypeTableEntry *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| 8008 | 8008 | bool depends_on_compile_var) |
| 8009 | 8009 | { |
| 8010 | if (!type_is_complete(container_type)) | |
| 8011 | resolve_container_type(ira->codegen, container_type); | |
| 8012 | ||
| 8010 | 8013 | size_t actual_field_count = container_type->data.structure.src_field_count; |
| 8011 | 8014 | |
| 8012 | 8015 | IrInstruction *first_non_const_instruction = nullptr; |
src/parser.cpp+24-11| ... | ... | @@ -684,11 +684,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo |
| 684 | 684 | AstNode *node = ast_create_node(pc, NodeTypeErrorType, token); |
| 685 | 685 | *token_index += 1; |
| 686 | 686 | return node; |
| 687 | } else if (token->id == TokenIdKeywordExtern) { | |
| 688 | *token_index += 1; | |
| 689 | AstNode *node = ast_parse_fn_proto(pc, token_index, true, VisibModPrivate); | |
| 690 | node->data.fn_proto.is_extern = true; | |
| 691 | return node; | |
| 692 | 687 | } else if (token->id == TokenIdAtSign) { |
| 693 | 688 | *token_index += 1; |
| 694 | 689 | Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); |
| ... | ... | @@ -742,6 +737,13 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo |
| 742 | 737 | if (container_decl) |
| 743 | 738 | return container_decl; |
| 744 | 739 | |
| 740 | if (token->id == TokenIdKeywordExtern) { | |
| 741 | *token_index += 1; | |
| 742 | AstNode *node = ast_parse_fn_proto(pc, token_index, true, VisibModPrivate); | |
| 743 | node->data.fn_proto.is_extern = true; | |
| 744 | return node; | |
| 745 | } | |
| 746 | ||
| 745 | 747 | if (!mandatory) |
| 746 | 748 | return nullptr; |
| 747 | 749 | |
| ... | ... | @@ -2224,28 +2226,39 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi |
| 2224 | 2226 | } |
| 2225 | 2227 | |
| 2226 | 2228 | /* |
| 2227 | ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}" | |
| 2229 | ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}" | |
| 2228 | 2230 | StructMember = (StructField | FnDef | GlobalVarDecl) |
| 2229 | 2231 | StructField = Symbol option(":" Expression) ",") |
| 2230 | 2232 | */ |
| 2231 | 2233 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2232 | 2234 | Token *first_token = &pc->tokens->at(*token_index); |
| 2235 | Token *container_kind_token; | |
| 2236 | ||
| 2237 | bool is_extern; | |
| 2238 | if (first_token->id == TokenIdKeywordExtern) { | |
| 2239 | container_kind_token = &pc->tokens->at(*token_index + 1); | |
| 2240 | is_extern = true; | |
| 2241 | } else { | |
| 2242 | container_kind_token = first_token; | |
| 2243 | is_extern = false; | |
| 2244 | } | |
| 2233 | 2245 | |
| 2234 | 2246 | ContainerKind kind; |
| 2235 | if (first_token->id == TokenIdKeywordStruct) { | |
| 2247 | if (container_kind_token->id == TokenIdKeywordStruct) { | |
| 2236 | 2248 | kind = ContainerKindStruct; |
| 2237 | } else if (first_token->id == TokenIdKeywordEnum) { | |
| 2249 | } else if (container_kind_token->id == TokenIdKeywordEnum) { | |
| 2238 | 2250 | kind = ContainerKindEnum; |
| 2239 | } else if (first_token->id == TokenIdKeywordUnion) { | |
| 2251 | } else if (container_kind_token->id == TokenIdKeywordUnion) { | |
| 2240 | 2252 | kind = ContainerKindUnion; |
| 2241 | 2253 | } else if (mandatory) { |
| 2242 | ast_invalid_token_error(pc, first_token); | |
| 2254 | ast_invalid_token_error(pc, container_kind_token); | |
| 2243 | 2255 | } else { |
| 2244 | 2256 | return nullptr; |
| 2245 | 2257 | } |
| 2246 | *token_index += 1; | |
| 2258 | *token_index += is_extern ? 2 : 1; | |
| 2247 | 2259 | |
| 2248 | 2260 | AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token); |
| 2261 | node->data.container_decl.is_extern = is_extern; | |
| 2249 | 2262 | node->data.container_decl.kind = kind; |
| 2250 | 2263 | |
| 2251 | 2264 | ast_eat_token(pc, token_index, TokenIdLBrace); |
std/cstr.zig+2-2| ... | ... | @@ -34,7 +34,7 @@ pub fn toSlice(str: &u8) -> []u8 { |
| 34 | 34 | |
| 35 | 35 | |
| 36 | 36 | /// A buffer that allocates memory and maintains a null byte at the end. |
| 37 | pub struct CBuf { | |
| 37 | pub const CBuf = struct { | |
| 38 | 38 | list: List(u8), |
| 39 | 39 | |
| 40 | 40 | /// Must deinitialize with deinit. |
| ... | ... | @@ -124,7 +124,7 @@ pub struct CBuf { |
| 124 | 124 | pub fn startsWithCStr(self: &const CBuf, s: &const u8) -> bool { |
| 125 | 125 | self.startsWithMem(s[0...strlen(s)]) |
| 126 | 126 | } |
| 127 | } | |
| 127 | }; | |
| 128 | 128 | |
| 129 | 129 | fn testSimpleCBuf() { |
| 130 | 130 | @setFnTest(this, true); |
std/io.zig+4-4| ... | ... | @@ -69,7 +69,7 @@ pub const OpenWrite = 0b0010; |
| 69 | 69 | pub const OpenCreate = 0b0100; |
| 70 | 70 | pub const OpenTruncate = 0b1000; |
| 71 | 71 | |
| 72 | pub struct OutStream { | |
| 72 | pub const OutStream = struct { | |
| 73 | 73 | fd: i32, |
| 74 | 74 | buffer: [buffer_size]u8, |
| 75 | 75 | index: usize, |
| ... | ... | @@ -153,11 +153,11 @@ pub struct OutStream { |
| 153 | 153 | return; |
| 154 | 154 | } |
| 155 | 155 | } |
| 156 | } | |
| 156 | }; | |
| 157 | 157 | |
| 158 | 158 | // TODO created a BufferedInStream struct and move some of this code there |
| 159 | 159 | // BufferedInStream API goes on top of minimal InStream API. |
| 160 | pub struct InStream { | |
| 160 | pub const InStream = struct { | |
| 161 | 161 | fd: i32, |
| 162 | 162 | |
| 163 | 163 | /// Call close to clean up. |
| ... | ... | @@ -360,7 +360,7 @@ pub struct InStream { |
| 360 | 360 | |
| 361 | 361 | return usize(stat.size); |
| 362 | 362 | } |
| 363 | } | |
| 363 | }; | |
| 364 | 364 | |
| 365 | 365 | pub fn parseUnsigned(inline T: type, buf: []u8, radix: u8) -> %T { |
| 366 | 366 | var x: T = 0; |
std/linux.zig+8-8| ... | ... | @@ -342,31 +342,31 @@ pub const socklen_t = u32; |
| 342 | 342 | pub const in_addr = u32; |
| 343 | 343 | pub const in6_addr = [16]u8; |
| 344 | 344 | |
| 345 | export struct sockaddr { | |
| 345 | pub const sockaddr = extern struct { | |
| 346 | 346 | family: sa_family_t, |
| 347 | 347 | port: u16, |
| 348 | 348 | data: [12]u8, |
| 349 | } | |
| 349 | }; | |
| 350 | 350 | |
| 351 | export struct sockaddr_in { | |
| 351 | pub const sockaddr_in = extern struct { | |
| 352 | 352 | family: sa_family_t, |
| 353 | 353 | port: u16, |
| 354 | 354 | addr: in_addr, |
| 355 | 355 | zero: [8]u8, |
| 356 | } | |
| 356 | }; | |
| 357 | 357 | |
| 358 | export struct sockaddr_in6 { | |
| 358 | pub const sockaddr_in6 = extern struct { | |
| 359 | 359 | family: sa_family_t, |
| 360 | 360 | port: u16, |
| 361 | 361 | flowinfo: u32, |
| 362 | 362 | addr: in6_addr, |
| 363 | 363 | scope_id: u32, |
| 364 | } | |
| 364 | }; | |
| 365 | 365 | |
| 366 | export struct iovec { | |
| 366 | pub const iovec = extern struct { | |
| 367 | 367 | iov_base: &u8, |
| 368 | 368 | iov_len: usize, |
| 369 | } | |
| 369 | }; | |
| 370 | 370 | |
| 371 | 371 | // |
| 372 | 372 | //const IF_NAMESIZE = 16; |
std/linux_x86_64.zig+6-6| ... | ... | @@ -442,7 +442,7 @@ pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg |
| 442 | 442 | : "rcx", "r11") |
| 443 | 443 | } |
| 444 | 444 | |
| 445 | export struct msghdr { | |
| 445 | pub const msghdr = extern struct { | |
| 446 | 446 | msg_name: &u8, |
| 447 | 447 | msg_namelen: socklen_t, |
| 448 | 448 | msg_iov: &iovec, |
| ... | ... | @@ -452,9 +452,9 @@ export struct msghdr { |
| 452 | 452 | msg_controllen: socklen_t, |
| 453 | 453 | __pad2: socklen_t, |
| 454 | 454 | msg_flags: i32, |
| 455 | } | |
| 455 | }; | |
| 456 | 456 | |
| 457 | export struct stat { | |
| 457 | pub const stat = extern struct { | |
| 458 | 458 | dev: u64, |
| 459 | 459 | ino: u64, |
| 460 | 460 | nlink: usize, |
| ... | ... | @@ -472,9 +472,9 @@ export struct stat { |
| 472 | 472 | mtim: timespec, |
| 473 | 473 | ctim: timespec, |
| 474 | 474 | __unused: [3]isize, |
| 475 | } | |
| 475 | }; | |
| 476 | 476 | |
| 477 | export struct timespec { | |
| 477 | pub const timespec = extern struct { | |
| 478 | 478 | tv_sec: isize, |
| 479 | 479 | tv_nsec: isize, |
| 480 | } | |
| 480 | }; |
std/math.zig+2-2| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | pub enum Cmp { | |
| 1 | pub const Cmp = enum { | |
| 2 | 2 | Equal, |
| 3 | 3 | Greater, |
| 4 | 4 | Less, |
| 5 | } | |
| 5 | }; | |
| 6 | 6 | |
| 7 | 7 | pub fn min(x: var, y: var) -> @typeOf(x + y) { |
| 8 | 8 | if (x < y) x else y |