Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ast, parser: implement simple AST poisoning #9525

Merged
merged 21 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ac05427
v.ast: add callarg node support
nedpals Mar 20, 2021
88b3beb
v.ast: add name_pos to callexpr
nedpals Mar 20, 2021
2b6c7f3
Merge branch 'master' of https://github.com/vlang/v into vls-gotodefi…
nedpals Mar 20, 2021
f7228aa
Merge branch 'master' of https://github.com/vlang/v into vls-gotodefi…
nedpals Mar 21, 2021
fa31827
scanner: fix eof token output
nedpals Mar 23, 2021
f887894
v/parser/tests: fix fn_decl_unexpected_eof.out
nedpals Mar 23, 2021
e42e2cc
Merge branch 'master' of https://github.com/vlang/v into vls-gotodefi…
nedpals Mar 23, 2021
2b7eb05
Merge branch 'scanner-fix-eof-token' into vls-gotodefinition-patches
nedpals Mar 23, 2021
0f00a08
v/parser: add name_pos to struct_init
nedpals Mar 24, 2021
15ec2a3
Merge branch 'master' of https://github.com/vlang/v into vls-gotodefi…
nedpals Mar 25, 2021
7f9cc76
parser, ast: add name_pos for struct_init_field
nedpals Mar 29, 2021
231ed4d
Merge branch 'master' of https://github.com/vlang/v into vls-gotodefi…
nedpals Mar 29, 2021
830f8b0
wip: struct decl fixes
nedpals Mar 29, 2021
9e26cc3
parser: rewind tokens when encountering a missing type error
nedpals Mar 30, 2021
8a38160
ast: add simple ast poisoning
nedpals Mar 30, 2021
5ada284
ast: add simple ast poisoning
nedpals Mar 30, 2021
354462c
Merge commit '8a381609dc5a8332b342e7d9e63a1f9be13fd527' into simple-a…
nedpals Mar 30, 2021
f13c609
cleanup unrelated changes
nedpals Mar 30, 2021
7fd61a6
Merge commit '5ada28483b90dbf5cdbc9ada61ffeea1000ee29e' into simple-a…
nedpals Mar 30, 2021
5dec20c
ast: remove leftover CallArg from other commits
nedpals Mar 30, 2021
6a1a9cc
cgen, jsgen, markused: add NodeError branch
nedpals Mar 30, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 18 additions & 12 deletions vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ pub type Expr = AnonFn | ArrayDecompose | ArrayInit | AsCast | Assoc | AtExpr |
CTempVar | CallExpr | CastExpr | ChanInit | CharLiteral | Comment | ComptimeCall |
ComptimeSelector | ConcatExpr | DumpExpr | EnumVal | FloatLiteral | GoExpr | Ident |
IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
MapInit | MatchExpr | None | OffsetOf | OrExpr | ParExpr | PostfixExpr | PrefixExpr |
RangeExpr | SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral |
StructInit | Type | TypeOf | UnsafeExpr
MapInit | MatchExpr | NodeError | None | OffsetOf | OrExpr | ParExpr | PostfixExpr |
PrefixExpr | RangeExpr | SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral |
StringLiteral | StructInit | Type | TypeOf | UnsafeExpr

pub type Stmt = AsmStmt | AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl |
DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl |
GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return |
SqlStmt | StructDecl | TypeDecl
GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | NodeError |
Return | SqlStmt | StructDecl | TypeDecl

// NB: when you add a new Expr or Stmt type with a .pos field, remember to update
// the .position() token.Position methods too.
Expand Down Expand Up @@ -1083,7 +1083,7 @@ pub:
pub struct AsmAddressing {
pub:
displacement u32 // 8, 16 or 32 bit literal value
scale int = -1 // 1, 2, 4, or 8 literal
scale int = -1 // 1, 2, 4, or 8 literal
mode AddressingMode
pos token.Position
pub mut:
Expand Down Expand Up @@ -1408,6 +1408,12 @@ pub mut:
sub_structs map[int]SqlExpr
}

pub struct NodeError {
pub:
idx int // index for referencing the related ast.File error
pos token.Position
}

