ast: use Block instead of UnsafeStmt (#5981)

pull/6039/head
Nick Treleaven 2020-08-02 12:06:44 +01:00 committed by GitHub
parent cc57b52773
commit 7f447bb82f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 49 deletions

View File

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

View File

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

View File

@ -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('}')
}
}
}

View File

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

View File

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

View File

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

View File

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