diff --git a/vlib/os/os.v b/vlib/os/os.v index 250bbee6d3..ec9d3fbe51 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -224,7 +224,7 @@ pub fn mv_by_cp(source string, target string) ?bool { return true } -fn vfopen(path, mode string) *C.FILE { +fn vfopen(path, mode string) &C.FILE { $if windows { return C._wfopen(path.to_wide(), mode.to_wide()) } $else { @@ -1016,9 +1016,9 @@ pub fn walk_ext(path, ext string) []string { return res } -// walk recursively traverse the given directory path. +// walk recursively traverses the given directory path. // When a file is encountred it will call the callback function with current file as argument. -pub fn walk(path string, fnc fn(path string)) { +pub fn walk(path string, f fn(path string)) { if !os.is_dir(path) { return } @@ -1028,10 +1028,10 @@ pub fn walk(path string, fnc fn(path string)) { for file in files { p := path + os.path_separator + file if os.is_dir(p) && !os.is_link(p) { - walk(p, fnc) + walk(p, f) } else if os.exists(p) { - fnc(p) + f(p) } } return @@ -1161,7 +1161,7 @@ pub const ( wd_at_startup = getwd() ) -// resource_abs_path returns an absolute path, for the given `path` +// resource_abs_path returns an absolute path, for the given `path` // (the path is expected to be relative to the executable program) // See https://discordapp.com/channels/592103645835821068/592294828432424960/630806741373943808 // It gives a convenient way to access program resources like images, fonts, sounds and so on, diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 4eece0e617..3c0799a44f 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -15,7 +15,7 @@ CastExpr | EnumVal pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | -HashStmt | AssignStmt | EnumDecl | TypeDecl +HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt // | IncDecStmt k // Stand-alone expression in a statement list. pub struct ExprStmt { @@ -385,6 +385,11 @@ pub: is_pub bool } +pub struct DeferStmt{ +pub: +stmts []Stmt +} + pub struct AssignExpr { pub: op token.Kind diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 594aee360a..a991cbfd37 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -244,6 +244,13 @@ pub fn (p mut Parser) stmt() ast.Stmt { p.parse_block() return ast.Stmt{} } + .key_defer { + p.next() + stmts := p.parse_block() + return ast.DeferStmt{ + stmts: stmts + } + } else { // `x := ...` // if p.tok.kind == .name && p.peek_tok.kind in [.decl_assign, .comma] { @@ -359,7 +366,7 @@ pub fn (p &Parser) error(s string) { if path.starts_with(workdir) { path = path.replace(workdir, '') } - final_msg_line := 'xxx$path:$p.tok.line_nr: error: $s' + final_msg_line := '$path:$p.tok.line_nr: error: $s' if colored_output { eprintln(term.bold(term.red(final_msg_line))) } @@ -476,7 +483,8 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) { name := p.tok.lit // type cast. TODO: finish // if name in table.builtin_type_names { - if name in p.table.type_idxs { + if name in p.table.type_idxs && !(name in ['stat', 'sigaction']) { + // TODO handle C.stat() to_typ := p.parse_type() p.check(.lpar) mut expr := ast.Expr{} @@ -914,7 +922,16 @@ fn (p mut Parser) if_expr() (ast.Expr,table.Type) { // } mut node := ast.Expr{} p.check(.key_if) - cond,_ := p.expr(0) + // `if x := opt() {` + mut cond := ast.Expr{} + if p.peek_tok.kind == .decl_assign { + p.next() + p.check(.decl_assign) + p.expr(0) + } + else { + cond,_ = p.expr(0) + } p.inside_if = false stmts := p.parse_block() mut else_stmts := []ast.Stmt @@ -974,6 +991,13 @@ fn (p mut Parser) string_expr() (ast.Expr,table.Type) { if p.tok.kind == .colon { p.next() } + // ${num:2d} + if p.tok.kind == .number { + p.next() + if p.tok.lit.len == 1 { + p.next() + } + } } return node,table.string_type } @@ -1341,8 +1365,14 @@ fn (p mut Parser) match_expr() (ast.Expr,table.Type) { } else { // Expression match - match_expr,_ := p.expr(0) - match_exprs << match_expr + for { + match_expr,_ := p.expr(0) + match_exprs << match_expr + if p.tok.kind != .comma { + break + } + p.check(.comma) + } } p.warn('match block') stmts := p.parse_block() @@ -1421,6 +1451,9 @@ fn (p mut Parser) type_decl() ast.TypeDecl { p.check(.pipe) } } + else { + p.check_name() + } return ast.TypeDecl{ name: name }