v2: defer; match a,b; if x :=

pull/3721/head
Alexander Medvednikov 2020-02-11 10:26:46 +01:00
parent f7b80c3c62
commit 9610821884
3 changed files with 50 additions and 12 deletions

View File

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

View File

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

View File

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