v/vlib/v/ast/ast.v

725 lines
11 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
import (
v.token
v.table
2019-12-22 02:34:37 +01:00
)
pub type TypeDecl = AliasTypeDecl | SumTypeDecl | FnTypeDecl
2020-04-09 15:33:46 +02:00
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | AssignExpr | PrefixExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr | ConcatExpr | Type | AsCast | TypeOf | StringInterLiteral
2020-04-09 15:33:46 +02:00
pub type Stmt = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | Comment | AssertStmt | UnsafeStmt | GoStmt | Block | InterfaceDecl
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
2020-03-02 10:53:38 +01:00
}
2020-03-24 15:44:17 +01:00
pub struct Block {
pub:
stmts []Stmt
}
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
typ table.Type
pos token.Position
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
}
2019-12-24 18:54:43 +01:00
pub struct StringLiteral {
pub:
2020-03-24 17:07:27 +01:00
val string
is_raw bool
is_c bool
2020-04-15 23:16:49 +02:00
is_js bool
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
expr_fmts []string
pos token.Position
2020-03-21 07:01:06 +01:00
mut:
expr_types []table.Type
}
2020-02-04 09:54:15 +01:00
pub struct CharLiteral {
pub:
val string
}
pub struct BoolLiteral {
pub:
val bool
}
// `foo.bar`
pub struct SelectorExpr {
pub:
2020-03-07 04:45:35 +01:00
pos token.Position
expr Expr
field string
mut:
expr_type table.Type
}
2019-12-28 11:02:06 +01:00
// module declaration
pub struct Module {
pub:
2019-12-28 09:43:22 +01:00
name string
path string
expr Expr
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
comment Comment
default_expr Expr
has_default_expr bool
attr string
2020-04-05 02:08:10 +02:00
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
mut:
typ table.Type
}
pub struct ConstField {
pub:
name string
expr Expr
is_pub bool
pos token.Position
mut:
typ table.Type
}
pub struct ConstDecl {
pub:
fields []ConstField
is_pub bool
pos token.Position
}
pub struct StructDecl {
pub:
2020-04-09 15:33:46 +02:00
pos token.Position
name string
fields []StructField
is_pub bool
mut_pos int // mut:
pub_pos int // pub:
pub_mut_pos int // pub mut:
is_c bool
2020-04-15 23:16:49 +02:00
is_js bool
2020-04-09 15:33:46 +02:00
is_union bool
}
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
}
pub struct StructInit {
pub:
2020-03-19 09:40:21 +01:00
pos token.Position
fields []string
exprs []Expr
mut:
2020-04-02 00:10:11 +02:00
typ table.Type
2020-03-19 09:40:21 +01:00
expr_types []table.Type
expected_types []table.Type
}
// import statement
pub struct Import {
pub:
pos token.Position
mod string
alias string
}
2019-12-27 13:57:49 +01:00
pub struct FnDecl {
pub:
2020-03-05 16:13:14 +01:00
name string
stmts []Stmt
return_type table.Type
args []table.Arg
2020-03-05 16:13:14 +01:00
is_deprecated bool
is_pub bool
is_variadic bool
receiver Field
is_method bool
rec_mut bool // is receiver mutable
is_c bool
2020-04-15 23:16:49 +02:00
is_js bool
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
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()`
is_method bool
mod string
mut:
2020-04-09 15:33:46 +02:00
name string
args []CallArg
2020-04-03 15:18:17 +02:00
expected_arg_types []table.Type
2020-04-09 15:33:46 +02:00
is_c bool
2020-04-15 23:16:49 +02:00
is_js bool
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
}
pub struct CallArg {
pub:
is_mut bool
expr Expr
mut:
typ table.Type
2019-12-27 13:57:49 +01:00
}
pub struct Return {
pub:
2020-03-06 13:43:22 +01:00
pos token.Position
exprs []Expr
2020-03-16 07:42:45 +01:00
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
is_mut bool
mut:
typ table.Type
pos token.Position
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
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
imports []Import
stmts []Stmt
scope &Scope
global_scope &Scope
}
pub struct IdentFn {
pub mut:
typ table.Type
}
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
}
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:
value string
is_c bool
2020-04-15 23:16:49 +02:00
is_js bool
tok_kind token.Kind
mod string
pos token.Position
2020-04-11 04:09:41 +02:00
is_mut bool
mut:
name string
kind IdentKind
info IdentInfo
2019-12-22 02:34:37 +01:00
}
2020-02-07 14:49:14 +01:00
pub fn (i &Ident) var_info() IdentVar {
2020-02-06 17:38:02 +01:00
match i.info {
IdentVar {
return it
}
else {
// return IdentVar{}
panic('Ident.var_info(): info is not IdentVar variant')
}
}
}
pub struct InfixExpr {
2019-12-22 02:34:37 +01:00
pub:
op token.Kind
pos token.Position
left Expr
right Expr
2020-03-07 04:45:35 +01:00
mut:
2020-03-07 00:34:14 +01:00
left_type table.Type
right_type table.Type
2019-12-22 02:34:37 +01:00
}
2020-01-06 16:13:12 +01:00
pub struct PostfixExpr {
pub:
op token.Kind
expr Expr
2020-02-04 07:37:38 +01:00
pos token.Position
2020-01-06 16:13:12 +01:00
}
pub struct PrefixExpr {
pub:
op token.Kind
right Expr
2020-03-28 14:38:16 +01:00
pos token.Position
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], [start..end] etc
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
branches []IfBranch
left Expr // `a` in `a := if ...`
pos token.Position
mut:
is_expr bool
typ table.Type
has_else bool
}
pub struct IfBranch {
pub:
2020-04-09 15:33:46 +02:00
cond Expr
stmts []Stmt
pos token.Position
comment Comment
}
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 {`
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-03-04 11:59:45 +01:00
pub struct MatchBranch {
pub:
exprs []Expr // left side
stmts []Stmt // right side
2020-04-09 15:33:46 +02:00
pos token.Position
comment Comment // comment above `xxx {`
2020-04-14 01:03:31 +02:00
is_else bool
2020-03-04 11:59:45 +01:00
}
pub struct CompIf {
pub:
2020-03-22 13:55:39 +01:00
val string
stmts []Stmt
is_not bool
2020-03-22 11:53:08 +01:00
pos token.Position
mut:
2020-03-22 14:54:31 +01:00
has_else bool
else_stmts []Stmt
2019-12-22 02:34:37 +01:00
}
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-03-21 10:22:16 +01:00
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 Expr // i++;
has_inc bool
stmts []Stmt
pos token.Position
}
2019-12-28 19:16:04 +01:00
pub struct ReturnStmt {
2020-03-18 15:39:26 +01:00
pub:
tok_kind token.Kind // or pos
2019-12-28 09:43:22 +01:00
results []Expr
pos token.Position
2019-12-22 02:34:37 +01:00
}
2020-02-04 09:54:15 +01:00
// #include etc
pub struct HashStmt {
pub:
2020-03-05 00:43:02 +01:00
val string
2020-02-04 09:54:15 +01:00
}
2020-02-10 14:42:57 +01:00
// filter(), map()
pub struct Lambda {
pub:
name string
}
2019-12-28 19:16:04 +01:00
pub struct AssignStmt {
pub:
2020-03-16 07:42:45 +01:00
left []Ident
right []Expr
op token.Kind
pos token.Position
mut:
left_types []table.Type
right_types []table.Type
2020-04-01 13:38:05 +02:00
is_static bool // for translated code only
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-03-18 13:55:46 +01:00
mut:
expr_type table.Type
}
// e.g. `[unsafe_fn]`
pub struct Attr {
pub:
name string
}
2019-12-28 19:16:04 +01:00
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-03-15 02:51:31 +01:00
mut:
typ table.Type
}
2020-04-09 19:23:49 +02:00
pub struct EnumField {
2020-04-10 14:44:01 +02:00
name string
pos token.Position
expr Expr
has_expr bool
2020-04-09 19:23:49 +02:00
}
pub struct EnumDecl {
pub:
2020-03-31 19:43:11 +02:00
name string
is_pub bool
2020-04-09 19:23:49 +02:00
fields []EnumField
// vals []string
// default_exprs []Expr
}
pub struct AliasTypeDecl {
pub:
2020-03-07 22:37:03 +01:00
name string
is_pub bool
parent_type table.Type
}
pub struct SumTypeDecl {
pub:
2020-03-07 22:37:03 +01:00
name string
is_pub bool
sub_types []table.Type
}
pub struct FnTypeDecl {
pub:
name string
is_pub bool
typ table.Type
}
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
mut:
ifdef string
2020-02-11 10:26:46 +01:00
}
2020-02-26 20:45:03 +01:00
pub struct UnsafeStmt {
pub:
stmts []Stmt
}
2020-02-28 14:41:19 +01:00
// `(3+4)`
pub struct ParExpr {
pub:
expr Expr
}
2020-01-06 16:13:12 +01:00
pub struct AssignExpr {
pub:
2020-03-16 07:42:45 +01:00
op token.Kind
pos token.Position
left Expr
val Expr
mut:
2020-03-16 07:42:45 +01:00
left_type table.Type
right_type table.Type
2020-01-06 16:13:12 +01:00
}
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:
pos token.Position
exprs []Expr
is_fixed bool
mod string
mut:
2020-03-04 02:50:32 +01:00
elem_type table.Type
typ table.Type
2019-12-30 09:38:12 +01:00
}
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-02-22 14:13:19 +01:00
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
}
pub struct CastExpr {
pub:
expr Expr // `buf`
arg Expr // `n` in `string(buf, n)`
typ table.Type // `string`
typname string
mut:
expr_type table.Type // `byteptr`
has_arg bool
}
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
mut:
expr_type table.Type
}
// `or { ... }`
pub struct OrExpr {
pub:
2020-04-09 15:33:46 +02:00
stmts []Stmt
is_used bool // if the or{} block is written down or left out
}
pub struct Assoc {
pub:
var_name string
fields []string
exprs []Expr
pos token.Position
2020-03-19 09:52:33 +01:00
mut:
typ table.Type
}
2020-02-18 18:13:34 +01:00
pub struct SizeOf {
pub:
typ table.Type
2020-02-18 18:13:34 +01:00
type_name string
}
2020-03-19 12:15:39 +01:00
pub struct TypeOf {
pub:
2020-03-31 19:43:11 +02:00
expr Expr
2020-03-28 17:37:22 +01:00
mut:
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:
vals []Expr
}
2020-02-19 19:54:36 +01:00
pub struct None {
pub:
foo int // todo
}
2020-03-18 01:19:23 +01:00
[inline]
pub fn expr_is_blank_ident(expr Expr) bool {
match expr {
Ident {
return it.kind == .blank_ident
}
else {
return false
}
}
}
[inline]
pub fn expr_is_call(expr Expr) bool {
return match expr {
2020-04-09 15:33:46 +02:00
CallExpr {
2020-03-18 01:19:23 +01:00
true
}
else {
2020-04-09 15:33:46 +02:00
false
}
2020-03-18 01:19:23 +01:00
}
}