v2: minor fixes

pull/4127/head
Alexander Medvednikov 2020-03-27 08:46:54 +01:00
parent 883a105aca
commit db59c621e8
8 changed files with 91 additions and 74 deletions

View File

@ -86,10 +86,7 @@ fn parse_flags(flag string, f mut flag.Instance, prefs mut flag.MainCmdPreferenc
exit(1) exit(1)
} }
else { else {
if flag in list_of_flags_that_allow_duplicates { prefs.unknown_flag = '-$flag'
f.allow_duplicate()
}
prefs.unknown_flag = '-$flag'
if !(flag in list_of_flags_with_param) { if !(flag in list_of_flags_with_param) {
return return
} }

View File

@ -22,8 +22,6 @@ fn parse_c_options(flag string, f mut flag.Instance, prefs mut pref.Preferences)
exit(1) exit(1)
} }
prefs.ccompiler = tmp prefs.ccompiler = tmp
// needed to enable CI compiling of -live examples.
f.allow_duplicate()
} }
'cg', 'cdebug' { 'cg', 'cdebug' {
f.is_equivalent_to(['cg', 'cdebug', 'g', 'debug']) f.is_equivalent_to(['cg', 'cdebug', 'g', 'debug'])
@ -60,7 +58,6 @@ fn parse_c_options(flag string, f mut flag.Instance, prefs mut pref.Preferences)
prefs.sanitize = f.bool() prefs.sanitize = f.bool()
} }
'cf', 'cflags' { 'cf', 'cflags' {
f.allow_duplicate()
cflag := f.string() or { cflag := f.string() or {
println('V error: Expected argument after `-$flag`.') println('V error: Expected argument after `-$flag`.')
exit(1) exit(1)

View File

@ -90,7 +90,6 @@ fn parse_options(flag string, f mut flag.Instance, prefs mut pref.Preferences) {
prefs.out_name = tmp prefs.out_name = tmp
} }
'd', 'define' { 'd', 'define' {
f.allow_duplicate()
define := f.string() or { define := f.string() or {
println('V error: Expected argument for `-$flag`.') println('V error: Expected argument for `-$flag`.')
exit(1) exit(1)
@ -105,7 +104,6 @@ fn parse_options(flag string, f mut flag.Instance, prefs mut pref.Preferences) {
} }
} }
'e', 'experiments' { 'e', 'experiments' {
f.allow_duplicate()
to_enable := f.string() or { to_enable := f.string() or {
println('V error: Expected argument for `-$flag`.') println('V error: Expected argument for `-$flag`.')
exit(1) exit(1)

View File

@ -44,11 +44,6 @@ fn (p mut Instance) parse_impl(args []string, value voidptr, callback void_cb) ?
p.equal_val = '' p.equal_val = ''
flag_name = next[1..] flag_name = next[1..]
} }
if p.encountered[flag_name] {
// Duplicate flags are opt-in
// This can be prevented with p.allow_duplicate()
return error('Duplicate flag: -$flag_name')
}
p.encountered[flag_name] = true p.encountered[flag_name] = true
p.current_flag = flag_name p.current_flag = flag_name
callback(flag_name, p, value) callback(flag_name, p, value)
@ -115,10 +110,6 @@ pub fn (p mut Instance) bool() bool {
return true return true
} }
pub fn (p mut Instance) allow_duplicate() {
p.encountered[p.current_flag] = false
}
pub fn (p mut Instance) is_equivalent_to(flags []string) { pub fn (p mut Instance) is_equivalent_to(flags []string) {
for v in flags { for v in flags {
p.encountered[v] = true p.encountered[v] = true

View File

@ -15,13 +15,6 @@ pub:
element_size int element_size int
} }
/*
struct Foo {
a []string
b [][]string
}
*/
// Internal function, used by V (`nums := []int`) // Internal function, used by V (`nums := []int`)
fn new_array(mylen int, cap int, elm_size int) array { fn new_array(mylen int, cap int, elm_size int) array {
cap_ := if cap == 0 { 1 } else { cap } cap_ := if cap == 0 { 1 } else { cap }
@ -39,6 +32,13 @@ pub fn make(len int, cap int, elm_size int) array {
return new_array(len, cap, elm_size) return new_array(len, cap, elm_size)
} }
/*
struct Foo {
a []string
b [][]string
}
*/
// Private function, used by V (`nums := [1, 2, 3]`) // Private function, used by V (`nums := [1, 2, 3]`)
fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array { fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array {
cap_ := if cap == 0 { 1 } else { cap } cap_ := if cap == 0 { 1 } else { cap }

View File

@ -1,6 +1,6 @@
struct AA { struct AA {
mut: mut:
val int val int
nums []int nums []int
} }
@ -11,32 +11,31 @@ mut:
struct CC { struct CC {
mut: mut:
b BB b BB
nums []int nums []int
aarr []AA aarr []AA
num int num int
} }
struct User { struct User {
name string name string
age int age int
} }
struct Foo { struct Foo {
@type string @type string
} }
struct Empty { struct Empty {}
}
//We need to make sure that this compiles with all the reserved names. // We need to make sure that this compiles with all the reserved names.
struct ReservedKeywords { struct ReservedKeywords {
delete int delete int
exit int exit int
unix int unix int
error int error int
malloc int malloc int
calloc int calloc int
free int free int
panic int panic int
auto int auto int
@ -66,6 +65,7 @@ fn test_empty_struct() {
fn test_struct_levels() { fn test_struct_levels() {
mut c := CC{} mut c := CC{}
println(c.nums.len)
assert c.nums.len == 0 assert c.nums.len == 0
c.nums << 3 c.nums << 3
assert c.nums.len == 1 assert c.nums.len == 1
@ -80,41 +80,49 @@ fn test_struct_levels() {
assert c.b.a.nums.len == 2 assert c.b.a.nums.len == 2
assert c.b.a.nums[0] == 0 assert c.b.a.nums[0] == 0
assert c.b.a.nums[1] == 2 assert c.b.a.nums[1] == 2
c.b.a.nums [0] = 7 c.b.a.nums[0] = 7
assert c.b.a.nums[0] == 7 assert c.b.a.nums[0] == 7
c.aarr << AA{val:8} c.aarr << AA{
val: 8
}
assert c.aarr.len == 1 assert c.aarr.len == 1
assert c.aarr[0].val == 8 assert c.aarr[0].val == 8
c.num = 20 c.num = 20
assert c.num == 20 assert c.num == 20
c.aarr[0].val = 10 c.aarr[0].val = 10
assert c.aarr[0].val == 10 assert c.aarr[0].val == 10
} }
fn test_struct_str() { fn test_struct_str() {
u := User{'Bob', 30} u := User{
println(u) // make sure the struct is printable 'Bob',30}
println(u) // make sure the struct is printable
// assert u.str() == '{name:"Bob", age:30}' // TODO // assert u.str() == '{name:"Bob", age:30}' // TODO
} }
fn test_at() { fn test_at() {
foo := Foo{ @type: 'test' } foo := Foo{
@type: 'test'
}
println(foo.@type) println(foo.@type)
} }
fn test_reserved_keywords() { fn test_reserved_keywords() {
//Make sure we can initialize them correctly using full syntax. // Make sure we can initialize them correctly using full syntax.
rk_holder := ReservedKeywords{0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3} rk_holder := ReservedKeywords{
//Test a few as it'll take too long to test all. If it's initialized 0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3}
//correctly, other fields are also probably valid. // Test a few as it'll take too long to test all. If it's initialized
// correctly, other fields are also probably valid.
assert rk_holder.unix == 5 assert rk_holder.unix == 5
assert rk_holder.while == 3 assert rk_holder.while == 3
rk_holder2 := ReservedKeywords{
rk_holder2 := ReservedKeywords{inline: 9, volatile: 11} inline: 9
//Make sure partial initialization works too. volatile: 11
}
// Make sure partial initialization works too.
assert rk_holder2.inline == 9 assert rk_holder2.inline == 9
assert rk_holder2.volatile == 11 assert rk_holder2.volatile == 11
assert rk_holder2.while == 0 //Zero value as not specified. assert rk_holder2.while == 0 // Zero value as not specified.
} }
struct User2 { struct User2 {
@ -128,32 +136,43 @@ fn test_mutable_fields() {
assert u.name == 'Peter' assert u.name == 'Peter'
} }
struct Def { struct Def {
a int a int
b int = 7 b int=7
} }
fn test_default_vals() { fn test_default_vals() {
d := Def{} d := Def{}
assert d.a == 0 assert d.a == 0
assert d.b == 7 assert d.b == 7
d2 := Def{10, 20} d2 := Def{
10,20}
assert d2.a == 10 assert d2.a == 10
assert d2.b == 20 assert d2.b == 20
} }
fn test_assoc_with_vars() { fn test_assoc_with_vars() {
def2 := Def { a: 12 } def2 := Def{
merged := { def2 | a: 42 } a: 12
}
merged := {
def2 |
a:42
}
assert merged.a == 42 assert merged.a == 42
assert merged.b == 7 assert merged.b == 7
} }
const ( const (
const_def = Def { a: 100 } const_def = Def{
a: 100
}
) )
fn test_assoc_with_constants() { fn test_assoc_with_constants() {
println(1)
/*
QTODO
merged := { const_def | a: 42 } merged := { const_def | a: 42 }
assert merged.a == 42 assert merged.a == 42
assert merged.b == 7 assert merged.b == 7
@ -161,23 +180,26 @@ fn test_assoc_with_constants() {
again := { const_def | b: 22 } again := { const_def | b: 22 }
assert again.a == 100 assert again.a == 100
assert again.b == 22 assert again.b == 22
*/
} }
struct AttrTest{ struct AttrTest {
a int // private immutable (default) a int // private immutable (default)
mut: mut:
b int // private mutable b int // private mutable
c int // (you can list multiple fields with the same access modifier) c int // (you can list multiple fields with the same access modifier)
pub: pub:
d int // public immmutable (readonly) d int // public immmutable (readonly)
pub mut: pub mut:
e int // public, but mutable only in parent module e int // public, but mutable only in parent module
__global: __global:
f int // public and mutable both inside and outside parent module f int // public and mutable both inside and outside parent module
} }
fn fooo(){ fn fooo() {
a:=AttrTest{1,2,3,4,5,6} a := AttrTest{
1,2,3,4,5,6}
} }
/* /*
@ -205,21 +227,24 @@ fn test_fixed_field() {
struct Config { struct Config {
n int n int
def int = 10 def int=10
} }
fn foo_config(c Config) { fn foo_config(c Config) {}
}
fn foo2(u User) { fn foo2(u User) {}
}
fn test_config() { fn test_config() {
foo_config({n: 10, def: 20})
/*
foo_config({
n: 10
def: 20
})
foo_config({}) foo_config({})
foo2({name:'Peter'}) foo2({
name: 'Peter'
})
*/
} }

View File

@ -114,7 +114,6 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
p.next() p.next()
p.check(.gt) p.check(.gt)
} }
// println('fn decl $name')
// Args // Args
args2,is_variadic := p.fn_args() args2,is_variadic := p.fn_args()
args << args2 args << args2
@ -258,3 +257,7 @@ fn (p mut Parser) fn_args() ([]table.Arg,bool) {
p.check(.rpar) p.check(.rpar)
return args,is_variadic return args,is_variadic
} }
fn (p &Parser) fileis(s string) bool {
return p.file_name.contains(s)
}

View File

@ -161,6 +161,7 @@ pub fn parse_files(paths []string, table &table.Table) []ast.File {
// /////////////// // ///////////////
mut files := []ast.File mut files := []ast.File
for path in paths { for path in paths {
// println('parse_files $path')
files << parse_file(path, table, .skip_comments) files << parse_file(path, table, .skip_comments)
} }
return files return files
@ -1483,6 +1484,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
p.next() // . p.next() // .
} }
mut name := p.check_name() mut name := p.check_name()
// println('struct decl $name')
p.check(.lcbr) p.check(.lcbr)
mut ast_fields := []ast.Field mut ast_fields := []ast.Field
mut fields := []table.Field mut fields := []table.Field
@ -1506,6 +1508,10 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
p.check(.colon) p.check(.colon)
mut_pos = fields.len mut_pos = fields.len
} }
else if p.tok.kind == .key_global {
p.check(.key_global)
p.check(.colon)
}
field_name := p.check_name() field_name := p.check_name()
// p.warn('field $field_name') // p.warn('field $field_name')
typ := p.parse_type() typ := p.parse_type()