From 37b13bf1512d8eed7308a2194c1935d91a33796c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 18 Dec 2016 17:24:52 -0500 Subject: [PATCH] hello.zig working with all structs anonymous --- doc/langref.md | 2 +- src/all_types.hpp | 4 ++++ src/analyze.cpp | 3 +++ src/ir.cpp | 3 +++ src/parser.cpp | 35 ++++++++++++++++++++++++----------- std/cstr.zig | 4 ++-- std/io.zig | 8 ++++---- std/linux.zig | 16 ++++++++-------- std/linux_x86_64.zig | 12 ++++++------ std/math.zig | 4 ++-- 10 files changed, 57 insertions(+), 34 deletions(-) diff --git a/doc/langref.md b/doc/langref.md index d3e0dd63d7..05c27a181a 100644 --- a/doc/langref.md +++ b/doc/langref.md @@ -151,7 +151,7 @@ GroupedExpression = "(" Expression ")" KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this" -ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}" +ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}" ``` diff --git a/src/all_types.hpp b/src/all_types.hpp index 74f25fc32b..15082b62aa 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -598,6 +598,7 @@ struct AstNodeContainerDecl { ContainerKind kind; ZigList fields; ZigList decls; + bool is_extern; }; struct AstNodeStructField { @@ -801,6 +802,7 @@ struct TypeStructField { }; struct TypeTableEntryStruct { AstNode *decl_node; + bool is_extern; bool is_packed; uint32_t src_field_count; uint32_t gen_field_count; @@ -827,6 +829,7 @@ struct TypeTableEntryError { struct TypeTableEntryEnum { AstNode *decl_node; + bool is_extern; uint32_t src_field_count; uint32_t gen_field_count; TypeEnumField *fields; @@ -845,6 +848,7 @@ struct TypeTableEntryEnum { struct TypeTableEntryUnion { AstNode *decl_node; + bool is_extern; uint32_t src_field_count; uint32_t gen_field_count; TypeStructField *fields; diff --git a/src/analyze.cpp b/src/analyze.cpp index ea3ba4aa7f..7651742986 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -838,12 +838,15 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKi switch (kind) { case ContainerKindStruct: entry->data.structure.decl_node = decl_node; + entry->data.structure.is_extern = decl_node->data.container_decl.is_extern; break; case ContainerKindEnum: entry->data.enumeration.decl_node = decl_node; + entry->data.enumeration.is_extern = decl_node->data.container_decl.is_extern; break; case ContainerKindUnion: entry->data.unionation.decl_node = decl_node; + entry->data.unionation.is_extern = decl_node->data.container_decl.is_extern; break; } diff --git a/src/ir.cpp b/src/ir.cpp index d2729d8ed1..ae6fd78d1f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -8007,6 +8007,9 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru TypeTableEntry *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, bool depends_on_compile_var) { + if (!type_is_complete(container_type)) + resolve_container_type(ira->codegen, container_type); + size_t actual_field_count = container_type->data.structure.src_field_count; IrInstruction *first_non_const_instruction = nullptr; diff --git a/src/parser.cpp b/src/parser.cpp index 0ee984d7fa..54994034f9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -684,11 +684,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo AstNode *node = ast_create_node(pc, NodeTypeErrorType, token); *token_index += 1; return node; - } else if (token->id == TokenIdKeywordExtern) { - *token_index += 1; - AstNode *node = ast_parse_fn_proto(pc, token_index, true, VisibModPrivate); - node->data.fn_proto.is_extern = true; - return node; } else if (token->id == TokenIdAtSign) { *token_index += 1; 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 if (container_decl) return container_decl; + if (token->id == TokenIdKeywordExtern) { + *token_index += 1; + AstNode *node = ast_parse_fn_proto(pc, token_index, true, VisibModPrivate); + node->data.fn_proto.is_extern = true; + return node; + } + if (!mandatory) return nullptr; @@ -2224,28 +2226,39 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi } /* -ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}" +ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}" StructMember = (StructField | FnDef | GlobalVarDecl) StructField = Symbol option(":" Expression) ",") */ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory) { Token *first_token = &pc->tokens->at(*token_index); + Token *container_kind_token; + + bool is_extern; + if (first_token->id == TokenIdKeywordExtern) { + container_kind_token = &pc->tokens->at(*token_index + 1); + is_extern = true; + } else { + container_kind_token = first_token; + is_extern = false; + } ContainerKind kind; - if (first_token->id == TokenIdKeywordStruct) { + if (container_kind_token->id == TokenIdKeywordStruct) { kind = ContainerKindStruct; - } else if (first_token->id == TokenIdKeywordEnum) { + } else if (container_kind_token->id == TokenIdKeywordEnum) { kind = ContainerKindEnum; - } else if (first_token->id == TokenIdKeywordUnion) { + } else if (container_kind_token->id == TokenIdKeywordUnion) { kind = ContainerKindUnion; } else if (mandatory) { - ast_invalid_token_error(pc, first_token); + ast_invalid_token_error(pc, container_kind_token); } else { return nullptr; } - *token_index += 1; + *token_index += is_extern ? 2 : 1; AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token); + node->data.container_decl.is_extern = is_extern; node->data.container_decl.kind = kind; ast_eat_token(pc, token_index, TokenIdLBrace); diff --git a/std/cstr.zig b/std/cstr.zig index afe8d5b404..ce847a5fbc 100644 --- a/std/cstr.zig +++ b/std/cstr.zig @@ -34,7 +34,7 @@ pub fn toSlice(str: &u8) -> []u8 { /// A buffer that allocates memory and maintains a null byte at the end. -pub struct CBuf { +pub const CBuf = struct { list: List(u8), /// Must deinitialize with deinit. @@ -124,7 +124,7 @@ pub struct CBuf { pub fn startsWithCStr(self: &const CBuf, s: &const u8) -> bool { self.startsWithMem(s[0...strlen(s)]) } -} +}; fn testSimpleCBuf() { @setFnTest(this, true); diff --git a/std/io.zig b/std/io.zig index 8fc4a5bc84..887c3cff80 100644 --- a/std/io.zig +++ b/std/io.zig @@ -69,7 +69,7 @@ pub const OpenWrite = 0b0010; pub const OpenCreate = 0b0100; pub const OpenTruncate = 0b1000; -pub struct OutStream { +pub const OutStream = struct { fd: i32, buffer: [buffer_size]u8, index: usize, @@ -153,11 +153,11 @@ pub struct OutStream { return; } } -} +}; // TODO created a BufferedInStream struct and move some of this code there // BufferedInStream API goes on top of minimal InStream API. -pub struct InStream { +pub const InStream = struct { fd: i32, /// Call close to clean up. @@ -360,7 +360,7 @@ pub struct InStream { return usize(stat.size); } -} +}; pub fn parseUnsigned(inline T: type, buf: []u8, radix: u8) -> %T { var x: T = 0; diff --git a/std/linux.zig b/std/linux.zig index 1444d480ab..813a2ea824 100644 --- a/std/linux.zig +++ b/std/linux.zig @@ -342,31 +342,31 @@ pub const socklen_t = u32; pub const in_addr = u32; pub const in6_addr = [16]u8; -export struct sockaddr { +pub const sockaddr = extern struct { family: sa_family_t, port: u16, data: [12]u8, -} +}; -export struct sockaddr_in { +pub const sockaddr_in = extern struct { family: sa_family_t, port: u16, addr: in_addr, zero: [8]u8, -} +}; -export struct sockaddr_in6 { +pub const sockaddr_in6 = extern struct { family: sa_family_t, port: u16, flowinfo: u32, addr: in6_addr, scope_id: u32, -} +}; -export struct iovec { +pub const iovec = extern struct { iov_base: &u8, iov_len: usize, -} +}; // //const IF_NAMESIZE = 16; diff --git a/std/linux_x86_64.zig b/std/linux_x86_64.zig index 3b42bfb461..0f8f163ce2 100644 --- a/std/linux_x86_64.zig +++ b/std/linux_x86_64.zig @@ -442,7 +442,7 @@ pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg : "rcx", "r11") } -export struct msghdr { +pub const msghdr = extern struct { msg_name: &u8, msg_namelen: socklen_t, msg_iov: &iovec, @@ -452,9 +452,9 @@ export struct msghdr { msg_controllen: socklen_t, __pad2: socklen_t, msg_flags: i32, -} +}; -export struct stat { +pub const stat = extern struct { dev: u64, ino: u64, nlink: usize, @@ -472,9 +472,9 @@ export struct stat { mtim: timespec, ctim: timespec, __unused: [3]isize, -} +}; -export struct timespec { +pub const timespec = extern struct { tv_sec: isize, tv_nsec: isize, -} +}; diff --git a/std/math.zig b/std/math.zig index acc9eaec73..06eaa3177a 100644 --- a/std/math.zig +++ b/std/math.zig @@ -1,8 +1,8 @@ -pub enum Cmp { +pub const Cmp = enum { Equal, Greater, Less, -} +}; pub fn min(x: var, y: var) -> @typeOf(x + y) { if (x < y) x else y