compiler: public consts and structs

pull/2523/head
Alexander Medvednikov 2019-10-24 12:19:05 +03:00
parent 71d965b6a2
commit 1c564bc118
4 changed files with 39 additions and 25 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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
}
}