2020-01-23 23:04:46 +03:00
|
|
|
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
2019-12-22 04:34:37 +03:00
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
module ast
|
|
|
|
|
2020-04-19 01:07:57 +03:00
|
|
|
import v.token
|
|
|
|
import v.table
|
2020-05-10 12:26:57 +03:00
|
|
|
import v.errors
|
2019-12-22 04:34:37 +03:00
|
|
|
|
2020-11-25 14:09:40 +03:00
|
|
|
pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
|
2020-03-07 19:37:55 +03:00
|
|
|
|
2020-12-29 18:14:08 +03:00
|
|
|
pub type Expr = AnonFn | ArrayDecompose | ArrayInit | AsCast | Assoc | AtExpr | BoolLiteral |
|
2021-01-05 17:11:43 +03:00
|
|
|
CTempVar | CallExpr | CastExpr | ChanInit | CharLiteral | Comment | ComptimeCall | ComptimeSelector |
|
2021-01-15 15:45:26 +03:00
|
|
|
ConcatExpr | EnumVal | FloatLiteral | GoExpr | Ident | IfExpr | IfGuardExpr | IndexExpr |
|
|
|
|
InfixExpr | IntegerLiteral | Likely | LockExpr | MapInit | MatchExpr | None | OrExpr |
|
|
|
|
ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectExpr | SelectorExpr | SizeOf |
|
|
|
|
SqlExpr | StringInterLiteral | StringLiteral | StructInit | Type | TypeOf | UnsafeExpr
|
2020-05-18 19:08:28 +03:00
|
|
|
|
2020-11-25 14:09:40 +03:00
|
|
|
pub type Stmt = 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
|
2020-04-04 06:14:40 +03:00
|
|
|
|
2020-11-04 14:34:12 +03:00
|
|
|
// NB: when you add a new Expr or Stmt type with a .pos field, remember to update
|
|
|
|
// the .position() token.Position methods too.
|
2020-11-25 14:09:40 +03:00
|
|
|
pub type ScopeObject = ConstField | GlobalField | Var
|
2020-04-04 06:14:40 +03:00
|
|
|
|
2021-01-09 07:36:38 +03:00
|
|
|
// TOOD: replace table.Param
|
|
|
|
pub type Node = ConstField | EnumField | Expr | Field | File | GlobalField | IfBranch |
|
|
|
|
MatchBranch | ScopeObject | SelectBranch | Stmt | StructField | StructInitField | table.Param
|
|
|
|
|
2020-03-03 17:06:21 +03:00
|
|
|
pub struct Type {
|
2020-03-02 12:53:38 +03:00
|
|
|
pub:
|
2020-03-04 17:48:43 +03:00
|
|
|
typ table.Type
|
2020-04-18 01:19:33 +03:00
|
|
|
pos token.Position
|
2020-03-02 12:53:38 +03:00
|
|
|
}
|
|
|
|
|
2020-08-02 14:06:44 +03:00
|
|
|
// `{stmts}` or `unsafe {stmts}`
|
2020-03-24 17:44:17 +03:00
|
|
|
pub struct Block {
|
|
|
|
pub:
|
2020-08-04 21:10:22 +03:00
|
|
|
stmts []Stmt
|
2020-08-02 14:06:44 +03:00
|
|
|
is_unsafe bool
|
2020-09-30 17:06:22 +03:00
|
|
|
pos token.Position
|
2020-03-24 17:44:17 +03:00
|
|
|
}
|
|
|
|
|
2020-01-06 18:13:12 +03:00
|
|
|
// | IncDecStmt k
|
2019-12-28 16:11:05 +03:00
|
|
|
// Stand-alone expression in a statement list.
|
|
|
|
pub struct ExprStmt {
|
|
|
|
pub:
|
2020-07-17 20:13:22 +03:00
|
|
|
expr Expr
|
|
|
|
pos token.Position
|
|
|
|
comments []Comment
|
|
|
|
is_expr bool
|
2020-05-21 23:35:43 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
typ table.Type
|
2019-12-28 16:11:05 +03:00
|
|
|
}
|
2019-12-22 04:34:37 +03:00
|
|
|
|
2019-12-26 13:21:41 +03:00
|
|
|
pub struct IntegerLiteral {
|
2019-12-26 05:40:18 +03:00
|
|
|
pub:
|
2020-03-17 04:49:15 +03:00
|
|
|
val string
|
2020-04-10 01:09:34 +03:00
|
|
|
pos token.Position
|
2019-12-26 05:40:18 +03:00
|
|
|
}
|
2019-12-24 20:54:43 +03:00
|
|
|
|
2019-12-27 12:03:29 +03:00
|
|
|
pub struct FloatLiteral {
|
|
|
|
pub:
|
|
|
|
val string
|
2020-04-20 15:49:26 +03:00
|
|
|
pos token.Position
|
2019-12-27 12:03:29 +03:00
|
|
|
}
|
|
|
|
|
2019-12-24 20:54:43 +03:00
|
|
|
pub struct StringLiteral {
|
|
|
|
pub:
|
2020-05-19 18:12:47 +03:00
|
|
|
val string
|
|
|
|
is_raw bool
|
|
|
|
language table.Language
|
|
|
|
pos token.Position
|
2019-12-24 20:54:43 +03:00
|
|
|
}
|
2019-12-22 04:34:37 +03:00
|
|
|
|
2020-03-21 09:01:06 +03:00
|
|
|
// 'name: $name'
|
|
|
|
pub struct StringInterLiteral {
|
|
|
|
pub:
|
|
|
|
vals []string
|
|
|
|
exprs []Expr
|
2020-06-16 11:41:51 +03:00
|
|
|
fwidths []int
|
|
|
|
precisions []int
|
|
|
|
pluss []bool
|
|
|
|
fills []bool
|
|
|
|
fmt_poss []token.Position
|
2020-04-10 11:59:07 +03:00
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-03-21 09:01:06 +03:00
|
|
|
expr_types []table.Type
|
2020-06-16 11:41:51 +03:00
|
|
|
fmts []byte
|
|
|
|
need_fmts []bool // an explicit non-default fmt required, e.g. `x`
|
2020-03-21 09:01:06 +03:00
|
|
|
}
|
|
|
|
|
2020-02-04 11:54:15 +03:00
|
|
|
pub struct CharLiteral {
|
|
|
|
pub:
|
|
|
|
val string
|
2020-04-20 15:49:26 +03:00
|
|
|
pos token.Position
|
2020-02-04 11:54:15 +03:00
|
|
|
}
|
|
|
|
|
2019-12-29 10:51:55 +03:00
|
|
|
pub struct BoolLiteral {
|
|
|
|
pub:
|
|
|
|
val bool
|
2020-04-20 15:49:26 +03:00
|
|
|
pos token.Position
|
2019-12-29 10:51:55 +03:00
|
|
|
}
|
|
|
|
|
2020-01-02 22:09:15 +03:00
|
|
|
// `foo.bar`
|
|
|
|
pub struct SelectorExpr {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position
|
|
|
|
expr Expr // expr.field_name
|
|
|
|
field_name string
|
|
|
|
is_mut bool // is used for the case `if mut ident.selector is MyType {`, it indicates if the root ident is mutable
|
|
|
|
mut_pos token.Position
|
|
|
|
next_token token.Kind
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-12-23 21:12:49 +03:00
|
|
|
expr_type table.Type // type of `Foo` in `Foo.bar`
|
|
|
|
typ table.Type // type of the entire thing (`Foo.bar`)
|
|
|
|
name_type table.Type // T in `T.name` or typeof in `typeof(expr).name`
|
|
|
|
scope &Scope
|
|
|
|
from_embed_type table.Type // holds the type of the embed that the method is called from
|
2020-01-02 22:09:15 +03:00
|
|
|
}
|
|
|
|
|
2020-12-10 02:59:39 +03:00
|
|
|
// root_ident returns the origin ident where the selector started.
|
|
|
|
pub fn (e &SelectorExpr) root_ident() Ident {
|
|
|
|
mut root := e.expr
|
|
|
|
for root is SelectorExpr {
|
2021-01-07 23:35:32 +03:00
|
|
|
// TODO: remove this line
|
2020-12-10 02:59:39 +03:00
|
|
|
selector_expr := root as SelectorExpr
|
|
|
|
root = selector_expr.expr
|
|
|
|
}
|
|
|
|
return root as Ident
|
|
|
|
}
|
|
|
|
|
2019-12-28 13:02:06 +03:00
|
|
|
// module declaration
|
2019-12-28 11:15:32 +03:00
|
|
|
pub struct Module {
|
|
|
|
pub:
|
2020-04-19 01:07:57 +03:00
|
|
|
name string
|
2021-01-08 18:24:42 +03:00
|
|
|
attrs []table.Attr
|
2020-05-16 17:12:23 +03:00
|
|
|
pos token.Position
|
2021-01-09 07:36:38 +03:00
|
|
|
name_pos token.Position // `name` in import name
|
2020-04-10 23:32:52 +03:00
|
|
|
is_skipped bool // module main can be skipped in single file programs
|
2019-12-28 11:15:32 +03:00
|
|
|
}
|
|
|
|
|
2020-04-05 03:08:10 +03:00
|
|
|
pub struct StructField {
|
|
|
|
pub:
|
2020-04-12 13:35:54 +03:00
|
|
|
pos token.Position
|
2020-09-11 15:37:14 +03:00
|
|
|
type_pos token.Position
|
2020-06-23 19:01:56 +03:00
|
|
|
comments []Comment
|
2020-04-12 13:35:54 +03:00
|
|
|
default_expr Expr
|
|
|
|
has_default_expr bool
|
2020-08-04 21:10:22 +03:00
|
|
|
attrs []table.Attr
|
2020-05-18 19:06:09 +03:00
|
|
|
is_public bool
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
name string
|
|
|
|
typ table.Type
|
2020-04-05 03:08:10 +03:00
|
|
|
}
|
|
|
|
|
2019-12-30 08:16:59 +03:00
|
|
|
pub struct Field {
|
|
|
|
pub:
|
|
|
|
name string
|
2020-04-09 16:33:46 +03:00
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
typ table.Type
|
2020-02-03 09:02:54 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// const field in const declaration group
|
2020-04-04 06:14:40 +03:00
|
|
|
pub struct ConstField {
|
2020-02-03 09:02:54 +03:00
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
mod string
|
|
|
|
name string
|
|
|
|
expr Expr // the value expr of field; everything after `=`
|
|
|
|
is_pub bool
|
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-12-28 14:52:04 +03:00
|
|
|
typ table.Type // the type of the const field, it can be any type in V
|
2021-01-03 23:10:25 +03:00
|
|
|
comments []Comment // comments before current const field
|
2020-04-04 06:14:40 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// const declaration
|
2020-04-04 06:14:40 +03:00
|
|
|
pub struct ConstDecl {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
is_pub bool
|
|
|
|
pos token.Position
|
2020-04-27 23:53:26 +03:00
|
|
|
pub mut:
|
2020-12-28 14:52:04 +03:00
|
|
|
fields []ConstField // all the const fields in the `const (...)` block
|
2021-01-03 23:10:25 +03:00
|
|
|
end_comments []Comment // comments that after last const field
|
2020-12-30 04:15:44 +03:00
|
|
|
is_block bool // const() block
|
2019-12-30 08:16:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct StructDecl {
|
|
|
|
pub:
|
2020-06-23 19:01:56 +03:00
|
|
|
pos token.Position
|
|
|
|
name string
|
2020-11-11 18:48:42 +03:00
|
|
|
gen_types []table.Type
|
2020-06-23 19:01:56 +03:00
|
|
|
is_pub bool
|
|
|
|
mut_pos int // mut:
|
|
|
|
pub_pos int // pub:
|
|
|
|
pub_mut_pos int // pub mut:
|
|
|
|
language table.Language
|
|
|
|
is_union bool
|
2020-08-04 21:10:22 +03:00
|
|
|
attrs []table.Attr
|
2020-06-23 19:01:56 +03:00
|
|
|
end_comments []Comment
|
2020-12-23 21:12:49 +03:00
|
|
|
embeds []Embed
|
2020-10-30 09:09:26 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
fields []StructField
|
2020-10-30 09:09:26 +03:00
|
|
|
}
|
|
|
|
|
2020-12-23 21:12:49 +03:00
|
|
|
pub struct Embed {
|
|
|
|
pub:
|
|
|
|
typ table.Type
|
|
|
|
pos token.Position
|
|
|
|
}
|
|
|
|
|
2020-10-30 09:09:26 +03:00
|
|
|
pub struct StructEmbedding {
|
|
|
|
pub:
|
|
|
|
name string
|
|
|
|
typ table.Type
|
|
|
|
pos token.Position
|
2019-12-30 08:16:59 +03:00
|
|
|
}
|
|
|
|
|
2020-03-31 20:59:38 +03:00
|
|
|
pub struct InterfaceDecl {
|
2020-04-05 13:31:39 +03:00
|
|
|
pub:
|
2020-10-15 23:12:59 +03:00
|
|
|
name string
|
|
|
|
field_names []string
|
|
|
|
is_pub bool
|
|
|
|
methods []FnDecl
|
|
|
|
pos token.Position
|
2020-10-14 22:48:49 +03:00
|
|
|
pre_comments []Comment
|
2020-03-31 20:59:38 +03:00
|
|
|
}
|
|
|
|
|
2020-04-17 03:38:39 +03:00
|
|
|
pub struct StructInitField {
|
|
|
|
pub:
|
|
|
|
expr Expr
|
2020-04-19 01:07:57 +03:00
|
|
|
pos token.Position
|
2020-10-14 22:48:49 +03:00
|
|
|
comments []Comment
|
2020-12-09 12:11:22 +03:00
|
|
|
next_comments []Comment
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-04-27 23:53:26 +03:00
|
|
|
name string
|
2020-04-17 03:38:39 +03:00
|
|
|
typ table.Type
|
|
|
|
expected_type table.Type
|
|
|
|
}
|
|
|
|
|
2020-12-23 21:12:49 +03:00
|
|
|
pub struct StructInitEmbed {
|
|
|
|
pub:
|
|
|
|
expr Expr
|
|
|
|
pos token.Position
|
|
|
|
comments []Comment
|
|
|
|
next_comments []Comment
|
|
|
|
pub mut:
|
|
|
|
name string
|
|
|
|
typ table.Type
|
|
|
|
expected_type table.Type
|
|
|
|
}
|
|
|
|
|
2019-12-30 08:16:59 +03:00
|
|
|
pub struct StructInit {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position
|
|
|
|
is_short bool
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-04 22:01:35 +03:00
|
|
|
pre_comments []Comment
|
|
|
|
typ table.Type
|
|
|
|
update_expr Expr
|
|
|
|
update_expr_type table.Type
|
|
|
|
update_expr_comments []Comment
|
|
|
|
has_update_expr bool
|
|
|
|
fields []StructInitField
|
|
|
|
embeds []StructInitEmbed
|
2019-12-30 08:16:59 +03:00
|
|
|
}
|
|
|
|
|
2019-12-28 11:15:32 +03:00
|
|
|
// import statement
|
|
|
|
pub struct Import {
|
|
|
|
pub:
|
2021-01-09 07:36:38 +03:00
|
|
|
mod string // the module name of the import
|
|
|
|
alias string // the `x` in `import xxx as x`
|
|
|
|
pos token.Position
|
|
|
|
mod_pos token.Position
|
|
|
|
alias_pos token.Position
|
2020-07-18 22:34:38 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
syms []ImportSymbol // the list of symbols in `import {symbol1, symbol2}`
|
2020-07-18 22:34:38 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// import symbol,for import {symbol} syntax
|
2020-07-18 22:34:38 +03:00
|
|
|
pub struct ImportSymbol {
|
|
|
|
pub:
|
2020-08-04 21:10:22 +03:00
|
|
|
pos token.Position
|
|
|
|
name string
|
2019-12-28 11:15:32 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// anonymous function
|
2020-04-17 22:59:19 +03:00
|
|
|
pub struct AnonFn {
|
|
|
|
pub:
|
2020-07-14 19:52:28 +03:00
|
|
|
decl FnDecl
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
typ table.Type // the type of anonymous fn. Both .typ and .decl.name are auto generated
|
2020-04-17 22:59:19 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// function or method declaration
|
2019-12-27 15:57:49 +03:00
|
|
|
pub struct FnDecl {
|
|
|
|
pub:
|
2020-12-10 12:51:22 +03:00
|
|
|
name string
|
|
|
|
mod string
|
|
|
|
params []table.Param
|
|
|
|
is_deprecated bool
|
|
|
|
is_pub bool
|
|
|
|
is_variadic bool
|
|
|
|
is_anon bool
|
2021-01-08 15:56:55 +03:00
|
|
|
is_manualfree bool // true, when [manualfree] is used on a fn
|
2020-12-10 12:51:22 +03:00
|
|
|
receiver Field
|
2020-12-31 14:41:30 +03:00
|
|
|
receiver_pos token.Position // `(u User)` in `fn (u User) name()` position
|
2020-12-10 12:51:22 +03:00
|
|
|
is_method bool
|
2020-12-31 14:41:30 +03:00
|
|
|
method_type_pos token.Position // `User` in ` fn (u User)` position
|
2020-12-10 12:51:22 +03:00
|
|
|
method_idx int
|
|
|
|
rec_mut bool // is receiver mutable
|
|
|
|
rec_share table.ShareType
|
|
|
|
language table.Language
|
|
|
|
no_body bool // just a definition `fn C.malloc()`
|
|
|
|
is_builtin bool // this function is defined in builtin/strconv
|
2020-12-31 14:41:30 +03:00
|
|
|
pos token.Position // function declaration position
|
|
|
|
body_pos token.Position // function bodys position
|
2020-12-10 12:51:22 +03:00
|
|
|
file string
|
|
|
|
is_generic bool
|
|
|
|
is_direct_arr bool // direct array access
|
|
|
|
attrs []table.Attr
|
2020-04-27 23:53:26 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
stmts []Stmt
|
|
|
|
return_type table.Type
|
|
|
|
comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl
|
|
|
|
next_comments []Comment // coments that are one line after the decl; used for InterfaceDecl
|
|
|
|
source_file &File = 0
|
|
|
|
scope &Scope
|
2019-12-29 09:24:17 +03:00
|
|
|
}
|
|
|
|
|
2020-09-18 02:09:00 +03:00
|
|
|
// break, continue
|
2020-02-04 10:29:50 +03:00
|
|
|
pub struct BranchStmt {
|
|
|
|
pub:
|
2020-12-06 10:02:36 +03:00
|
|
|
kind token.Kind
|
|
|
|
label string
|
|
|
|
pos token.Position
|
2020-02-04 10:29:50 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// function or method call expr
|
2019-12-29 09:24:17 +03:00
|
|
|
pub struct CallExpr {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position
|
|
|
|
left Expr // `user` in `user.register()`
|
|
|
|
mod string
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-11-14 14:59:03 +03:00
|
|
|
name string // left.name()
|
2020-04-27 23:53:26 +03:00
|
|
|
is_method bool
|
2020-07-13 21:04:16 +03:00
|
|
|
is_field bool // temp hack, remove ASAP when re-impl CallExpr / Selector (joe)
|
2020-04-09 16:33:46 +03:00
|
|
|
args []CallArg
|
2020-04-03 16:18:17 +03:00
|
|
|
expected_arg_types []table.Type
|
2020-05-19 18:12:47 +03:00
|
|
|
language table.Language
|
2020-04-09 16:33:46 +03:00
|
|
|
or_block OrExpr
|
|
|
|
left_type table.Type // type of `user`
|
|
|
|
receiver_type table.Type // User
|
|
|
|
return_type table.Type
|
2020-04-25 16:57:11 +03:00
|
|
|
should_be_skipped bool
|
2020-05-21 04:58:50 +03:00
|
|
|
generic_type table.Type // TODO array, to support multiple types
|
2020-11-15 12:13:35 +03:00
|
|
|
generic_list_pos token.Position
|
2020-10-22 04:51:25 +03:00
|
|
|
free_receiver bool // true if the receiver expression needs to be freed
|
2020-12-12 11:01:12 +03:00
|
|
|
scope &Scope
|
2020-12-23 21:12:49 +03:00
|
|
|
from_embed_type table.Type // holds the type of the embed that the method is called from
|
2021-01-10 00:47:33 +03:00
|
|
|
comments []Comment
|
2020-03-14 13:11:43 +03:00
|
|
|
}
|
|
|
|
|
2020-09-05 13:00:35 +03:00
|
|
|
/*
|
|
|
|
pub struct AutofreeArgVar {
|
|
|
|
name string
|
|
|
|
idx int
|
|
|
|
}
|
|
|
|
*/
|
2020-12-28 14:52:04 +03:00
|
|
|
// function call argument: `f(callarg)`
|
2020-03-14 13:11:43 +03:00
|
|
|
pub struct CallArg {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
is_mut bool
|
|
|
|
share table.ShareType
|
|
|
|
expr Expr
|
|
|
|
comments []Comment
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-09-05 13:00:35 +03:00
|
|
|
typ table.Type
|
2020-11-09 16:24:46 +03:00
|
|
|
is_tmp_autofree bool // this tells cgen that a tmp variable has to be used for the arg expression in order to free it after the call
|
2020-10-30 21:26:08 +03:00
|
|
|
pos token.Position
|
2020-09-05 13:00:35 +03:00
|
|
|
// tmp_name string // for autofree
|
2019-12-27 15:57:49 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// function return statement
|
2019-12-27 15:57:49 +03:00
|
|
|
pub struct Return {
|
|
|
|
pub:
|
2020-07-17 20:13:22 +03:00
|
|
|
pos token.Position
|
|
|
|
exprs []Expr
|
|
|
|
comments []Comment
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
types []table.Type
|
2019-12-27 15:57:49 +03:00
|
|
|
}
|
|
|
|
|
2019-12-22 04:34:37 +03:00
|
|
|
/*
|
|
|
|
pub enum Expr {
|
2020-01-22 23:34:38 +03:00
|
|
|
Binary(InfixExpr)
|
2019-12-22 04:34:37 +03:00
|
|
|
If(IfExpr)
|
|
|
|
Integer(IntegerExpr)
|
|
|
|
}
|
|
|
|
*/
|
2019-12-24 20:54:43 +03:00
|
|
|
/*
|
2019-12-22 04:34:37 +03:00
|
|
|
pub struct Stmt {
|
|
|
|
pos int
|
|
|
|
//end int
|
|
|
|
}
|
2019-12-24 20:54:43 +03:00
|
|
|
*/
|
2020-03-10 14:01:37 +03:00
|
|
|
pub struct Var {
|
2019-12-24 20:54:43 +03:00
|
|
|
pub:
|
2020-10-29 03:09:38 +03:00
|
|
|
name string
|
|
|
|
expr Expr
|
|
|
|
share table.ShareType
|
|
|
|
is_mut bool
|
|
|
|
is_autofree_tmp bool
|
|
|
|
is_arg bool // fn args should not be autofreed
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
typ table.Type
|
|
|
|
sum_type_casts []table.Type // nested sum types require nested smart casting, for that a list of types is needed
|
|
|
|
pos token.Position
|
|
|
|
is_used bool
|
|
|
|
is_changed bool // to detect mutable vars that are never changed
|
2020-12-06 10:38:21 +03:00
|
|
|
//
|
2020-12-05 22:52:50 +03:00
|
|
|
// (for setting the position after the or block for autofree)
|
2021-01-12 06:38:43 +03:00
|
|
|
is_or bool // `x := foo() or { ... }`
|
|
|
|
is_tmp bool // for tmp for loop vars, so that autofree can skip them
|
2019-12-24 20:54:43 +03:00
|
|
|
}
|
|
|
|
|
2020-11-11 11:18:15 +03:00
|
|
|
// used for smartcasting only
|
|
|
|
// struct fields change type in scopes
|
|
|
|
pub struct ScopeStructField {
|
|
|
|
pub:
|
2020-11-23 18:16:13 +03:00
|
|
|
struct_type table.Type // type of struct
|
|
|
|
name string
|
|
|
|
pos token.Position
|
|
|
|
typ table.Type
|
|
|
|
sum_type_casts []table.Type // nested sum types require nested smart casting, for that a list of types is needed
|
2020-11-11 11:18:15 +03:00
|
|
|
}
|
|
|
|
|
2020-10-03 08:03:44 +03:00
|
|
|
pub struct GlobalField {
|
2020-02-03 09:02:54 +03:00
|
|
|
pub:
|
2020-04-09 16:33:46 +03:00
|
|
|
name string
|
|
|
|
expr Expr
|
2020-04-07 19:51:39 +03:00
|
|
|
has_expr bool
|
2020-05-16 17:12:23 +03:00
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-04-09 16:33:46 +03:00
|
|
|
typ table.Type
|
2020-10-03 08:03:44 +03:00
|
|
|
comments []Comment
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct GlobalDecl {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position
|
2020-10-03 08:03:44 +03:00
|
|
|
pub mut:
|
|
|
|
fields []GlobalField
|
|
|
|
end_comments []Comment
|
2020-02-03 09:02:54 +03:00
|
|
|
}
|
|
|
|
|
2021-01-14 17:20:11 +03:00
|
|
|
pub struct EmbeddedFile {
|
|
|
|
pub:
|
|
|
|
rpath string // used in the source code, as an ID/key to the embed
|
|
|
|
apath string // absolute path during compilation to the resource
|
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// Each V source file is represented by one ast.File structure.
|
|
|
|
// When the V compiler runs, the parser will fill an []ast.File.
|
|
|
|
// That array is then passed to V's checker.
|
2019-12-30 14:10:46 +03:00
|
|
|
pub struct File {
|
2019-12-24 20:54:43 +03:00
|
|
|
pub:
|
2021-01-15 21:28:18 +03:00
|
|
|
path string // absolute path of the source file - '/projects/v/file.v'
|
|
|
|
path_base string // file name - 'file.v' (useful for tracing)
|
2021-01-12 06:38:43 +03:00
|
|
|
mod Module // the module of the source file (from `module xyz` at the top)
|
|
|
|
global_scope &Scope
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-12-07 20:13:03 +03:00
|
|
|
scope &Scope
|
2021-01-14 17:20:11 +03:00
|
|
|
stmts []Stmt // all the statements in the source file
|
|
|
|
imports []Import // all the imports
|
|
|
|
auto_imports []string // imports that were implicitely added
|
|
|
|
embedded_files []EmbeddedFile // list of files to embed in the binary
|
2020-12-28 14:52:04 +03:00
|
|
|
imported_symbols map[string]string // used for `import {symbol}`, it maps symbol => module.symbol
|
2021-01-03 23:10:25 +03:00
|
|
|
errors []errors.Error // all the checker errors in the file
|
|
|
|
warnings []errors.Warning // all the checker warings in the file
|
2020-12-07 20:13:03 +03:00
|
|
|
generic_fns []&FnDecl
|
2020-02-17 14:25:18 +03:00
|
|
|
}
|
|
|
|
|
2020-03-11 18:10:46 +03:00
|
|
|
pub struct IdentFn {
|
2020-02-17 14:25:18 +03:00
|
|
|
pub mut:
|
2020-03-11 18:10:46 +03:00
|
|
|
typ table.Type
|
2020-01-19 01:26:14 +03:00
|
|
|
}
|
|
|
|
|
2020-07-22 19:10:31 +03:00
|
|
|
// TODO: (joe) remove completely, use ident.obj
|
|
|
|
// instead which points to the scope object
|
2020-01-19 01:26:14 +03:00
|
|
|
pub struct IdentVar {
|
2020-02-06 15:57:35 +03:00
|
|
|
pub mut:
|
2020-03-13 07:57:51 +03:00
|
|
|
typ table.Type
|
|
|
|
is_mut bool
|
|
|
|
is_static bool
|
|
|
|
is_optional bool
|
2020-07-04 13:44:25 +03:00
|
|
|
share table.ShareType
|
2020-01-19 01:26:14 +03:00
|
|
|
}
|
|
|
|
|
2020-11-25 14:09:40 +03:00
|
|
|
pub type IdentInfo = IdentFn | IdentVar
|
2020-01-19 01:26:14 +03:00
|
|
|
|
|
|
|
pub enum IdentKind {
|
2020-02-17 14:25:18 +03:00
|
|
|
unresolved
|
2020-01-19 01:26:14 +03:00
|
|
|
blank_ident
|
|
|
|
variable
|
2020-02-03 09:02:54 +03:00
|
|
|
constant
|
2020-04-04 06:14:40 +03:00
|
|
|
global
|
2020-02-17 14:25:18 +03:00
|
|
|
function
|
2019-12-24 20:54:43 +03:00
|
|
|
}
|
2019-12-28 16:11:05 +03:00
|
|
|
|
2019-12-22 04:34:37 +03:00
|
|
|
// A single identifier
|
2019-12-28 16:11:05 +03:00
|
|
|
pub struct Ident {
|
|
|
|
pub:
|
2020-05-19 18:12:47 +03:00
|
|
|
language table.Language
|
2019-12-31 12:53:30 +03:00
|
|
|
tok_kind token.Kind
|
2020-01-19 01:26:14 +03:00
|
|
|
pos token.Position
|
2020-11-27 05:08:42 +03:00
|
|
|
mut_pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
scope &Scope
|
|
|
|
obj ScopeObject
|
|
|
|
mod string
|
|
|
|
name string
|
|
|
|
kind IdentKind
|
|
|
|
info IdentInfo
|
|
|
|
is_mut bool
|
2019-12-22 04:34:37 +03:00
|
|
|
}
|
|
|
|
|
2020-02-07 16:49:14 +03:00
|
|
|
pub fn (i &Ident) var_info() IdentVar {
|
2020-11-25 14:09:40 +03:00
|
|
|
match mut i.info {
|
2020-02-06 19:38:02 +03:00
|
|
|
IdentVar {
|
2020-11-24 15:58:29 +03:00
|
|
|
return i.info
|
2020-02-06 19:38:02 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// return IdentVar{}
|
|
|
|
panic('Ident.var_info(): info is not IdentVar variant')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-29 04:13:10 +03:00
|
|
|
// left op right
|
|
|
|
// See: token.Kind.is_infix
|
2020-01-22 23:34:38 +03:00
|
|
|
pub struct InfixExpr {
|
2019-12-22 04:34:37 +03:00
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
op token.Kind
|
|
|
|
pos token.Position
|
2020-10-21 22:58:40 +03:00
|
|
|
pub mut:
|
2020-07-14 19:52:28 +03:00
|
|
|
left Expr
|
|
|
|
right Expr
|
|
|
|
left_type table.Type
|
|
|
|
right_type table.Type
|
|
|
|
auto_locked string
|
2021-01-06 23:19:40 +03:00
|
|
|
or_block OrExpr
|
2019-12-22 04:34:37 +03:00
|
|
|
}
|
|
|
|
|
2020-09-29 04:13:10 +03:00
|
|
|
// ++, --
|
2020-01-06 18:13:12 +03:00
|
|
|
pub struct PostfixExpr {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
op token.Kind
|
|
|
|
expr Expr
|
|
|
|
pos token.Position
|
2020-07-13 15:01:32 +03:00
|
|
|
pub mut:
|
2020-07-14 19:52:28 +03:00
|
|
|
auto_locked string
|
2020-01-06 18:13:12 +03:00
|
|
|
}
|
|
|
|
|
2020-09-29 04:13:10 +03:00
|
|
|
// See: token.Kind.is_prefix
|
2020-01-06 18:13:12 +03:00
|
|
|
pub struct PrefixExpr {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
op token.Kind
|
|
|
|
right Expr
|
|
|
|
pos token.Position
|
2020-08-18 00:35:36 +03:00
|
|
|
pub mut:
|
|
|
|
right_type table.Type
|
2020-08-23 03:12:05 +03:00
|
|
|
or_block OrExpr
|
2020-01-06 18:13:12 +03:00
|
|
|
}
|
|
|
|
|
2020-01-07 14:14:10 +03:00
|
|
|
pub struct IndexExpr {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position
|
|
|
|
left Expr
|
|
|
|
index Expr // [0], RangeExpr [start..end] or map[key]
|
|
|
|
or_expr OrExpr
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-04-03 11:41:01 +03:00
|
|
|
left_type table.Type // array, map, fixed array
|
2020-04-09 16:33:46 +03:00
|
|
|
is_setter bool
|
2020-01-07 14:14:10 +03:00
|
|
|
}
|
|
|
|
|
2019-12-28 21:16:04 +03:00
|
|
|
pub struct IfExpr {
|
2019-12-29 10:51:55 +03:00
|
|
|
pub:
|
2020-09-18 01:58:54 +03:00
|
|
|
is_comptime bool
|
2020-07-20 17:48:33 +03:00
|
|
|
tok_kind token.Kind
|
|
|
|
left Expr // `a` in `a := if ...`
|
|
|
|
pos token.Position
|
|
|
|
post_comments []Comment
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
branches []IfBranch // includes all `else if` branches
|
|
|
|
is_expr bool
|
|
|
|
typ table.Type
|
|
|
|
has_else bool
|
2020-03-20 16:39:56 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct IfBranch {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
cond Expr
|
|
|
|
pos token.Position
|
|
|
|
body_pos token.Position
|
|
|
|
comments []Comment
|
2020-07-08 16:17:28 +03:00
|
|
|
pub mut:
|
2020-11-27 05:08:42 +03:00
|
|
|
stmts []Stmt
|
|
|
|
smartcast bool // true when cond is `x is SumType`, set in checker.if_expr // no longer needed with union sum types TODO: remove
|
2020-12-12 11:01:12 +03:00
|
|
|
scope &Scope
|
2020-02-03 09:02:54 +03:00
|
|
|
}
|
|
|
|
|
2020-07-12 13:58:33 +03:00
|
|
|
pub struct UnsafeExpr {
|
|
|
|
pub:
|
2020-09-22 06:28:29 +03:00
|
|
|
expr Expr
|
|
|
|
pos token.Position
|
2020-07-12 13:58:33 +03:00
|
|
|
}
|
|
|
|
|
2020-07-04 13:44:25 +03:00
|
|
|
pub struct LockExpr {
|
|
|
|
pub:
|
|
|
|
stmts []Stmt
|
|
|
|
is_rlock bool
|
|
|
|
pos token.Position
|
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
lockeds []Ident // `x`, `y` in `lock x, y {`
|
|
|
|
is_expr bool
|
|
|
|
typ table.Type
|
2020-07-04 13:44:25 +03:00
|
|
|
}
|
|
|
|
|
2020-02-05 12:00:11 +03:00
|
|
|
pub struct MatchExpr {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
tok_kind token.Kind
|
|
|
|
cond Expr
|
|
|
|
branches []MatchBranch
|
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-11-25 14:09:40 +03:00
|
|
|
is_expr bool // returns a value
|
|
|
|
return_type table.Type
|
|
|
|
cond_type table.Type // type of `x` in `match x {`
|
|
|
|
expected_type table.Type // for debugging only
|
|
|
|
is_sum_type bool
|
2020-02-05 12:00:11 +03:00
|
|
|
}
|
|
|
|
|
2020-03-04 13:59:45 +03:00
|
|
|
pub struct MatchBranch {
|
|
|
|
pub:
|
2021-01-03 23:10:25 +03:00
|
|
|
exprs []Expr // left side
|
2020-11-11 23:53:21 +03:00
|
|
|
ecmnts [][]Comment // inline comments for each left side expr
|
2021-01-03 23:10:25 +03:00
|
|
|
stmts []Stmt // right side
|
2020-07-03 16:10:39 +03:00
|
|
|
pos token.Position
|
2020-10-14 22:48:49 +03:00
|
|
|
comments []Comment // comment above `xxx {`
|
2020-07-03 16:10:39 +03:00
|
|
|
is_else bool
|
2020-07-02 16:44:03 +03:00
|
|
|
post_comments []Comment
|
2020-12-12 11:01:12 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
scope &Scope
|
2020-03-04 13:59:45 +03:00
|
|
|
}
|
|
|
|
|
2020-09-16 16:34:57 +03:00
|
|
|
pub struct SelectExpr {
|
|
|
|
pub:
|
|
|
|
branches []SelectBranch
|
|
|
|
pos token.Position
|
2020-09-19 03:14:35 +03:00
|
|
|
has_exception bool
|
2020-09-16 16:34:57 +03:00
|
|
|
pub mut:
|
2021-01-03 23:10:25 +03:00
|
|
|
is_expr bool // returns a value
|
2020-09-16 16:34:57 +03:00
|
|
|
expected_type table.Type // for debugging only
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SelectBranch {
|
|
|
|
pub:
|
2021-01-03 23:10:25 +03:00
|
|
|
stmt Stmt // `a := <-ch` or `ch <- a`
|
2020-09-16 16:34:57 +03:00
|
|
|
stmts []Stmt // right side
|
|
|
|
pos token.Position
|
|
|
|
comment Comment // comment above `select {`
|
|
|
|
is_else bool
|
|
|
|
is_timeout bool
|
|
|
|
post_comments []Comment
|
|
|
|
}
|
|
|
|
|
2020-07-25 01:02:44 +03:00
|
|
|
pub enum CompForKind {
|
|
|
|
methods
|
|
|
|
fields
|
|
|
|
}
|
|
|
|
|
2020-07-03 16:10:39 +03:00
|
|
|
pub struct CompFor {
|
|
|
|
pub:
|
|
|
|
val_var string
|
|
|
|
stmts []Stmt
|
2020-07-25 01:02:44 +03:00
|
|
|
kind CompForKind
|
2020-11-04 14:34:12 +03:00
|
|
|
pos token.Position
|
2020-07-03 16:10:39 +03:00
|
|
|
pub mut:
|
|
|
|
// expr Expr
|
2021-01-12 06:38:43 +03:00
|
|
|
typ table.Type
|
2020-07-03 16:10:39 +03:00
|
|
|
}
|
|
|
|
|
2019-12-30 08:16:59 +03:00
|
|
|
pub struct ForStmt {
|
|
|
|
pub:
|
2020-02-19 13:06:36 +03:00
|
|
|
cond Expr
|
|
|
|
stmts []Stmt
|
|
|
|
is_inf bool // `for {}`
|
2020-03-18 16:50:21 +03:00
|
|
|
pos token.Position
|
2020-11-20 14:23:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
label string // `label: for {`
|
|
|
|
scope &Scope
|
2020-01-07 02:14:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ForInStmt {
|
|
|
|
pub:
|
2020-10-14 14:23:58 +03:00
|
|
|
key_var string
|
|
|
|
val_var string
|
|
|
|
cond Expr
|
|
|
|
is_range bool
|
|
|
|
high Expr // `10` in `for i in 0..10 {`
|
|
|
|
stmts []Stmt
|
|
|
|
pos token.Position
|
2020-10-13 17:27:24 +03:00
|
|
|
val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array
|
2020-10-14 14:23:58 +03:00
|
|
|
// and the array cannot be indexed inside the loop
|
2020-10-15 23:12:59 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
key_type table.Type
|
|
|
|
val_type table.Type
|
|
|
|
cond_type table.Type
|
|
|
|
kind table.Kind // array/map/string
|
|
|
|
label string // `label: for {`
|
|
|
|
scope &Scope
|
2020-01-07 02:14:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ForCStmt {
|
|
|
|
pub:
|
2020-03-11 04:44:30 +03:00
|
|
|
init Stmt // i := 0;
|
|
|
|
has_init bool
|
|
|
|
cond Expr // i < 10;
|
2020-04-10 10:00:14 +03:00
|
|
|
has_cond bool
|
2020-06-16 14:20:16 +03:00
|
|
|
inc Stmt // i++; i += 2
|
2020-04-10 10:00:14 +03:00
|
|
|
has_inc bool
|
2020-03-11 04:44:30 +03:00
|
|
|
stmts []Stmt
|
2020-03-18 16:50:21 +03:00
|
|
|
pos token.Position
|
2020-11-20 14:23:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
label string // `label: for {`
|
|
|
|
scope &Scope
|
2019-12-30 08:16:59 +03:00
|
|
|
}
|
|
|
|
|
2020-02-04 11:54:15 +03:00
|
|
|
// #include etc
|
|
|
|
pub struct HashStmt {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
mod string
|
|
|
|
pos token.Position
|
2020-08-28 09:24:04 +03:00
|
|
|
pub mut:
|
2020-10-17 18:27:06 +03:00
|
|
|
val string // example: 'include <openssl/rand.h> # please install openssl // comment'
|
|
|
|
kind string // : 'include'
|
|
|
|
main string // : '<openssl/rand.h>'
|
|
|
|
msg string // : 'please install openssl'
|
2020-02-04 11:54:15 +03:00
|
|
|
}
|
|
|
|
|
2020-08-12 06:54:51 +03:00
|
|
|
/*
|
|
|
|
// filter(), map(), sort()
|
2020-02-10 16:42:57 +03:00
|
|
|
pub struct Lambda {
|
|
|
|
pub:
|
|
|
|
name string
|
|
|
|
}
|
2020-08-12 06:54:51 +03:00
|
|
|
*/
|
2020-12-28 14:52:04 +03:00
|
|
|
// variable assign statement
|
2019-12-28 21:16:04 +03:00
|
|
|
pub struct AssignStmt {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
right []Expr
|
|
|
|
op token.Kind // include: =,:=,+=,-=,*=,/= and so on; for a list of all the assign operators, see vlib/token/token.v
|
|
|
|
pos token.Position
|
|
|
|
comments []Comment
|
|
|
|
end_comments []Comment
|
2020-04-27 23:53:26 +03:00
|
|
|
pub mut:
|
2020-06-16 14:20:16 +03:00
|
|
|
left []Expr
|
2020-05-27 04:20:22 +03:00
|
|
|
left_types []table.Type
|
|
|
|
right_types []table.Type
|
|
|
|
is_static bool // for translated code only
|
2020-06-16 14:20:16 +03:00
|
|
|
is_simple bool // `x+=2` in `for x:=1; ; x+=2`
|
2020-05-26 19:00:51 +03:00
|
|
|
has_cross_var bool
|
2019-12-28 21:16:04 +03:00
|
|
|
}
|
2020-02-06 19:38:02 +03:00
|
|
|
|
2020-03-02 21:00:33 +03:00
|
|
|
pub struct AsCast {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
expr Expr
|
|
|
|
typ table.Type
|
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-03-18 15:55:46 +03:00
|
|
|
expr_type table.Type
|
2020-03-02 21:00:33 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// an enum value, like OS.macos or .macos
|
2020-02-11 01:19:50 +03:00
|
|
|
pub struct EnumVal {
|
2020-02-10 22:33:34 +03:00
|
|
|
pub:
|
2020-02-25 17:02:34 +03:00
|
|
|
enum_name string
|
|
|
|
val string
|
2020-03-15 02:46:08 +03:00
|
|
|
mod string // for full path `mod_Enum_val`
|
2020-02-25 17:02:34 +03:00
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
typ table.Type
|
2020-02-11 01:19:50 +03:00
|
|
|
}
|
2020-02-10 22:33:34 +03:00
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// enum field in enum declaration
|
2020-04-09 20:23:49 +03:00
|
|
|
pub struct EnumField {
|
2020-05-18 19:06:09 +03:00
|
|
|
pub:
|
2020-12-25 22:41:59 +03:00
|
|
|
name string
|
|
|
|
pos token.Position
|
2020-12-28 14:52:04 +03:00
|
|
|
comments []Comment // comment after Enumfield in the same line
|
|
|
|
next_comments []Comment // comments between current EnumField and next EnumField
|
2021-01-03 23:10:25 +03:00
|
|
|
expr Expr // the value of current EnumField; 123 in `ename = 123`
|
|
|
|
has_expr bool // true, when .expr has a value
|
2020-04-09 20:23:49 +03:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:52:04 +03:00
|
|
|
// enum declaration
|
2020-02-11 01:19:50 +03:00
|
|
|
pub struct EnumDecl {
|
|
|
|
pub:
|
2020-07-10 17:43:02 +03:00
|
|
|
name string
|
|
|
|
is_pub bool
|
2021-01-03 23:10:25 +03:00
|
|
|
is_flag bool // true when the enum has [flag] tag,for bit field enum
|
|
|
|
is_multi_allowed bool // true when the enum has [_allow_multiple_values] tag
|
|
|
|
comments []Comment // comments before the first EnumField
|
|
|
|
fields []EnumField // all the enum fields
|
2020-12-28 14:52:04 +03:00
|
|
|
attrs []table.Attr // attributes of enum declaration
|
2020-07-10 17:43:02 +03:00
|
|
|
pos token.Position
|
2020-02-11 01:19:50 +03:00
|
|
|
}
|
|
|
|
|
2020-03-07 19:37:55 +03:00
|
|
|
pub struct AliasTypeDecl {
|
|
|
|
pub:
|
2020-03-08 00:37:03 +03:00
|
|
|
name string
|
|
|
|
is_pub bool
|
2020-03-07 19:37:55 +03:00
|
|
|
parent_type table.Type
|
2020-04-19 01:07:57 +03:00
|
|
|
pos token.Position
|
2020-11-20 12:51:50 +03:00
|
|
|
comments []Comment
|
2020-03-07 19:37:55 +03:00
|
|
|
}
|
|
|
|
|
2020-11-11 11:18:15 +03:00
|
|
|
// New implementation of sum types
|
2020-11-25 14:09:40 +03:00
|
|
|
pub struct SumTypeDecl {
|
2020-11-11 11:18:15 +03:00
|
|
|
pub:
|
2020-11-29 00:40:40 +03:00
|
|
|
name string
|
|
|
|
is_pub bool
|
|
|
|
pos token.Position
|
|
|
|
comments []Comment
|
2020-11-11 11:18:15 +03:00
|
|
|
pub mut:
|
2020-11-29 00:40:40 +03:00
|
|
|
variants []SumTypeVariant
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SumTypeVariant {
|
|
|
|
pub:
|
|
|
|
typ table.Type
|
|
|
|
pos token.Position
|
2020-11-11 11:18:15 +03:00
|
|
|
}
|
|
|
|
|
2020-03-11 18:10:46 +03:00
|
|
|
pub struct FnTypeDecl {
|
|
|
|
pub:
|
2020-11-20 12:51:50 +03:00
|
|
|
name string
|
|
|
|
is_pub bool
|
|
|
|
typ table.Type
|
|
|
|
pos token.Position
|
|
|
|
comments []Comment
|
2020-03-11 18:10:46 +03:00
|
|
|
}
|
|
|
|
|
2020-04-09 16:33:46 +03:00
|
|
|
// TODO: handle this differently
|
|
|
|
// v1 excludes non current os ifdefs so
|
|
|
|
// the defer's never get added in the first place
|
2020-02-18 00:50:04 +03:00
|
|
|
pub struct DeferStmt {
|
2020-02-11 12:26:46 +03:00
|
|
|
pub:
|
2020-02-18 00:50:04 +03:00
|
|
|
stmts []Stmt
|
2020-11-04 14:34:12 +03:00
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-03-27 09:21:22 +03:00
|
|
|
ifdef string
|
2020-02-11 12:26:46 +03:00
|
|
|
}
|
|
|
|
|
2020-02-28 16:41:19 +03:00
|
|
|
// `(3+4)`
|
|
|
|
pub struct ParExpr {
|
|
|
|
pub:
|
|
|
|
expr Expr
|
2020-11-04 14:34:12 +03:00
|
|
|
pos token.Position
|
2020-02-28 16:41:19 +03:00
|
|
|
}
|
|
|
|
|
2020-03-16 10:33:42 +03:00
|
|
|
pub struct GoStmt {
|
|
|
|
pub:
|
2021-01-15 15:45:26 +03:00
|
|
|
pos token.Position
|
|
|
|
pub mut:
|
|
|
|
call_expr CallExpr
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct GoExpr {
|
|
|
|
pub:
|
|
|
|
pos token.Position
|
|
|
|
pub mut:
|
|
|
|
go_stmt GoStmt
|
|
|
|
mut:
|
|
|
|
return_type table.Type
|
2020-03-16 10:33:42 +03:00
|
|
|
}
|
|
|
|
|
2020-02-18 00:50:04 +03:00
|
|
|
pub struct GotoLabel {
|
2020-02-17 16:15:42 +03:00
|
|
|
pub:
|
2020-02-18 00:50:04 +03:00
|
|
|
name string
|
2020-11-04 14:34:12 +03:00
|
|
|
pos token.Position
|
2020-02-17 16:15:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct GotoStmt {
|
|
|
|
pub:
|
2020-02-18 00:50:04 +03:00
|
|
|
name string
|
2020-11-04 14:34:12 +03:00
|
|
|
pos token.Position
|
2020-02-17 16:15:42 +03:00
|
|
|
}
|
|
|
|
|
2019-12-30 11:38:12 +03:00
|
|
|
pub struct ArrayInit {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position // `[]` in []Type{} position
|
|
|
|
elem_type_pos token.Position // `Type` in []Type{} position
|
|
|
|
exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array
|
|
|
|
ecmnts [][]Comment // optional iembed comments after each expr
|
|
|
|
is_fixed bool
|
2021-01-14 05:51:13 +03:00
|
|
|
has_val bool // fixed size literal `[expr, expr]!`
|
2021-01-12 06:38:43 +03:00
|
|
|
mod string
|
|
|
|
len_expr Expr // len: expr
|
|
|
|
cap_expr Expr // cap: expr
|
|
|
|
default_expr Expr // init: expr
|
|
|
|
has_len bool
|
|
|
|
has_cap bool
|
|
|
|
has_default bool
|
2020-12-01 13:20:27 +03:00
|
|
|
pub mut:
|
|
|
|
expr_types []table.Type // [Dog, Cat] // also used for interface_types
|
2021-01-03 23:10:25 +03:00
|
|
|
is_interface bool // array of interfaces e.g. `[]Animal` `[Dog{}, Cat{}]`
|
2020-12-01 13:20:27 +03:00
|
|
|
interface_type table.Type // Animal
|
|
|
|
elem_type table.Type // element type
|
|
|
|
typ table.Type // array type
|
2019-12-30 11:38:12 +03:00
|
|
|
}
|
|
|
|
|
2020-12-29 18:14:08 +03:00
|
|
|
pub struct ArrayDecompose {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
expr Expr
|
|
|
|
pos token.Position
|
2020-12-29 18:14:08 +03:00
|
|
|
pub mut:
|
|
|
|
expr_type table.Type
|
|
|
|
arg_type table.Type
|
|
|
|
}
|
|
|
|
|
2020-08-14 22:18:42 +03:00
|
|
|
pub struct ChanInit {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position
|
|
|
|
cap_expr Expr
|
|
|
|
has_cap bool
|
2020-08-14 22:18:42 +03:00
|
|
|
pub mut:
|
2020-09-05 13:00:35 +03:00
|
|
|
typ table.Type
|
|
|
|
elem_type table.Type
|
2020-08-14 22:18:42 +03:00
|
|
|
}
|
|
|
|
|
2020-02-22 16:13:19 +03:00
|
|
|
pub struct MapInit {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position
|
|
|
|
keys []Expr
|
|
|
|
vals []Expr
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-03-07 18:23:10 +03:00
|
|
|
typ table.Type
|
2020-03-07 10:13:00 +03:00
|
|
|
key_type table.Type
|
|
|
|
value_type table.Type
|
2020-02-22 16:13:19 +03:00
|
|
|
}
|
|
|
|
|
2020-02-02 16:31:54 +03:00
|
|
|
// s[10..20]
|
|
|
|
pub struct RangeExpr {
|
|
|
|
pub:
|
2020-03-07 00:24:39 +03:00
|
|
|
low Expr
|
|
|
|
high Expr
|
|
|
|
has_high bool
|
|
|
|
has_low bool
|
2020-11-04 14:34:12 +03:00
|
|
|
pos token.Position
|
2020-02-02 16:31:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-10 19:05:26 +03:00
|
|
|
// NB: &string(x) gets parsed as ast.PrefixExpr{ right: ast.CastExpr{...} }
|
|
|
|
// TODO: that is very likely a parsing bug. It should get parsed as just
|
|
|
|
// ast.CastExpr{...}, where .typname is '&string' instead.
|
|
|
|
// The current situation leads to special cases in vfmt and cgen
|
|
|
|
// (see prefix_expr_cast_expr in fmt.v, and .is_amp in cgen.v)
|
|
|
|
// .in_prexpr is also needed because of that, because the checker needs to
|
|
|
|
// show warnings about the deprecated C->V conversions `string(x)` and
|
|
|
|
// `string(x,y)`, while skipping the real pointer casts like `&string(x)`.
|
2020-02-10 16:43:17 +03:00
|
|
|
pub struct CastExpr {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
expr Expr // `buf` in `string(buf, n)`
|
|
|
|
arg Expr // `n` in `string(buf, n)`
|
|
|
|
typ table.Type // `string` TODO rename to `type_to_cast_to`
|
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-05 18:02:04 +03:00
|
|
|
typname string // TypeSymbol.name
|
2020-03-11 21:00:51 +03:00
|
|
|
expr_type table.Type // `byteptr`
|
|
|
|
has_arg bool
|
2020-08-10 19:05:26 +03:00
|
|
|
in_prexpr bool // is the parent node an ast.PrefixExpr
|
2020-02-10 16:43:17 +03:00
|
|
|
}
|
|
|
|
|
2020-02-26 17:51:05 +03:00
|
|
|
pub struct AssertStmt {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
pos token.Position
|
2020-10-21 22:58:40 +03:00
|
|
|
pub mut:
|
|
|
|
expr Expr
|
2020-02-26 17:51:05 +03:00
|
|
|
}
|
|
|
|
|
2020-02-28 17:36:41 +03:00
|
|
|
// `if [x := opt()] {`
|
|
|
|
pub struct IfGuardExpr {
|
2020-02-27 20:02:40 +03:00
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
var_name string
|
|
|
|
expr Expr
|
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-03-17 18:40:41 +03:00
|
|
|
expr_type table.Type
|
2020-02-27 20:02:40 +03:00
|
|
|
}
|
|
|
|
|
2020-05-23 09:51:15 +03:00
|
|
|
pub enum OrKind {
|
|
|
|
absent
|
|
|
|
block
|
|
|
|
propagate
|
|
|
|
}
|
|
|
|
|
2020-02-28 17:36:41 +03:00
|
|
|
// `or { ... }`
|
|
|
|
pub struct OrExpr {
|
|
|
|
pub:
|
2020-05-23 09:51:15 +03:00
|
|
|
stmts []Stmt
|
|
|
|
kind OrKind
|
2020-05-25 06:32:33 +03:00
|
|
|
pos token.Position
|
2020-02-28 17:36:41 +03:00
|
|
|
}
|
|
|
|
|
2020-09-13 04:00:20 +03:00
|
|
|
/*
|
2020-09-12 17:40:52 +03:00
|
|
|
// `or { ... }`
|
|
|
|
pub struct OrExpr2 {
|
|
|
|
pub:
|
|
|
|
call_expr CallExpr
|
|
|
|
stmts []Stmt // inside `or { }`
|
|
|
|
kind OrKind
|
|
|
|
pos token.Position
|
|
|
|
}
|
2020-09-13 04:00:20 +03:00
|
|
|
*/
|
2020-02-18 19:29:47 +03:00
|
|
|
pub struct Assoc {
|
|
|
|
pub:
|
2020-03-01 15:07:51 +03:00
|
|
|
var_name string
|
|
|
|
fields []string
|
|
|
|
exprs []Expr
|
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
typ table.Type
|
|
|
|
scope &Scope
|
2020-02-18 19:29:47 +03:00
|
|
|
}
|
|
|
|
|
2020-02-18 20:13:34 +03:00
|
|
|
pub struct SizeOf {
|
|
|
|
pub:
|
2021-01-13 08:13:39 +03:00
|
|
|
is_type bool
|
|
|
|
expr Expr // checker uses this to set typ
|
|
|
|
pos token.Position
|
|
|
|
pub mut:
|
|
|
|
typ table.Type
|
2020-02-18 20:13:34 +03:00
|
|
|
}
|
|
|
|
|
2020-06-09 17:36:18 +03:00
|
|
|
pub struct Likely {
|
|
|
|
pub:
|
2020-06-16 13:14:22 +03:00
|
|
|
expr Expr
|
|
|
|
pos token.Position
|
2020-06-09 18:08:31 +03:00
|
|
|
is_likely bool // false for _unlikely_
|
2020-06-09 17:36:18 +03:00
|
|
|
}
|
|
|
|
|
2020-03-19 14:15:39 +03:00
|
|
|
pub struct TypeOf {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
expr Expr
|
|
|
|
pos token.Position
|
2020-05-09 16:16:48 +03:00
|
|
|
pub mut:
|
2020-03-28 19:37:22 +03:00
|
|
|
expr_type table.Type
|
2020-03-19 14:15:39 +03:00
|
|
|
}
|
|
|
|
|
2020-04-05 03:08:10 +03:00
|
|
|
pub struct Comment {
|
2020-02-18 22:20:15 +03:00
|
|
|
pub:
|
2020-04-09 16:33:46 +03:00
|
|
|
text string
|
2020-04-05 03:08:10 +03:00
|
|
|
is_multi bool
|
2020-04-09 16:33:46 +03:00
|
|
|
line_nr int
|
|
|
|
pos token.Position
|
2020-02-18 22:20:15 +03:00
|
|
|
}
|
|
|
|
|
2020-03-01 16:57:54 +03:00
|
|
|
pub struct ConcatExpr {
|
|
|
|
pub:
|
2021-01-12 06:38:43 +03:00
|
|
|
vals []Expr
|
|
|
|
pos token.Position
|
2020-05-16 00:14:53 +03:00
|
|
|
pub mut:
|
|
|
|
return_type table.Type
|
2020-03-01 16:57:54 +03:00
|
|
|
}
|
|
|
|
|
2020-11-05 11:12:32 +03:00
|
|
|
// @FN, @STRUCT, @MOD etc. See full list in token.valid_at_tokens
|
|
|
|
pub struct AtExpr {
|
|
|
|
pub:
|
|
|
|
name string
|
|
|
|
pos token.Position
|
|
|
|
kind token.AtKind
|
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
val string
|
2020-11-05 11:12:32 +03:00
|
|
|
}
|
|
|
|
|
2021-01-05 17:11:43 +03:00
|
|
|
pub struct ComptimeSelector {
|
|
|
|
pub:
|
|
|
|
has_parens bool // if $() is used, for vfmt
|
|
|
|
left Expr
|
|
|
|
field_expr Expr
|
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
left_type table.Type
|
|
|
|
typ table.Type
|
2021-01-05 17:11:43 +03:00
|
|
|
}
|
|
|
|
|
2020-05-25 06:32:33 +03:00
|
|
|
pub struct ComptimeCall {
|
2020-06-06 11:05:26 +03:00
|
|
|
pub:
|
2021-01-05 17:11:43 +03:00
|
|
|
has_parens bool // if $() is used, for vfmt
|
2020-06-06 11:05:26 +03:00
|
|
|
method_name string
|
|
|
|
left Expr
|
2020-06-06 22:36:24 +03:00
|
|
|
is_vweb bool
|
2020-06-07 13:26:45 +03:00
|
|
|
vweb_tmpl File
|
2020-07-03 16:10:39 +03:00
|
|
|
args_var string
|
2021-01-14 17:20:11 +03:00
|
|
|
is_embed bool
|
|
|
|
embed_file EmbeddedFile
|
2020-06-06 11:05:26 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
sym table.TypeSymbol
|
2020-05-25 06:32:33 +03:00
|
|
|
}
|
|
|
|
|
2020-02-19 21:54:36 +03:00
|
|
|
pub struct None {
|
|
|
|
pub:
|
2020-06-16 13:14:22 +03:00
|
|
|
pos token.Position
|
|
|
|
foo int // todo
|
|
|
|
}
|
|
|
|
|
2020-06-19 17:43:32 +03:00
|
|
|
/*
|
|
|
|
pub enum SqlExprKind {
|
|
|
|
select_
|
|
|
|
insert
|
|
|
|
update
|
|
|
|
}
|
|
|
|
*/
|
2020-06-24 15:32:14 +03:00
|
|
|
pub enum SqlStmtKind {
|
|
|
|
insert
|
|
|
|
update
|
|
|
|
delete
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SqlStmt {
|
2020-06-19 17:43:32 +03:00
|
|
|
pub:
|
2020-06-27 17:19:12 +03:00
|
|
|
kind SqlStmtKind
|
2021-01-03 23:10:25 +03:00
|
|
|
db_expr Expr // `db` in `sql db {`
|
2020-06-19 17:43:32 +03:00
|
|
|
object_var_name string // `user`
|
2020-06-19 18:05:57 +03:00
|
|
|
table_type table.Type
|
2020-06-27 17:19:12 +03:00
|
|
|
pos token.Position
|
|
|
|
where_expr Expr
|
|
|
|
updated_columns []string // for `update set x=y`
|
2021-01-03 23:10:25 +03:00
|
|
|
update_exprs []Expr // for `update`
|
2020-06-25 15:43:07 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
table_name string
|
|
|
|
fields []table.Field
|
2020-06-19 17:43:32 +03:00
|
|
|
}
|
|
|
|
|
2020-06-16 13:14:22 +03:00
|
|
|
pub struct SqlExpr {
|
2020-06-17 01:59:33 +03:00
|
|
|
pub:
|
2020-06-27 17:19:12 +03:00
|
|
|
typ table.Type
|
|
|
|
is_count bool
|
|
|
|
db_expr Expr // `db` in `sql db {`
|
|
|
|
where_expr Expr
|
|
|
|
has_where bool
|
|
|
|
has_offset bool
|
|
|
|
offset_expr Expr
|
2020-07-02 20:29:22 +03:00
|
|
|
has_order bool
|
|
|
|
order_expr Expr
|
|
|
|
has_desc bool
|
2020-06-27 17:19:12 +03:00
|
|
|
is_array bool
|
|
|
|
table_type table.Type
|
|
|
|
pos token.Position
|
|
|
|
has_limit bool
|
|
|
|
limit_expr Expr
|
2020-06-25 13:05:24 +03:00
|
|
|
pub mut:
|
2021-01-12 06:38:43 +03:00
|
|
|
table_name string
|
|
|
|
fields []table.Field
|
2020-02-19 21:54:36 +03:00
|
|
|
}
|
2020-03-18 10:41:49 +03:00
|
|
|
|
2020-03-18 03:19:23 +03:00
|
|
|
[inline]
|
2020-06-16 14:20:16 +03:00
|
|
|
pub fn (expr Expr) is_blank_ident() bool {
|
2020-11-25 14:09:40 +03:00
|
|
|
match expr {
|
2020-06-19 12:46:08 +03:00
|
|
|
Ident { return expr.kind == .blank_ident }
|
2020-04-19 01:07:57 +03:00
|
|
|
else { return false }
|
2020-03-18 03:19:23 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-11 09:59:55 +03:00
|
|
|
pub fn (expr Expr) position() token.Position {
|
2020-04-17 03:38:39 +03:00
|
|
|
// all uncommented have to be implemented
|
2020-11-25 14:09:40 +03:00
|
|
|
match expr {
|
2020-09-22 06:28:29 +03:00
|
|
|
// KEKW2
|
2020-07-07 18:10:39 +03:00
|
|
|
AnonFn {
|
|
|
|
return expr.decl.pos
|
|
|
|
}
|
2021-01-15 15:45:26 +03:00
|
|
|
ArrayInit, AsCast, Assoc, AtExpr, BoolLiteral, CallExpr, CastExpr, ChanInit, CharLiteral, ConcatExpr, Comment, EnumVal, FloatLiteral, GoExpr, Ident, IfExpr, IndexExpr, IntegerLiteral, Likely, LockExpr, MapInit, MatchExpr, None, OrExpr, ParExpr, PostfixExpr, PrefixExpr, RangeExpr, SelectExpr, SelectorExpr, SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, Type, TypeOf, UnsafeExpr {
|
2020-06-19 12:46:08 +03:00
|
|
|
return expr.pos
|
2020-04-22 21:20:49 +03:00
|
|
|
}
|
2020-12-29 18:14:08 +03:00
|
|
|
ArrayDecompose {
|
|
|
|
return expr.pos
|
|
|
|
}
|
2020-11-04 14:34:12 +03:00
|
|
|
IfGuardExpr {
|
|
|
|
return expr.expr.position()
|
|
|
|
}
|
2021-01-05 17:11:43 +03:00
|
|
|
ComptimeCall, ComptimeSelector {
|
2020-11-04 14:34:12 +03:00
|
|
|
return expr.left.position()
|
|
|
|
}
|
2020-04-17 03:38:39 +03:00
|
|
|
InfixExpr {
|
2020-06-19 12:46:08 +03:00
|
|
|
left_pos := expr.left.position()
|
|
|
|
right_pos := expr.right.position()
|
2020-04-17 03:38:39 +03:00
|
|
|
return token.Position{
|
2020-06-19 12:46:08 +03:00
|
|
|
line_nr: expr.pos.line_nr
|
2020-04-17 03:38:39 +03:00
|
|
|
pos: left_pos.pos
|
|
|
|
len: right_pos.pos - left_pos.pos + right_pos.len
|
|
|
|
}
|
|
|
|
}
|
2020-11-04 14:34:12 +03:00
|
|
|
CTempVar {
|
2020-04-22 21:20:49 +03:00
|
|
|
return token.Position{}
|
|
|
|
}
|
2020-11-04 14:34:12 +03:00
|
|
|
// Please, do NOT use else{} here.
|
|
|
|
// This match is exhaustive *on purpose*, to help force
|
|
|
|
// maintaining/implementing proper .pos fields.
|
2020-04-17 03:38:39 +03:00
|
|
|
}
|
|
|
|
}
|
2020-04-29 13:31:18 +03:00
|
|
|
|
2020-08-17 22:10:47 +03:00
|
|
|
pub fn (expr Expr) is_lvalue() bool {
|
2020-11-25 14:09:40 +03:00
|
|
|
match expr {
|
2020-09-05 13:00:35 +03:00
|
|
|
Ident { return true }
|
2020-10-21 22:58:40 +03:00
|
|
|
CTempVar { return true }
|
2020-09-05 13:00:35 +03:00
|
|
|
IndexExpr { return expr.left.is_lvalue() }
|
|
|
|
SelectorExpr { return expr.expr.is_lvalue() }
|
2020-08-17 22:10:47 +03:00
|
|
|
else {}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-09-19 19:18:36 +03:00
|
|
|
pub fn (expr Expr) is_expr() bool {
|
2020-11-25 14:09:40 +03:00
|
|
|
match expr {
|
2020-09-22 06:28:29 +03:00
|
|
|
IfExpr { return expr.is_expr }
|
|
|
|
MatchExpr { return expr.is_expr }
|
2020-09-19 19:18:36 +03:00
|
|
|
else {}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2020-12-11 06:46:06 +03:00
|
|
|
pub fn (expr Expr) is_lit() bool {
|
|
|
|
return match expr {
|
|
|
|
BoolLiteral, StringLiteral, IntegerLiteral { true }
|
|
|
|
else { false }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-30 17:06:22 +03:00
|
|
|
// check if stmt can be an expression in C
|
2020-10-14 14:23:58 +03:00
|
|
|
pub fn (stmt Stmt) check_c_expr() ? {
|
2020-11-25 14:09:40 +03:00
|
|
|
match stmt {
|
2020-10-14 14:23:58 +03:00
|
|
|
AssignStmt {
|
|
|
|
return
|
|
|
|
}
|
2020-09-30 17:06:22 +03:00
|
|
|
ExprStmt {
|
2020-10-14 14:23:58 +03:00
|
|
|
if stmt.expr.is_expr() {
|
|
|
|
return
|
|
|
|
}
|
2021-01-07 22:32:02 +03:00
|
|
|
return error('unsupported statement (`$stmt.expr.type_name()`)')
|
2020-09-30 17:06:22 +03:00
|
|
|
}
|
|
|
|
else {}
|
|
|
|
}
|
2021-01-07 22:32:02 +03:00
|
|
|
return error('unsupported statement (`$stmt.type_name()`)')
|
2020-09-30 17:06:22 +03:00
|
|
|
}
|
|
|
|
|
2020-10-21 22:58:40 +03:00
|
|
|
// CTempVar is used in cgen only, to hold nodes for temporary variables
|
|
|
|
pub struct CTempVar {
|
|
|
|
pub:
|
2021-01-03 23:10:25 +03:00
|
|
|
name string // the name of the C temporary variable; used by g.expr(x)
|
|
|
|
orig Expr // the original expression, which produced the C temp variable; used by x.str()
|
2020-10-21 22:58:40 +03:00
|
|
|
typ table.Type // the type of the original expression
|
2021-01-03 23:10:25 +03:00
|
|
|
is_ptr bool // whether the type is a pointer
|
2020-10-21 22:58:40 +03:00
|
|
|
}
|
|
|
|
|
2020-05-11 09:59:55 +03:00
|
|
|
pub fn (stmt Stmt) position() token.Position {
|
2020-11-25 14:09:40 +03:00
|
|
|
match stmt {
|
2020-12-25 22:43:50 +03:00
|
|
|
AssertStmt, AssignStmt, Block, BranchStmt, CompFor, ConstDecl, DeferStmt, EnumDecl, ExprStmt, FnDecl, ForCStmt, ForInStmt, ForStmt, GotoLabel, GotoStmt, Import, Return, StructDecl, GlobalDecl, HashStmt, InterfaceDecl, Module, SqlStmt {
|
|
|
|
return stmt.pos
|
|
|
|
}
|
|
|
|
GoStmt {
|
2021-01-15 15:45:26 +03:00
|
|
|
return stmt.call_expr.pos
|
2020-12-25 22:43:50 +03:00
|
|
|
}
|
|
|
|
TypeDecl {
|
|
|
|
match stmt {
|
2020-11-25 14:09:40 +03:00
|
|
|
AliasTypeDecl, FnTypeDecl, SumTypeDecl { return stmt.pos }
|
2020-12-25 22:43:50 +03:00
|
|
|
}
|
|
|
|
}
|
2020-11-04 14:34:12 +03:00
|
|
|
// Please, do NOT use else{} here.
|
|
|
|
// This match is exhaustive *on purpose*, to help force
|
|
|
|
// maintaining/implementing proper .pos fields.
|
2020-04-29 13:31:18 +03:00
|
|
|
}
|
|
|
|
}
|
2020-05-02 22:51:55 +03:00
|
|
|
|
2021-01-09 07:36:38 +03:00
|
|
|
pub fn (node Node) position() token.Position {
|
|
|
|
match node {
|
|
|
|
Stmt {
|
|
|
|
mut pos := node.position()
|
|
|
|
if node is Import {
|
|
|
|
for sym in node.syms {
|
|
|
|
pos = pos.extend(sym.pos)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pos
|
|
|
|
}
|
|
|
|
Expr {
|
|
|
|
return node.position()
|
|
|
|
}
|
|
|
|
StructField {
|
|
|
|
return node.pos.extend(node.type_pos)
|
|
|
|
}
|
|
|
|
MatchBranch, SelectBranch, Field, EnumField, ConstField, StructInitField, GlobalField, table.Param {
|
|
|
|
return node.pos
|
|
|
|
}
|
|
|
|
IfBranch {
|
|
|
|
return node.pos.extend(node.body_pos)
|
|
|
|
}
|
|
|
|
ScopeObject {
|
|
|
|
match node {
|
|
|
|
ConstField, GlobalField, Var { return node.pos }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
File {
|
|
|
|
mut pos := token.Position{}
|
|
|
|
if node.stmts.len > 0 {
|
|
|
|
first_pos := node.stmts.first().position()
|
|
|
|
last_pos := node.stmts.last().position()
|
|
|
|
pos = first_pos.extend_with_last_line(last_pos, last_pos.line_nr)
|
|
|
|
}
|
|
|
|
return pos
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (node Node) children() []Node {
|
|
|
|
mut children := []Node{}
|
|
|
|
if node is Expr {
|
|
|
|
match node {
|
|
|
|
StringInterLiteral, Assoc, ArrayInit {
|
|
|
|
return node.exprs.map(Node(it))
|
|
|
|
}
|
|
|
|
SelectorExpr, PostfixExpr, UnsafeExpr, AsCast, ParExpr, IfGuardExpr, SizeOf, Likely, TypeOf, ArrayDecompose {
|
|
|
|
children << node.expr
|
|
|
|
}
|
|
|
|
LockExpr, OrExpr {
|
|
|
|
return node.stmts.map(Node(it))
|
|
|
|
}
|
|
|
|
StructInit {
|
|
|
|
return node.fields.map(Node(it))
|
|
|
|
}
|
|
|
|
AnonFn {
|
|
|
|
children << Stmt(node.decl)
|
|
|
|
}
|
|
|
|
CallExpr {
|
|
|
|
children << node.left
|
|
|
|
children << Expr(node.or_block)
|
|
|
|
}
|
|
|
|
InfixExpr {
|
|
|
|
children << node.left
|
|
|
|
children << node.right
|
|
|
|
}
|
|
|
|
PrefixExpr {
|
|
|
|
children << node.right
|
|
|
|
}
|
|
|
|
IndexExpr {
|
|
|
|
children << node.left
|
|
|
|
children << node.index
|
|
|
|
}
|
|
|
|
IfExpr {
|
|
|
|
children << node.left
|
|
|
|
children << node.branches.map(Node(it))
|
|
|
|
}
|
|
|
|
MatchExpr {
|
|
|
|
children << node.cond
|
|
|
|
children << node.branches.map(Node(it))
|
|
|
|
}
|
|
|
|
SelectExpr {
|
|
|
|
return node.branches.map(Node(it))
|
|
|
|
}
|
|
|
|
ChanInit {
|
|
|
|
children << node.cap_expr
|
|
|
|
}
|
|
|
|
MapInit {
|
|
|
|
children << node.keys.map(Node(it))
|
|
|
|
children << node.vals.map(Node(it))
|
|
|
|
}
|
|
|
|
RangeExpr {
|
|
|
|
children << node.low
|
|
|
|
children << node.high
|
|
|
|
}
|
|
|
|
CastExpr {
|
|
|
|
children << node.expr
|
|
|
|
children << node.arg
|
|
|
|
}
|
|
|
|
ConcatExpr {
|
|
|
|
return node.vals.map(Node(it))
|
|
|
|
}
|
|
|
|
ComptimeCall, ComptimeSelector {
|
|
|
|
children << node.left
|
|
|
|
}
|
|
|
|
else {}
|
|
|
|
}
|
|
|
|
} else if node is Stmt {
|
|
|
|
match node {
|
|
|
|
Block, DeferStmt, ForCStmt, ForInStmt, ForStmt, CompFor {
|
|
|
|
return node.stmts.map(Node(it))
|
|
|
|
}
|
|
|
|
ExprStmt, AssertStmt {
|
|
|
|
children << node.expr
|
|
|
|
}
|
|
|
|
InterfaceDecl {
|
|
|
|
return node.methods.map(Node(Stmt(it)))
|
|
|
|
}
|
|
|
|
AssignStmt {
|
|
|
|
children << node.left.map(Node(it))
|
|
|
|
children << node.right.map(Node(it))
|
|
|
|
}
|
|
|
|
Return {
|
|
|
|
return node.exprs.map(Node(it))
|
|
|
|
}
|
|
|
|
// NB: these four decl nodes cannot be merged as one branch
|
|
|
|
StructDecl {
|
|
|
|
return node.fields.map(Node(it))
|
|
|
|
}
|
|
|
|
GlobalDecl {
|
|
|
|
return node.fields.map(Node(it))
|
|
|
|
}
|
|
|
|
ConstDecl {
|
|
|
|
return node.fields.map(Node(it))
|
|
|
|
}
|
|
|
|
EnumDecl {
|
|
|
|
return node.fields.map(Node(it))
|
|
|
|
}
|
|
|
|
FnDecl {
|
|
|
|
if node.is_method {
|
|
|
|
children << Node(node.receiver)
|
|
|
|
}
|
|
|
|
children << node.params.map(Node(it))
|
|
|
|
children << node.stmts.map(Node(it))
|
|
|
|
}
|
|
|
|
else {}
|
|
|
|
}
|
|
|
|
} else if node is ScopeObject {
|
|
|
|
match node {
|
|
|
|
GlobalField, ConstField, Var { children << node.expr }
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
match node {
|
|
|
|
GlobalField, ConstField, EnumField, StructInitField {
|
|
|
|
children << node.expr
|
|
|
|
}
|
|
|
|
SelectBranch {
|
|
|
|
children << node.stmt
|
|
|
|
children << node.stmts.map(Node(it))
|
|
|
|
}
|
|
|
|
IfBranch, File {
|
|
|
|
return node.stmts.map(Node(it))
|
|
|
|
}
|
|
|
|
MatchBranch {
|
|
|
|
children << node.stmts.map(Node(it))
|
|
|
|
children << node.exprs.map(Node(it))
|
|
|
|
}
|
|
|
|
else {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return children
|
|
|
|
}
|
|
|
|
|
2020-05-02 22:51:55 +03:00
|
|
|
// TODO: remove this fugly hack :-|
|
2020-05-03 22:13:40 +03:00
|
|
|
// fe2ex/1 and ex2fe/1 are used to convert back and forth from
|
2020-05-02 22:51:55 +03:00
|
|
|
// table.FExpr to ast.Expr , which in turn is needed to break
|
|
|
|
// a dependency cycle between v.ast and v.table, for the single
|
|
|
|
// field table.Field.default_expr, which should be ast.Expr
|
|
|
|
pub fn fe2ex(x table.FExpr) Expr {
|
|
|
|
res := Expr{}
|
2020-12-23 21:13:42 +03:00
|
|
|
unsafe { C.memcpy(&res, &x, sizeof(Expr)) }
|
2020-05-02 22:51:55 +03:00
|
|
|
return res
|
|
|
|
}
|
2020-05-18 19:06:09 +03:00
|
|
|
|
2020-05-02 22:51:55 +03:00
|
|
|
pub fn ex2fe(x Expr) table.FExpr {
|
|
|
|
res := table.FExpr{}
|
2020-12-23 21:13:42 +03:00
|
|
|
unsafe { C.memcpy(&res, &x, sizeof(table.FExpr)) }
|
2020-05-02 22:51:55 +03:00
|
|
|
return res
|
|
|
|
}
|