[inline]
pub fn (expr Expr) is_blank_ident() bool {
match expr {
Expand All @@ -1422,12 +1428,12 @@ pub fn (expr Expr) position() token.Position {
AnonFn {
return expr.decl.pos
}
ArrayDecompose, ArrayInit, AsCast, Assoc, AtExpr, BoolLiteral, CallExpr, CastExpr, ChanInit,
CharLiteral, ConcatExpr, Comment, ComptimeCall, ComptimeSelector, EnumVal, DumpExpr, FloatLiteral,
GoExpr, Ident, IfExpr, IndexExpr, IntegerLiteral, Likely, LockExpr, MapInit, MatchExpr,
None, OffsetOf, OrExpr, ParExpr, PostfixExpr, PrefixExpr, RangeExpr, SelectExpr, SelectorExpr,
SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, Type, TypeOf, UnsafeExpr
{
NodeError, ArrayDecompose, ArrayInit, AsCast, Assoc, AtExpr, BoolLiteral, CallExpr, CastExpr,
ChanInit, CharLiteral, ConcatExpr, Comment, ComptimeCall, ComptimeSelector, EnumVal, DumpExpr,
FloatLiteral, GoExpr, Ident, IfExpr, IndexExpr, IntegerLiteral, Likely, LockExpr, MapInit,
MatchExpr, None, OffsetOf, OrExpr, ParExpr, PostfixExpr, PrefixExpr, RangeExpr, SelectExpr,
SelectorExpr, SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, Type, TypeOf,
UnsafeExpr {
return expr.pos
}
IfGuardExpr {
Expand Down
2 changes: 2 additions & 0 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -3322,6 +3322,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
}
// c.expected_type = table.void_type
match mut node {
ast.NodeError {}
ast.AsmStmt {
c.asm_stmt(mut node)
}
Expand Down Expand Up @@ -3948,6 +3949,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
return table.void_type
}
match mut node {
ast.NodeError {}
ast.CTempVar {
return node.typ
}
Expand Down
2 changes: 2 additions & 0 deletions vlib/v/fmt/fmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
eprintln('stmt: ${node.pos:-42} | node: ${node.type_name():-20}')
}
match node {
ast.NodeError {}
ast.AsmStmt {
f.asm_stmt(node)
}
Expand Down Expand Up @@ -480,6 +481,7 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
eprintln('expr: ${node.position():-42} | node: ${node.type_name():-20} | $node.str()')
}
match mut node {
ast.NodeError {}
ast.AnonFn {
f.fn_decl(node.decl)
}
Expand Down
2 changes: 2 additions & 0 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
// g.cur_mod = node.name
g.cur_mod = node
}
ast.NodeError {}
ast.Return {
g.write_defer_stmts_when_needed()
// af := g.autofree && node.exprs.len > 0 && node.exprs[0] is ast.CallExpr && !g.is_builtin_mod
Expand Down Expand Up @@ -3013,6 +3014,7 @@ fn (mut g Gen) expr(node ast.Expr) {
ast.MapInit {
g.map_init(node)
}
ast.NodeError {}
ast.None {
g.write('_const_none__')
}
Expand Down
4 changes: 3 additions & 1 deletion vlib/v/gen/js/js.v
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
ast.Module {
// skip: namespacing implemented externally
}
ast.NodeError {}
ast.Return {
if g.defer_stmts.len > 0 {
g.gen_defer_stmts()
Expand All @@ -445,6 +446,7 @@ fn (mut g JsGen) stmt(node ast.Stmt) {

fn (mut g JsGen) expr(node ast.Expr) {
match node {
ast.NodeError {}
ast.CTempVar {
g.write('/* ast.CTempVar: node.name */')
}
Expand Down Expand Up @@ -693,7 +695,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) {
} else {
g.write(' $op ')
// TODO: Multiple types??
should_cast :=
should_cast :=
(g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables)
&& (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last())

Expand Down
2 changes: 2 additions & 0 deletions vlib/v/markused/walker.v
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ pub fn (mut w Walker) stmt(node ast.Stmt) {
ast.InterfaceDecl {}
ast.Module {}
ast.TypeDecl {}
ast.NodeError {}
}
}

Expand Down Expand Up @@ -335,6 +336,7 @@ fn (mut w Walker) expr(node ast.Expr) {
ast.UnsafeExpr {
w.expr(node.expr)
}
ast.NodeError {}
}
}

Expand Down
19 changes: 7 additions & 12 deletions vlib/v/parser/assign.v
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,16 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
// a, b := a + 1, b
for r in right {
p.check_undefined_variables(left, r) or {
p.error('check_undefined_variables failed')
return ast.Stmt{}
return p.error('check_undefined_variables failed')
}
}
} else if left.len > 1 {
// a, b = b, a
for r in right {
has_cross_var = p.check_cross_variables(left, r)
if op !in [.assign, .decl_assign] {
p.error_with_pos('unexpected $op.str(), expecting := or = or comma', pos)
return ast.Stmt{}
return p.error_with_pos('unexpected $op.str(), expecting := or = or comma',
pos)
}
if has_cross_var {
break
Expand All @@ -133,18 +132,16 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
ast.Ident {
if op == .decl_assign {
if p.scope.known_var(lx.name) {
p.error_with_pos('redefinition of `$lx.name`', lx.pos)
return ast.Stmt{}
return p.error_with_pos('redefinition of `$lx.name`', lx.pos)
}
mut share := table.ShareType(0)
if lx.info is ast.IdentVar {
iv := lx.info as ast.IdentVar
share = iv.share
if iv.is_static {
if !p.pref.translated && !p.pref.is_fmt && !p.inside_unsafe_fn {
p.error_with_pos('static variables are supported only in -translated mode or in [unsafe] fn',
return p.error_with_pos('static variables are supported only in -translated mode or in [unsafe] fn',
lx.pos)
return ast.Stmt{}
}
is_static = true
}
Expand Down Expand Up @@ -175,19 +172,17 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
}
ast.IndexExpr {
if op == .decl_assign {
p.error_with_pos('non-name `$lx.left[$lx.index]` on left side of `:=`',
return p.error_with_pos('non-name `$lx.left[$lx.index]` on left side of `:=`',
lx.pos)
return ast.Stmt{}
}
lx.is_setter = true
}
ast.ParExpr {}
ast.PrefixExpr {}
ast.SelectorExpr {
if op == .decl_assign {
p.error_with_pos('struct fields can only be declared during the initialization',
return p.error_with_pos('struct fields can only be declared during the initialization',
lx.pos)
return ast.Stmt{}
}
}
else {
Expand Down
29 changes: 11 additions & 18 deletions vlib/v/parser/for.v
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
p.open_scope()
p.inside_for = true
if p.tok.kind == .key_match {
p.error('cannot use `match` in `for` loop')
return ast.Stmt{}
return p.error('cannot use `match` in `for` loop')
}
// defer { p.close_scope() }
// Infinite loop
Expand All @@ -34,8 +33,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
&& p.peek_token(2).kind != .key_mut && p.peek_token(3).kind != .key_in) {
// `for i := 0; i < 10; i++ {` or `for a,b := 0,1; a < 10; a++ {`
if p.tok.kind == .key_mut {
p.error('`mut` is not needed in `for ;;` loops: use `for i := 0; i < n; i ++ {`')
return ast.Stmt{}
return p.error('`mut` is not needed in `for ;;` loops: use `for i := 0; i < n; i ++ {`')
}
mut init := ast.Stmt{}
mut cond := p.new_true_expr()
Expand All @@ -55,8 +53,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
if p.tok.kind != .semicolon {
// Disallow `for i := 0; i++; i < ...`
if p.tok.kind == .name && p.peek_tok.kind in [.inc, .dec] {
p.error('cannot use $p.tok.lit$p.peek_tok.kind as value')
return ast.Stmt{}
return p.error('cannot use $p.tok.lit$p.peek_tok.kind as value')
}
cond = p.expr(0)
has_cond = true
Expand Down Expand Up @@ -112,16 +109,14 @@ fn (mut p Parser) for_stmt() ast.Stmt {
val_var_pos = p.tok.position()
val_var_name = p.check_name()
if key_var_name == val_var_name && key_var_name != '_' {
p.error_with_pos('key and value in a for loop cannot be the same', val_var_pos)
return ast.Stmt{}
return p.error_with_pos('key and value in a for loop cannot be the same',
val_var_pos)
}
if p.scope.known_var(key_var_name) {
p.error('redefinition of key iteration variable `$key_var_name`')
return ast.Stmt{}
return p.error('redefinition of key iteration variable `$key_var_name`')
}
if p.scope.known_var(val_var_name) {
p.error('redefinition of value iteration variable `$val_var_name`')
return ast.Stmt{}
return p.error('redefinition of value iteration variable `$val_var_name`')
}
p.scope.register(ast.Var{
name: key_var_name
Expand All @@ -130,13 +125,11 @@ fn (mut p Parser) for_stmt() ast.Stmt {
is_tmp: true
})
} else if p.scope.known_var(val_var_name) {
p.error('redefinition of value iteration variable `$val_var_name`')
return ast.Stmt{}
return p.error('redefinition of value iteration variable `$val_var_name`')
}
p.check(.key_in)
if p.tok.kind == .name && p.tok.lit in [key_var_name, val_var_name] {
p.error('in a `for x in array` loop, the key or value iteration variable `$p.tok.lit` can not be the same as the array variable')
return ast.Stmt{}
return p.error('in a `for x in array` loop, the key or value iteration variable `$p.tok.lit` can not be the same as the array variable')
}
// arr_expr
cond := p.expr(0)
Expand All @@ -156,8 +149,8 @@ fn (mut p Parser) for_stmt() ast.Stmt {
is_tmp: true
})
if key_var_name.len > 0 {
p.error_with_pos('cannot declare index variable with range `for`', key_var_pos)
return ast.Stmt{}
return p.error_with_pos('cannot declare index variable with range `for`',
key_var_pos)
}
} else {
// this type will be set in checker
Expand Down
Loading