v2: minor fixes
parent
883a105aca
commit
db59c621e8
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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'
|
||||||
|
})
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue