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 | pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | CompFor | CompIf |
ConstDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | ConstDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt |
GlobalDecl | GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | GlobalDecl | GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module |
Return | SqlStmt | StructDecl | TypeDecl | UnsafeStmt Return | SqlStmt | StructDecl | TypeDecl
pub type ScopeObject = ConstField | GlobalDecl | Var pub type ScopeObject = ConstField | GlobalDecl | Var
@ -33,9 +33,11 @@ pub:
pos token.Position pos token.Position
} }
// `{stmts}` or `unsafe {stmts}`
pub struct Block { pub struct Block {
pub: pub:
stmts []Stmt stmts []Stmt
is_unsafe bool
} }
// | IncDecStmt k // | IncDecStmt k
@ -719,11 +721,6 @@ pub mut:
ifdef string ifdef string
} }
pub struct UnsafeStmt {
pub:
stmts []Stmt
}
// `(3+4)` // `(3+4)`
pub struct ParExpr { pub struct ParExpr {
pub: pub:
@ -1104,8 +1101,6 @@ pub fn (stmt Stmt) position() token.Position {
/* /*
// TypeDecl { // TypeDecl {
// } // }
// UnsafeStmt {
// }
*/ */
// //
else { return token.Position{} } else { return token.Position{} }

View File

@ -1940,7 +1940,14 @@ fn (mut c Checker) stmt(node ast.Stmt) {
} }
ast.Attr {} ast.Attr {}
ast.Block { ast.Block {
if node.is_unsafe {
assert !c.inside_unsafe
c.inside_unsafe = true
c.stmts(node.stmts) c.stmts(node.stmts)
c.inside_unsafe = false
} else {
c.stmts(node.stmts)
}
} }
ast.BranchStmt { ast.BranchStmt {
if c.in_for_count == 0 { if c.in_for_count == 0 {
@ -2141,12 +2148,6 @@ fn (mut c Checker) stmt(node ast.Stmt) {
ast.TypeDecl { ast.TypeDecl {
c.type_decl(node) 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 { if stmts.filter(it is ast.Return).len > 0 {
return true return true
} }
mut has_unsafe_return := false for stmt in stmts {
for _, stmt in stmts { if stmt is ast.Block {
if stmt is ast.UnsafeStmt { if has_top_return(stmt.stmts) {
for ustmt in stmt.stmts {
if ustmt is ast.Return {
has_unsafe_return = true
}
}
}
}
if has_unsafe_return {
return true return true
} }
}
}
exprs := stmts.filter(it is ast.ExprStmt).map(it as ast.ExprStmt) exprs := stmts.filter(it is ast.ExprStmt).map(it as ast.ExprStmt)
has_panic_exit := exprs.filter(it.expr is has_panic_exit := exprs.filter(it.expr is
ast.CallExpr).map(it.expr as ast.CallExpr).filter(it.name == 'panic' || 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 { ast.Block {
if node.is_unsafe {
f.write('unsafe ')
}
f.writeln('{') f.writeln('{')
f.stmts(node.stmts) f.stmts(node.stmts)
f.writeln('}') f.writeln('}')
@ -512,11 +515,6 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
// already handled in f.imports // already handled in f.imports
f.type_decl(it) 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]') g.writeln('// Attr: [$node.name]')
} }
ast.Block { ast.Block {
if node.is_unsafe {
g.writeln('{ // Unsafe block')
} else {
g.writeln('{') g.writeln('{')
}
g.stmts(node.stmts) g.stmts(node.stmts)
g.writeln('}') g.writeln('}')
} }
@ -880,11 +884,6 @@ fn (mut g Gen) stmt(node ast.Stmt) {
ast.TypeDecl { ast.TypeDecl {
g.writeln('// 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) 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 { ast.TypeDecl {
// skip JS has no 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 { ast.AssignStmt {
g.assign_stmt(node) g.assign_stmt(node)
} }
ast.Block {
g.stmts(node.stmts)
}
ast.ConstDecl {} ast.ConstDecl {}
ast.ExprStmt { ast.ExprStmt {
g.expr(node.expr) g.expr(node.expr)
@ -632,9 +635,6 @@ fn (mut g Gen) stmt(node ast.Stmt) {
g.ret() g.ret()
} }
ast.StructDecl {} ast.StructDecl {}
ast.UnsafeStmt {
g.stmts(node.stmts)
}
else { else {
println('x64.stmt(): bad node: ' + typeof(node)) 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 { .key_unsafe {
if p.peek_tok.kind == .lcbr {
// unsafe {
p.next() p.next()
assert !p.inside_unsafe assert !p.inside_unsafe
p.inside_unsafe = true p.inside_unsafe = true
stmts := p.parse_block() stmts := p.parse_block()
p.inside_unsafe = false p.inside_unsafe = false
return ast.UnsafeStmt{ return ast.Block{
stmts: stmts 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 { .hash {