From 7f447bb82f92b98619fe2c351ea27a6ad56ebfaa Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Sun, 2 Aug 2020 12:06:44 +0100 Subject: [PATCH] ast: use Block instead of UnsafeStmt (#5981) --- vlib/v/ast/ast.v | 11 +++-------- vlib/v/checker/checker.v | 29 ++++++++++++----------------- vlib/v/fmt/fmt.v | 8 +++----- vlib/v/gen/cgen.v | 11 +++++------ vlib/v/gen/js/js.v | 3 --- vlib/v/gen/x64/gen.v | 6 +++--- vlib/v/parser/parser.v | 27 ++++++++++++++++++++------- 7 files changed, 46 insertions(+), 49 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index d7e604a88e..654c929978 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -18,7 +18,7 @@ pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CallExpr | C pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | CompFor | CompIf | ConstDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | - Return | SqlStmt | StructDecl | TypeDecl | UnsafeStmt + Return | SqlStmt | StructDecl | TypeDecl pub type ScopeObject = ConstField | GlobalDecl | Var @@ -33,9 +33,11 @@ pub: pos token.Position } +// `{stmts}` or `unsafe {stmts}` pub struct Block { pub: stmts []Stmt + is_unsafe bool } // | IncDecStmt k @@ -719,11 +721,6 @@ pub mut: ifdef string } -pub struct UnsafeStmt { -pub: - stmts []Stmt -} - // `(3+4)` pub struct ParExpr { pub: @@ -1104,8 +1101,6 @@ pub fn (stmt Stmt) position() token.Position { /* // TypeDecl { // } - // UnsafeStmt { - // } */ // else { return token.Position{} } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index db7ff3d498..bdcdf79d5f 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1940,7 +1940,14 @@ fn (mut c Checker) stmt(node ast.Stmt) { } ast.Attr {} ast.Block { - c.stmts(node.stmts) + if node.is_unsafe { + assert !c.inside_unsafe + c.inside_unsafe = true + c.stmts(node.stmts) + c.inside_unsafe = false + } else { + c.stmts(node.stmts) + } } ast.BranchStmt { if c.in_for_count == 0 { @@ -2141,12 +2148,6 @@ fn (mut c Checker) stmt(node ast.Stmt) { ast.TypeDecl { c.type_decl(node) } - ast.UnsafeStmt { - assert !c.inside_unsafe - c.inside_unsafe = true - c.stmts(node.stmts) - c.inside_unsafe = false - } } } @@ -3399,19 +3400,13 @@ fn has_top_return(stmts []ast.Stmt) bool { if stmts.filter(it is ast.Return).len > 0 { return true } - mut has_unsafe_return := false - for _, stmt in stmts { - if stmt is ast.UnsafeStmt { - for ustmt in stmt.stmts { - if ustmt is ast.Return { - has_unsafe_return = true - } + for stmt in stmts { + if stmt is ast.Block { + if has_top_return(stmt.stmts) { + return true } } } - if has_unsafe_return { - return true - } exprs := stmts.filter(it is ast.ExprStmt).map(it as ast.ExprStmt) has_panic_exit := exprs.filter(it.expr is ast.CallExpr).map(it.expr as ast.CallExpr).filter(it.name == 'panic' || diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 048b2d780b..a2456b0573 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -294,6 +294,9 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) { } } ast.Block { + if node.is_unsafe { + f.write('unsafe ') + } f.writeln('{') f.stmts(node.stmts) f.writeln('}') @@ -512,11 +515,6 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) { // already handled in f.imports f.type_decl(it) } - ast.UnsafeStmt { - f.writeln('unsafe {') - f.stmts(it.stmts) - f.writeln('}') - } } } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index ab5f58777f..c327627b9f 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -677,7 +677,11 @@ fn (mut g Gen) stmt(node ast.Stmt) { g.writeln('// Attr: [$node.name]') } ast.Block { - g.writeln('{') + if node.is_unsafe { + g.writeln('{ // Unsafe block') + } else { + g.writeln('{') + } g.stmts(node.stmts) g.writeln('}') } @@ -880,11 +884,6 @@ fn (mut g Gen) stmt(node ast.Stmt) { ast.TypeDecl { g.writeln('// TypeDecl') } - ast.UnsafeStmt { - g.writeln('{ // Unsafe block') - g.stmts(node.stmts) - g.writeln('}') - } } g.stmt_path_pos.delete(g.stmt_path_pos.len - 1) } diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 1a75273c53..fa59ec4990 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -506,9 +506,6 @@ fn (mut g JsGen) stmt(node ast.Stmt) { ast.TypeDecl { // skip JS has no typedecl } - ast.UnsafeStmt { - g.stmts(node.stmts) - } } } diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index b428e7402a..5301b2c179 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -604,6 +604,9 @@ fn (mut g Gen) stmt(node ast.Stmt) { ast.AssignStmt { g.assign_stmt(node) } + ast.Block { + g.stmts(node.stmts) + } ast.ConstDecl {} ast.ExprStmt { g.expr(node.expr) @@ -632,9 +635,6 @@ fn (mut g Gen) stmt(node ast.Stmt) { g.ret() } ast.StructDecl {} - ast.UnsafeStmt { - g.stmts(node.stmts) - } else { println('x64.stmt(): bad node: ' + typeof(node)) } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 95f187d5b3..dd926fce0e 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -602,13 +602,26 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt { } } .key_unsafe { - p.next() - assert !p.inside_unsafe - p.inside_unsafe = true - stmts := p.parse_block() - p.inside_unsafe = false - return ast.UnsafeStmt{ - stmts: stmts + if p.peek_tok.kind == .lcbr { + // unsafe { + p.next() + assert !p.inside_unsafe + p.inside_unsafe = true + stmts := p.parse_block() + p.inside_unsafe = false + return ast.Block{ + stmts: stmts + is_unsafe: true + } + } else { + p.error_with_pos('please use `unsafe {`', p.tok.position()) + } + // unsafe( ; NB: this will be never reached + pos := p.tok.position() + ex := p.expr(0) + return ast.ExprStmt{ + expr: ex + pos: pos } } .hash {