diff --git a/vlib/compiler/enum.v b/vlib/compiler/enum.v index e5520749f5..8765ea2284 100644 --- a/vlib/compiler/enum.v +++ b/vlib/compiler/enum.v @@ -40,10 +40,7 @@ fn (p mut Parser) enum_decl(_enum_name string) { if p.tok == .comma { p.next() } - // !!!! NAME free - if p.first_pass() { - p.table.register_const(name, enum_name, p.mod) - } + // TODO free name [memory] val++ } p.table.register_type2(Type { diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index 3a1e077575..e1a8d5d729 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -330,13 +330,14 @@ fn (p mut Parser) parse(pass Pass) { p.check(.name) } case TokenKind.key_pub: - if p.peek() == .key_fn { - p.fn_decl() - } else if p.peek() == .key_struct { - p.error('structs can\'t be declared public *yet*') - // TODO public structs - } else { - p.error('wrong pub keyword usage') + next := p.peek() + match next { + .key_fn { p.fn_decl() } + .key_const { p.const_decl() } + .key_struct { p.struct_decl() } + else { + p.error('wrong pub keyword usage') + } } case TokenKind.key_fn: p.fn_decl() @@ -493,6 +494,10 @@ fn (p mut Parser) import_statement() { } fn (p mut Parser) const_decl() { + is_pub := p.tok == .key_pub + if is_pub { + p.next() + } if p.tok == .key_import { p.error_with_token_index( '`import const` was removed from the language, ' + @@ -530,7 +535,7 @@ fn (p mut Parser) const_decl() { } else { typ = p.get_type() } - p.table.register_const(name, typ, p.mod) + p.table.register_const(name, typ, p.mod, is_pub) p.cgen.consts << ('extern ' + p.table.cgen_name_type_pair(name, typ)) + ';' continue // Don't generate C code when building a .vh file @@ -542,7 +547,7 @@ fn (p mut Parser) const_decl() { p.error('redefinition of `$name`') } if p.first_pass() { - p.table.register_const(name, typ, p.mod) + p.table.register_const(name, typ, p.mod, is_pub) } // Check to see if this constant exists, and is void. If so, try and get the type again: if my_const := p.v.table.find_const(name) { @@ -650,6 +655,10 @@ fn key_to_type_cat(tok TokenKind) TypeCategory { // also unions and interfaces fn (p mut Parser) struct_decl() { + is_pub := p.tok == .key_pub + if is_pub { + p.next() + } // V can generate Objective C for integration with Cocoa // `[objc_interface:ParentInterface]` is_objc := p.attr.starts_with('objc_interface') @@ -730,6 +739,7 @@ fn (p mut Parser) struct_decl() { is_c: is_c cat: cat parent: objc_parent + is_public: is_pub } } // Struct `C.Foo` declaration, no body @@ -740,7 +750,7 @@ fn (p mut Parser) struct_decl() { p.fgen(' ') p.check(.lcbr) // Struct fields - mut is_pub := false + mut is_pub_field := false mut is_mut := false mut names := []string// to avoid dup names TODO alloc perf /* @@ -761,10 +771,10 @@ fn (p mut Parser) struct_decl() { mut did_gen_something := false for p.tok != .rcbr { if p.tok == .key_pub { - if is_pub { + if is_pub_field { p.error('structs can only have one `pub:`, all public fields have to be grouped') } - is_pub = true + is_pub_field = true p.fmt_dec() p.check(.key_pub) if p.tok != .key_mut { @@ -813,7 +823,7 @@ fn (p mut Parser) struct_decl() { continue } // `pub` access mod - access_mod := if is_pub{AccessMod.public} else { AccessMod.private} + access_mod := if is_pub_field { AccessMod.public } else { AccessMod.private} p.fgen(' ') field_type := p.get_type() if field_type == name { diff --git a/vlib/compiler/table.v b/vlib/compiler/table.v index aaf6ff4747..a9dfab3530 100644 --- a/vlib/compiler/table.v +++ b/vlib/compiler/table.v @@ -100,6 +100,7 @@ mut: line_nr int token_idx int // this is a token index, which will be used by error reporting is_for_var bool + is_public bool // for consts } struct Type { @@ -108,6 +109,7 @@ mut: mod string name string cat TypeCategory + is_public bool fields []Var methods []Fn parent string @@ -254,10 +256,10 @@ fn new_table(obfuscate bool) &Table { for c in reserved_type_param_names { t.register_type(c) } - t.register_const('stdin', 'int', 'main') - t.register_const('stdout', 'int', 'main') - t.register_const('stderr', 'int', 'main') - t.register_const('errno', 'int', 'main') + t.register_const('stdin', 'int', 'main', true) + t.register_const('stdout', 'int', 'main', true) + t.register_const('stderr', 'int', 'main', true) + t.register_const('errno', 'int', 'main', true) t.register_type_with_parent('map_string', 'map') t.register_type_with_parent('map_int', 'map') return t @@ -306,13 +308,14 @@ fn (table &Table) known_mod(mod string) bool { return mod in table.modules } -fn (t mut Table) register_const(name, typ, mod string) { - t.consts << Var { +fn (t mut Table) register_const(name, typ, mod string, is_pub bool) { + t.consts << Var{ name: name typ: typ is_const: true mod: mod idx: -1 + is_public: is_pub } } diff --git a/vlib/compiler/tests/const_test.v b/vlib/compiler/tests/const_test.v index 03a57594a4..4b639e4799 100644 --- a/vlib/compiler/tests/const_test.v +++ b/vlib/compiler/tests/const_test.v @@ -1,10 +1,14 @@ -const ( +pub const ( // c = a // TODO a = b b = 1 ) +struct Foo { + +} + fn test_const() { assert a == 1 // assert c == 1 // TODO: This will not build yet -} \ No newline at end of file +}