v/vlib/v/ast/ast.v

1164 lines
21 KiB
V
Raw Normal View History

2020-01-23 21:04:46 +01:00
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
2019-12-22 02:34:37 +01: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 00:07:57 +02:00
import v.token
import v.table
import v.errors
2019-12-22 02:34:37 +01:00
2020-04-25 20:58:00 +02:00
pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CallExpr | CastExpr |
2020-09-05 12:00:35 +02:00
ChanInit | CharLiteral | Comment | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral |
Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr |
SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit | Type |
TypeOf | UnsafeExpr
2020-05-18 18:08:28 +02:00
pub type Stmt = AssertStmt | AssignStmt | Block | BranchStmt | CompFor | CompIf | ConstDecl |
DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl |
GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return |
SqlStmt | StructDecl | TypeDecl
pub type ScopeObject = ConstField | GlobalDecl | Var
// pub type Type = StructType | ArrayType
// pub struct StructType {
// fields []Field
// }
// pub struct ArrayType {}
pub struct Type {
2020-03-02 10:53:38 +01:00
pub:
typ table.Type
pos token.Position
2020-03-02 10:53:38 +01:00
}
// `{stmts}` or `unsafe {stmts}`
2020-03-24 15:44:17 +01:00
pub struct Block {
pub:
stmts []Stmt
is_unsafe bool
2020-03-24 15:44:17 +01:00
}
2020-01-06 16:13:12 +01:00
// | IncDecStmt k
2019-12-28 14:11:05 +01:00
// Stand-alone expression in a statement list.
pub struct ExprStmt {
pub:
expr Expr
pos token.Position
comments []Comment
is_expr bool
2020-05-21 22:35:43 +02:00
pub mut:
typ table.Type
2019-12-28 14:11:05 +01:00
}
2019-12-22 02:34:37 +01:00
2019-12-26 11:21:41 +01:00
pub struct IntegerLiteral {
pub:
val string
2020-04-10 00:09:34 +02:00
pos token.Position
}
2019-12-24 18:54:43 +01:00
2019-12-27 10:03:29 +01:00
pub struct FloatLiteral {
pub:
val string
2020-04-20 14:49:26 +02:00
pos token.Position
2019-12-27 10:03:29 +01:00
}
2019-12-24 18:54:43 +01:00
pub struct StringLiteral {
pub:
val string
is_raw bool
language table.Language
pos token.Position
2019-12-24 18:54:43 +01:00
}
2019-12-22 02:34:37 +01:00
2020-03-21 07:01:06 +01:00
// 'name: $name'
pub struct StringInterLiteral {
pub:
vals []string
exprs []Expr
fwidths []int
precisions []int
pluss []bool
fills []bool
fmt_poss []token.Position
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
2020-03-21 07:01:06 +01:00
expr_types []table.Type
fmts []byte
need_fmts []bool // an explicit non-default fmt required, e.g. `x`
2020-03-21 07:01:06 +01:00
}
2020-02-04 09:54:15 +01:00
pub struct CharLiteral {
pub:
val string
2020-04-20 14:49:26 +02:00
pos token.Position
2020-02-04 09:54:15 +01:00
}
pub struct BoolLiteral {
pub:
val bool
2020-04-20 14:49:26 +02:00
pos token.Position
}
// `foo.bar`
pub struct SelectorExpr {
pub:
2020-05-18 18:06:09 +02:00
pos token.Position
expr Expr // expr.field_name
2020-05-18 18:06:09 +02:00
field_name string
2020-05-09 15:16:48 +02:00
pub mut:
expr_type table.Type // type of `Foo` in `Foo.bar`
2020-06-27 16:19:12 +02:00
typ table.Type // type of the entire thing (`Foo.bar`)
}
2019-12-28 11:02:06 +01:00
// module declaration
pub struct Module {
pub:
2020-04-19 00:07:57 +02:00
name string
path string
expr Expr
2020-05-16 16:12:23 +02:00
pos token.Position
is_skipped bool // module main can be skipped in single file programs
}
2020-04-05 02:08:10 +02:00
pub struct StructField {
pub:
name string
pos token.Position
comments []Comment
default_expr Expr
has_default_expr bool
attrs []table.Attr
2020-05-18 18:06:09 +02:00
is_public bool
2020-05-09 15:16:48 +02:00
pub mut:
typ table.Type
2020-04-05 02:08:10 +02:00
}
pub struct Field {
pub:
name string
2020-04-09 15:33:46 +02:00
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
typ table.Type
}
pub struct ConstField {
pub:
mod string
name string
expr Expr
is_pub bool
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
typ table.Type
comments []Comment
}
pub struct ConstDecl {
pub:
2020-09-05 12:00:35 +02:00
is_pub bool
pos token.Position
pub mut:
2020-09-05 12:00:35 +02:00
fields []ConstField
end_comments []Comment
}
pub struct StructDecl {
pub:
pos token.Position
name string
fields []StructField
is_pub bool
mut_pos int // mut:
pub_pos int // pub:
pub_mut_pos int // pub mut:
language table.Language
is_union bool
attrs []table.Attr
end_comments []Comment
}
pub struct InterfaceDecl {
2020-04-05 12:31:39 +02:00
pub:
2020-03-31 20:26:15 +02:00
name string
field_names []string
2020-07-14 18:52:28 +02:00
is_pub bool
2020-04-22 20:20:49 +02:00
methods []FnDecl
2020-05-18 18:06:09 +02:00
pos token.Position
}
pub struct StructInitField {
pub:
expr Expr
2020-04-19 00:07:57 +02:00
pos token.Position
2020-07-01 20:07:33 +02:00
comment Comment
2020-05-09 15:16:48 +02:00
pub mut:
name string
typ table.Type
expected_type table.Type
}
pub struct StructInit {
pub:
pos token.Position
is_short bool
2020-05-09 15:16:48 +02:00
pub mut:
typ table.Type
fields []StructInitField
}
// import statement
pub struct Import {
pub:
pos token.Position
mod string
alias string
pub mut:
syms []ImportSymbol
}
pub enum ImportSymbolKind {
fn_
type_
}
pub struct ImportSymbol {
pub:
pos token.Position
name string
kind ImportSymbolKind
}
2020-04-17 21:59:19 +02:00
pub struct AnonFn {
pub:
2020-07-14 18:52:28 +02:00
decl FnDecl
2020-05-09 15:16:48 +02:00
pub mut:
2020-07-14 18:52:28 +02:00
typ table.Type
2020-04-17 21:59:19 +02:00
}
2019-12-27 13:57:49 +01:00
pub struct FnDecl {
pub:
2020-03-05 16:13:14 +01:00
name string
mod string
args []table.Arg // parameters
2020-03-05 16:13:14 +01:00
is_deprecated bool
is_pub bool
is_variadic bool
2020-04-17 21:59:19 +02:00
is_anon bool
2020-03-05 16:13:14 +01:00
receiver Field
receiver_pos token.Position
2020-03-05 16:13:14 +01:00
is_method bool
rec_mut bool // is receiver mutable
rec_share table.ShareType
language table.Language
2020-03-06 16:31:40 +01:00
no_body bool // just a definition `fn C.malloc()`
2020-04-10 18:11:43 +02:00
is_builtin bool // this function is defined in builtin/strconv
2020-03-21 19:52:19 +01:00
pos token.Position
body_pos token.Position
file string
2020-05-21 03:58:50 +02:00
is_generic bool
2020-08-24 09:04:50 +02:00
is_direct_arr bool // direct array access
attrs []table.Attr
pub mut:
stmts []Stmt
return_type table.Type
2019-12-29 07:24:17 +01:00
}
pub struct BranchStmt {
pub:
tok token.Token
}
2019-12-29 07:24:17 +01:00
pub struct CallExpr {
pub:
2020-04-09 15:33:46 +02:00
pos token.Position
left Expr // `user` in `user.register()`
mod string
2020-05-09 15:16:48 +02:00
pub mut:
2020-04-09 15:33:46 +02:00
name string
is_method bool
2020-07-13 20:04:16 +02:00
is_field bool // temp hack, remove ASAP when re-impl CallExpr / Selector (joe)
2020-04-09 15:33:46 +02:00
args []CallArg
2020-04-03 15:18:17 +02:00
expected_arg_types []table.Type
language table.Language
2020-04-09 15:33:46 +02:00
or_block OrExpr
left_type table.Type // type of `user`
receiver_type table.Type // User
return_type table.Type
should_be_skipped bool
2020-05-21 03:58:50 +02:00
generic_type table.Type // TODO array, to support multiple types
2020-09-05 12:00:35 +02:00
// autofree_vars []AutofreeArgVar
// autofree_vars_ids []int
}
2020-09-05 12:00:35 +02:00
/*
pub struct AutofreeArgVar {
name string
idx int
}
*/
pub struct CallArg {
pub:
2020-09-05 12:00:35 +02:00
is_mut bool
share table.ShareType
expr Expr
comments []Comment
2020-05-09 15:16:48 +02:00
pub mut:
2020-09-05 12:00:35 +02:00
typ table.Type
2020-09-06 13:02:29 +02:00
is_tmp_autofree bool
2020-09-05 12:00:35 +02:00
// tmp_name string // for autofree
2019-12-27 13:57:49 +01:00
}
pub struct Return {
pub:
pos token.Position
exprs []Expr
comments []Comment
2020-05-09 15:16:48 +02:00
pub mut:
types []table.Type
2019-12-27 13:57:49 +01:00
}
2019-12-22 02:34:37 +01:00
/*
pub enum Expr {
Binary(InfixExpr)
2019-12-22 02:34:37 +01:00
If(IfExpr)
Integer(IntegerExpr)
}
*/
2019-12-24 18:54:43 +01:00
/*
2019-12-22 02:34:37 +01:00
pub struct Stmt {
pos int
//end int
}
2019-12-24 18:54:43 +01:00
*/
pub struct Var {
2019-12-24 18:54:43 +01:00
pub:
name string
expr Expr
share table.ShareType
is_mut bool
is_arg bool // fn args should not be autofreed
2020-05-09 15:16:48 +02:00
pub mut:
typ table.Type
pos token.Position
is_used bool
is_changed bool // to detect mutable vars that are never changed
2019-12-24 18:54:43 +01:00
}
pub struct GlobalDecl {
pub:
2020-04-09 15:33:46 +02:00
name string
expr Expr
2020-04-07 18:51:39 +02:00
has_expr bool
2020-05-16 16:12:23 +02:00
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
2020-04-09 15:33:46 +02:00
typ table.Type
}
2019-12-30 12:10:46 +01:00
pub struct File {
2019-12-24 18:54:43 +01:00
pub:
2020-04-09 15:33:46 +02:00
path string
mod Module
global_scope &Scope
2020-05-09 15:16:48 +02:00
pub mut:
scope &Scope
stmts []Stmt
imports []Import
2020-05-18 18:06:09 +02:00
errors []errors.Error
warnings []errors.Warning
}
pub struct IdentFn {
pub mut:
typ table.Type
}
// TODO: (joe) remove completely, use ident.obj
// instead which points to the scope object
pub struct IdentVar {
pub mut:
2020-03-13 05:57:51 +01:00
typ table.Type
is_mut bool
is_static bool
is_optional bool
share table.ShareType
}
pub type IdentInfo = IdentFn | IdentVar
pub enum IdentKind {
unresolved
blank_ident
variable
constant
global
function
2019-12-24 18:54:43 +01:00
}
2019-12-28 14:11:05 +01:00
2019-12-22 02:34:37 +01:00
// A single identifier
2019-12-28 14:11:05 +01:00
pub struct Ident {
pub:
language table.Language
tok_kind token.Kind
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
obj ScopeObject
mod string
name string
kind IdentKind
info IdentInfo
is_mut bool
2019-12-22 02:34:37 +01:00
}
2020-02-07 14:49:14 +01:00
pub fn (i &Ident) var_info() IdentVar {
2020-06-19 11:46:08 +02:00
match i.info as info {
2020-02-06 17:38:02 +01:00
IdentVar {
return *info
2020-02-06 17:38:02 +01:00
}
else {
// return IdentVar{}
panic('Ident.var_info(): info is not IdentVar variant')
}
}
}
pub struct InfixExpr {
2019-12-22 02:34:37 +01:00
pub:
2020-07-14 18:52:28 +02:00
op token.Kind
pos token.Position
left Expr
right Expr
2020-05-09 15:16:48 +02:00
pub mut:
2020-07-14 18:52:28 +02:00
left_type table.Type
right_type table.Type
auto_locked string
2019-12-22 02:34:37 +01:00
}
2020-01-06 16:13:12 +01:00
pub struct PostfixExpr {
pub:
2020-07-14 18:52:28 +02:00
op token.Kind
expr Expr
pos token.Position
pub mut:
2020-07-14 18:52:28 +02:00
auto_locked string
2020-01-06 16:13:12 +01:00
}
pub struct PrefixExpr {
pub:
op token.Kind
right Expr
pos token.Position
pub mut:
right_type table.Type
or_block OrExpr
2020-01-06 16:13:12 +01:00
}
2020-01-07 12:14:10 +01:00
pub struct IndexExpr {
pub:
2020-04-09 15:33:46 +02:00
pos token.Position
left Expr
index Expr // [0] or RangeExpr [start..end]
2020-05-09 15:16:48 +02:00
pub mut:
left_type table.Type // array, map, fixed array
2020-04-09 15:33:46 +02:00
is_setter bool
2020-01-07 12:14:10 +01:00
}
2019-12-28 19:16:04 +01:00
pub struct IfExpr {
pub:
tok_kind token.Kind
left Expr // `a` in `a := if ...`
pos token.Position
post_comments []Comment
2020-05-09 15:16:48 +02:00
pub mut:
branches []IfBranch // includes all `else if` branches
is_expr bool
typ table.Type
has_else bool
}
pub struct IfBranch {
pub:
2020-07-14 18:52:28 +02:00
cond Expr
stmts []Stmt
pos token.Position
body_pos token.Position
comments []Comment
left_as_name string // `name` in `if cond is SumType as name`
mut_name bool // `if mut name is`
2020-07-08 15:17:28 +02:00
pub mut:
smartcast bool // true when cond is `x is SumType`, set in checker.if_expr
}
2020-07-12 12:58:33 +02:00
pub struct UnsafeExpr {
pub:
2020-07-14 18:52:28 +02:00
stmts []Stmt
pos token.Position
2020-07-12 12:58:33 +02:00
}
pub struct LockExpr {
pub:
stmts []Stmt
is_rlock bool
pos token.Position
pub mut:
lockeds []Ident // `x`, `y` in `lock x, y {`
is_expr bool
typ table.Type
}
pub struct MatchExpr {
pub:
tok_kind token.Kind
cond Expr
branches []MatchBranch
pos token.Position
2020-04-09 15:33:46 +02:00
is_mut bool // `match mut ast_node {`
var_name string // `match cond as var_name {`
2020-05-09 15:16:48 +02:00
pub mut:
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-05-31 10:22:18 +02:00
is_interface bool
}
2020-03-04 11:59:45 +01:00
pub struct MatchBranch {
pub:
exprs []Expr // left side
stmts []Stmt // right side
pos token.Position
comment Comment // comment above `xxx {`
is_else bool
post_comments []Comment
2020-03-04 11:59:45 +01:00
}
/*
CompIf.is_opt:
`$if xyz? {}` => this compile time `if` is optional,
and .is_opt reflects the presence of ? at the end.
When .is_opt is true, the code should compile, even
if `xyz` is NOT defined.
If .is_opt is false, then when `xyz` is not defined,
the compilation will fail.
`$if method.type is string {}` will produce CompIf with:
.is_typecheck true,
.tchk_expr: method.type
.tchk_type: string
.tchk_match: true on each iteration, having a string `method.type`
*/
pub enum CompIfKind {
platform
typecheck
}
pub struct CompIf {
pub:
val string
stmts []Stmt
is_not bool
kind CompIfKind
tchk_expr Expr
tchk_type table.Type
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
tchk_match bool
is_opt bool
2020-03-22 14:54:31 +01:00
has_else bool
else_stmts []Stmt
2019-12-22 02:34:37 +01:00
}
pub enum CompForKind {
methods
fields
}
pub struct CompFor {
pub:
val_var string
stmts []Stmt
kind CompForKind
pub mut:
// expr Expr
typ table.Type
}
pub struct ForStmt {
pub:
2020-02-19 11:06:36 +01:00
cond Expr
stmts []Stmt
is_inf bool // `for {}`
pos token.Position
2020-01-07 00:14:19 +01:00
}
pub struct ForInStmt {
pub:
2020-03-24 07:25:10 +01: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-05-09 15:16:48 +02:00
pub mut:
2020-03-24 07:25:10 +01:00
key_type table.Type
val_type table.Type
cond_type table.Type
kind table.Kind // array/map/string
2020-01-07 00:14:19 +01:00
}
pub struct ForCStmt {
pub:
init Stmt // i := 0;
has_init bool
cond Expr // i < 10;
has_cond bool
inc Stmt // i++; i += 2
has_inc bool
stmts []Stmt
pos token.Position
}
2020-02-04 09:54:15 +01:00
// #include etc
pub struct HashStmt {
pub:
mod string
pos token.Position
pub mut:
val string
2020-02-04 09:54:15 +01:00
}
2020-08-12 05:54:51 +02:00
/*
// filter(), map(), sort()
2020-02-10 14:42:57 +01:00
pub struct Lambda {
pub:
name string
}
2020-08-12 05:54:51 +02:00
*/
2019-12-28 19:16:04 +01:00
pub struct AssignStmt {
pub:
2020-05-27 03:20:22 +02:00
right []Expr
op token.Kind
pos token.Position
comments []Comment
pub mut:
left []Expr
2020-05-27 03:20:22 +02:00
left_types []table.Type
right_types []table.Type
is_static bool // for translated code only
is_simple bool // `x+=2` in `for x:=1; ; x+=2`
2020-05-26 18:00:51 +02:00
has_cross_var bool
2019-12-28 19:16:04 +01:00
}
2020-02-06 17:38:02 +01:00
pub struct AsCast {
pub:
2020-03-18 13:55:46 +01:00
expr Expr
typ table.Type
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
2020-03-18 13:55:46 +01:00
expr_type table.Type
}
pub struct EnumVal {
pub:
2020-02-25 15:02:34 +01:00
enum_name string
val string
2020-03-15 00:46:08 +01:00
mod string // for full path `mod_Enum_val`
2020-02-25 15:02:34 +01:00
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
2020-03-15 02:51:31 +01:00
typ table.Type
}
2020-04-09 19:23:49 +02:00
pub struct EnumField {
2020-05-18 18:06:09 +02:00
pub:
2020-04-10 14:44:01 +02:00
name string
pos token.Position
comments []Comment
2020-04-10 14:44:01 +02:00
expr Expr
has_expr bool
2020-04-09 19:23:49 +02:00
}
pub struct EnumDecl {
pub:
name string
is_pub bool
is_flag bool // true when the enum has [flag] tag
is_multi_allowed bool
comments []Comment // enum Abc { /* comments */ ... }
fields []EnumField
pos token.Position
}
pub struct AliasTypeDecl {
pub:
2020-03-07 22:37:03 +01:00
name string
is_pub bool
parent_type table.Type
2020-04-19 00:07:57 +02:00
pos token.Position
}
pub struct SumTypeDecl {
pub:
2020-03-07 22:37:03 +01:00
name string
is_pub bool
sub_types []table.Type
2020-04-19 00:07:57 +02:00
pos token.Position
}
pub struct FnTypeDecl {
pub:
name string
is_pub bool
typ table.Type
2020-04-19 00:07:57 +02:00
pos token.Position
}
2020-04-09 15:33:46 +02:00
// TODO: handle this differently
// v1 excludes non current os ifdefs so
// the defer's never get added in the first place
2020-02-17 22:50:04 +01:00
pub struct DeferStmt {
2020-02-11 10:26:46 +01:00
pub:
2020-02-17 22:50:04 +01:00
stmts []Stmt
2020-05-09 15:16:48 +02:00
pub mut:
ifdef string
2020-02-11 10:26:46 +01:00
}
2020-02-28 14:41:19 +01:00
// `(3+4)`
pub struct ParExpr {
pub:
expr Expr
}
pub struct GoStmt {
pub:
2020-04-03 15:18:17 +02:00
call_expr Expr
}
2020-02-17 22:50:04 +01:00
pub struct GotoLabel {
2020-02-17 14:15:42 +01:00
pub:
2020-02-17 22:50:04 +01:00
name string
2020-02-17 14:15:42 +01:00
}
pub struct GotoStmt {
pub:
2020-02-17 22:50:04 +01:00
name string
2020-02-17 14:15:42 +01:00
}
2019-12-30 09:38:12 +01:00
pub struct ArrayInit {
pub:
2020-04-29 12:20:22 +02:00
pos token.Position
2020-05-31 10:22:18 +02:00
elem_type_pos token.Position
exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array
2020-04-29 12:20:22 +02:00
is_fixed bool
has_val bool // fixed size literal `[expr, expr]!!`
2020-04-29 12:20:22 +02:00
mod string
len_expr Expr
cap_expr Expr
default_expr Expr // init: expr
2020-04-29 12:20:22 +02:00
has_len bool
has_cap bool
has_default bool
2020-05-09 15:16:48 +02:00
pub mut:
2020-04-29 12:20:22 +02:00
is_interface bool // array of interfaces e.g. `[]Animal` `[Dog{}, Cat{}]`
interface_types []table.Type // [Dog, Cat]
interface_type table.Type // Animal
elem_type table.Type
typ table.Type
2019-12-30 09:38:12 +01:00
}
pub struct ChanInit {
pub:
2020-09-05 12:00:35 +02:00
pos token.Position
cap_expr Expr
has_cap bool
pub mut:
2020-09-05 12:00:35 +02:00
typ table.Type
elem_type table.Type
}
2020-02-22 14:13:19 +01:00
pub struct MapInit {
pub:
2020-03-07 16:23:10 +01:00
pos token.Position
keys []Expr
vals []Expr
2020-05-09 15:16:48 +02:00
pub mut:
2020-03-07 16:23:10 +01:00
typ table.Type
2020-03-07 08:13:00 +01:00
key_type table.Type
value_type table.Type
2020-02-22 14:13:19 +01:00
}
2020-02-02 14:31:54 +01:00
// s[10..20]
pub struct RangeExpr {
pub:
2020-03-06 22:24:39 +01:00
low Expr
high Expr
has_high bool
has_low bool
2020-02-02 14:31:54 +01: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)`.
pub struct CastExpr {
pub:
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`
2020-05-06 12:05:24 +02:00
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
typname string
expr_type table.Type // `byteptr`
has_arg bool
in_prexpr bool // is the parent node an ast.PrefixExpr
}
pub struct AssertStmt {
pub:
expr Expr
2020-03-26 10:44:59 +01:00
pos token.Position
}
// `if [x := opt()] {`
pub struct IfGuardExpr {
pub:
2020-03-17 16:40:41 +01:00
var_name string
expr Expr
2020-05-09 15:16:48 +02:00
pub mut:
2020-03-17 16:40:41 +01:00
expr_type table.Type
}
2020-05-23 08:51:15 +02:00
pub enum OrKind {
absent
block
propagate
}
// `or { ... }`
pub struct OrExpr {
pub:
2020-05-23 08:51:15 +02:00
stmts []Stmt
kind OrKind
pos token.Position
}
pub struct Assoc {
pub:
var_name string
fields []string
exprs []Expr
pos token.Position
2020-05-09 15:16:48 +02:00
pub mut:
2020-03-19 09:52:33 +01:00
typ table.Type
}
2020-02-18 18:13:34 +01:00
pub struct SizeOf {
pub:
is_type bool
typ table.Type
2020-02-18 18:13:34 +01:00
type_name string
expr Expr
pos token.Position
2020-02-18 18:13:34 +01:00
}
pub struct Likely {
pub:
2020-06-16 12:14:22 +02:00
expr Expr
pos token.Position
is_likely bool // false for _unlikely_
}
2020-03-19 12:15:39 +01:00
pub struct TypeOf {
pub:
2020-03-31 19:43:11 +02:00
expr Expr
2020-05-09 15:16:48 +02:00
pub mut:
2020-03-28 17:37:22 +01:00
expr_type table.Type
2020-03-19 12:15:39 +01:00
}
2020-04-05 02:08:10 +02:00
pub struct Comment {
2020-02-18 20:20:15 +01:00
pub:
2020-04-09 15:33:46 +02:00
text string
2020-04-05 02:08:10 +02:00
is_multi bool
2020-04-09 15:33:46 +02:00
line_nr int
pos token.Position
2020-02-18 20:20:15 +01:00
}
2020-03-01 14:57:54 +01:00
pub struct ConcatExpr {
pub:
2020-05-18 18:06:09 +02:00
vals []Expr
2020-05-15 23:14:53 +02:00
pub mut:
return_type table.Type
2020-03-01 14:57:54 +01:00
}
pub struct ComptimeCall {
pub:
method_name string
left Expr
2020-06-06 21:36:24 +02:00
is_vweb bool
vweb_tmpl File
args_var string
pub mut:
sym table.TypeSymbol
}
2020-02-19 19:54:36 +01:00
pub struct None {
pub:
2020-06-16 12:14:22 +02:00
pos token.Position
foo int // todo
}
2020-06-19 16:43:32 +02:00
/*
pub enum SqlExprKind {
select_
insert
update
}
*/
2020-06-24 14:32:14 +02:00
pub enum SqlStmtKind {
insert
update
delete
}
pub struct SqlStmt {
2020-06-19 16:43:32 +02:00
pub:
2020-06-27 16:19:12 +02:00
kind SqlStmtKind
db_expr Expr // `db` in `sql db {`
2020-06-19 16:43:32 +02:00
object_var_name string // `user`
table_type table.Type
2020-06-27 16:19:12 +02:00
pos token.Position
where_expr Expr
updated_columns []string // for `update set x=y`
update_exprs []Expr // for `update`
pub mut:
2020-06-27 16:19:12 +02:00
table_name string
fields []table.Field
2020-06-19 16:43:32 +02:00
}
2020-06-16 12:14:22 +02:00
pub struct SqlExpr {
2020-06-17 00:59:33 +02:00
pub:
2020-06-27 16:19:12 +02: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 19:29:22 +02:00
has_order bool
order_expr Expr
has_desc bool
2020-06-27 16:19:12 +02:00
is_array bool
table_type table.Type
pos token.Position
has_limit bool
limit_expr Expr
pub mut:
2020-06-27 16:19:12 +02:00
table_name string
fields []table.Field
2020-02-19 19:54:36 +01:00
}
2020-03-18 01:19:23 +01:00
[inline]
pub fn (expr Expr) is_blank_ident() bool {
2020-03-18 01:19:23 +01:00
match expr {
2020-06-19 11:46:08 +02:00
Ident { return expr.kind == .blank_ident }
2020-04-19 00:07:57 +02:00
else { return false }
2020-03-18 01:19:23 +01:00
}
}
pub fn (expr Expr) position() token.Position {
// all uncommented have to be implemented
2020-04-22 20:20:49 +02:00
match mut expr {
AnonFn {
return expr.decl.pos
}
2020-04-22 20:20:49 +02:00
ArrayInit {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
AsCast {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
Assoc {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
BoolLiteral {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
// ast.Ident { }
2020-04-22 20:20:49 +02:00
CallExpr {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
CastExpr {
return expr.pos
}
2020-04-22 20:20:49 +02:00
CharLiteral {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
Comment {
return expr.pos
}
2020-04-22 20:20:49 +02:00
EnumVal {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
FloatLiteral {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
Ident {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
IfExpr {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
2020-07-04 23:38:12 +02:00
// ast.IfGuardExpr { }
2020-04-22 20:20:49 +02:00
IndexExpr {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
InfixExpr {
2020-06-19 11:46:08 +02:00
left_pos := expr.left.position()
right_pos := expr.right.position()
2020-06-27 16:19:12 +02:00
if left_pos.pos == 0 || right_pos.pos == 0 {
2020-06-19 11:46:08 +02:00
return expr.pos
}
return token.Position{
2020-06-19 11:46:08 +02:00
line_nr: expr.pos.line_nr
pos: left_pos.pos
len: right_pos.pos - left_pos.pos + right_pos.len
}
}
2020-04-22 20:20:49 +02:00
IntegerLiteral {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
MapInit {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
MatchExpr {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
None {
2020-06-19 11:46:08 +02:00
return expr.pos
}
2020-04-22 20:20:49 +02:00
PostfixExpr {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
2020-07-04 23:38:12 +02:00
// ast.None { }
2020-04-22 20:20:49 +02:00
PrefixExpr {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
2020-07-04 23:38:12 +02:00
// ast.ParExpr { }
2020-04-22 20:20:49 +02:00
SelectorExpr {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
SizeOf {
return expr.pos
}
2020-04-22 20:20:49 +02:00
StringLiteral {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
StringInterLiteral {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
2020-07-04 23:38:12 +02:00
// ast.Type { }
2020-04-22 20:20:49 +02:00
StructInit {
2020-06-19 11:46:08 +02:00
return expr.pos
2020-04-22 20:20:49 +02:00
}
Likely {
2020-06-19 11:46:08 +02:00
return expr.pos
}
2020-07-04 23:38:12 +02:00
// ast.TypeOf { }
2020-04-22 20:20:49 +02:00
else {
return token.Position{}
}
}
}
2020-04-29 12:31:18 +02:00
pub fn (expr Expr) is_lvalue() bool {
match expr {
2020-09-05 12:00:35 +02:00
Ident { return true }
IndexExpr { return expr.left.is_lvalue() }
SelectorExpr { return expr.expr.is_lvalue() }
else {}
}
return false
}
pub fn (stmt Stmt) position() token.Position {
match stmt {
2020-06-19 11:46:08 +02:00
AssertStmt { return stmt.pos }
AssignStmt { return stmt.pos }
2020-07-04 23:38:12 +02:00
/*
// Attr {
2020-04-29 12:31:18 +02:00
// }
// Block {
// }
// BranchStmt {
// }
2020-07-04 23:38:12 +02:00
*/
2020-06-19 11:46:08 +02:00
CompIf { return stmt.pos }
ConstDecl { return stmt.pos }
2020-07-04 23:38:12 +02:00
/*
// DeferStmt {
2020-04-29 12:31:18 +02:00
// }
2020-07-04 23:38:12 +02:00
*/
2020-06-19 11:46:08 +02:00
EnumDecl { return stmt.pos }
ExprStmt { return stmt.pos }
FnDecl { return stmt.pos }
ForCStmt { return stmt.pos }
ForInStmt { return stmt.pos }
ForStmt { return stmt.pos }
2020-07-04 23:38:12 +02:00
/*
// GlobalDecl {
2020-04-29 12:31:18 +02:00
// }
// GoStmt {
// }
// GotoLabel {
// }
// GotoStmt {
// }
// HashStmt {
// }
2020-07-04 23:38:12 +02:00
*/
2020-06-19 11:46:08 +02:00
Import { return stmt.pos }
2020-07-04 23:38:12 +02:00
/*
// InterfaceDecl {
2020-04-29 12:31:18 +02:00
// }
// Module {
// }
2020-07-04 23:38:12 +02:00
*/
2020-06-19 11:46:08 +02:00
Return { return stmt.pos }
StructDecl { return stmt.pos }
2020-07-04 23:38:12 +02:00
/*
// TypeDecl {
2020-04-29 12:31:18 +02:00
// }
2020-07-04 23:38:12 +02:00
*/
//
2020-05-18 18:06:09 +02:00
else { return token.Position{} }
2020-04-29 12:31:18 +02:00
}
}
// TODO: remove this fugly hack :-|
// fe2ex/1 and ex2fe/1 are used to convert back and forth from
// 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{}
unsafe {
C.memcpy(&res, &x, sizeof(Expr))
}
return res
}
2020-05-18 18:06:09 +02:00
pub fn ex2fe(x Expr) table.FExpr {
res := table.FExpr{}
unsafe {
C.memcpy(&res, &x, sizeof(table.FExpr))
}
return res
}