From ee0a0afb25c23a7ece65ce3cfe389a24eedae220 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sat, 29 Feb 2020 17:03:32 +0300 Subject: [PATCH] v2: process `or` block for `CallExpr` --- vlib/v/ast/ast.v | 13 +++++++------ vlib/v/fmt/fmt.v | 14 +++++++++++--- vlib/v/fmt/tests/simple_expected.vv | 14 ++++++++++++++ vlib/v/fmt/tests/simple_input.vv | 14 ++++++++++++++ vlib/v/parser/fn.v | 12 ++++++++---- 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index a3fd1d5658..6bd502f04d 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -8,14 +8,14 @@ import ( v.table ) -pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | -FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | -AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | +pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | +FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | +AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr -pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | -ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | -HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | +pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | +ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | +HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | LineComment | MultiLineComment | AssertStmt | UnsafeStmt pub type Type = StructType | ArrayType @@ -154,6 +154,7 @@ mut: args []Expr is_c bool muts []bool + or_block OrExpr } pub struct MethodCallExpr { diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index e8aeeebadf..f4d5724c3a 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -324,16 +324,24 @@ fn (f mut Fmt) expr(node ast.Expr) { } ast.CallExpr { f.write('${it.name}(') - for i, expr in it.args { + for i, arg in it.args { if it.muts[i] { f.write('mut ') } - f.expr(expr) - if i != it.args.len - 1 { + if i > 0 { + f.wrap_long_line() + } + f.expr(arg) + if i < it.args.len - 1 { f.write(', ') } } f.write(')') + if it.or_block.stmts.len > 0 { + f.writeln(' or {') + f.stmts(it.or_block.stmts) + f.write('}') + } } ast.CharLiteral { f.write('`$it.val`') diff --git a/vlib/v/fmt/tests/simple_expected.vv b/vlib/v/fmt/tests/simple_expected.vv index c7ad7c5d08..3ec758809a 100644 --- a/vlib/v/fmt/tests/simple_expected.vv +++ b/vlib/v/fmt/tests/simple_expected.vv @@ -138,3 +138,17 @@ fn unsafe_fn() { malloc(2) } } + +fn fn_with_or() int { + fn_with_optional() or { + return 10 + } + return 20 +} + +fn (f Foo) method_with_or() int { + f.fn_with_optional() or { + return 10 + } + return 20 +} diff --git a/vlib/v/fmt/tests/simple_input.vv b/vlib/v/fmt/tests/simple_input.vv index a5c00a7b1e..92b8fdeec0 100644 --- a/vlib/v/fmt/tests/simple_input.vv +++ b/vlib/v/fmt/tests/simple_input.vv @@ -138,3 +138,17 @@ fn fn_with_multi_return() (int,string) { fn unsafe_fn() { unsafe { malloc(2) } } + +fn fn_with_or() int { + fn_with_optional() or { + return 10 + } + return 20 +} + +fn (f Foo) method_with_or() int { + f.fn_with_optional() or { + return 10 + } + return 20 +} diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 8e76510b5d..20f865c1f1 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -14,6 +14,11 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr { fn_name := if is_c {'C.$name' } else if mod.len > 0 { '${mod}.$name' } else { name } p.check(.lpar) args, muts := p.call_args() + mut or_stmts := []ast.Stmt + if p.tok.kind == .key_orelse { + p.next() + or_stmts = p.parse_block() + } node := ast.CallExpr{ name: fn_name args: args @@ -22,10 +27,9 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr { pos: tok.position() is_c: is_c - } - if p.tok.kind == .key_orelse { - p.next() - p.parse_block() + or_block: ast.OrExpr{ + stmts: or_stmts + } } return node }