all: a massive merge of ast and table modules

pull/9554/head^2
Alexander Medvednikov 2021-04-02 01:57:09 +03:00
parent 043f6420f7
commit 7385f8e56b
88 changed files with 1839 additions and 1792 deletions

View File

@ -1,5 +1,12 @@
module main
import os
import log
import flag
import time
import vweb
import net.urllib
// This tool regenerates V's bootstrap .c files
// every time the V master branch is updated.
// if run with the --serve flag it will run in webhook
@ -13,12 +20,6 @@ module main
// --log-file path to log file used when --log-to is 'file'
// --dry-run dont push anything to remote repo
// --force force update even if already up to date
import os
import log
import flag
import time
import vweb
import net.urllib
// git credentials
const (

View File

@ -5,7 +5,7 @@ import net.urllib
import strings
import markdown
import v.scanner
import v.table
import v.ast
import v.token
import v.doc
import v.pref
@ -344,7 +344,7 @@ fn get_src_link(repo_url string, file_name string, line_nr int) string {
return url.str()
}
fn html_highlight(code string, tb &table.Table) string {
fn html_highlight(code string, tb &ast.Table) string {
builtin := ['bool', 'string', 'i8', 'i16', 'int', 'i64', 'i128', 'byte', 'u16', 'u32', 'u64',
'u128', 'rune', 'f32', 'f64', 'int_literal', 'float_literal', 'byteptr', 'voidptr', 'any']
highlight_code := fn (tok token.Token, typ HighlightTokenTyp) string {
@ -425,7 +425,7 @@ fn html_highlight(code string, tb &table.Table) string {
return buf.str()
}
fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool, tb &table.Table) string {
fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool, tb &ast.Table) string {
mut dnw := strings.new_builder(200)
head_tag := if head { 'h1' } else { 'h2' }
comments := dn.merge_comments_without_examples()

View File

@ -3,7 +3,7 @@ module main
import os
import v.doc
import term
import v.table
import v.ast
import v.scanner
import v.token
import strings
@ -137,7 +137,7 @@ fn gen_footer_text(d &doc.Doc, include_timestamp bool) string {
return '$footer_text Generated on: $time_str'
}
fn color_highlight(code string, tb &table.Table) string {
fn color_highlight(code string, tb &ast.Table) string {
builtin := ['bool', 'string', 'i8', 'i16', 'int', 'i64', 'i128', 'byte', 'u16', 'u32', 'u64',
'u128', 'rune', 'f32', 'f64', 'int_literal', 'float_literal', 'byteptr', 'voidptr', 'any']
highlight_code := fn (tok token.Token, typ HighlightTokenTyp) string {

View File

@ -12,7 +12,6 @@ import v.pref
import v.fmt
import v.util
import v.parser
import v.table
import vhelp
struct FormatOptions {
@ -156,7 +155,7 @@ fn (foptions &FormatOptions) format_file(file string) {
if foptions.is_verbose {
eprintln('vfmt2 running fmt.fmt over file: $file')
}
table := table.new_table()
table := ast.new_table()
// checker := checker.new_checker(table, prefs)
file_ast := parser.parse_file(file, table, .parse_comments, prefs, &ast.Scope{
parent: 0
@ -180,7 +179,7 @@ fn (foptions &FormatOptions) format_pipe() {
eprintln('vfmt2 running fmt.fmt over stdin')
}
input_text := os.get_raw_lines_joined()
table := table.new_table()
table := ast.new_table()
// checker := checker.new_checker(table, prefs)
file_ast := parser.parse_text(input_text, '', table, .parse_comments, prefs, &ast.Scope{
parent: 0

View File

@ -28,6 +28,7 @@ const (
'vlib/v/tests/generics_return_generics_struct_test.v', /* generic fn param removed */
'vlib/v/tests/interop_test.v', /* bad comment formatting */
'vlib/v/tests/generics_test.v', /* some silent error */
'vlib/v/gen/js/tests/js.v', /* local `hello` fn, gets replaced with module `hello` aliased as `hl` */
]
vfmt_verify_list = [
'cmd/',
@ -55,7 +56,7 @@ const (
'vlib/v/eval/',
'vlib/v/fmt/',
'vlib/v/gen/c/',
//'vlib/v/gen/js/',
'vlib/v/gen/js/',
'vlib/v/gen/x64/',
'vlib/v/live/',
'vlib/v/markused/',
@ -64,7 +65,6 @@ const (
'vlib/v/pref/',
'vlib/v/preludes',
'vlib/v/scanner/',
'vlib/v/table/',
'vlib/v/tests/',
'vlib/v/token/',
'vlib/v/util/',

View File

@ -3,7 +3,6 @@ import flag
import term
import time
import v.parser
import v.table
import v.ast
import v.pref
@ -34,7 +33,7 @@ mut:
cut_index int // the cut position in the source from context.path
max_index int // the maximum index (equivalent to the file content length)
// parser context in the worker processes:
table table.Table
table ast.Table
scope ast.Scope
pref &pref.Preferences
period_ms int // print periodic progress
@ -48,7 +47,7 @@ fn main() {
context.log('> worker ${pid:5} starts parsing at cut_index: ${context.cut_index:5} | $context.path')
// A worker's process job is to try to parse a single given file in context.path.
// It can crash/panic freely.
context.table = table.new_table()
context.table = ast.new_table()
context.scope = &ast.Scope{
parent: 0
}

View File

@ -7,8 +7,8 @@ import os.cmdline
import v.vet
import v.pref
import v.parser
import v.table
import v.token
import v.ast
import term
struct Vet {
@ -94,7 +94,7 @@ fn (mut vt Vet) vet_file(path string) {
vt.file = path
mut prefs := pref.new_preferences()
prefs.is_vet = true
table := table.new_table()
table := ast.new_table()
vt.vprintln("vetting file '$path'...")
_, errors := parser.parse_vet_file(path, table, prefs)
// Transfer errors from scanner and parser

View File

@ -25,9 +25,9 @@ or `Preferences.compile_defines_all` **if any file is defined**.
## Parsing files
To parse something a new template is created as the first step:
```v
import v.table
import v.ast
table := table.new_table()
table := ast.new_table()
```
a new preference is created:

View File

@ -4,7 +4,6 @@
module ast
import v.token
import v.table
import v.errors
import v.pref
@ -16,7 +15,7 @@ pub type Expr = AnonFn | ArrayDecompose | ArrayInit | AsCast | Assoc | AtExpr |
Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
MapInit | MatchExpr | NodeError | None | OffsetOf | OrExpr | ParExpr | PostfixExpr |
PrefixExpr | RangeExpr | SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral |
StringLiteral | StructInit | Type | TypeOf | UnsafeExpr
StringLiteral | StructInit | TypeNode | TypeOf | UnsafeExpr
pub type Stmt = AsmStmt | AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl |
DeferStmt | EmptyStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt |
@ -27,14 +26,14 @@ pub type Stmt = AsmStmt | AssertStmt | AssignStmt | Block | BranchStmt | CompFor
// the .position() token.Position methods too.
pub type ScopeObject = AsmRegister | ConstField | GlobalField | Var
// TODO: replace table.Param
pub type Node = CallArg | ConstField | EnumField | Expr | Field | File | GlobalField |
IfBranch | MatchBranch | NodeError | ScopeObject | SelectBranch | Stmt | StructField |
StructInitField | table.Param
// TODO: replace Param
pub type Node = CallArg | ConstField | EmptyNode | EnumField | Expr | File | GlobalField |
IfBranch | MatchBranch | NodeError | Param | ScopeObject | SelectBranch | Stmt | StructField |
StructInitField
pub struct Type {
pub struct TypeNode {
pub:
typ table.Type
typ Type
pos token.Position
}
@ -55,6 +54,14 @@ pub fn empty_stmt() Stmt {
return EmptyStmt{}
}
pub struct EmptyNode {
x int
}
pub fn empty_node() Node {
return EmptyNode{}
}
// `{stmts}` or `unsafe {stmts}`
pub struct Block {
pub:
@ -72,7 +79,7 @@ pub:
comments []Comment
is_expr bool
pub mut:
typ table.Type
typ Type
}
pub struct IntegerLiteral {
@ -91,7 +98,7 @@ pub struct StringLiteral {
pub:
val string
is_raw bool
language table.Language
language Language
pos token.Position
}
@ -107,7 +114,7 @@ pub:
fmt_poss []token.Position
pos token.Position
pub mut:
expr_types []table.Type
expr_types []Type
fmts []byte
need_fmts []bool // an explicit non-default fmt required, e.g. `x`
}
@ -133,12 +140,12 @@ pub:
mut_pos token.Position
next_token token.Kind
pub mut:
expr Expr // expr.field_name
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`
expr Expr // expr.field_name
expr_type Type // type of `Foo` in `Foo.bar`
typ Type // type of the entire thing (`Foo.bar`)
name_type 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
from_embed_type Type // holds the type of the embed that the method is called from
}
// root_ident returns the origin ident where the selector started.
@ -157,7 +164,7 @@ pub struct Module {
pub:
name string // encoding.base64
short_name string // base64
attrs []table.Attr
attrs []Attr
pos token.Position
name_pos token.Position // `name` in import name
is_skipped bool // module main can be skipped in single file programs
@ -170,20 +177,26 @@ pub:
comments []Comment
default_expr Expr
has_default_expr bool
attrs []table.Attr
is_public bool
attrs []Attr
is_pub bool
default_val string
is_mut bool
is_global bool
pub mut:
name string
typ table.Type
default_expr_typ Type
name string
typ Type
}
/*
pub struct Field {
pub:
name string
pos token.Position
pub mut:
typ table.Type
typ Type
}
*/
// const field in const declaration group
pub struct ConstField {
@ -194,8 +207,8 @@ pub:
is_pub bool
pos token.Position
pub mut:
typ table.Type // the type of the const field, it can be any type in V
comments []Comment // comments before current const field
typ Type // the type of the const field, it can be any type in V
comments []Comment // comments before current const field
}
// const declaration
@ -213,7 +226,7 @@ pub struct StructDecl {
pub:
pos token.Position
name string
gen_types []table.Type
gen_types []Type
is_pub bool
// _pos fields for vfmt
mut_pos int // mut:
@ -221,9 +234,9 @@ pub:
pub_mut_pos int // pub mut:
global_pos int // __global:
module_pos int // module:
language table.Language
language Language
is_union bool
attrs []table.Attr
attrs []Attr
end_comments []Comment
embeds []Embed
pub mut:
@ -232,14 +245,14 @@ pub mut:
pub struct Embed {
pub:
typ table.Type
typ Type
pos token.Position
}
pub struct StructEmbedding {
pub:
name string
typ table.Type
typ Type
pos token.Position
}
@ -264,8 +277,8 @@ pub:
next_comments []Comment
pub mut:
name string
typ table.Type
expected_type table.Type
typ Type
expected_type Type
}
pub struct StructInitEmbed {
@ -276,8 +289,8 @@ pub:
next_comments []Comment
pub mut:
name string
typ table.Type
expected_type table.Type
typ Type
expected_type Type
}
pub struct StructInit {
@ -288,9 +301,9 @@ pub:
pub mut:
unresolved bool
pre_comments []Comment
typ table.Type
typ Type
update_expr Expr
update_expr_type table.Type
update_expr_type Type
update_expr_comments []Comment
has_update_expr bool
fields []StructInitField
@ -323,8 +336,8 @@ pub:
pub struct AnonFn {
pub mut:
decl FnDecl
typ table.Type // the type of anonymous fn. Both .typ and .decl.name are auto generated
has_gen bool // has been generated
typ Type // the type of anonymous fn. Both .typ and .decl.name are auto generated
has_gen bool // has been generated
}
// function or method declaration
@ -332,23 +345,23 @@ pub struct FnDecl {
pub:
name string
mod string
params []table.Param
params []Param
is_deprecated bool
is_pub bool
is_variadic bool
is_anon bool
is_manualfree bool // true, when [manualfree] is used on a fn
is_main bool // true for `fn main()`
is_test bool // true for `fn test_abcde`
is_conditional bool // true for `[if abc] fn abc(){}`
receiver Field
is_manualfree bool // true, when [manualfree] is used on a fn
is_main bool // true for `fn main()`
is_test bool // true for `fn test_abcde`
is_conditional bool // true for `[if abc] fn abc(){}`
receiver StructField // TODO this is not a struct field
receiver_pos token.Position // `(u User)` in `fn (u User) name()` position
is_method bool
method_type_pos token.Position // `User` in ` fn (u User)` position
method_idx int
rec_mut bool // is receiver mutable
rec_share table.ShareType
language table.Language
rec_share ShareType
language Language
no_body bool // just a definition `fn C.malloc()`
is_builtin bool // this function is defined in builtin/strconv
pos token.Position // function declaration position
@ -356,12 +369,12 @@ pub:
file string
generic_params []GenericParam
is_direct_arr bool // direct array access
attrs []table.Attr
attrs []Attr
skip_gen bool // this function doesn't need to be generated (for example [if foo])
pub mut:
stmts []Stmt
defer_stmts []DeferStmt
return_type table.Type
return_type Type
has_return bool
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
@ -394,19 +407,19 @@ pub mut:
is_method bool
is_field bool // temp hack, remove ASAP when re-impl CallExpr / Selector (joe)
args []CallArg
expected_arg_types []table.Type
language table.Language
expected_arg_types []Type
language Language
or_block OrExpr
left Expr // `user` in `user.register()`
left_type table.Type // type of `user`
receiver_type table.Type // User
return_type table.Type
left Expr // `user` in `user.register()`
left_type Type // type of `user`
receiver_type Type // User
return_type Type
should_be_skipped bool
generic_types []table.Type
generic_types []Type
generic_list_pos token.Position
free_receiver bool // true if the receiver expression needs to be freed
scope &Scope
from_embed_type table.Type // holds the type of the embed that the method is called from
from_embed_type Type // holds the type of the embed that the method is called from
comments []Comment
}
@ -420,11 +433,11 @@ pub struct AutofreeArgVar {
pub struct CallArg {
pub:
is_mut bool
share table.ShareType
share ShareType
expr Expr
comments []Comment
pub mut:
typ table.Type
typ Type
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
pos token.Position
// tmp_name string // for autofree
@ -437,7 +450,7 @@ pub:
exprs []Expr
comments []Comment
pub mut:
types []table.Type
types []Type
}
/*
@ -457,15 +470,15 @@ pub struct Var {
pub:
name string
expr Expr
share table.ShareType
share ShareType
is_mut bool
is_autofree_tmp bool
is_arg bool // fn args should not be autofreed
is_auto_deref bool
pub mut:
typ table.Type
orig_type table.Type // original sumtype type; 0 if it's not a sumtype
sum_type_casts []table.Type // nested sum types require nested smart casting, for that a list of types is needed
typ Type
orig_type Type // original sumtype type; 0 if it's not a sumtype
sum_type_casts []Type // nested sum types require nested smart casting, for that a list of types is needed
// TODO: move this to a real docs site later
// 10 <- original type (orig_type)
// [11, 12, 13] <- cast order (sum_type_casts)
@ -483,12 +496,12 @@ pub mut:
// struct fields change type in scopes
pub struct ScopeStructField {
pub:
struct_type table.Type // type of struct
struct_type 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
orig_type table.Type // original sumtype type; 0 if it's not a sumtype
typ Type
sum_type_casts []Type // nested sum types require nested smart casting, for that a list of types is needed
orig_type Type // original sumtype type; 0 if it's not a sumtype
// TODO: move this to a real docs site later
// 10 <- original type (orig_type)
// [11, 12, 13] <- cast order (sum_type_casts)
@ -502,7 +515,7 @@ pub:
has_expr bool
pos token.Position
pub mut:
typ table.Type
typ Type
comments []Comment
}
@ -520,8 +533,8 @@ pub:
apath string // absolute path during compilation to the resource
}
// Each V source file is represented by one ast.File structure.
// When the V compiler runs, the parser will fill an []ast.File.
// Each V source file is represented by one File structure.
// When the V compiler runs, the parser will fill an []File.
// That array is then passed to V's checker.
pub struct File {
pub:
@ -545,18 +558,18 @@ pub mut:
pub struct IdentFn {
pub mut:
typ table.Type
typ Type
}
// TODO: (joe) remove completely, use ident.obj
// instead which points to the scope object
pub struct IdentVar {
pub mut:
typ table.Type
typ Type
is_mut bool
is_static bool
is_optional bool
share table.ShareType
share ShareType
}
pub type IdentInfo = IdentFn | IdentVar
@ -573,7 +586,7 @@ pub enum IdentKind {
// A single identifier
pub struct Ident {
pub:
language table.Language
language Language
tok_kind token.Kind
pos token.Position
mut_pos token.Position
@ -609,8 +622,8 @@ pub:
pub mut:
left Expr
right Expr
left_type table.Type
right_type table.Type
left_type Type
right_type Type
auto_locked string
or_block OrExpr
}
@ -631,7 +644,7 @@ pub:
op token.Kind
pos token.Position
pub mut:
right_type table.Type
right_type Type
right Expr
or_block OrExpr
is_option bool // IfGuard
@ -644,7 +657,7 @@ pub:
or_expr OrExpr
pub mut:
left Expr
left_type table.Type // array, map, fixed array
left_type Type // array, map, fixed array
is_setter bool
is_map bool
is_array bool
@ -662,7 +675,7 @@ pub:
pub mut:
branches []IfBranch // includes all `else if` branches
is_expr bool
typ table.Type
typ Type
has_else bool
}
@ -692,7 +705,7 @@ pub:
pub mut:
lockeds []Ident // `x`, `y` in `lock x, y {`
is_expr bool
typ table.Type
typ Type
}
pub struct MatchExpr {
@ -704,9 +717,9 @@ pub:
comments []Comment // comments before the first branch
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
return_type Type
cond_type Type // type of `x` in `match x {`
expected_type Type // for debugging only
is_sum_type bool
}
@ -728,8 +741,8 @@ pub:
pos token.Position
has_exception bool
pub mut:
is_expr bool // returns a value
expected_type table.Type // for debugging only
is_expr bool // returns a value
expected_type Type // for debugging only
}
pub struct SelectBranch {
@ -757,7 +770,7 @@ pub:
typ_pos token.Position
pub mut:
// expr Expr
typ table.Type
typ Type
}
pub struct ForStmt {
@ -783,11 +796,11 @@ pub:
val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array
// and the array cannot be indexed inside the loop
pub mut:
key_type table.Type
val_type table.Type
cond_type table.Type
kind table.Kind // array/map/string
label string // `label: for {`
key_type Type
val_type Type
cond_type Type
kind Kind // array/map/string
label string // `label: for {`
scope &Scope
}
@ -837,8 +850,8 @@ pub:
pub mut:
right []Expr
left []Expr
left_types []table.Type
right_types []table.Type
left_types []Type
right_types []Type
is_static bool // for translated code only
is_simple bool // `x+=2` in `for x:=1; ; x+=2`
has_cross_var bool
@ -847,10 +860,10 @@ pub mut:
pub struct AsCast {
pub:
expr Expr
typ table.Type
typ Type
pos token.Position
pub mut:
expr_type table.Type
expr_type Type
}
// an enum value, like OS.macos or .macos
@ -861,7 +874,7 @@ pub:
mod string // for full path `mod_Enum_val`
pos token.Position
pub mut:
typ table.Type
typ Type
}
// enum field in enum declaration
@ -880,11 +893,11 @@ pub struct EnumDecl {
pub:
name string
is_pub bool
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
attrs []table.Attr // attributes of enum declaration
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
attrs []Attr // attributes of enum declaration
pos token.Position
}
@ -892,7 +905,7 @@ pub struct AliasTypeDecl {
pub:
name string
is_pub bool
parent_type table.Type
parent_type Type
pos token.Position
comments []Comment
}
@ -904,14 +917,14 @@ pub:
is_pub bool
pos token.Position
comments []Comment
typ table.Type
typ Type
pub mut:
variants []SumTypeVariant
}
pub struct SumTypeVariant {
pub:
typ table.Type
typ Type
pos token.Position
}
@ -919,7 +932,7 @@ pub struct FnTypeDecl {
pub:
name string
is_pub bool
typ table.Type
typ Type
pos token.Position
comments []Comment
}
@ -956,7 +969,7 @@ pub:
pub mut:
go_stmt GoStmt
mut:
return_type table.Type
return_type Type
}
pub struct GotoLabel {
@ -988,9 +1001,9 @@ pub:
has_cap bool
has_default bool
pub mut:
expr_types []table.Type // [Dog, Cat] // also used for interface_types
elem_type table.Type // element type
typ table.Type // array type
expr_types []Type // [Dog, Cat] // also used for interface_types
elem_type Type // element type
typ Type // array type
}
pub struct ArrayDecompose {
@ -998,8 +1011,8 @@ pub:
expr Expr
pos token.Position
pub mut:
expr_type table.Type
arg_type table.Type
expr_type Type
arg_type Type
}
pub struct ChanInit {
@ -1008,8 +1021,8 @@ pub:
cap_expr Expr
has_cap bool
pub mut:
typ table.Type
elem_type table.Type
typ Type
elem_type Type
}
pub struct MapInit {
@ -1020,9 +1033,9 @@ pub:
comments [][]Comment // comments after key-value pairs
pre_cmnts []Comment // comments before the first key-value pair
pub mut:
typ table.Type
key_type table.Type
value_type table.Type
typ Type
key_type Type
value_type Type
}
// s[10..20]
@ -1035,9 +1048,9 @@ pub:
pos token.Position
}
// NB: &string(x) gets parsed as ast.PrefixExpr{ right: ast.CastExpr{...} }
// NB: &string(x) gets parsed as PrefixExpr{ right: CastExpr{...} }
// TODO: that is very likely a parsing bug. It should get parsed as just
// ast.CastExpr{...}, where .typname is '&string' instead.
// 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
@ -1045,15 +1058,15 @@ pub:
// `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`
expr Expr // `buf` in `string(buf, n)`
arg Expr // `n` in `string(buf, n)`
typ Type // `string` TODO rename to `type_to_cast_to`
pos token.Position
pub mut:
typname string // TypeSymbol.name
expr_type table.Type // `byteptr`
typname string // TypeSymbol.name
expr_type Type // `byteptr`
has_arg bool
in_prexpr bool // is the parent node an ast.PrefixExpr
in_prexpr bool // is the parent node an PrefixExpr
}
pub struct AsmStmt {
@ -1091,7 +1104,7 @@ pub struct AsmRegister {
pub:
name string // eax or r12d
mut:
typ table.Type
typ Type
size int
}
@ -1143,7 +1156,7 @@ pub:
constraint string // '=r'
expr Expr // (a)
comments []Comment // // this is a comment
typ table.Type
typ Type
pos token.Position
}
@ -1243,7 +1256,7 @@ pub:
pos token.Position
pub mut:
expr Expr
expr_type table.Type
expr_type Type
}
pub enum OrKind {
@ -1279,7 +1292,7 @@ pub:
exprs []Expr
pos token.Position
pub mut:
typ table.Type
typ Type
scope &Scope
}
@ -1289,12 +1302,12 @@ pub:
expr Expr // checker uses this to set typ
pos token.Position
pub mut:
typ table.Type
typ Type
}
pub struct OffsetOf {
pub:
struct_type table.Type
struct_type Type
field string
pos token.Position
}
@ -1311,7 +1324,7 @@ pub:
expr Expr
pos token.Position
pub mut:
expr_type table.Type
expr_type Type
}
pub struct DumpExpr {
@ -1319,7 +1332,7 @@ pub:
expr Expr
pos token.Position
pub mut:
expr_type table.Type
expr_type Type
cname string // filled in the checker
}
@ -1336,7 +1349,7 @@ pub:
vals []Expr
pos token.Position
pub mut:
return_type table.Type
return_type Type
}
// @FN, @STRUCT, @MOD etc. See full list in token.valid_at_tokens
@ -1356,8 +1369,8 @@ pub:
field_expr Expr
pos token.Position
pub mut:
left_type table.Type
typ table.Type
left_type Type
typ Type
}
pub struct ComptimeCall {
@ -1379,8 +1392,8 @@ pub:
is_env bool
env_pos token.Position
pub mut:
sym table.TypeSymbol
result_type table.Type
sym TypeSymbol
result_type Type
env_value string
args []CallArg
}
@ -1407,14 +1420,14 @@ pub:
updated_columns []string // for `update set x=y`
update_exprs []Expr // for `update`
pub mut:
table_expr Type
fields []table.Field
table_expr TypeNode
fields []StructField
sub_structs map[int]SqlStmt
}
pub struct SqlExpr {
pub:
typ table.Type
typ Type
is_count bool
db_expr Expr // `db` in `sql db {`
has_where bool
@ -1429,14 +1442,14 @@ pub:
limit_expr Expr
pub mut:
where_expr Expr
table_expr Type
fields []table.Field
table_expr TypeNode
fields []StructField
sub_structs map[int]SqlExpr
}
pub struct NodeError {
pub:
idx int // index for referencing the related ast.File error
idx int // index for referencing the related File error
pos token.Position
}
@ -1462,8 +1475,8 @@ pub fn (expr Expr) position() token.Position {
ChanInit, CharLiteral, ConcatExpr, Comment, ComptimeCall, ComptimeSelector, EnumVal, DumpExpr,
FloatLiteral, GoExpr, Ident, IfExpr, IndexExpr, IntegerLiteral, Likely, LockExpr, MapInit,
MatchExpr, None, OffsetOf, OrExpr, ParExpr, PostfixExpr, PrefixExpr, RangeExpr, SelectExpr,
SelectorExpr, SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, Type, TypeOf,
UnsafeExpr {
SelectorExpr, SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, TypeNode,
TypeOf, UnsafeExpr {
return expr.pos
}
IfGuardExpr {
@ -1559,10 +1572,10 @@ pub fn (stmt Stmt) check_c_expr() ? {
// CTempVar is used in cgen only, to hold nodes for temporary variables
pub struct CTempVar {
pub:
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()
typ table.Type // the type of the original expression
is_ptr bool // whether the type is a pointer
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()
typ Type // the type of the original expression
is_ptr bool // whether the type is a pointer
}
pub fn (node Node) position() token.Position {
@ -1570,6 +1583,9 @@ pub fn (node Node) position() token.Position {
NodeError {
return token.Position{}
}
EmptyNode {
return token.Position{}
}
Stmt {
mut pos := node.pos
if node is Import {
@ -1585,8 +1601,7 @@ pub fn (node Node) position() token.Position {
StructField {
return node.pos.extend(node.type_pos)
}
MatchBranch, SelectBranch, Field, EnumField, ConstField, StructInitField, GlobalField,
table.Param {
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, Param {
return node.pos
}
IfBranch {
@ -1760,27 +1775,6 @@ pub fn (node Node) children() []Node {
return children
}
// 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 {
unsafe {
res := Expr{}
C.memcpy(&res, &x, sizeof(Expr))
return res
}
}
pub fn ex2fe(x Expr) table.FExpr {
unsafe {
res := table.FExpr{}
C.memcpy(&res, &x, sizeof(table.FExpr))
return res
}
}
// helper for dealing with `m[k1][k2][k3][k3] = value`
pub fn (mut lx IndexExpr) recursive_mapset_is_setter(val bool) {
lx.is_setter = val
@ -1792,7 +1786,7 @@ pub fn (mut lx IndexExpr) recursive_mapset_is_setter(val bool) {
}
// return all the registers for a give architecture
pub fn all_registers(mut t table.Table, arch pref.Arch) map[string]ScopeObject {
pub fn all_registers(mut t Table, arch pref.Arch) map[string]ScopeObject {
mut res := map[string]ScopeObject{}
match arch {
.amd64, .i386 {
@ -1809,7 +1803,7 @@ pub fn all_registers(mut t table.Table, arch pref.Arch) map[string]ScopeObject {
for name, max_num in array {
for i in 0 .. max_num {
hash_index := name.index('#') or {
panic('ast.all_registers: no hashtag found')
panic('all_registers: no hashtag found')
}
assembled_name := '${name[..hash_index]}$i${name[hash_index + 1..]}'
res[assembled_name] = AsmRegister{
@ -1850,7 +1844,7 @@ pub fn all_registers(mut t table.Table, arch pref.Arch) map[string]ScopeObject {
}
}
else { // TODO
panic('ast.all_registers: unhandled arch')
panic('all_registers: unhandled arch')
}
}
@ -1858,7 +1852,7 @@ pub fn all_registers(mut t table.Table, arch pref.Arch) map[string]ScopeObject {
}
// only for arm and riscv because x86 has different sized registers
fn gen_all_registers(mut t table.Table, without_numbers []string, with_numbers map[string]int, bit_size int) map[string]ScopeObject {
fn gen_all_registers(mut t Table, without_numbers []string, with_numbers map[string]int, bit_size int) map[string]ScopeObject {
mut res := map[string]ScopeObject{}
for name in without_numbers {
res[name] = AsmRegister{
@ -1869,7 +1863,7 @@ fn gen_all_registers(mut t table.Table, without_numbers []string, with_numbers m
}
for name, max_num in with_numbers {
for i in 0 .. max_num {
hash_index := name.index('#') or { panic('ast.all_registers: no hashtag found') }
hash_index := name.index('#') or { panic('all_registers: no hashtag found') }
assembled_name := '${name[..hash_index]}$i${name[hash_index + 1..]}'
res[assembled_name] = AsmRegister{
name: assembled_name

View File

@ -1,7 +1,7 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module table
module ast
import v.token

View File

@ -1,13 +1,13 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module table
module ast
import v.cflag
// check if cflag is in table
fn (mytable &Table) has_cflag(flag cflag.CFlag) bool {
for cf in mytable.cflags {
fn (t &Table) has_cflag(flag cflag.CFlag) bool {
for cf in t.cflags {
if cf.os == flag.os && cf.name == flag.name && cf.value == flag.value {
return true
}
@ -15,9 +15,9 @@ fn (mytable &Table) has_cflag(flag cflag.CFlag) bool {
return false
}
// parse the flags to (table.cflags) []CFlag
// parse the flags to (ast.cflags) []CFlag
// Note: clean up big time (joe-c)
pub fn (mut mytable Table) parse_cflag(cflg string, mod string, ctimedefines []string) ?bool {
pub fn (mut t Table) parse_cflag(cflg string, mod string, ctimedefines []string) ?bool {
allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L']
flag_orig := cflg.trim_space()
mut flag := flag_orig
@ -78,8 +78,8 @@ pub fn (mut mytable Table) parse_cflag(cflg string, mod string, ctimedefines []s
name: name
value: value
}
if !mytable.has_cflag(cf) {
mytable.cflags << cf
if !t.has_cflag(cf) {
t.cflags << cf
}
if index == -1 {
break

View File

@ -1,4 +1,4 @@
import v.table
import v.ast
import v.cflag
const (
@ -10,7 +10,7 @@ const (
)
fn test_parse_valid_cflags() {
mut t := table.new_table()
mut t := ast.new_table()
expected_flags := [
make_flag('freebsd', '-I', '/usr/local/include/freetype2'),
make_flag('linux', '-l', 'glfw'),
@ -36,7 +36,7 @@ fn test_parse_valid_cflags() {
}
fn test_parse_invalid_cflags() {
mut t := table.new_table()
mut t := ast.new_table()
// -I, -L, -l must have values
assert_parse_invalid_flag(mut t, 'windows -l')
assert_parse_invalid_flag(mut t, '-I')
@ -53,11 +53,11 @@ fn test_parse_invalid_cflags() {
assert t.cflags.len == 0
}
fn parse_valid_flag(mut t table.Table, flag string) {
fn parse_valid_flag(mut t ast.Table, flag string) {
t.parse_cflag(flag, module_name, cdefines) or {}
}
fn assert_parse_invalid_flag(mut t table.Table, flag string) {
fn assert_parse_invalid_flag(mut t ast.Table, flag string) {
t.parse_cflag(flag, module_name, cdefines) or { return }
assert false
}

View File

@ -1,11 +1,11 @@
module ast
import v.table
import v.ast
pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr {
pub fn resolve_init(node StructInit, typ Type, t &Table) Expr {
type_sym := t.get_type_symbol(typ)
if type_sym.kind == .array {
array_info := type_sym.info as table.Array
array_info := type_sym.info as Array
mut has_len := false
mut has_cap := false
mut has_default := false
@ -32,7 +32,7 @@ pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr {
}
}
}
return ArrayInit{
return ast.ArrayInit{
// TODO: mod is not being set for now, we could need this in future
// mod: mod
pos: node.pos
@ -47,16 +47,16 @@ pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr {
exprs: exprs
}
} else if type_sym.kind == .map {
map_info := type_sym.info as table.Map
map_info := type_sym.info as Map
mut keys := []Expr{}
mut vals := []Expr{}
for field in node.fields {
keys << StringLiteral{
keys << ast.StringLiteral{
val: field.name
}
vals << field.expr
}
return MapInit{
return ast.MapInit{
typ: typ
key_type: map_info.key_type
value_type: map_info.value_type
@ -65,7 +65,7 @@ pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr {
}
}
// struct / other (sumtype?)
return StructInit{
return ast.StructInit{
...node
unresolved: false
}

View File

@ -3,7 +3,7 @@
// that can be found in the LICENSE file.
module ast
import v.table
import v.ast
pub struct Scope {
pub mut:
@ -18,7 +18,7 @@ pub mut:
}
pub fn new_scope(parent &Scope, start_pos int) &Scope {
return &Scope{
return &ast.Scope{
parent: parent
start_pos: start_pos
}
@ -54,7 +54,7 @@ pub fn (s &Scope) find(name string) ?ScopeObject {
return none
}
pub fn (s &Scope) find_struct_field(struct_type table.Type, field_name string) ?ScopeStructField {
pub fn (s &Scope) find_struct_field(struct_type Type, field_name string) ?ScopeStructField {
for sc := s; true; sc = sc.parent {
for field in sc.struct_fields {
if field.struct_type == struct_type && field.name == field_name {
@ -103,7 +103,7 @@ pub fn (s &Scope) known_var(name string) bool {
return false
}
pub fn (mut s Scope) update_var_type(name string, typ table.Type) {
pub fn (mut s Scope) update_var_type(name string, typ Type) {
s.end_pos = s.end_pos // TODO mut bug
mut obj := s.objects[name]
match mut obj {

View File

@ -3,7 +3,7 @@
// that can be found in the LICENSE file.
module ast
import v.table
import v.ast
import v.util
import strings
@ -19,7 +19,7 @@ pub fn (node &FnDecl) modname() string {
}
// These methods are used only by vfmt, vdoc, and for debugging.
pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string, m2a map[string]string) string {
pub fn (node &FnDecl) stringify(t &Table, cur_mod string, m2a map[string]string) string {
mut f := strings.new_builder(30)
if node.is_pub {
f.write_string('pub ')
@ -117,7 +117,7 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string, m2a map[string]s
}
}
f.write_string(')')
if node.return_type != table.void_type {
if node.return_type != ast.void_type {
mut rs := util.no_cur_mod(t.type_to_str(node.return_type), cur_mod)
for mod, alias in m2a {
rs = rs.replace(mod, alias)
@ -351,8 +351,8 @@ pub fn (x Expr) str() string {
StringLiteral {
return "'$x.val'"
}
Type {
return 'Type($x.typ)'
TypeNode {
return 'TypeNode($x.typ)'
}
TypeOf {
return 'typeof($x.expr.str())'

View File

@ -1,7 +1,7 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module table
module ast
import v.cflag
import v.token
@ -18,7 +18,7 @@ pub mut:
cflags []cflag.CFlag
redefined_fns []string
fn_gen_types map[string][][]Type // for generic functions
cmod_prefix string // needed for table.type_to_str(Type) while vfmt; contains `os.`
cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.`
is_fmt bool
used_fns map[string]bool // filled in by the checker, when pref.skip_unused = true;
used_consts map[string]bool // filled in by the checker, when pref.skip_unused = true;
@ -82,6 +82,7 @@ fn (p []Param) equals(o []Param) bool {
return true
}
/*
pub struct Var {
pub:
name string
@ -89,6 +90,7 @@ pub:
mut:
typ Type
}
*/
pub fn new_table() &Table {
mut t := &Table{
@ -240,14 +242,14 @@ pub fn (t &Table) type_find_method(s &TypeSymbol, name string) ?Fn {
return none
}
fn (t &Table) register_aggregate_field(mut sym TypeSymbol, name string) ?Field {
fn (t &Table) register_aggregate_field(mut sym TypeSymbol, name string) ?StructField {
if sym.kind != .aggregate {
panic('Unexpected type symbol: $sym.kind')
}
mut agg_info := sym.info as Aggregate
// an aggregate always has at least 2 types
mut found_once := false
mut new_field := Field{
mut new_field := StructField{
// default_expr: ast.empty_expr()
}
for typ in agg_info.types {
@ -276,7 +278,7 @@ pub fn (t &Table) struct_has_field(s &TypeSymbol, name string) bool {
}
// search from current type up through each parent looking for field
pub fn (t &Table) find_field(s &TypeSymbol, name string) ?Field {
pub fn (t &Table) find_field(s &TypeSymbol, name string) ?StructField {
// println('find_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
mut ts := s
for {
@ -316,13 +318,13 @@ pub fn (t &Table) find_field(s &TypeSymbol, name string) ?Field {
}
// search for a given field, looking through embedded fields
pub fn (t &Table) find_field_with_embeds(sym &TypeSymbol, field_name string) ?Field {
pub fn (t &Table) find_field_with_embeds(sym &TypeSymbol, field_name string) ?StructField {
if f := t.find_field(sym, field_name) {
return f
} else {
// look for embedded field
if sym.info is Struct {
mut found_fields := []Field{}
mut found_fields := []StructField{}
mut embed_of_found_fields := []Type{}
for embed in sym.info.embeds {
embed_sym := t.get_type_symbol(embed)
@ -347,7 +349,7 @@ pub fn (t &Table) resolve_common_sumtype_fields(sym_ &TypeSymbol) {
if info.found_fields {
return
}
mut field_map := map[string]Field{}
mut field_map := map[string]StructField{}
mut field_usages := map[string]int{}
for variant in info.variants {
mut v_sym := t.get_type_symbol(variant)
@ -360,7 +362,7 @@ pub fn (t &Table) resolve_common_sumtype_fields(sym_ &TypeSymbol) {
v_sym.info.fields
}
else {
[]Field{}
[]StructField{}
}
}
for field in fields {
@ -867,8 +869,8 @@ pub fn (mut t Table) register_fn_gen_type(fn_name string, types []Type) {
// TODO: there is a bug when casting sumtype the other way if its pointer
// so until fixed at least show v (not C) error `x(variant) = y(SumType*)`
pub fn (mytable &Table) sumtype_has_variant(parent Type, variant Type) bool {
parent_sym := mytable.get_type_symbol(parent)
pub fn (t &Table) sumtype_has_variant(parent Type, variant Type) bool {
parent_sym := t.get_type_symbol(parent)
if parent_sym.kind == .sum_type {
parent_info := parent_sym.info as SumType
for v in parent_info.variants {
@ -894,11 +896,11 @@ pub fn (t &Table) known_type_names() []string {
// has_deep_child_no_ref returns true if type is struct and has any child or nested child with the type of the given name
// the given name consists of module and name (`mod.Name`)
// it doesn't care about childs that are references
pub fn (mytable &Table) has_deep_child_no_ref(ts &TypeSymbol, name string) bool {
pub fn (t &Table) has_deep_child_no_ref(ts &TypeSymbol, name string) bool {
if ts.info is Struct {
for field in ts.info.fields {
sym := mytable.get_type_symbol(field.typ)
if !field.typ.is_ptr() && (sym.name == name || mytable.has_deep_child_no_ref(sym, name)) {
sym := t.get_type_symbol(field.typ)
if !field.typ.is_ptr() && (sym.name == name || t.has_deep_child_no_ref(sym, name)) {
return true
}
}

View File

@ -9,7 +9,7 @@
// flag: (int(type)>>24) & 0xff
// nr_muls: (int(type)>>16) & 0xff
// idx: u16(type) & 0xffff
module table
module ast
import strings
import v.pref
@ -109,10 +109,10 @@ pub fn (t ShareType) str() string {
pub fn (t Type) atomic_typename() string {
idx := t.idx()
match idx {
table.u32_type_idx { return 'atomic_uint' }
table.int_type_idx { return 'atomic_int' }
table.u64_type_idx { return 'atomic_ullong' }
table.i64_type_idx { return 'atomic_llong' }
ast.u32_type_idx { return 'atomic_uint' }
ast.int_type_idx { return 'atomic_int' }
ast.u64_type_idx { return 'atomic_ullong' }
ast.i64_type_idx { return 'atomic_llong' }
else { return 'unknown_atomic' }
}
}
@ -133,12 +133,12 @@ pub fn (t Type) idx() int {
[inline]
pub fn (t Type) is_void() bool {
return t == table.void_type
return t == ast.void_type
}
[inline]
pub fn (t Type) is_full() bool {
return t != 0 && t != table.void_type
return t != 0 && t != ast.void_type
}
// return nr_muls for `t`
@ -273,42 +273,42 @@ pub fn new_type_ptr(idx int, nr_muls int) Type {
// built in pointers (voidptr, byteptr, charptr)
[inline]
pub fn (typ Type) is_pointer() bool {
return typ.idx() in table.pointer_type_idxs
return typ.idx() in ast.pointer_type_idxs
}
[inline]
pub fn (typ Type) is_float() bool {
return typ.idx() in table.float_type_idxs
return typ.idx() in ast.float_type_idxs
}
[inline]
pub fn (typ Type) is_int() bool {
return typ.idx() in table.integer_type_idxs
return typ.idx() in ast.integer_type_idxs
}
[inline]
pub fn (typ Type) is_signed() bool {
return typ.idx() in table.signed_integer_type_idxs
return typ.idx() in ast.signed_integer_type_idxs
}
[inline]
pub fn (typ Type) is_unsigned() bool {
return typ.idx() in table.unsigned_integer_type_idxs
return typ.idx() in ast.unsigned_integer_type_idxs
}
[inline]
pub fn (typ Type) is_int_literal() bool {
return typ.idx() == table.int_literal_type_idx
return typ.idx() == ast.int_literal_type_idx
}
[inline]
pub fn (typ Type) is_number() bool {
return typ.idx() in table.number_type_idxs
return typ.idx() in ast.number_type_idxs
}
[inline]
pub fn (typ Type) is_string() bool {
return typ.idx() in table.string_type_idxs
return typ.idx() in ast.string_type_idxs
}
pub const (
@ -408,11 +408,11 @@ pub:
}
// returns TypeSymbol kind only if there are no type modifiers
pub fn (table &Table) type_kind(typ Type) Kind {
pub fn (t &Table) type_kind(typ Type) Kind {
if typ.nr_muls() > 0 || typ.has_flag(.optional) {
return Kind.placeholder
}
return table.get_type_symbol(typ).kind
return t.get_type_symbol(typ).kind
}
pub enum Kind {
@ -585,7 +585,7 @@ pub fn (mut t Table) register_builtin_type_symbols() {
cname: '__v_thread'
mod: 'builtin'
info: Thread{
return_type: table.void_type
return_type: ast.void_type
}
)
t.register_type_symbol(kind: .interface_, name: 'IError', cname: 'IError', mod: 'builtin')
@ -688,7 +688,7 @@ pub:
attrs []Attr
pub mut:
embeds []Type
fields []Field
fields []StructField
is_typedef bool // C. [typedef]
is_union bool
is_heap bool
@ -705,7 +705,7 @@ pub mut:
pub struct Interface {
pub mut:
types []Type
fields []Field
fields []StructField
methods []Fn
}
@ -725,22 +725,23 @@ pub:
pub struct Aggregate {
mut:
fields []Field // used for faster lookup inside the module
fields []StructField // used for faster lookup inside the module
pub:
types []Type
}
// NB: FExpr here is a actually an ast.Expr .
// It should always be used by casting to ast.Expr, using ast.fe2ex()/ast.ex2fe()
// That hack is needed to break an import cycle between v.ast and v.table .
pub type FExpr = byteptr | voidptr
// That hack is needed to break an import cycle between v.ast and v.ast .
// pub type FExpr = byteptr | voidptr
/*
pub struct Field {
pub:
name string
pub mut:
typ Type
default_expr FExpr
default_expr Expr
has_default_expr bool
default_expr_typ Type
default_val string
@ -749,8 +750,9 @@ pub mut:
is_mut bool
is_global bool
}
*/
pub fn (f &Field) equals(o &Field) bool {
pub fn (f &StructField) equals(o &StructField) bool {
// TODO: f.is_mut == o.is_mut was removed here to allow read only access
// to (mut/not mut), but otherwise equal fields; some other new checks are needed:
// - if node is declared mut, and we mutate node.stmts, all stmts fields must be mutable
@ -793,19 +795,19 @@ pub struct SumType {
pub:
variants []Type
pub mut:
fields []Field
fields []StructField
found_fields bool
}
// human readable type name
pub fn (table &Table) type_to_str(t Type) string {
return table.type_to_str_using_aliases(t, map[string]string{})
pub fn (t &Table) type_to_str(typ Type) string {
return t.type_to_str_using_aliases(typ, map[string]string{})
}
// type name in code (for builtin)
pub fn (mytable &Table) type_to_code(t Type) string {
match t {
table.int_literal_type, table.float_literal_type { return mytable.get_type_symbol(t).kind.str() }
ast.int_literal_type, ast.float_literal_type { return mytable.get_type_symbol(t).kind.str() }
else { return mytable.type_to_str_using_aliases(t, map[string]string{}) }
}
}
@ -824,7 +826,7 @@ pub fn (mytable &Table) type_to_str_using_aliases(t Type, import_aliases map[str
res = sym.kind.str()
}
.array {
if t == table.array_type {
if t == ast.array_type {
return 'array'
}
if t.has_flag(.variadic) {
@ -869,7 +871,7 @@ pub fn (mytable &Table) type_to_str_using_aliases(t Type, import_aliases map[str
}
}
.map {
if int(t) == table.map_type_idx {
if int(t) == ast.map_type_idx {
return 'map'
}
info := sym.info as Map
@ -969,7 +971,7 @@ pub fn (t &Table) fn_signature(func &Fn, opts FnSignatureOpts) string {
sb.write_string('$styp')
}
sb.write_string(')')
if func.return_type != table.void_type {
if func.return_type != ast.void_type {
sb.write_string(' ${t.type_to_str(func.return_type)}')
}
return sb.str()
@ -1014,7 +1016,7 @@ pub fn (t &TypeSymbol) str_method_info() (bool, bool, int) {
return has_str_method, expects_ptr, nr_args
}
pub fn (t &TypeSymbol) find_field(name string) ?Field {
pub fn (t &TypeSymbol) find_field(name string) ?StructField {
match t.info {
Aggregate { return t.info.find_field(name) }
Struct { return t.info.find_field(name) }
@ -1024,7 +1026,7 @@ pub fn (t &TypeSymbol) find_field(name string) ?Field {
}
}
fn (a &Aggregate) find_field(name string) ?Field {
fn (a &Aggregate) find_field(name string) ?StructField {
for field in a.fields {
if field.name == name {
return field
@ -1033,7 +1035,7 @@ fn (a &Aggregate) find_field(name string) ?Field {
return none
}
pub fn (i &Interface) find_field(name string) ?Field {
pub fn (i &Interface) find_field(name string) ?StructField {
for field in i.fields {
if field.name == name {
return field
@ -1058,7 +1060,7 @@ pub fn (i &Interface) has_method(name string) bool {
return false
}
pub fn (s Struct) find_field(name string) ?Field {
pub fn (s Struct) find_field(name string) ?StructField {
for field in s.fields {
if field.name == name {
return field
@ -1067,14 +1069,14 @@ pub fn (s Struct) find_field(name string) ?Field {
return none
}
pub fn (s Struct) get_field(name string) Field {
pub fn (s Struct) get_field(name string) StructField {
if field := s.find_field(name) {
return field
}
panic('unknown field `$name`')
}
pub fn (s &SumType) find_field(name string) ?Field {
pub fn (s &SumType) find_field(name string) ?StructField {
for field in s.fields {
if field.name == name {
return field

View File

@ -0,0 +1,81 @@
import v.ast
fn test_idx() {
mut t := ast.new_type(ast.void_type_idx)
assert t.idx() == ast.void_type_idx
t = ast.new_type(ast.i8_type_idx)
assert t.idx() == ast.i8_type_idx
}
fn test_muls() {
mut t := ast.new_type(ast.void_type_idx)
idx := t.idx()
assert t.nr_muls() == 0
for i in 0 .. 32 {
t = t.set_nr_muls(i)
assert t.nr_muls() == i
}
t = t.set_nr_muls(0)
assert t.nr_muls() == 0
assert t.is_ptr() == false
t = t.to_ptr()
assert t.nr_muls() == 1
assert t.is_ptr() == true
t = t.to_ptr()
assert t.nr_muls() == 2
assert t.is_ptr() == true
t = t.deref()
assert t.nr_muls() == 1
assert t.is_ptr() == true
t = t.deref()
assert t.nr_muls() == 0
assert t.is_ptr() == false
assert t.idx() == idx
}
fn test_flags() {
mut t := ast.new_type(ast.void_type_idx)
idx := t.idx()
nr_muls := t.nr_muls()
t = t.set_flag(ast.TypeFlag.optional)
assert t.has_flag(ast.TypeFlag.optional) == true
assert t.has_flag(ast.TypeFlag.variadic) == false
assert t.has_flag(ast.TypeFlag.generic) == false
t = t.set_flag(ast.TypeFlag.variadic)
assert t.has_flag(ast.TypeFlag.optional) == true
assert t.has_flag(ast.TypeFlag.variadic) == true
assert t.has_flag(ast.TypeFlag.generic) == false
t = t.set_flag(ast.TypeFlag.generic)
assert t.has_flag(ast.TypeFlag.optional) == true
assert t.has_flag(ast.TypeFlag.variadic) == true
assert t.has_flag(ast.TypeFlag.generic) == true
assert t.idx() == idx
assert t.nr_muls() == nr_muls
t = t.clear_flag(ast.TypeFlag.optional)
assert t.has_flag(ast.TypeFlag.optional) == false
assert t.has_flag(ast.TypeFlag.variadic) == true
assert t.has_flag(ast.TypeFlag.generic) == true
t = t.clear_flag(ast.TypeFlag.variadic)
assert t.has_flag(ast.TypeFlag.optional) == false
assert t.has_flag(ast.TypeFlag.variadic) == false
assert t.has_flag(ast.TypeFlag.generic) == true
t = t.clear_flag(ast.TypeFlag.generic)
assert t.has_flag(ast.TypeFlag.optional) == false
assert t.has_flag(ast.TypeFlag.variadic) == false
assert t.has_flag(ast.TypeFlag.generic) == false
assert t.idx() == idx
assert t.nr_muls() == nr_muls
}
fn test_derive() {
mut t := ast.new_type(ast.i8_type_idx)
t = t.set_flag(ast.TypeFlag.generic)
t = t.set_flag(ast.TypeFlag.variadic)
t = t.set_nr_muls(10)
mut t2 := ast.new_type(ast.i16_type_idx)
t2 = t2.derive(t)
assert t2.has_flag(ast.TypeFlag.optional) == false
assert t2.has_flag(ast.TypeFlag.variadic) == true
assert t2.has_flag(ast.TypeFlag.generic) == true
assert t2.nr_muls() == 10
}

View File

@ -1,11 +1,10 @@
import v.ast
import v.ast.walker
import v.parser
import v.table
import v.pref
fn parse_text(text string) ast.File {
tbl := table.new_table()
tbl := ast.new_table()
prefs := pref.new_preferences()
scope := &ast.Scope{
parent: 0

View File

@ -1,11 +1,10 @@
module builder
import os
import v.ast
import v.token
import v.table
import v.pref
import v.util
import v.ast
import v.vmod
import v.checker
import v.parser
@ -26,14 +25,14 @@ pub mut:
module_search_paths []string
parsed_files []ast.File
cached_msvc MsvcResult
table &table.Table
table &ast.Table
ccoptions CcompilerOptions
}
pub fn new_builder(pref &pref.Preferences) Builder {
rdir := os.real_path(pref.path)
compiled_dir := if os.is_dir(rdir) { rdir } else { os.dir(rdir) }
mut table := table.new_table()
mut table := ast.new_table()
table.is_fmt = false
if pref.use_color == .always {
util.emanager.set_support_color(true)
@ -100,7 +99,7 @@ pub fn (mut b Builder) parse_imports() {
continue
}
import_path := b.find_module_path(mod, ast_file.path) or {
// v.parsers[i].error_with_token_index('cannot import module "$mod" (not found)', v.parsers[i].import_table.get_import_tok_idx(mod))
// v.parsers[i].error_with_token_index('cannot import module "$mod" (not found)', v.parsers[i].import_ast.get_import_tok_idx(mod))
// break
error_with_pos('cannot import module "$mod" (not found)', ast_file.path,
imp.pos)
@ -108,7 +107,7 @@ pub fn (mut b Builder) parse_imports() {
}
v_files := b.v_files_from_dir(import_path)
if v_files.len == 0 {
// v.parsers[i].error_with_token_index('cannot import module "$mod" (no .v files in "$import_path")', v.parsers[i].import_table.get_import_tok_idx(mod))
// v.parsers[i].error_with_token_index('cannot import module "$mod" (no .v files in "$import_path")', v.parsers[i].import_ast.get_import_tok_idx(mod))
error_with_pos('cannot import module "$mod" (no .v files in "$import_path")',
ast_file.path, imp.pos)
}

View File

@ -430,8 +430,8 @@ fn (mut v Builder) setup_output_name() {
v.pref.cache_manager.save('.description.txt', v.pref.path, '${v.pref.path:-30} @ $v.pref.cache_manager.vopts\n') or {
panic(err)
}
// println('v.table.imports:')
// println(v.table.imports)
// println('v.ast.imports:')
// println(v.ast.imports)
}
if os.is_dir(v.pref.out_name) {
verror("'$v.pref.out_name' is a directory")
@ -913,15 +913,15 @@ fn (mut c Builder) cc_windows_cross() {
println(c.pref.out_name + ' has been successfully compiled')
}
fn (mut v Builder) build_thirdparty_obj_files() {
v.log('build_thirdparty_obj_files: v.table.cflags: $v.table.cflags')
for flag in v.get_os_cflags() {
fn (mut b Builder) build_thirdparty_obj_files() {
b.log('build_thirdparty_obj_files: v.ast.cflags: $b.table.cflags')
for flag in b.get_os_cflags() {
if flag.value.ends_with('.o') {
rest_of_module_flags := v.get_rest_of_module_cflags(flag)
if v.pref.ccompiler == 'msvc' {
v.build_thirdparty_obj_file_with_msvc(flag.value, rest_of_module_flags)
rest_of_module_flags := b.get_rest_of_module_cflags(flag)
if b.pref.ccompiler == 'msvc' {
b.build_thirdparty_obj_file_with_msvc(flag.value, rest_of_module_flags)
} else {
v.build_thirdparty_obj_file(flag.value, rest_of_module_flags)
b.build_thirdparty_obj_file(flag.value, rest_of_module_flags)
}
}
}

View File

@ -260,7 +260,7 @@ pub fn (mut v Builder) cc_msvc() {
println('`builtin.obj` not found')
exit(1)
}
for imp in v.table.imports {
for imp in v.ast.imports {
if imp == 'webview' {
continue
}

View File

@ -3,16 +3,15 @@
// that can be found in the LICENSE file.
module checker
import v.table
import v.token
import v.ast
import v.token
pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.Type, language table.Language) ? {
pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language) ? {
mut expected := expected_
// variadic
if expected.has_flag(.variadic) {
exp_type_sym := c.table.get_type_symbol(expected_)
exp_info := exp_type_sym.info as table.Array
exp_info := exp_type_sym.info as ast.Array
expected = exp_info.elem_type
}
if language == .c {
@ -21,29 +20,29 @@ pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.T
return
}
// mode_t - currently using u32 as mode_t for C fns
// if got.idx() in [table.int_type_idx, table.u32_type_idx] && expected.idx() in [table.int_type_idx, table.u32_type_idx] {
// if got.idx() in [ast.int_type_idx, ast.u32_type_idx] && expected.idx() in [ast.int_type_idx, ast.u32_type_idx] {
// return
// }
// allow number to be used as size_t
if got.is_number() && expected.idx() == table.size_t_type_idx {
if got.is_number() && expected.idx() == ast.size_t_type_idx {
return
}
// allow bool & int to be used interchangeably for C functions
if (got.idx() == table.bool_type_idx
&& expected.idx() in [table.int_type_idx, table.int_literal_type_idx])
|| (expected.idx() == table.bool_type_idx
&& got.idx() in [table.int_type_idx, table.int_literal_type_idx]) {
if (got.idx() == ast.bool_type_idx
&& expected.idx() in [ast.int_type_idx, ast.int_literal_type_idx])
|| (expected.idx() == ast.bool_type_idx
&& got.idx() in [ast.int_type_idx, ast.int_literal_type_idx]) {
return
}
if got.idx() == table.string_type_idx
&& expected in [table.byteptr_type_idx, table.charptr_type_idx] {
if got.idx() == ast.string_type_idx
&& expected in [ast.byteptr_type_idx, ast.charptr_type_idx] {
return
}
exp_sym := c.table.get_type_symbol(expected)
// unknown C types are set to int, allow int to be used for types like `&C.FILE`
// eg. `C.fflush(C.stderr)` - error: cannot use `int` as `&C.FILE` in argument 1 to `C.fflush`
if expected.is_ptr() && exp_sym.language == .c && exp_sym.kind == .placeholder
&& got == table.int_type_idx {
&& got == ast.int_type_idx {
return
}
// return
@ -54,7 +53,7 @@ pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.T
return error('cannot use `${c.table.type_to_str(got.clear_flag(.variadic))}` as `${c.table.type_to_str(expected.clear_flag(.variadic))}`')
}
pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
pub fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool {
got_, exp_ := c.table.unalias_num_type(got), c.table.unalias_num_type(expected)
if got_.idx() == exp_.idx() {
// this is returning true even if one type is a ptr
@ -65,11 +64,11 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
return true
}
// allow pointers to be initialized with 0. TODO: use none instead
if expected.is_ptr() && got_ == table.int_literal_type {
if expected.is_ptr() && got_ == ast.int_literal_type {
return true
}
// TODO: use sym so it can be absorbed into below [.voidptr, .any] logic
if expected.idx() == table.array_type_idx || got.idx() == table.array_type_idx {
if expected.idx() == ast.array_type_idx || got.idx() == ast.array_type_idx {
return true
}
got_sym, exp_sym := c.table.get_type_symbol(got), c.table.get_type_symbol(expected)
@ -100,15 +99,15 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
return c.check_matching_function_symbols(got_sym, exp_sym)
}
// allow using Error as a string for now (avoid a breaking change)
if got == table.error_type_idx && expected == table.string_type_idx {
if got == ast.error_type_idx && expected == ast.string_type_idx {
return true
}
return false
}
pub fn (mut c Checker) check_matching_function_symbols(got_type_sym &table.TypeSymbol, exp_type_sym &table.TypeSymbol) bool {
got_info := got_type_sym.info as table.FnType
exp_info := exp_type_sym.info as table.FnType
pub fn (mut c Checker) check_matching_function_symbols(got_type_sym &ast.TypeSymbol, exp_type_sym &ast.TypeSymbol) bool {
got_info := got_type_sym.info as ast.FnType
exp_info := exp_type_sym.info as ast.FnType
got_fn := got_info.func
exp_fn := exp_info.func
// we are using check() to compare return type & args as they might include
@ -137,39 +136,39 @@ pub fn (mut c Checker) check_matching_function_symbols(got_type_sym &table.TypeS
}
[inline]
fn (mut c Checker) check_shift(left_type table.Type, right_type table.Type, left_pos token.Position, right_pos token.Position) table.Type {
fn (mut c Checker) check_shift(left_type ast.Type, right_type ast.Type, left_pos token.Position, right_pos token.Position) ast.Type {
if !left_type.is_int() {
// maybe it's an int alias? TODO move this to is_int() ?
sym := c.table.get_type_symbol(left_type)
if sym.kind == .alias && (sym.info as table.Alias).parent_type.is_int() {
if sym.kind == .alias && (sym.info as ast.Alias).parent_type.is_int() {
return left_type
}
if c.pref.translated && left_type == table.bool_type {
if c.pref.translated && left_type == ast.bool_type {
// allow `bool << 2` in translated C code
return table.int_type
return ast.int_type
}
c.error('invalid operation: shift on type `$sym.name`', left_pos)
return table.void_type
return ast.void_type
} else if !right_type.is_int() {
c.error('cannot shift non-integer type `${c.table.get_type_symbol(right_type).name}` into type `${c.table.get_type_symbol(left_type).name}`',
right_pos)
return table.void_type
return ast.void_type
}
return left_type
}
pub fn (c &Checker) promote(left_type table.Type, right_type table.Type) table.Type {
pub fn (c &Checker) promote(left_type ast.Type, right_type ast.Type) ast.Type {
if left_type.is_ptr() || left_type.is_pointer() {
if right_type.is_int() {
return left_type
} else {
return table.void_type
return ast.void_type
}
} else if right_type.is_ptr() || right_type.is_pointer() {
if left_type.is_int() {
return right_type
} else {
return table.void_type
return ast.void_type
}
}
if left_type == right_type {
@ -179,13 +178,13 @@ pub fn (c &Checker) promote(left_type table.Type, right_type table.Type) table.T
return c.promote_num(left_type, right_type)
} else if left_type.has_flag(.optional) != right_type.has_flag(.optional) {
// incompatible
return table.void_type
return ast.void_type
} else {
return left_type // default to left if not automatic promotion possible
}
}
fn (c &Checker) promote_num(left_type table.Type, right_type table.Type) table.Type {
fn (c &Checker) promote_num(left_type ast.Type, right_type ast.Type) ast.Type {
// sort the operands to save time
mut type_hi := left_type
mut type_lo := right_type
@ -195,38 +194,38 @@ fn (c &Checker) promote_num(left_type table.Type, right_type table.Type) table.T
idx_hi := type_hi.idx()
idx_lo := type_lo.idx()
// the following comparisons rely on the order of the indices in table/types.v
if idx_hi == table.int_literal_type_idx {
if idx_hi == ast.int_literal_type_idx {
return type_lo
} else if idx_hi == table.float_literal_type_idx {
if idx_lo in table.float_type_idxs {
} else if idx_hi == ast.float_literal_type_idx {
if idx_lo in ast.float_type_idxs {
return type_lo
} else {
return table.void_type
return ast.void_type
}
} else if type_hi.is_float() {
if idx_hi == table.f32_type_idx {
if idx_lo in [table.i64_type_idx, table.u64_type_idx] {
return table.void_type
if idx_hi == ast.f32_type_idx {
if idx_lo in [ast.i64_type_idx, ast.u64_type_idx] {
return ast.void_type
} else {
return type_hi
}
} else { // f64, float_literal
return type_hi
}
} else if idx_lo >= table.byte_type_idx { // both operands are unsigned
} else if idx_lo >= ast.byte_type_idx { // both operands are unsigned
return type_hi
} else if idx_lo >= table.i8_type_idx
&& (idx_hi <= table.i64_type_idx || idx_hi == table.rune_type_idx) { // both signed
return if idx_lo == table.i64_type_idx { type_lo } else { type_hi }
} else if idx_hi - idx_lo < (table.byte_type_idx - table.i8_type_idx) {
} else if idx_lo >= ast.i8_type_idx
&& (idx_hi <= ast.i64_type_idx || idx_hi == ast.rune_type_idx) { // both signed
return if idx_lo == ast.i64_type_idx { type_lo } else { type_hi }
} else if idx_hi - idx_lo < (ast.byte_type_idx - ast.i8_type_idx) {
return type_lo // conversion unsigned -> signed if signed type is larger
} else {
return table.void_type // conversion signed -> unsigned not allowed
return ast.void_type // conversion signed -> unsigned not allowed
}
}
// TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged
pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool {
pub fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
if got == expected {
return true
}
@ -242,7 +241,7 @@ pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool {
if exp_idx == got_idx {
return true
}
if exp_idx == table.voidptr_type_idx || exp_idx == table.byteptr_type_idx {
if exp_idx == ast.voidptr_type_idx || exp_idx == ast.byteptr_type_idx {
if got.is_ptr() || got.is_pointer() {
return true
}
@ -250,25 +249,25 @@ pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool {
// allow direct int-literal assignment for pointers for now
// maybe in the future optionals should be used for that
if expected.is_ptr() || expected.is_pointer() {
if got == table.int_literal_type {
if got == ast.int_literal_type {
return true
}
}
if got_idx == table.voidptr_type_idx || got_idx == table.byteptr_type_idx {
if got_idx == ast.voidptr_type_idx || got_idx == ast.byteptr_type_idx {
if expected.is_ptr() || expected.is_pointer() {
return true
}
}
if expected == table.charptr_type && got == table.char_type.to_ptr() {
if expected == ast.charptr_type && got == ast.char_type.to_ptr() {
return true
}
if !c.check_basic(got, expected) { // TODO: this should go away...
return false
}
if got.is_number() && expected.is_number() {
if got == table.rune_type && expected == table.byte_type {
if got == ast.rune_type && expected == ast.byte_type {
return true
} else if expected == table.rune_type && got == table.byte_type {
} else if expected == ast.rune_type && got == ast.byte_type {
return true
}
if c.promote_num(expected, got) != expected {
@ -282,7 +281,7 @@ pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool {
return true
}
pub fn (mut c Checker) check_expected(got table.Type, expected table.Type) ? {
pub fn (mut c Checker) check_expected(got ast.Type, expected ast.Type) ? {
if c.check_types(got, expected) {
return
}
@ -290,30 +289,30 @@ pub fn (mut c Checker) check_expected(got table.Type, expected table.Type) ? {
}
[inline]
fn (c &Checker) expected_msg(got table.Type, expected table.Type) string {
fn (c &Checker) expected_msg(got ast.Type, expected ast.Type) string {
exps := c.table.type_to_str(expected)
gots := c.table.type_to_str(got)
return 'expected `$exps`, not `$gots`'
}
pub fn (mut c Checker) symmetric_check(left table.Type, right table.Type) bool {
pub fn (mut c Checker) symmetric_check(left ast.Type, right ast.Type) bool {
// allow direct int-literal assignment for pointers for now
// maybe in the future optionals should be used for that
if right.is_ptr() || right.is_pointer() {
if left == table.int_literal_type {
if left == ast.int_literal_type {
return true
}
}
// allow direct int-literal assignment for pointers for now
if left.is_ptr() || left.is_pointer() {
if right == table.int_literal_type {
if right == ast.int_literal_type {
return true
}
}
return c.check_basic(left, right)
}
pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte {
pub fn (c &Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) byte {
if ftyp.has_flag(.optional) {
return `s`
} else if typ.is_float() {
@ -328,16 +327,16 @@ pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte {
mut sym := c.table.get_type_symbol(c.unwrap_generic(ftyp))
if sym.kind == .alias {
// string aliases should be printable
info := sym.info as table.Alias
info := sym.info as ast.Alias
sym = c.table.get_type_symbol(info.parent_type)
if info.parent_type == table.string_type {
if info.parent_type == ast.string_type {
return `s`
}
}
if sym.kind == .function {
return `s`
}
if ftyp in [table.string_type, table.bool_type]
if ftyp in [ast.string_type, ast.bool_type]
|| sym.kind in [.enum_, .array, .array_fixed, .struct_, .map, .multi_return, .sum_type, .interface_, .none_]
|| ftyp.has_flag(.optional) || sym.has_method('str') {
return `s`
@ -347,7 +346,7 @@ pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte {
}
}
pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ table.Type, what string) {
pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) {
mut pos := token.Position{}
match expr {
ast.Ident {
@ -376,7 +375,7 @@ pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ table.Type, what st
}
}
pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.Type {
pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
inside_println_arg_save := c.inside_println_arg
c.inside_println_arg = true
for i, expr in node.exprs {
@ -392,7 +391,7 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.T
if fmt == `_` { // set default representation for type if none has been given
fmt = c.get_default_fmt(ftyp, typ)
if fmt == `_` {
if typ != table.void_type {
if typ != ast.void_type {
c.error('no known default format for type `${c.table.get_type_name(ftyp)}`',
node.fmt_poss[i])
}
@ -413,7 +412,7 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.T
|| (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`])
|| (typ.is_pointer() && fmt !in [`p`, `x`, `X`])
|| (typ.is_string() && fmt != `s`)
|| (typ.idx() in [table.i64_type_idx, table.f64_type_idx] && fmt == `c`) {
|| (typ.idx() in [ast.i64_type_idx, ast.f64_type_idx] && fmt == `c`) {
c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`',
node.fmt_poss[i])
}
@ -425,18 +424,18 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.T
}
}
c.inside_println_arg = inside_println_arg_save
return table.string_type
return ast.string_type
}
pub fn (mut c Checker) infer_fn_types(f table.Fn, mut call_expr ast.CallExpr) {
mut inferred_types := []table.Type{}
pub fn (mut c Checker) infer_fn_types(f ast.Fn, mut call_expr ast.CallExpr) {
mut inferred_types := []ast.Type{}
for gi, gt_name in f.generic_names {
// skip known types
if gi < call_expr.generic_types.len {
inferred_types << call_expr.generic_types[gi]
continue
}
mut typ := table.void_type
mut typ := ast.void_type
for i, param in f.params {
arg_i := if i != 0 && call_expr.is_method { i - 1 } else { i }
if call_expr.args.len <= arg_i {
@ -453,16 +452,16 @@ pub fn (mut c Checker) infer_fn_types(f table.Fn, mut call_expr ast.CallExpr) {
}
arg_sym := c.table.get_type_symbol(arg.typ)
if arg_sym.kind == .array && param_type_sym.kind == .array {
mut arg_elem_info := arg_sym.info as table.Array
mut param_elem_info := param_type_sym.info as table.Array
mut arg_elem_info := arg_sym.info as ast.Array
mut param_elem_info := param_type_sym.info as ast.Array
mut arg_elem_sym := c.table.get_type_symbol(arg_elem_info.elem_type)
mut param_elem_sym := c.table.get_type_symbol(param_elem_info.elem_type)
for {
if arg_elem_sym.kind == .array && param_elem_sym.kind == .array
&& c.cur_fn.generic_params.filter(it.name == param_elem_sym.name).len == 0 {
arg_elem_info = arg_elem_sym.info as table.Array
arg_elem_info = arg_elem_sym.info as ast.Array
arg_elem_sym = c.table.get_type_symbol(arg_elem_info.elem_type)
param_elem_info = param_elem_sym.info as table.Array
param_elem_info = param_elem_sym.info as ast.Array
param_elem_sym = c.table.get_type_symbol(param_elem_info.elem_type)
} else {
typ = arg_elem_info.elem_type
@ -475,7 +474,7 @@ pub fn (mut c Checker) infer_fn_types(f table.Fn, mut call_expr ast.CallExpr) {
break
}
}
if typ == table.void_type {
if typ == ast.void_type {
c.error('could not infer generic type `$gt_name` in call to `$f.name`', call_expr.pos)
return
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,7 @@
vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv:12:7: error: possible type mismatch of compared values of `==` operation
10 | x := ityp == table.string_type
10 | x := ityp == ast.string_type
11 | // the next line should produce at least a warning, or even an error, without an explicit cast:
12 | z := isym == table.string_type
| ~~~~~~~~~~~~~~~~~~~~~~~~~
12 | z := isym == ast.string_type
| ~~~~~~~~~~~~~~~~~~~~~~~
13 | println(typeof(isym).name)
14 | println(typeof(table.string_type).name)
14 | println(typeof(ast.string_type).name)

View File

@ -1,17 +1,17 @@
import v.table
import v.ast
fn main() {
t := table.new_table()
ityp := table.int_type
t := ast.new_table()
ityp := ast.int_type
isym := t.get_type_symbol(ityp)
println(ityp.debug())
println(isym)
println(isym.debug())
x := ityp == table.string_type
x := ityp == ast.string_type
// the next line should produce at least a warning, or even an error, without an explicit cast:
z := isym == table.string_type
z := isym == ast.string_type
println(typeof(isym).name)
println(typeof(table.string_type).name)
println(typeof(ast.string_type).name)
println(x)
println(z)
}

View File

@ -8,7 +8,6 @@ import v.fmt
import v.parser
import v.pref
import v.scanner
import v.table
import v.token
// SymbolKind categorizes the symbols it documents.
@ -92,7 +91,7 @@ pub struct Doc {
pub mut:
prefs &pref.Preferences = new_vdoc_preferences()
base_path string
table &table.Table = &table.Table{}
table &ast.Table = &ast.Table{}
checker checker.Checker = checker.Checker{
table: 0
cur_fn: 0
@ -152,7 +151,7 @@ pub fn new_vdoc_preferences() &pref.Preferences {
pub fn new(input_path string) Doc {
mut d := Doc{
base_path: os.real_path(input_path)
table: table.new_table()
table: ast.new_table()
head: DocNode{}
contents: map[string]DocNode{}
time_generated: time.now()

View File

@ -1,4 +1,4 @@
// import v.table
// import v.ast
import v.doc
// fn test_generate_with_pos() {}

View File

@ -1,9 +1,8 @@
module doc
import os
import v.table
import v.parser
import v.ast
import v.parser
import v.pref
// get_parent_mod returns the parent mod name, in dot format.
@ -40,7 +39,7 @@ fn get_parent_mod(input_dir string) ?string {
}
return error('No V files found.')
}
tbl := table.new_table()
tbl := ast.new_table()
scope := &ast.Scope{
parent: 0
}

View File

@ -3,7 +3,6 @@ module doc
import strings
import v.ast
import v.token
import v.table
// merge_comments merges all the comment contents into a single text.
pub fn merge_comments(comments []ast.Comment) string {
@ -140,9 +139,9 @@ pub fn (d Doc) stmt_pub(stmt ast.Stmt) bool {
}
}
// type_to_str is a wrapper function around `fmt.table.type_to_str`.
pub fn (mut d Doc) type_to_str(typ table.Type) string {
// why is it the default behaviour of table.type_to_str
// type_to_str is a wrapper function around `fmt.ast.type_to_str`.
pub fn (mut d Doc) type_to_str(typ ast.Type) string {
// why is it the default behaviour of ast.type_to_str
// to convert math.bits.Type to bits.Type?
d.table.cmod_prefix = d.orig_mod_name + '.'
return d.fmt.table.type_to_str(typ).all_after('&')

View File

@ -5,7 +5,6 @@ module eval
import v.ast
import v.checker
import v.table
import v.pref
pub type Object = int | string
@ -14,14 +13,14 @@ pub struct Eval {
mut:
checker checker.Checker
vars map[string]Var
table &table.Table
table &ast.Table
}
pub struct Var {
value Object
}
pub fn (mut e Eval) eval(file ast.File, table &table.Table) string {
pub fn (mut e Eval) eval(file ast.File, table &ast.Table) string {
vpref := &pref.Preferences{}
e.table = table
mut res := ''

View File

@ -3,9 +3,9 @@
// that can be found in the LICENSE file.
module fmt
import v.table
import v.ast
pub fn (mut f Fmt) attrs(attrs []table.Attr) {
pub fn (mut f Fmt) attrs(attrs []ast.Attr) {
mut sorted_attrs := attrs.clone()
// Sort the attributes. The ones with arguments come first.
sorted_attrs.sort(a.arg.len > b.arg.len)
@ -22,7 +22,7 @@ pub struct AttrsOptions {
inline bool
}
pub fn (mut f Fmt) single_line_attrs(attrs []table.Attr, options AttrsOptions) {
pub fn (mut f Fmt) single_line_attrs(attrs []ast.Attr, options AttrsOptions) {
if attrs.len == 0 {
return
}
@ -44,7 +44,7 @@ pub fn (mut f Fmt) single_line_attrs(attrs []table.Attr, options AttrsOptions) {
}
}
fn inline_attrs_len(attrs []table.Attr) int {
fn inline_attrs_len(attrs []ast.Attr) int {
if attrs.len == 0 {
return 0
}

View File

@ -5,7 +5,6 @@ module fmt
import math.mathutil as mu
import v.ast
import v.table
import strings
import v.util
import v.pref
@ -18,7 +17,7 @@ const (
pub struct Fmt {
pub mut:
table &table.Table
table &ast.Table
out_imports strings.Builder
out strings.Builder
indent int
@ -49,7 +48,7 @@ pub mut:
pref &pref.Preferences
}
pub fn fmt(file ast.File, table &table.Table, pref &pref.Preferences, is_debug bool) string {
pub fn fmt(file ast.File, table &ast.Table, pref &pref.Preferences, is_debug bool) string {
mut f := Fmt{
out: strings.new_builder(1000)
out_imports: strings.new_builder(200)
@ -113,7 +112,7 @@ fn (mut f Fmt) write_indent() {
f.line_len += f.indent * 4
}
fn (mut f Fmt) write_language_prefix(lang table.Language) {
fn (mut f Fmt) write_language_prefix(lang ast.Language) {
match lang {
.c { f.write('C.') }
.js { f.write('JS.') }
@ -223,7 +222,7 @@ pub fn (mut f Fmt) short_module(name string) string {
//=== Import-related methods ===//
pub fn (mut f Fmt) mark_types_import_as_used(typ table.Type) {
pub fn (mut f Fmt) mark_types_import_as_used(typ ast.Type) {
sym := f.table.get_type_symbol(typ)
f.mark_import_as_used(sym.name)
}
@ -617,7 +616,7 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
ast.StructInit {
f.struct_init(node)
}
ast.Type {
ast.TypeNode {
f.type_expr(node)
}
ast.TypeOf {
@ -1261,7 +1260,7 @@ pub fn (mut f Fmt) fn_type_decl(node ast.FnTypeDecl) {
f.write('pub ')
}
typ_sym := f.table.get_type_symbol(node.typ)
fn_typ_info := typ_sym.info as table.FnType
fn_typ_info := typ_sym.info as ast.FnType
fn_info := fn_typ_info.func
fn_name := f.no_cur_mod(node.name)
f.write('type $fn_name = fn (')
@ -1293,7 +1292,7 @@ pub fn (mut f Fmt) fn_type_decl(node ast.FnTypeDecl) {
}
}
f.write(')')
if fn_info.return_type.idx() != table.void_type_idx {
if fn_info.return_type.idx() != ast.void_type_idx {
ret_str := f.no_cur_mod(f.table.type_to_str_using_aliases(fn_info.return_type,
f.mod2alias))
f.write(' $ret_str')
@ -1335,7 +1334,7 @@ pub fn (mut f Fmt) array_decompose(node ast.ArrayDecompose) {
}
pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
if node.exprs.len == 0 && node.typ != 0 && node.typ != table.void_type {
if node.exprs.len == 0 && node.typ != 0 && node.typ != ast.void_type {
// `x := []string{}`
f.mark_types_import_as_used(node.typ)
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
@ -1530,7 +1529,7 @@ pub fn (mut f Fmt) call_expr(node ast.CallExpr) {
f.use_short_fn_args = false
if node.args.len > 0 && node.args.last().expr is ast.StructInit {
struct_expr := node.args.last().expr as ast.StructInit
if struct_expr.typ == table.void_type {
if struct_expr.typ == ast.void_type {
f.use_short_fn_args = true
}
}
@ -2005,7 +2004,7 @@ pub fn (mut f Fmt) lock_expr(node ast.LockExpr) {
pub fn (mut f Fmt) map_init(node ast.MapInit) {
if node.keys.len == 0 {
if node.typ > table.void_type {
if node.typ > ast.void_type {
f.mark_types_import_as_used(node.typ)
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
} else {
@ -2269,7 +2268,7 @@ pub fn (mut f Fmt) string_literal(node ast.StringLiteral) {
use_double_quote := node.val.contains("'") && !node.val.contains('"')
if node.is_raw {
f.write('r')
} else if node.language == table.Language.c {
} else if node.language == ast.Language.c {
f.write('c')
}
if node.is_raw {
@ -2323,7 +2322,7 @@ pub fn (mut f Fmt) string_inter_literal(node ast.StringInterLiteral) {
f.write(quote)
}
pub fn (mut f Fmt) type_expr(node ast.Type) {
pub fn (mut f Fmt) type_expr(node ast.TypeNode) {
f.write(f.table.type_to_str(node.typ))
}

View File

@ -4,10 +4,9 @@
import os
import term
import benchmark
import v.ast
import v.fmt
import v.parser
import v.table
import v.ast
import v.pref
import v.util
import v.util.vtest
@ -54,7 +53,7 @@ fn test_fmt() {
eprintln(fmt_bench.step_message_fail('cannot read from $vrelpath'))
continue
}
table := table.new_table()
table := ast.new_table()
file_ast := parser.parse_file(ipath, table, .parse_comments, fpref, &ast.Scope{
parent: 0
})

View File

@ -7,7 +7,6 @@ import benchmark
import v.ast
import v.fmt
import v.parser
import v.table
import v.pref
import v.util
@ -49,7 +48,7 @@ fn test_fmt() {
eprintln(fmt_bench.step_message_fail('cannot read from $opath'))
continue
}
table := table.new_table()
table := ast.new_table()
file_ast := parser.parse_file(ipath, table, .parse_comments, fpref, &ast.Scope{
parent: 0
})

View File

@ -7,7 +7,6 @@ import benchmark
import v.ast
import v.fmt
import v.parser
import v.table
import v.pref
import v.util
@ -47,7 +46,7 @@ fn test_vlib_fmt() {
eprintln(fmt_bench.step_message_fail('cannot read from $opath'))
continue
}
table := table.new_table()
table := ast.new_table()
file_ast := parser.parse_file(ipath, table, .parse_comments, fpref, &ast.Scope{
parent: 0
})

View File

@ -4,7 +4,6 @@ module c
import strings
import v.ast
import v.table
fn (mut g Gen) array_init(node ast.ArrayInit) {
type_sym := g.table.get_type_symbol(node.typ)
@ -36,7 +35,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
}
} else if node.has_default {
g.expr(node.default_expr)
info := type_sym.info as table.ArrayFixed
info := type_sym.info as ast.ArrayFixed
for _ in 1 .. info.size {
g.write(', ')
g.expr(node.default_expr)
@ -81,7 +80,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
g.write('&($elem_type_str[]){')
g.expr(node.default_expr)
g.write('})')
} else if node.has_len && node.elem_type == table.string_type {
} else if node.has_len && node.elem_type == ast.string_type {
g.write('&($elem_type_str[]){')
g.write('_SLIT("")')
g.write('})')
@ -134,9 +133,9 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
// inp_typ := g.typ(node.receiver_type)
ret_sym := g.table.get_type_symbol(node.return_type)
inp_sym := g.table.get_type_symbol(node.receiver_type)
ret_info := ret_sym.info as table.Array
ret_info := ret_sym.info as ast.Array
ret_elem_type := g.typ(ret_info.elem_type)
inp_info := inp_sym.info as table.Array
inp_info := inp_sym.info as ast.Array
inp_elem_type := g.typ(inp_info.elem_type)
if inp_sym.kind != .array {
verror('map() requires an array')
@ -209,7 +208,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
// println(rec_sym.kind)
verror('.sort() is an array method')
}
info := rec_sym.info as table.Array
info := rec_sym.info as ast.Array
// No arguments means we are sorting an array of builtins (e.g. `numbers.sort()`)
// The type for the comparison fns is the type of the element itself.
mut typ := info.elem_type
@ -228,10 +227,10 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
if is_default {
// users.sort() or users.sort(a > b)
compare_fn = match typ {
table.int_type, table.int_type.to_ptr() { 'compare_ints' }
table.u64_type, table.u64_type.to_ptr() { 'compare_u64s' }
table.string_type, table.string_type.to_ptr() { 'compare_strings' }
table.f64_type, table.f64_type.to_ptr() { 'compare_floats' }
ast.int_type, ast.int_type.to_ptr() { 'compare_ints' }
ast.u64_type, ast.u64_type.to_ptr() { 'compare_u64s' }
ast.string_type, ast.string_type.to_ptr() { 'compare_strings' }
ast.f64_type, ast.f64_type.to_ptr() { 'compare_floats' }
else { '' }
}
if compare_fn != '' && is_reverse {
@ -248,7 +247,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
compare_fn += '_reverse'
}
// Register a new custom `compare_xxx` function for qsort()
g.table.register_fn(name: compare_fn, return_type: table.int_type)
g.table.register_fn(name: compare_fn, return_type: ast.int_type)
infix_expr := node.args[0].expr as ast.InfixExpr
// Variables `a` and `b` are used in the `.sort(a < b)` syntax, so we can reuse them
// when generating the function as long as the args are named the same.
@ -270,7 +269,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
g.definitions.writeln('$field_type a_ = $left_expr_str;')
g.definitions.writeln('$field_type b_ = $right_expr_str;')
mut op1, mut op2 := '', ''
if infix_expr.left_type == table.string_type {
if infix_expr.left_type == ast.string_type {
if is_reverse {
op1 = 'string_gt(a_, b_)'
op2 = 'string_lt(a_, b_)'
@ -316,7 +315,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
if sym.kind != .array {
verror('filter() requires an array')
}
info := sym.info as table.Array
info := sym.info as ast.Array
styp := g.typ(node.return_type)
elem_type_str := g.typ(info.elem_type)
g.empty_line = true
@ -379,7 +378,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
// `nums.insert(0, 2)` `nums.insert(0, [2,3,4])`
fn (mut g Gen) gen_array_insert(node ast.CallExpr) {
left_sym := g.table.get_type_symbol(node.left_type)
left_info := left_sym.info as table.Array
left_info := left_sym.info as ast.Array
elem_type_str := g.typ(left_info.elem_type)
arg2_sym := g.table.get_type_symbol(node.args[1].typ)
is_arg2_array := arg2_sym.kind == .array && node.args[1].typ == node.left_type
@ -399,11 +398,11 @@ fn (mut g Gen) gen_array_insert(node ast.CallExpr) {
g.write('.len)')
} else {
g.write(', &($elem_type_str[]){')
if left_info.elem_type == table.string_type {
if left_info.elem_type == ast.string_type {
g.write('string_clone(')
}
g.expr(node.args[1].expr)
if left_info.elem_type == table.string_type {
if left_info.elem_type == ast.string_type {
g.write(')')
}
g.write('})')
@ -413,7 +412,7 @@ fn (mut g Gen) gen_array_insert(node ast.CallExpr) {
// `nums.prepend(2)` `nums.prepend([2,3,4])`
fn (mut g Gen) gen_array_prepend(node ast.CallExpr) {
left_sym := g.table.get_type_symbol(node.left_type)
left_info := left_sym.info as table.Array
left_info := left_sym.info as ast.Array
elem_type_str := g.typ(left_info.elem_type)
arg_sym := g.table.get_type_symbol(node.args[0].typ)
is_arg_array := arg_sym.kind == .array && node.args[0].typ == node.left_type
@ -436,12 +435,12 @@ fn (mut g Gen) gen_array_prepend(node ast.CallExpr) {
}
}
fn (mut g Gen) gen_array_contains_method(left_type table.Type) string {
fn (mut g Gen) gen_array_contains_method(left_type ast.Type) string {
mut left_sym := g.table.get_type_symbol(left_type)
mut left_type_str := g.typ(left_type).replace('*', '')
fn_name := '${left_type_str}_contains'
if !left_sym.has_method('contains') {
left_info := left_sym.info as table.Array
left_info := left_sym.info as ast.Array
mut elem_type_str := g.typ(left_info.elem_type)
elem_sym := g.table.get_type_symbol(left_info.elem_type)
if elem_sym.kind == .function {
@ -474,11 +473,11 @@ fn (mut g Gen) gen_array_contains_method(left_type table.Type) string {
fn_builder.writeln('\treturn false;')
fn_builder.writeln('}')
g.auto_fn_definitions << fn_builder.str()
left_sym.register_method(&table.Fn{
left_sym.register_method(&ast.Fn{
name: 'contains'
params: [table.Param{
params: [ast.Param{
typ: left_type
}, table.Param{
}, ast.Param{
typ: left_info.elem_type
}]
})
@ -499,12 +498,12 @@ fn (mut g Gen) gen_array_contains(node ast.CallExpr) {
g.write(')')
}
fn (mut g Gen) gen_array_index_method(left_type table.Type) string {
fn (mut g Gen) gen_array_index_method(left_type ast.Type) string {
mut left_sym := g.table.get_type_symbol(left_type)
mut left_type_str := g.typ(left_type).trim('*')
fn_name := '${left_type_str}_index'
if !left_sym.has_method('index') {
info := left_sym.info as table.Array
info := left_sym.info as ast.Array
mut elem_type_str := g.typ(info.elem_type)
elem_sym := g.table.get_type_symbol(info.elem_type)
if elem_sym.kind == .function {
@ -537,11 +536,11 @@ fn (mut g Gen) gen_array_index_method(left_type table.Type) string {
fn_builder.writeln('\treturn -1;')
fn_builder.writeln('}')
g.auto_fn_definitions << fn_builder.str()
left_sym.register_method(&table.Fn{
left_sym.register_method(&ast.Fn{
name: 'index'
params: [table.Param{
params: [ast.Param{
typ: left_type
}, table.Param{
}, ast.Param{
typ: info.elem_type
}]
})
@ -578,7 +577,7 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) {
tmp := g.new_tmp_var()
s := g.go_before_stmt(0)
sym := g.table.get_type_symbol(node.left_type)
info := sym.info as table.Array
info := sym.info as ast.Array
// styp := g.typ(node.return_type)
elem_type_str := g.typ(info.elem_type)
g.empty_line = true
@ -642,7 +641,7 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) {
tmp := g.new_tmp_var()
s := g.go_before_stmt(0)
sym := g.table.get_type_symbol(node.left_type)
info := sym.info as table.Array
info := sym.info as ast.Array
// styp := g.typ(node.return_type)
elem_type_str := g.typ(info.elem_type)
g.empty_line = true

View File

@ -4,7 +4,6 @@
module c
import v.ast
import v.table
fn (mut g Gen) gen_assert_stmt(original_assert_statement ast.AssertStmt) {
mut node := original_assert_statement
@ -84,7 +83,7 @@ fn (mut g Gen) gen_assert_metainfo(node ast.AssertStmt) string {
return metaname
}
fn (mut g Gen) gen_assert_single_expr(expr ast.Expr, typ table.Type) {
fn (mut g Gen) gen_assert_single_expr(expr ast.Expr, typ ast.Type) {
unknown_value := '*unknown value*'
match expr {
ast.CastExpr, ast.IndexExpr, ast.MatchExpr {
@ -100,7 +99,7 @@ fn (mut g Gen) gen_assert_single_expr(expr ast.Expr, typ table.Type) {
g.gen_expr_to_string(expr, typ)
}
}
ast.Type {
ast.TypeNode {
sym := g.table.get_type_symbol(typ)
g.write(ctoslit('$sym.name'))
}

View File

@ -3,9 +3,9 @@
module c
import strings
import v.table
import v.ast
fn (mut g Gen) gen_sumtype_equality_fn(left table.Type) string {
fn (mut g Gen) gen_sumtype_equality_fn(left ast.Type) string {
ptr_typ := g.typ(left).trim('*')
if ptr_typ in g.sumtype_fn_definitions {
return ptr_typ
@ -58,7 +58,7 @@ fn (mut g Gen) gen_sumtype_equality_fn(left table.Type) string {
return ptr_typ
}
fn (mut g Gen) gen_struct_equality_fn(left table.Type) string {
fn (mut g Gen) gen_struct_equality_fn(left ast.Type) string {
ptr_typ := g.typ(left).trim('*')
if ptr_typ in g.struct_fn_definitions {
return ptr_typ
@ -115,14 +115,14 @@ fn (mut g Gen) gen_struct_equality_fn(left table.Type) string {
return ptr_typ
}
fn (mut g Gen) gen_alias_equality_fn(left table.Type) string {
fn (mut g Gen) gen_alias_equality_fn(left ast.Type) string {
ptr_typ := g.typ(left).trim('*')
if ptr_typ in g.alias_fn_definitions {
return ptr_typ
}
g.alias_fn_definitions << ptr_typ
left_sym := g.table.get_type_symbol(left)
info := left_sym.info as table.Alias
info := left_sym.info as ast.Alias
g.type_definitions.writeln('static bool ${ptr_typ}_alias_eq($ptr_typ a, $ptr_typ b); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static bool ${ptr_typ}_alias_eq($ptr_typ a, $ptr_typ b) {')
@ -157,7 +157,7 @@ fn (mut g Gen) gen_alias_equality_fn(left table.Type) string {
return ptr_typ
}
fn (mut g Gen) gen_array_equality_fn(left table.Type) string {
fn (mut g Gen) gen_array_equality_fn(left ast.Type) string {
ptr_typ := g.typ(left).trim('*')
if ptr_typ in g.array_fn_definitions {
return ptr_typ
@ -209,7 +209,7 @@ fn (mut g Gen) gen_array_equality_fn(left table.Type) string {
return ptr_typ
}
fn (mut g Gen) gen_fixed_array_equality_fn(left table.Type) string {
fn (mut g Gen) gen_fixed_array_equality_fn(left ast.Type) string {
ptr_typ := g.typ(left).trim('*')
if ptr_typ in g.array_fn_definitions {
return ptr_typ
@ -259,7 +259,7 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left table.Type) string {
return ptr_typ
}
fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
fn (mut g Gen) gen_map_equality_fn(left ast.Type) string {
ptr_typ := g.typ(left).trim('*')
if ptr_typ in g.map_fn_definitions {
return ptr_typ
@ -281,7 +281,7 @@ fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
kind := g.table.type_kind(value_typ)
if kind == .function {
value_sym := g.table.get_type_symbol(value_typ)
func := value_sym.info as table.FnType
func := value_sym.info as ast.FnType
ret_styp := g.typ(func.func.return_type)
fn_builder.write_string('\t\t$ret_styp (*v) (')
arg_len := func.func.params.len

View File

@ -2,26 +2,26 @@
// Use of this source code is governed by an MIT license that can be found in the LICENSE file.
module c
import v.table
import v.ast
import v.util
fn should_use_indent_func(kind table.Kind) bool {
fn should_use_indent_func(kind ast.Kind) bool {
return kind in [.struct_, .alias, .array, .array_fixed, .map, .sum_type, .interface_]
}
fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_default(sym ast.TypeSymbol, styp string, str_fn_name string) {
mut convertor := ''
mut typename_ := ''
if sym.parent_idx in table.integer_type_idxs {
if sym.parent_idx in ast.integer_type_idxs {
convertor = 'int'
typename_ = 'int'
} else if sym.parent_idx == table.f32_type_idx {
} else if sym.parent_idx == ast.f32_type_idx {
convertor = 'float'
typename_ = 'f32'
} else if sym.parent_idx == table.f64_type_idx {
} else if sym.parent_idx == ast.f64_type_idx {
convertor = 'double'
typename_ = 'f64'
} else if sym.parent_idx == table.bool_type_idx {
} else if sym.parent_idx == ast.bool_type_idx {
convertor = 'bool'
typename_ = 'bool'
} else {
@ -40,7 +40,7 @@ fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp string, str_fn_name st
g.auto_str_funcs.writeln('}')
}
fn (g &Gen) type_to_fmt(typ table.Type) string {
fn (g &Gen) type_to_fmt(typ ast.Type) string {
sym := g.table.get_type_symbol(typ)
if typ.is_ptr() && (typ.is_int() || typ.is_float()) {
return '%.*s\\000'
@ -61,11 +61,11 @@ fn (g &Gen) type_to_fmt(typ table.Type) string {
return '%d\\000'
}
fn (mut g Gen) gen_str_for_type(typ table.Type) string {
fn (mut g Gen) gen_str_for_type(typ ast.Type) string {
styp := g.typ(typ).replace('*', '')
mut sym := g.table.get_type_symbol(g.unwrap_generic(typ))
mut str_fn_name := styp_to_str_fn_name(styp)
if mut sym.info is table.Alias {
if mut sym.info is ast.Alias {
if sym.info.is_import {
sym = g.table.get_type_symbol(sym.info.parent_type)
str_fn_name = styp_to_str_fn_name(sym.name)
@ -79,38 +79,38 @@ fn (mut g Gen) gen_str_for_type(typ table.Type) string {
}
g.str_types << already_generated_key
match mut sym.info {
table.Alias {
ast.Alias {
if sym.info.is_import {
g.gen_str_default(sym, styp, str_fn_name)
} else {
g.gen_str_for_alias(sym.info, styp, str_fn_name)
}
}
table.Array {
ast.Array {
g.gen_str_for_array(sym.info, styp, str_fn_name)
}
table.ArrayFixed {
ast.ArrayFixed {
g.gen_str_for_array_fixed(sym.info, styp, str_fn_name)
}
table.Enum {
ast.Enum {
g.gen_str_for_enum(sym.info, styp, str_fn_name)
}
table.FnType {
ast.FnType {
g.gen_str_for_fn_type(sym.info, styp, str_fn_name)
}
table.Struct {
ast.Struct {
g.gen_str_for_struct(sym.info, styp, str_fn_name)
}
table.Map {
ast.Map {
g.gen_str_for_map(sym.info, styp, str_fn_name)
}
table.MultiReturn {
ast.MultiReturn {
g.gen_str_for_multi_return(sym.info, styp, str_fn_name)
}
table.SumType {
ast.SumType {
g.gen_str_for_union_sum_type(sym.info, styp, str_fn_name)
}
table.Interface {
ast.Interface {
g.gen_str_for_interface(sym.info, styp, str_fn_name)
}
else {
@ -129,7 +129,7 @@ fn (mut g Gen) gen_str_for_type(typ table.Type) string {
return str_fn_name
}
fn (mut g Gen) gen_str_for_option(typ table.Type, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string) {
parent_type := typ.clear_flag(.optional)
sym := g.table.get_type_symbol(parent_type)
sym_has_str_method, _, _ := sym.str_method_info()
@ -157,7 +157,7 @@ fn (mut g Gen) gen_str_for_option(typ table.Type, styp string, str_fn_name strin
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) gen_str_for_alias(info table.Alias, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string) {
sym := g.table.get_type_symbol(info.parent_type)
sym_has_str_method, _, _ := sym.str_method_info()
mut parent_str_fn_name := styp_to_str_fn_name(sym.name.replace('.', '__'))
@ -177,10 +177,10 @@ fn (mut g Gen) gen_str_for_alias(info table.Alias, styp string, str_fn_name stri
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string) {
mut typ := info.elem_type
mut sym := g.table.get_type_symbol(info.elem_type)
if mut sym.info is table.Alias {
if mut sym.info is ast.Alias {
typ = sym.info.parent_type
sym = g.table.get_type_symbol(typ)
}
@ -245,7 +245,7 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name stri
}
}
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, x);')
if g.is_autofree && typ != table.bool_type {
if g.is_autofree && typ != ast.bool_type {
// no need to free "true"/"false" literals
g.auto_str_funcs.writeln('\t\tstring_free(&x);')
}
@ -260,10 +260,10 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name stri
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_fn_name string) {
mut typ := info.elem_type
mut sym := g.table.get_type_symbol(info.elem_type)
if mut sym.info is table.Alias {
if mut sym.info is ast.Alias {
typ = sym.info.parent_type
sym = g.table.get_type_symbol(typ)
}
@ -322,10 +322,10 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp string, str_f
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
mut key_typ := info.key_type
mut key_sym := g.table.get_type_symbol(key_typ)
if mut key_sym.info is table.Alias {
if mut key_sym.info is ast.Alias {
key_typ = key_sym.info.parent_type
key_sym = g.table.get_type_symbol(key_typ)
}
@ -337,7 +337,7 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string)
mut val_typ := info.value_type
mut val_sym := g.table.get_type_symbol(val_typ)
if mut val_sym.info is table.Alias {
if mut val_sym.info is ast.Alias {
val_typ = val_sym.info.parent_type
val_sym = g.table.get_type_symbol(val_typ)
}
@ -393,7 +393,7 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string)
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) gen_str_for_multi_return(info table.MultiReturn, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str_fn_name string) {
for typ in info.types {
sym := g.table.get_type_symbol(typ)
if !sym.has_method('str') {
@ -447,7 +447,7 @@ fn (mut g Gen) gen_str_for_multi_return(info table.MultiReturn, styp string, str
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name string) {
// TODO: short it if possible
// generates all definitions of substructs
mut fnames2strfunc := map{
@ -534,7 +534,7 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name st
g.auto_str_funcs.writeln('}')
}
fn struct_auto_str_func(sym &table.TypeSymbol, field_type table.Type, fn_name string, field_name string) string {
fn struct_auto_str_func(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string) string {
has_custom_str, expects_ptr, _ := sym.str_method_info()
if sym.kind == .enum_ {
return '${fn_name}(it.${c_name(field_name)})'
@ -574,7 +574,7 @@ fn struct_auto_str_func(sym &table.TypeSymbol, field_type table.Type, fn_name st
}
}
fn (mut g Gen) gen_str_for_enum(info table.Enum, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_enum(info ast.Enum, styp string, str_fn_name string) {
s := util.no_dots(styp)
g.type_definitions.writeln('static string ${str_fn_name}($styp it); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp it) { /* gen_str_for_enum */')
@ -606,7 +606,7 @@ fn (mut g Gen) gen_str_for_enum(info table.Enum, styp string, str_fn_name string
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) gen_str_for_interface(info table.Interface, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_name string) {
mut gen_fn_names := map[string]string{}
for typ in info.types {
sym := g.table.get_type_symbol(typ)
@ -641,7 +641,7 @@ fn (mut g Gen) gen_str_for_interface(info table.Interface, styp string, str_fn_n
func_name = 'indent_$func_name'
}
deref := if sym_has_str_method && str_method_expects_ptr { ' ' } else { '*' }
value_fmt := if typ == table.string_type { "'%.*s\\000'" } else { '%.*s\\000' }
value_fmt := if typ == ast.string_type { "'%.*s\\000'" } else { '%.*s\\000' }
g.auto_str_funcs.write_string('\tif (x._interface_idx == _${styp}_${subtype.cname}_index)')
g.auto_str_funcs.write_string(' return _STR("${clean_interface_v_type_name}($value_fmt)", 2, ')
@ -655,7 +655,7 @@ fn (mut g Gen) gen_str_for_interface(info table.Interface, styp string, str_fn_n
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, str_fn_name string) {
mut gen_fn_names := map[string]string{}
for typ in info.variants {
sym := g.table.get_type_symbol(typ)
@ -678,7 +678,7 @@ fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_f
g.auto_str_funcs.writeln('\tswitch(x._typ) {')
for typ in info.variants {
mut value_fmt := '%.*s\\000'
if typ == table.string_type {
if typ == ast.string_type {
value_fmt = "'$value_fmt'"
}
typ_str := g.typ(typ)
@ -704,7 +704,7 @@ fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_f
g.auto_str_funcs.writeln('}')
}
fn (mut g Gen) fn_decl_str(info table.FnType) string {
fn (mut g Gen) fn_decl_str(info ast.FnType) string {
mut fn_str := 'fn ('
for i, arg in info.func.params {
if i > 0 {
@ -713,13 +713,13 @@ fn (mut g Gen) fn_decl_str(info table.FnType) string {
fn_str += util.strip_main_name(g.table.get_type_name(arg.typ))
}
fn_str += ')'
if info.func.return_type != table.void_type {
if info.func.return_type != ast.void_type {
fn_str += ' ${util.strip_main_name(g.table.get_type_name(info.func.return_type))}'
}
return fn_str
}
fn (mut g Gen) gen_str_for_fn_type(info table.FnType, styp string, str_fn_name string) {
fn (mut g Gen) gen_str_for_fn_type(info ast.FnType, styp string, str_fn_name string) {
g.type_definitions.writeln('static string ${str_fn_name}(); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}() { return _SLIT("${g.fn_decl_str(info)}");}')
}

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,6 @@ module c
import os
import v.ast
import v.table
import v.util
fn (mut g Gen) comptime_selector(node ast.ComptimeSelector) {
@ -123,7 +122,7 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) {
} else {
// last argument; try to expand if it's []string
idx := i - node.args.len
if m.params[i].typ.is_int() || m.params[i].typ.idx() == table.bool_type_idx {
if m.params[i].typ.is_int() || m.params[i].typ.idx() == ast.bool_type_idx {
// Gets the type name and cast the string to the type with the string_<type> function
type_name := g.table.type_symbols[int(m.params[i].typ)].str()
g.write('string_${type_name}(((string*)${node.args[node.args.len - 1]}.data) [$idx])')
@ -140,7 +139,7 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) {
}
mut j := 0
for method in node.sym.methods {
// if method.return_type != table.void_type {
// if method.return_type != ast.void_type {
if method.return_type != node.result_type {
continue
}
@ -165,7 +164,7 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) {
}
}
fn cgen_attrs(attrs []table.Attr) []string {
fn cgen_attrs(attrs []ast.Attr) []string {
mut res := []string{cap: attrs.len}
for attr in attrs {
// we currently don't quote 'arg' (otherwise we could just use `s := attr.str()`)
@ -287,12 +286,12 @@ fn (mut g Gen) comp_if_cond(cond ast.Expr) bool {
.key_is, .not_is {
left := cond.left
mut name := ''
mut exp_type := table.Type(0)
got_type := (cond.right as ast.Type).typ
mut exp_type := ast.Type(0)
got_type := (cond.right as ast.TypeNode).typ
if left is ast.SelectorExpr {
name = '${left.expr}.$left.field_name'
exp_type = g.comptime_var_type_map[name]
} else if left is ast.Type {
} else if left is ast.TypeNode {
name = left.str()
// this is only allowed for generics currently, otherwise blocked by checker
exp_type = g.unwrap_generic(left.typ)
@ -333,7 +332,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
sym := g.table.get_type_symbol(g.unwrap_generic(node.typ))
g.writeln('/* \$for $node.val_var in ${sym.name}($node.kind.str()) */ {')
g.indent++
// vweb_result_type := table.new_type(g.table.find_type_idx('vweb.Result'))
// vweb_result_type := ast.new_type(g.table.find_type_idx('vweb.Result'))
mut i := 0
// g.writeln('string method = _SLIT("");')
if node.kind == .methods {
@ -345,7 +344,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
}
for method in methods { // sym.methods {
/*
if method.return_type != vweb_result_type { // table.void_type {
if method.return_type != vweb_result_type { // ast.void_type {
continue
}
*/
@ -414,7 +413,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
}
} else if node.kind == .fields {
// TODO add fields
if sym.info is table.Struct {
if sym.info is ast.Struct {
mut fields := sym.info.fields.filter(it.attrs.len == 0)
fields_with_attrs := sym.info.fields.filter(it.attrs.len > 0)
fields << fields_with_attrs

View File

@ -1,9 +1,8 @@
module c
import v.ast
import v.table
fn (mut g Gen) new_ctemp_var(expr ast.Expr, expr_type table.Type) ast.CTempVar {
fn (mut g Gen) new_ctemp_var(expr ast.Expr, expr_type ast.Type) ast.CTempVar {
return ast.CTempVar{
name: g.new_tmp_var()
typ: expr_type
@ -12,7 +11,7 @@ fn (mut g Gen) new_ctemp_var(expr ast.Expr, expr_type table.Type) ast.CTempVar {
}
}
fn (mut g Gen) new_ctemp_var_then_gen(expr ast.Expr, expr_type table.Type) ast.CTempVar {
fn (mut g Gen) new_ctemp_var_then_gen(expr ast.Expr, expr_type ast.Type) ast.CTempVar {
x := g.new_ctemp_var(expr, expr_type)
g.gen_ctemp_var(x)
return x

View File

@ -1,7 +1,6 @@
module c
import v.ast
import v.table
fn (mut g Gen) dump_expr(node ast.DumpExpr) {
sexpr := ctoslit(node.expr.str())
@ -20,7 +19,7 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) {
fn (mut g Gen) dump_expr_definitions() {
if g.pref.build_mode == .build_module {
for dump_type, cname in g.table.dumps {
is_ptr := table.Type(dump_type).is_ptr()
is_ptr := ast.Type(dump_type).is_ptr()
ptr_suffix := if is_ptr { '*' } else { '' }
dump_fn_name := '_v_dump_expr_$cname' + (if is_ptr { '_ptr' } else { '' })
g.definitions.writeln('$cname$ptr_suffix ${dump_fn_name}(string fpath, int line, string sexpr, $cname$ptr_suffix x) {')
@ -28,7 +27,7 @@ fn (mut g Gen) dump_expr_definitions() {
} else {
for dump_type, cname in g.table.dumps {
to_string_fn_name := g.gen_str_for_type(dump_type)
is_ptr := table.Type(dump_type).is_ptr()
is_ptr := ast.Type(dump_type).is_ptr()
ptr_astarisk := if is_ptr { '*' } else { '' }
dump_fn_name := '_v_dump_expr_$cname' + (if is_ptr { '_ptr' } else { '' })
g.definitions.writeln('$cname$ptr_astarisk ${dump_fn_name}(string fpath, int line, string sexpr, $cname$ptr_astarisk x) {')

View File

@ -30,7 +30,7 @@ fn (mut g Gen) gen_embed_file_init(node ast.ComptimeCall) {
g.writeln('} // \$embed_file("$node.embed_file.apath")')
}
// gen_embedded_data embeds data into the V target executable.
// gen_embedded_data embeds data into the V target execuast.
fn (mut g Gen) gen_embedded_data() {
/*
TODO implement compression.

View File

@ -4,7 +4,6 @@
module c
import v.ast
import v.table
import v.util
fn (mut g Gen) is_used_by_main(node ast.FnDecl) bool {
@ -302,7 +301,7 @@ fn (mut g Gen) gen_fn_decl(node ast.FnDecl, skip bool) {
} else {
g.defer_stmts = []
}
if node.return_type != table.void_type && node.stmts.len > 0 && node.stmts.last() !is ast.Return {
if node.return_type != ast.void_type && node.stmts.len > 0 && node.stmts.last() !is ast.Return {
default_expr := g.type_default(node.return_type)
// TODO: perf?
if default_expr == '{0}' {
@ -353,7 +352,7 @@ fn (mut g Gen) write_defer_stmts_when_needed() {
}
// fn decl args
fn (mut g Gen) fn_args(args []table.Param, is_variadic bool) ([]string, []string) {
fn (mut g Gen) fn_args(args []ast.Param, is_variadic bool) ([]string, []string) {
mut fargs := []string{}
mut fargtypes := []string{}
if args.len == 0 {
@ -366,7 +365,7 @@ fn (mut g Gen) fn_args(args []table.Param, is_variadic bool) ([]string, []string
arg_type_sym := g.table.get_type_symbol(typ)
mut arg_type_name := g.typ(typ) // util.no_dots(arg_type_sym.name)
if arg_type_sym.kind == .function {
info := arg_type_sym.info as table.FnType
info := arg_type_sym.info as ast.FnType
func := info.func
if !info.is_anon {
g.write(arg_type_name + ' ' + caname)
@ -449,7 +448,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
if is_gen_or_and_assign_rhs {
unwrapped_typ := node.return_type.clear_flag(.optional)
unwrapped_styp := g.typ(unwrapped_typ)
if unwrapped_typ == table.void_type {
if unwrapped_typ == ast.void_type {
g.write('\n $cur_line')
} else if g.table.get_type_symbol(node.return_type).kind == .multi_return {
g.write('\n $cur_line $tmp_opt /*U*/')
@ -462,7 +461,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
}
}
pub fn (g &Gen) unwrap_generic(typ table.Type) table.Type {
pub fn (g &Gen) unwrap_generic(typ ast.Type) ast.Type {
if typ.has_flag(.generic) {
sym := g.table.get_type_symbol(typ)
for i, generic_param in g.cur_fn.generic_params {
@ -486,7 +485,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
typ_sym := g.table.get_type_symbol(unwrapped_rec_type)
rec_cc_type := g.cc_type(unwrapped_rec_type, false)
mut receiver_type_name := util.no_dots(rec_cc_type)
if typ_sym.kind == .interface_ && (typ_sym.info as table.Interface).defines_method(node.name) {
if typ_sym.kind == .interface_ && (typ_sym.info as ast.Interface).defines_method(node.name) {
// Speaker_name_table[s._interface_idx].speak(s._object)
$if debug_interface_method_call ? {
eprintln('>>> interface typ_sym.name: $typ_sym.name | receiver_type_name: $receiver_type_name')
@ -628,7 +627,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
}
}
for i, generic_type in node.generic_types {
if generic_type != table.void_type && generic_type != 0 {
if generic_type != ast.void_type && generic_type != 0 {
// Using _T_ to differentiate between get<string> and get_string
// `foo<int>()` => `foo_T_int()`
if i == 0 {
@ -767,7 +766,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
g.writeln('string $tmp2 = json__json_print_pretty($json_obj);')
}
} else {
ast_type := node.args[0].expr as ast.Type
ast_type := node.args[0].expr as ast.TypeNode
// `json.decode(User, s)` => json.decode_User(s)
typ := c_name(g.typ(ast_type.typ))
fn_name := c_name(name) + '_' + typ
@ -818,18 +817,18 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
// g.generate_tmp_autofree_arg_vars(node, name)
// Handle `print(x)`
mut print_auto_str := false
if is_print && node.args[0].typ != table.string_type { // && !free_tmp_arg_vars {
if is_print && node.args[0].typ != ast.string_type { // && !free_tmp_arg_vars {
mut typ := node.args[0].typ
if typ == 0 {
g.checker_bug('print arg.typ is 0', node.pos)
}
mut sym := g.table.get_type_symbol(typ)
if mut sym.info is table.Alias {
if mut sym.info is ast.Alias {
typ = sym.info.parent_type
sym = g.table.get_type_symbol(typ)
}
// check if alias parent also not a string
if typ != table.string_type {
if typ != ast.string_type {
expr := node.args[0].expr
if g.is_autofree && !typ.has_flag(.optional) {
// Create a temporary variable so that the value can be freed
@ -930,7 +929,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
} else {
scope.register(ast.Var{
name: t
typ: table.string_type
typ: ast.string_type
is_autofree_tmp: true
pos: node.pos
})
@ -1009,7 +1008,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
if is_variadic && i == expected_types.len - 1 {
break
}
use_tmp_var_autofree := g.is_autofree && arg.typ == table.string_type && arg.is_tmp_autofree
use_tmp_var_autofree := g.is_autofree && arg.typ == ast.string_type && arg.is_tmp_autofree
&& !g.inside_const && !g.is_builtin_mod
// g.write('/* af=$arg.is_tmp_autofree */')
// some c fn definitions dont have args (cfns.v) or are not updated in checker
@ -1053,7 +1052,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
varg_type := expected_types.last()
variadic_count := args.len - arg_nr
arr_sym := g.table.get_type_symbol(varg_type)
mut arr_info := arr_sym.info as table.Array
mut arr_info := arr_sym.info as ast.Array
if varg_type.has_flag(.generic) {
if fn_def := g.table.find_fn(node.name) {
varg_type_name := g.table.type_to_str(varg_type)
@ -1088,9 +1087,9 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
}
[inline]
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type, lang table.Language) {
arg_is_ptr := expected_type.is_ptr() || expected_type.idx() in table.pointer_type_idxs
expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in table.pointer_type_idxs
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang ast.Language) {
arg_is_ptr := expected_type.is_ptr() || expected_type.idx() in ast.pointer_type_idxs
expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in ast.pointer_type_idxs
if expected_type == 0 {
g.checker_bug('ref_or_deref_arg expected_type is 0', arg.pos)
}
@ -1158,7 +1157,7 @@ fn (g &Gen) fileis(s string) bool {
return g.file.path.contains(s)
}
fn (mut g Gen) write_fn_attrs(attrs []table.Attr) string {
fn (mut g Gen) write_fn_attrs(attrs []ast.Attr) string {
mut msvc_attrs := ''
for attr in attrs {
match attr.name {

View File

@ -4,7 +4,6 @@
module c
import v.ast
import v.table
import v.util
fn (mut g Gen) index_expr(node ast.IndexExpr) {
@ -46,7 +45,7 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) {
g.expr(node.left)
} else if sym.kind == .array_fixed {
// Convert a fixed array to V array when doing `fixed_arr[start..end]`
info := sym.info as table.ArrayFixed
info := sym.info as ast.ArrayFixed
g.write('array_slice(new_array_from_c_array(')
g.write('$info.size')
g.write(', $info.size')
@ -77,7 +76,7 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) {
if range.has_high {
g.expr(range.high)
} else if sym.kind == .array_fixed {
info := sym.info as table.ArrayFixed
info := sym.info as ast.ArrayFixed
g.write('$info.size')
} else if node.left_type.is_ptr() {
g.write('(')
@ -92,10 +91,10 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) {
g.write(')')
}
fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) {
fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) {
gen_or := node.or_expr.kind != .absent || node.is_option
left_is_ptr := node.left_type.is_ptr()
info := sym.info as table.Array
info := sym.info as ast.Array
elem_type_str := g.typ(info.elem_type)
elem_type := info.elem_type
elem_typ := g.table.get_type_symbol(elem_type)
@ -104,7 +103,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) {
is_selector := node.left is ast.SelectorExpr
if g.is_assign_lhs && !is_selector && node.is_setter {
is_direct_array_access := g.fn_decl != 0 && g.fn_decl.is_direct_arr
is_op_assign := g.assign_op != .assign && info.elem_type != table.string_type
is_op_assign := g.assign_op != .assign && info.elem_type != ast.string_type
array_ptr_type_str := match elem_typ.kind {
.function { 'voidptr*' }
else { '$elem_type_str*' }
@ -175,7 +174,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) {
.function { 'voidptr*' }
else { '$elem_type_str*' }
}
needs_clone := info.elem_type == table.string_type_idx && g.is_autofree && !g.is_assign_lhs
needs_clone := info.elem_type == ast.string_type_idx && g.is_autofree && !g.is_assign_lhs
is_gen_or_and_assign_rhs := gen_or && !g.discard_or_result
cur_line := if is_gen_or_and_assign_rhs {
line := g.go_before_stmt(0)
@ -193,7 +192,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) {
g.write('/*2*/string_clone(')
}
if g.is_fn_index_call {
if elem_typ.info is table.FnType {
if elem_typ.info is ast.FnType {
g.write('((')
g.write_fn_ptr_decl(&elem_typ.info, '')
g.write(')(*($array_ptr_type_str)/*ee elem_typ */array_get(')
@ -257,11 +256,11 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) {
}
}
fn (mut g Gen) index_of_fixed_array(node ast.IndexExpr, sym table.TypeSymbol) {
info := sym.info as table.ArrayFixed
fn (mut g Gen) index_of_fixed_array(node ast.IndexExpr, sym ast.TypeSymbol) {
info := sym.info as ast.ArrayFixed
elem_type := info.elem_type
elem_sym := g.table.get_type_symbol(elem_type)
is_fn_index_call := g.is_fn_index_call && elem_sym.info is table.FnType
is_fn_index_call := g.is_fn_index_call && elem_sym.info is ast.FnType
if is_fn_index_call {
g.write('(*')
@ -289,17 +288,17 @@ fn (mut g Gen) index_of_fixed_array(node ast.IndexExpr, sym table.TypeSymbol) {
}
}
fn (mut g Gen) index_of_map(node ast.IndexExpr, sym table.TypeSymbol) {
fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
gen_or := node.or_expr.kind != .absent || node.is_option
left_is_ptr := node.left_type.is_ptr()
info := sym.info as table.Map
info := sym.info as ast.Map
key_type_str := g.typ(info.key_type)
elem_type := info.value_type
elem_type_str := g.typ(elem_type)
elem_typ := g.table.get_type_symbol(elem_type)
get_and_set_types := elem_typ.kind in [.struct_, .map]
if g.is_assign_lhs && !g.is_arraymap_set && !get_and_set_types {
if g.assign_op == .assign || info.value_type == table.string_type {
if g.assign_op == .assign || info.value_type == ast.string_type {
g.is_arraymap_set = true
g.write('map_set_1(')
} else {
@ -335,7 +334,7 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym table.TypeSymbol) {
g.arraymap_set_pos = g.out.len
g.write(', &($elem_type_str[]) { ')
}
if g.assign_op != .assign && info.value_type != table.string_type {
if g.assign_op != .assign && info.value_type != ast.string_type {
zero := g.type_default(info.value_type)
g.write('$zero })))')
}
@ -370,7 +369,7 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym table.TypeSymbol) {
g.write('$elem_type_str* $tmp_opt_ptr = ($elem_type_str*)/*ee elem_ptr_typ */(map_get_1_check(')
} else {
if g.is_fn_index_call {
if elem_typ.info is table.FnType {
if elem_typ.info is ast.FnType {
g.write('((')
g.write_fn_ptr_decl(&elem_typ.info, '')
g.write(')(*(voidptr*)map_get_1(')

View File

@ -3,7 +3,7 @@
// that can be found in the LICENSE file.
module c
import v.table
import v.ast
import v.util
import strings
@ -18,7 +18,7 @@ import strings
// return res;
// }
// Codegen json_decode/encode funcs
fn (mut g Gen) gen_json_for_type(typ table.Type) {
fn (mut g Gen) gen_json_for_type(typ ast.Type) {
utyp := g.unwrap_generic(typ)
mut dec := strings.new_builder(100)
mut enc := strings.new_builder(100)
@ -73,13 +73,13 @@ $enc_fn_dec {
// enc += g.encode_array(t)
} else if sym.kind == .map {
// Handle maps
m := sym.info as table.Map
m := sym.info as ast.Map
g.gen_json_for_type(m.key_type)
g.gen_json_for_type(m.value_type)
dec.writeln(g.decode_map(m.key_type, m.value_type))
enc.writeln(g.encode_map(m.key_type, m.value_type))
} else if sym.kind == .alias {
a := sym.info as table.Alias
a := sym.info as ast.Alias
parent_typ := a.parent_type
psym := g.table.get_type_symbol(parent_typ)
if is_js_prim(g.typ(parent_typ)) {
@ -87,14 +87,14 @@ $enc_fn_dec {
return
}
enc.writeln('\to = cJSON_CreateObject();')
if psym.info !is table.Struct {
if psym.info !is ast.Struct {
verror('json: $sym.name is not struct')
}
g.gen_struct_enc_dec(psym.info, styp, mut enc, mut dec)
} else {
enc.writeln('\to = cJSON_CreateObject();')
// Structs. Range through fields
if sym.info !is table.Struct {
if sym.info !is ast.Struct {
verror('json: $sym.name is not struct')
}
g.gen_struct_enc_dec(sym.info, styp, mut enc, mut dec)
@ -110,8 +110,8 @@ $enc_fn_dec {
}
[inline]
fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc strings.Builder, mut dec strings.Builder) {
info := type_info as table.Struct
fn (mut g Gen) gen_struct_enc_dec(type_info ast.TypeInfo, styp string, mut enc strings.Builder, mut dec strings.Builder) {
info := type_info as ast.Struct
for field in info.fields {
if field.attrs.contains('skip') {
continue
@ -143,7 +143,7 @@ fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc
// it has to be decoded from a unix timestamp number
dec.writeln('\tres.${c_name(field.name)} = time__unix(json__decode_u64(js_get(root, "$name")));')
} else if field_sym.kind == .alias {
alias := field_sym.info as table.Alias
alias := field_sym.info as ast.Alias
parent_type := g.typ(alias.parent_type)
parent_dec_name := js_dec_name(parent_type)
if is_js_prim(parent_type) {
@ -171,7 +171,7 @@ fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc
mut enc_name := js_enc_name(field_type)
if !is_js_prim(field_type) {
if field_sym.kind == .alias {
ainfo := field_sym.info as table.Alias
ainfo := field_sym.info as ast.Alias
enc_name = js_enc_name(g.typ(ainfo.parent_type))
}
}
@ -206,7 +206,7 @@ fn is_js_prim(typ string) bool {
]
}
fn (mut g Gen) decode_array(value_type table.Type) string {
fn (mut g Gen) decode_array(value_type ast.Type) string {
styp := g.typ(value_type)
fn_name := js_dec_name(styp)
mut s := ''
@ -236,7 +236,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string {
'
}
fn (mut g Gen) encode_array(value_type table.Type) string {
fn (mut g Gen) encode_array(value_type ast.Type) string {
styp := g.typ(value_type)
fn_name := js_enc_name(styp)
return '
@ -247,7 +247,7 @@ fn (mut g Gen) encode_array(value_type table.Type) string {
'
}
fn (mut g Gen) decode_map(key_type table.Type, value_type table.Type) string {
fn (mut g Gen) decode_map(key_type ast.Type, value_type ast.Type) string {
styp := g.typ(key_type)
styp_v := g.typ(value_type)
key_type_symbol := g.table.get_type_symbol(key_type)
@ -281,7 +281,7 @@ fn (mut g Gen) decode_map(key_type table.Type, value_type table.Type) string {
'
}
fn (mut g Gen) encode_map(key_type table.Type, value_type table.Type) string {
fn (mut g Gen) encode_map(key_type ast.Type, value_type ast.Type) string {
styp := g.typ(key_type)
styp_v := g.typ(value_type)
fn_name_v := js_enc_name(styp_v)

View File

@ -4,7 +4,6 @@ module c
import v.ast
import strings
import v.table
import v.util
// pg,mysql etc
@ -133,7 +132,7 @@ fn (mut g Gen) sqlite3_stmt(node ast.SqlStmt, typ SqlType) {
continue
}
x := '${node.object_var_name}.$field.name'
if field.typ == table.string_type {
if field.typ == ast.string_type {
g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i + 0}, ${x}.str, ${x}.len, 0);')
} else if g.table.type_symbols[int(field.typ)].kind == .struct_ {
// insert again
@ -249,14 +248,14 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_
// array_User array_tmp;
// for { User tmp; ... array_tmp << tmp; }
array_sym := g.table.get_type_symbol(node.typ)
array_info := array_sym.info as table.Array
array_info := array_sym.info as ast.Array
elem_type_str = g.typ(array_info.elem_type)
g.writeln('$styp ${tmp}_array = __new_array(0, 10, sizeof($elem_type_str));')
g.writeln('while (1) {')
g.writeln('\t$elem_type_str $tmp = ($elem_type_str) {')
//
sym := g.table.get_type_symbol(array_info.elem_type)
info := sym.info as table.Struct
info := sym.info as ast.Struct
for i, field in info.fields {
g.zero_struct_field(field)
if i != info.fields.len - 1 {
@ -271,7 +270,7 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_
// If we don't, string values are going to be nil etc for fields that are not returned
// by the db engine.
sym := g.table.get_type_symbol(node.typ)
info := sym.info as table.Struct
info := sym.info as ast.Struct
for i, field in info.fields {
g.zero_struct_field(field)
if i != info.fields.len - 1 {
@ -293,7 +292,7 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_
}
for i, field in node.fields {
mut func := 'sqlite3_column_int'
if field.typ == table.string_type {
if field.typ == ast.string_type {
func = 'sqlite3_column_text'
string_data := g.new_tmp_var()
g.writeln('byteptr $string_data = ${func}($g.sql_stmt_name, $i);')
@ -415,9 +414,9 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
g.inc_sql_i()
info := expr.info as ast.IdentVar
ityp := info.typ
if ityp == table.string_type {
if ityp == ast.string_type {
g.sql_bind_string('${expr.name}.str', '${expr.name}.len', typ)
} else if ityp == table.int_type {
} else if ityp == ast.int_type {
g.sql_bind_int(expr.name, typ)
} else {
verror('bad sql type=$ityp ident_name=$expr.name')
@ -426,7 +425,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
}
ast.SelectorExpr {
g.inc_sql_i()
if expr.typ == table.int_type {
if expr.typ == ast.int_type {
if expr.expr !is ast.Ident {
verror('orm selector not ident')
}

View File

@ -4,7 +4,6 @@ module c
import v.ast
import v.util
import v.table
fn (mut g Gen) write_str_fn_definitions() {
// _STR function can't be defined in vlib
@ -26,7 +25,7 @@ void _STR_PRINT_ARG(const char *fmt, char** refbufp, int *nbytes, int *memsize,
}
// increase buffer (somewhat exponentially)
*memsize += (*memsize + *memsize) / 3 + guess;
#ifdef _VGCBOEHM
#ifdef _VGCBOEHM
*refbufp = (char*)GC_REALLOC((void*)*refbufp, *memsize);
#else
*refbufp = (char*)realloc((void*)*refbufp, *memsize);
@ -39,7 +38,7 @@ string _STR(const char *fmt, int nfmts, ...) {
va_list argptr;
int memsize = 128;
int nbytes = 0;
#ifdef _VGCBOEHM
#ifdef _VGCBOEHM
char* buf = (char*)GC_MALLOC(memsize);
#else
char* buf = (char*)malloc(memsize);
@ -222,7 +221,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
mut typ := g.unwrap_generic(node.expr_types[i])
sym := g.table.get_type_symbol(typ)
if sym.kind == .alias {
typ = (sym.info as table.Alias).parent_type
typ = (sym.info as ast.Alias).parent_type
}
// write correct format specifier to intermediate string
g.write('%')
@ -256,11 +255,11 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.write('${fmt}c')
} else {
g.write('$fmt"PRI${fspec:c}')
if typ in [table.i8_type, table.byte_type] {
if typ in [ast.i8_type, ast.byte_type] {
g.write('8')
} else if typ in [table.i16_type, table.u16_type] {
} else if typ in [ast.i16_type, ast.u16_type] {
g.write('16')
} else if typ in [table.i64_type, table.u64_type] {
} else if typ in [ast.i64_type, ast.u64_type] {
g.write('64')
} else {
g.write('32')
@ -280,7 +279,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
// Build args
for i, expr in node.exprs {
typ := g.unwrap_generic(node.expr_types[i])
if typ == table.string_type {
if typ == ast.string_type {
if g.inside_vweb_tmpl {
g.write('vweb__filter(')
if expr.is_auto_deref_var() {
@ -299,11 +298,11 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
} else if typ.is_number() || typ.is_pointer() || node.fmts[i] == `d` {
if typ.is_signed() && node.fmts[i] in [`x`, `X`, `o`] {
// convert to unsigned first befors C's integer propagation strikes
if typ == table.i8_type {
if typ == ast.i8_type {
g.write('(byte)(')
} else if typ == table.i16_type {
} else if typ == ast.i16_type {
g.write('(u16)(')
} else if typ == table.int_type {
} else if typ == ast.int_type {
g.write('(u32)(')
} else {
g.write('(u64)(')
@ -335,7 +334,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.write(')')
}
fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) {
fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
is_shared := etype.has_flag(.shared_f)
mut typ := etype
if is_shared {
@ -343,7 +342,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) {
}
mut sym := g.table.get_type_symbol(typ)
// when type is alias, print the aliased value
if mut sym.info is table.Alias {
if mut sym.info is ast.Alias {
parent_sym := g.table.get_type_symbol(sym.info.parent_type)
if parent_sym.has_method('str') {
typ = sym.info.parent_type
@ -356,9 +355,9 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) {
g.write('${str_fn_name}(')
g.expr(expr)
g.write(')')
} else if typ == table.string_type {
} else if typ == ast.string_type {
g.expr(expr)
} else if typ == table.bool_type {
} else if typ == ast.bool_type {
g.expr(expr)
g.write(' ? _SLIT("true") : _SLIT("false")')
} else if sym.kind == .none_ {

View File

@ -1,5 +1,6 @@
module js
import v.table
import v.ast
fn (mut g JsGen) to_js_typ_def_val(s string) string {
mut dval := ''
@ -13,25 +14,26 @@ fn (mut g JsGen) to_js_typ_def_val(s string) string {
return dval
}
fn (mut g JsGen) to_js_typ_val(t table.Type) string {
fn (mut g JsGen) to_js_typ_val(t ast.Type) string {
sym := g.table.get_type_symbol(t)
mut styp := ''
mut prefix := if g.file.mod.name == 'builtin' { 'new ' } else { '' }
mut prefix := if g.file.mod.name == 'builtin' { 'new ' } else { '' }
match sym.kind {
.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal, .size_t {
styp = '${prefix}${g.sym_to_js_typ(sym)}(0)'
.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal,
.size_t {
styp = '$prefix${g.sym_to_js_typ(sym)}(0)'
}
.bool {
styp = '${prefix}${g.sym_to_js_typ(sym)}(false)'
styp = '$prefix${g.sym_to_js_typ(sym)}(false)'
}
.string {
styp = '${prefix}${g.sym_to_js_typ(sym)}("")'
styp = '$prefix${g.sym_to_js_typ(sym)}("")'
}
.map {
styp = 'new Map()'
}
.array {
styp = '${prefix}${g.sym_to_js_typ(sym)}()'
styp = '$prefix${g.sym_to_js_typ(sym)}()'
}
.struct_ {
styp = 'new ${g.js_name(sym.name)}(${g.to_js_typ_def_val(sym.name)})'
@ -44,26 +46,60 @@ fn (mut g JsGen) to_js_typ_val(t table.Type) string {
return styp
}
fn (mut g JsGen) sym_to_js_typ(sym table.TypeSymbol) string {
fn (mut g JsGen) sym_to_js_typ(sym ast.TypeSymbol) string {
mut styp := ''
match sym.kind {
.i8 { styp = 'i8' }
.i16 { styp = 'i16' }
.int { styp = 'int' }
.i64 { styp = 'i64' }
.byte { styp = 'byte' }
.u16 { styp = 'u16' }
.u32 { styp = 'u32' }
.u64 { styp = 'u64' }
.f32 { styp = 'f32' }
.f64 { styp = 'f64' }
.int_literal { styp = 'int_literal' }
.float_literal { styp = 'float_literal' }
.size_t { styp = 'size_t' }
.bool { styp = 'bool' }
.string { styp = 'string' }
.map { styp = 'map' }
.array { styp = 'array' }
.i8 {
styp = 'i8'
}
.i16 {
styp = 'i16'
}
.int {
styp = 'int'
}
.i64 {
styp = 'i64'
}
.byte {
styp = 'byte'
}
.u16 {
styp = 'u16'
}
.u32 {
styp = 'u32'
}
.u64 {
styp = 'u64'
}
.f32 {
styp = 'f32'
}
.f64 {
styp = 'f64'
}
.int_literal {
styp = 'int_literal'
}
.float_literal {
styp = 'float_literal'
}
.size_t {
styp = 'size_t'
}
.bool {
styp = 'bool'
}
.string {
styp = 'string'
}
.map {
styp = 'map'
}
.array {
styp = 'array'
}
else {
// TODO
styp = 'undefined'
@ -73,7 +109,7 @@ fn (mut g JsGen) sym_to_js_typ(sym table.TypeSymbol) string {
}
// V type to JS type
pub fn (mut g JsGen) typ(t table.Type) string {
pub fn (mut g JsGen) typ(t ast.Type) string {
sym := g.table.get_type_symbol(t)
mut styp := ''
match sym.kind {
@ -90,7 +126,8 @@ pub fn (mut g JsGen) typ(t table.Type) string {
.byteptr, .charptr {
styp = '${g.sym_to_js_typ(sym)}'
}
.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal, .size_t {
.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal,
.size_t {
styp = '${g.sym_to_js_typ(sym)}'
}
.bool {
@ -104,11 +141,11 @@ pub fn (mut g JsGen) typ(t table.Type) string {
}
// 'array_array_int' => 'number[][]'
.array {
info := sym.info as table.Array
info := sym.info as ast.Array
styp = '${g.sym_to_js_typ(sym)}(${g.typ(info.elem_type)})'
}
.array_fixed {
info := sym.info as table.ArrayFixed
info := sym.info as ast.ArrayFixed
styp = '${g.sym_to_js_typ(sym)}(${g.typ(info.elem_type)})'
}
.chan {
@ -116,7 +153,7 @@ pub fn (mut g JsGen) typ(t table.Type) string {
}
// 'map[string]int' => 'Map<string, number>'
.map {
info := sym.info as table.Map
info := sym.info as ast.Map
key := g.typ(info.key_type)
val := g.typ(info.value_type)
styp = 'Map<$key, $val>'
@ -131,7 +168,7 @@ pub fn (mut g JsGen) typ(t table.Type) string {
.generic_struct_inst {}
// 'multi_return_int_int' => '[number, number]'
.multi_return {
info := sym.info as table.MultiReturn
info := sym.info as ast.MultiReturn
types := info.types.map(g.typ(it))
joined := types.join(', ')
styp = '[$joined]'
@ -153,7 +190,7 @@ pub fn (mut g JsGen) typ(t table.Type) string {
}
// 'anon_fn_7_7_1' => '(a number, b number) => void'
.function {
info := sym.info as table.FnType
info := sym.info as ast.FnType
styp = g.fn_typ(info.func.params, info.func.return_type)
}
.interface_ {
@ -181,7 +218,7 @@ pub fn (mut g JsGen) typ(t table.Type) string {
return styp
}
fn (mut g JsGen) fn_typ(args []table.Param, return_type table.Type) string {
fn (mut g JsGen) fn_typ(args []ast.Param, return_type ast.Type) string {
mut res := '('
for i, arg in args {
res += '$arg.name: ${g.typ(arg.typ)}'
@ -194,7 +231,9 @@ fn (mut g JsGen) fn_typ(args []table.Param, return_type table.Type) string {
fn (mut g JsGen) struct_typ(s string) string {
ns := get_ns(s)
if ns == 'JS' { return s[3..] }
if ns == 'JS' {
return s[3..]
}
mut name := if ns == g.ns.name { s.split('.').last() } else { g.get_alias(s) }
mut styp := ''
for i, v in name.split('.') {
@ -210,26 +249,25 @@ fn (mut g JsGen) struct_typ(s string) string {
return styp + '["prototype"]'
}
struct BuiltinPrototypeCongig {
typ_name string
val_name string = 'val'
default_value string
constructor string = 'this.val = val'
value_of string = 'this.val'
to_string string = 'this.val.toString()'
eq string = 'this.val === other.val'
extras string
has_strfn bool
struct BuiltinPrototypeConfig {
typ_name string
val_name string = 'val'
default_value string
constructor string = 'this.val = val'
value_of string = 'this.val'
to_string string = 'this.val.toString()'
eq string = 'this.val === other.val'
extras string
has_strfn bool
}
// ugly arguments but not sure a config struct would be worth it
fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeCongig) {
g.writeln('function ${c.typ_name}(${c.val_name} = ${c.default_value}) { ${c.constructor} }')
fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeConfig) {
g.writeln('function ${c.typ_name}($c.val_name = $c.default_value) { $c.constructor }')
g.writeln('${c.typ_name}.prototype = {')
g.inc_indent()
g.writeln('${c.val_name}: ${c.default_value},')
g.writeln('$c.val_name: $c.default_value,')
if c.extras.len > 0 {
g.writeln('${c.extras},')
g.writeln('$c.extras,')
}
for method in g.method_fn_decls[c.typ_name] {
g.inside_def_typ_decl = true
@ -237,10 +275,12 @@ fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeCongig) {
g.inside_def_typ_decl = false
g.writeln(',')
}
g.writeln('valueOf() { return ${c.value_of} },')
g.writeln('toString() { return ${c.to_string} },')
g.writeln('eq(other) { return ${c.eq} },')
if c.has_strfn { g.writeln('str() { return new string(this.toString()) }') }
g.writeln('valueOf() { return $c.value_of },')
g.writeln('toString() { return $c.to_string },')
g.writeln('eq(other) { return $c.eq },')
if c.has_strfn {
g.writeln('str() { return new string(this.toString()) }')
}
g.dec_indent()
g.writeln('};\n')
}
@ -253,39 +293,39 @@ fn (mut g JsGen) gen_builtin_type_defs() {
match typ_name {
'i8', 'i16', 'int', 'i64', 'u16', 'u32', 'u64', 'int_literal', 'size_t' {
// TODO: Bounds checking
g.gen_builtin_prototype({
g.gen_builtin_prototype(
typ_name: typ_name
default_value: 'new Number(0)'
constructor: 'this.val = val | 0'
value_of: 'this.val | 0'
to_string: 'this.valueOf().toString()'
eq: 'this.valueOf() === other.valueOf()'
})
)
}
'byte' {
g.gen_builtin_prototype({
g.gen_builtin_prototype(
typ_name: typ_name
default_value: 'new Number(0)'
constructor: 'this.val = typeof(val) == "string" ? val.charCodeAt() : (val | 0)'
value_of: 'this.val | 0'
to_string: 'String.fromCharCode(this.val)'
eq: 'this.valueOf() === other.valueOf()'
})
)
}
'f32', 'f64', 'float_literal' {
g.gen_builtin_prototype({
g.gen_builtin_prototype(
typ_name: typ_name
default_value: 'new Number(0)'
})
)
}
'bool' {
g.gen_builtin_prototype({
g.gen_builtin_prototype(
typ_name: typ_name
default_value: 'new Boolean(false)'
})
)
}
'string' {
g.gen_builtin_prototype({
g.gen_builtin_prototype(
typ_name: typ_name
val_name: 'str'
default_value: 'new String("")'
@ -294,10 +334,10 @@ fn (mut g JsGen) gen_builtin_type_defs() {
to_string: 'this.str'
eq: 'this.str === other.str'
has_strfn: false
})
)
}
'map' {
g.gen_builtin_prototype({
g.gen_builtin_prototype(
typ_name: typ_name
val_name: 'map'
default_value: 'new Map()'
@ -305,10 +345,10 @@ fn (mut g JsGen) gen_builtin_type_defs() {
value_of: 'this.map'
to_string: 'this.map.toString()'
eq: 'vEq(this, other)'
})
)
}
'array' {
g.gen_builtin_prototype({
g.gen_builtin_prototype(
typ_name: typ_name
val_name: 'arr'
default_value: 'new Array()'
@ -316,7 +356,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
value_of: 'this.arr'
to_string: 'JSON.stringify(this.arr.map(it => it.valueOf()))'
eq: 'vEq(this, other)'
})
)
}
else {}
}

View File

@ -2,7 +2,6 @@ module js
import strings
import v.ast
import v.table
import v.token
import v.pref
import v.util
@ -19,7 +18,7 @@ const (
// used to generate type structs
v_types = ['i8', 'i16', 'int', 'i64', 'byte', 'u16', 'u32', 'u64', 'f32', 'f64',
'int_literal', 'float_literal', 'size_t', 'bool', 'string', 'map', 'array']
shallow_equatables = [table.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64,
shallow_equatables = [ast.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64,
.int_literal, .float_literal, .size_t, .bool, .string]
)
@ -34,7 +33,7 @@ mut:
}
struct JsGen {
table &table.Table
table &ast.Table
pref &pref.Preferences
mut:
definitions strings.Builder
@ -58,11 +57,11 @@ mut:
method_fn_decls map[string][]ast.FnDecl
builtin_fns []string // Functions defined in `builtin`
empty_line bool
cast_stack []table.Type
cast_stack []ast.Type
call_stack []ast.CallExpr
}
pub fn gen(files []ast.File, table &table.Table, pref &pref.Preferences) string {
pub fn gen(files []ast.File, table &ast.Table, pref &pref.Preferences) string {
mut g := &JsGen{
definitions: strings.new_builder(100)
table: table
@ -356,7 +355,7 @@ fn (mut g JsGen) stmts(stmts []ast.Stmt) {
fn (mut g JsGen) stmt(node ast.Stmt) {
g.stmt_start_pos = g.ns.out.len
match node {
ast.EmptyStmt{}
ast.EmptyStmt {}
ast.AsmStmt {
panic('inline asm is not supported by js')
}
@ -587,7 +586,7 @@ fn (mut g JsGen) expr(node ast.Expr) {
// `user := User{name: 'Bob'}`
g.gen_struct_init(node)
}
ast.Type {
ast.TypeNode {
// skip: JS has no types
// TODO maybe?
}
@ -697,7 +696,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) {
} else {
g.write(' $op ')
// TODO: Multiple types??
should_cast :=
should_cast :=
(g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables)
&& (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last())
@ -723,7 +722,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) {
}
}
fn (mut g JsGen) gen_attrs(attrs []table.Attr) {
fn (mut g JsGen) gen_attrs(attrs []ast.Attr) {
for attr in attrs {
g.writeln('/* [$attr.name] */')
}
@ -875,7 +874,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl) {
g.fn_decl = voidptr(0)
}
fn (mut g JsGen) fn_args(args []table.Param, is_variadic bool) {
fn (mut g JsGen) fn_args(args []ast.Param, is_variadic bool) {
for i, arg in args {
name := g.js_name(arg.name)
is_varg := i == args.len - 1 && is_variadic
@ -1388,7 +1387,7 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
// TODO Does this cover all cases?
g.expr(expr.left)
g.write('[')
g.cast_stack << table.int_type_idx
g.cast_stack << ast.int_type_idx
g.expr(expr.index)
g.cast_stack.delete_last()
g.write(']')
@ -1480,52 +1479,52 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
}
}
fn (mut g JsGen) greater_typ(left table.Type, right table.Type) table.Type {
fn (mut g JsGen) greater_typ(left ast.Type, right ast.Type) ast.Type {
l := int(left)
r := int(right)
lr := [l, r]
if table.string_type_idx in lr {
return table.Type(table.string_type_idx)
if ast.string_type_idx in lr {
return ast.Type(ast.string_type_idx)
}
should_float := (l in table.integer_type_idxs && r in table.float_type_idxs)
|| (r in table.integer_type_idxs && l in table.float_type_idxs)
should_float := (l in ast.integer_type_idxs && r in ast.float_type_idxs)
|| (r in ast.integer_type_idxs && l in ast.float_type_idxs)
if should_float {
if table.f64_type_idx in lr {
return table.Type(table.f64_type_idx)
if ast.f64_type_idx in lr {
return ast.Type(ast.f64_type_idx)
}
if table.f32_type_idx in lr {
return table.Type(table.f32_type_idx)
if ast.f32_type_idx in lr {
return ast.Type(ast.f32_type_idx)
}
return table.Type(table.float_literal_type)
return ast.Type(ast.float_literal_type)
}
should_int := (l in table.integer_type_idxs && r in table.integer_type_idxs)
should_int := (l in ast.integer_type_idxs && r in ast.integer_type_idxs)
if should_int {
// cant add to u64 - if (table.u64_type_idx in lr) { return table.Type(table.u64_type_idx) }
// cant add to u64 - if (ast.u64_type_idx in lr) { return ast.Type(ast.u64_type_idx) }
// just guessing this order
if table.i64_type_idx in lr {
return table.Type(table.i64_type_idx)
if ast.i64_type_idx in lr {
return ast.Type(ast.i64_type_idx)
}
if table.u32_type_idx in lr {
return table.Type(table.u32_type_idx)
if ast.u32_type_idx in lr {
return ast.Type(ast.u32_type_idx)
}
if table.int_type_idx in lr {
return table.Type(table.int_type_idx)
if ast.int_type_idx in lr {
return ast.Type(ast.int_type_idx)
}
if table.u16_type_idx in lr {
return table.Type(table.u16_type_idx)
if ast.u16_type_idx in lr {
return ast.Type(ast.u16_type_idx)
}
if table.i16_type_idx in lr {
return table.Type(table.i16_type_idx)
if ast.i16_type_idx in lr {
return ast.Type(ast.i16_type_idx)
}
if table.byte_type_idx in lr {
return table.Type(table.byte_type_idx)
if ast.byte_type_idx in lr {
return ast.Type(ast.byte_type_idx)
}
if table.i8_type_idx in lr {
return table.Type(table.i8_type_idx)
if ast.i8_type_idx in lr {
return ast.Type(ast.i8_type_idx)
}
return table.Type(table.int_literal_type_idx)
return ast.Type(ast.int_literal_type_idx)
}
return table.Type(l)
return ast.Type(l)
}
fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) {
@ -1561,7 +1560,7 @@ fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) {
}
fn (mut g JsGen) gen_string_inter_literal(it ast.StringInterLiteral) {
should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == table.string_type_idx)
should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == ast.string_type_idx)
if should_cast {
if g.file.mod.name == 'builtin' {
g.write('new ')
@ -1600,7 +1599,7 @@ fn (mut g JsGen) gen_string_inter_literal(it ast.StringInterLiteral) {
fn (mut g JsGen) gen_string_literal(it ast.StringLiteral) {
text := it.val.replace("'", "\\'")
should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == table.string_type_idx)
should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == ast.string_type_idx)
if should_cast {
if g.file.mod.name == 'builtin' {
g.write('new ')
@ -1639,11 +1638,11 @@ fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) {
if sym.kind == .sum_type {
// TODO: JS sumtypes not implemented yet
} else if sym.kind == .array_fixed {
fixed_info := sym.info as table.ArrayFixed
fixed_info := sym.info as ast.ArrayFixed
typ_name := g.table.get_type_name(fixed_info.elem_type)
g.write('"[$fixed_info.size]$typ_name"')
} else if sym.kind == .function {
info := sym.info as table.FnType
info := sym.info as ast.FnType
fn_info := info.func
mut repr := 'fn ('
for i, arg in fn_info.params {
@ -1653,7 +1652,7 @@ fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) {
repr += g.table.get_type_name(arg.typ)
}
repr += ')'
if fn_info.return_type != table.void_type {
if fn_info.return_type != ast.void_type {
repr += ' ${g.table.get_type_name(fn_info.return_type)}'
}
g.write('"$repr"')
@ -1663,8 +1662,8 @@ fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) {
}
fn (mut g JsGen) gen_type_cast_expr(it ast.CastExpr) {
is_literal := ((it.expr is ast.IntegerLiteral && it.typ in table.integer_type_idxs)
|| (it.expr is ast.FloatLiteral && it.typ in table.float_type_idxs))
is_literal := ((it.expr is ast.IntegerLiteral && it.typ in ast.integer_type_idxs)
|| (it.expr is ast.FloatLiteral && it.typ in ast.float_type_idxs))
// Skip cast if type is the same as the parrent caster
if g.cast_stack.len > 0 && is_literal {
if it.typ == g.cast_stack[g.cast_stack.len - 1] {
@ -1690,7 +1689,7 @@ fn (mut g JsGen) gen_type_cast_expr(it ast.CastExpr) {
}
fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) {
typ := table.Type(table.int_type)
typ := ast.Type(ast.int_type)
// Don't wrap integers for use in JS.foo functions.
// TODO: call.language always seems to be "v", parser bug?
@ -1710,7 +1709,7 @@ fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) {
// Skip cast if type is the same as the parrent caster
if g.cast_stack.len > 0 {
if g.cast_stack[g.cast_stack.len - 1] in table.integer_type_idxs {
if g.cast_stack[g.cast_stack.len - 1] in ast.integer_type_idxs {
g.write('$it.val')
return
}
@ -1724,7 +1723,7 @@ fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) {
}
fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) {
typ := table.Type(table.f32_type)
typ := ast.Type(ast.f32_type)
// Don't wrap integers for use in JS.foo functions.
// TODO: call.language always seems to be "v", parser bug?
@ -1734,7 +1733,7 @@ fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) {
for i, t in call.args {
if t.expr is ast.FloatLiteral {
if t.expr == it {
if call.expected_arg_types[i] in table.integer_type_idxs {
if call.expected_arg_types[i] in ast.integer_type_idxs {
g.write(int(it.val.f64()).str())
} else {
g.write(it.val)
@ -1748,10 +1747,10 @@ fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) {
// Skip cast if type is the same as the parrent caster
if g.cast_stack.len > 0 {
if g.cast_stack[g.cast_stack.len - 1] in table.float_type_idxs {
if g.cast_stack[g.cast_stack.len - 1] in ast.float_type_idxs {
g.write('$it.val')
return
} else if g.cast_stack[g.cast_stack.len - 1] in table.integer_type_idxs {
} else if g.cast_stack[g.cast_stack.len - 1] in ast.integer_type_idxs {
g.write(int(it.val.f64()).str())
return
}

View File

@ -4,7 +4,7 @@ import v.ast
struct JsDoc {
mut:
gen &JsGen
gen &JsGen
}
fn new_jsdoc(gen &JsGen) &JsDoc {
@ -14,12 +14,16 @@ fn new_jsdoc(gen &JsGen) &JsDoc {
}
fn (mut d JsDoc) write(s string) {
if !d.gen.enable_doc { return }
if !d.gen.enable_doc {
return
}
d.gen.write(s)
}
fn (mut d JsDoc) writeln(s string) {
if !d.gen.enable_doc { return }
if !d.gen.enable_doc {
return
}
d.gen.writeln(s)
}
@ -45,7 +49,9 @@ fn (mut d JsDoc) gen_fac_fn(fields []ast.StructField) {
// Marked as optional: structs have default default values,
// so all struct members don't have to be initialized.
d.write('$field.name?: ${d.gen.typ(field.typ)}')
if i < fields.len - 1 { d.write(', ') }
if i < fields.len - 1 {
d.write(', ')
}
}
d.writeln('}} init')
d.writeln('*/')

View File

@ -7,7 +7,7 @@ const (
)
fn testsuite_end() {
os.rmdir_all(output_dir) or { }
os.rmdir_all(output_dir) or {}
}
const there_is_node_available = is_nodejs_working()

View File

@ -69,4 +69,4 @@ function vEq(a, b) {
return a!==a && b!==b;
};
"
)
)

View File

@ -1,5 +1,10 @@
fn map_cb(s string) string { return 'CB: $s' }
fn filter_cb(n int) bool { return n < 4 }
fn map_cb(s string) string {
return 'CB: $s'
}
fn filter_cb(n int) bool {
return n < 4
}
fn variadic(args ...int) {
println(args)
@ -13,111 +18,119 @@ fn vararg_test() {
// TODO Remove `fn main` once vet supports scripts
fn main() {
vararg_test()
vararg_test()
arr1 := ['Hello', 'JS', 'Backend']
mut arr2 := [1, 2, 3, 4, 5]
arr1 := ['Hello', 'JS', 'Backend']
mut arr2 := [1, 2, 3, 4, 5]
// Array slices
slice1 := arr1[1..3]
slice2 := arr2[..3]
slice3 := arr2[3..]
// Array slices
slice1 := arr1[1..3]
slice2 := arr2[..3]
slice3 := arr2[3..]
// Array indexes
idx1 := slice1[1]
arr2[0] = 1
arr2[0 + 1] = 2
println(arr2)
// Array indexes
idx1 := slice1[1]
arr2[0] = 1
arr2[0 + 1] = 2
println(arr2)
// TODO: This does not work for now
// arr2[0..1] = arr2[3..4]
// println(arr2)
// TODO: This does not work for now
// arr2[0..1] = arr2[3..4]
// println(arr2)
// Array push operator
arr2 << 6
arr2 << [7, 8, 9]
println(arr2)
println('\n\n')
// Array push operator
arr2 << 6
arr2 << [7, 8, 9]
println(arr2)
println('\n\n')
// String slices
mut slice4 := idx1[..4]
print('Back\t=> ')
println(slice4) // 'Back'
// String slices
mut slice4 := idx1[..4]
print('Back\t=> ')
println(slice4) // 'Back'
// String indexes
idx2 := slice4[0]
print('66\t=> ')
println(idx2)
// TODO:
// slice4[3] = `c`
// String indexes
idx2 := slice4[0]
print('66\t=> ')
println(idx2)
// TODO:
// slice4[3] = `c`
// Maps
mut m := map[string]string
key := 'key'
m[key] = 'value'
val := m['key']
print('value\t=> ')
println(val)
// Maps
mut m := map[string]string{}
key := 'key'
m[key] = 'value'
val := m['key']
print('value\t=> ')
println(val)
// 'in' / '!in'
print('true\t=> ')
println('JS' in arr1)
print('false\t=> ')
println(3 !in arr2)
print('true\t=> ')
println('key' in m)
print('true\t=> ')
println('badkey' !in m)
print('true\t=> ')
println('o' in 'hello')
// 'in' / '!in'
print('true\t=> ')
println('JS' in arr1)
print('false\t=> ')
println(3 !in arr2)
print('true\t=> ')
println('key' in m)
print('true\t=> ')
println('badkey' !in m)
print('true\t=> ')
println('o' in 'hello')
// for in
for _ in arr1 {}
println('0 to 8\t=>')
for i, _ in arr2 { println(i) }
println('\n\n4 to 5\t=> ')
for _, v in slice3 { println(v) }
// for in
for _ in arr1 {}
println('0 to 8\t=>')
for i, _ in arr2 {
println(i)
}
println('\n\n4 to 5\t=> ')
for _, v in slice3 {
println(v)
}
println(int(1.5))
println(int(1.5))
println('\n\n')
println('\n\n')
// map
a := arr1.map('VAL: $it')
b := arr1.map(map_cb)
c := arr1.map(map_cb(it))
d := arr1.map(fn(a string) string { return 'ANON: $a' })
// I don't know when this would ever be used,
// but it's what the C backend does ¯\_(ツ)_/¯
e := arr1.map(456)
// map
a := arr1.map('VAL: $it')
b := arr1.map(map_cb)
c := arr1.map(map_cb(it))
d := arr1.map(fn (a string) string {
return 'ANON: $a'
})
// I don't know when this would ever be used,
// but it's what the C backend does ¯\_(ツ)_/¯
e := arr1.map(456)
println(a)
println(b)
println(c)
println(d)
println(e)
println(a)
println(b)
println(c)
println(d)
println(e)
println('\n\n')
println('\n\n')
// filter
aa := arr2.filter(it < 4)
bb := arr2.filter(filter_cb)
cc := arr2.filter(filter_cb(it))
dd := arr2.filter(fn(a int) bool { return a < 4 })
// filter
aa := arr2.filter(it < 4)
bb := arr2.filter(filter_cb)
cc := arr2.filter(filter_cb(it))
dd := arr2.filter(fn (a int) bool {
return a < 4
})
println(aa)
println(bb)
println(cc)
println(dd)
println(aa)
println(bb)
println(cc)
println(dd)
// fixed arrays: implemented as normal arrays
f1 := [1, 2, 3, 4, 5]!
mut f2 := [8]f32
f2[0] = f32(1.23)
f3 := ['foo', 'bar']!
f4 := [u64(0xffffffffffffffff), 0xdeadface]!
// fixed arrays: implemented as normal arrays
f1 := [1, 2, 3, 4, 5]!
mut f2 := [8]f32{}
f2[0] = f32(1.23)
f3 := ['foo', 'bar']!
f4 := [u64(0xffffffffffffffff), 0xdeadface]!
println('
println('
$f1
$f2
$f3

View File

@ -1,4 +1,4 @@
import hello
import v.gen.js.tests.hello
enum Test {
foo = 2
@ -8,13 +8,12 @@ enum Test {
// TODO Remove `fn main` once vet supports scripts
fn main() {
mut a := hello.Ccc.a
a = .b
a = .c
println(a)
mut a := hello.Ccc.a
a = .b
a = .c
println(a)
mut b := Test.foo
b = .bar
println(b)
mut b := Test.foo
b = .bar
println(b)
}

View File

@ -1,6 +1,6 @@
module hello
import hello.hello1
import v.gen.js.tests.hello.hello1
pub const (
hello = 'Hello'
@ -25,9 +25,9 @@ pub enum Ccc {
pub fn debugger() string {
v := Bbb{}
return hello
return hello.hello
}
pub fn excited() string {
return "$hello1.nested() $debugger()!"
return '$hello1.nested() $debugger()!'
}

View File

@ -1,5 +1,5 @@
fn test_fn(s1, s2 string) {
print(if s1 == s2 {'true'} else {'false'})
fn test_fn(s1 string, s2 string) {
print(if s1 == s2 { 'true' } else { 'false' })
print('\t=> ')
println('"$s1", "$s2"')
}
@ -60,7 +60,7 @@ fn implicit_str() {
test_fn('int $i', 'int 42')
test_fn('$i', '42')
check := '$i' == '42'
//println(check)
// println(check)
text := '$i' + '42'
test_fn(text, '4242')
}
@ -89,9 +89,9 @@ fn interpolation_string_prefix_expr() {
r := 1
c := 2
js := 1
test_fn('>${3+r}<', '>4<')
test_fn('>${3 + r}<', '>4<')
test_fn('${r == js} $js', 'true 1')
test_fn('>${js+c} ${js+r==c}<', '>3 true<')
test_fn('>${js + c} ${js + r == c}<', '>3 true<')
}
/*
@ -134,8 +134,8 @@ fn utf8_string_interpolation() {
test_fn('$a $st $m', 'à-côté Sträßle 10')
zz := '>${a:10}< >${st:-8}< >${m:5}<-'
zz_expected := '> à-côté< >Sträßle < > 10<-'
//println(' zz: $zz')
//println('zz_expected: $zz_expected')
// println(' zz: $zz')
// println('zz_expected: $zz_expected')
test_fn(zz, zz_expected)
// e := '\u20AC' // Eurosign doesn' work with MSVC and tcc
e := ''
@ -153,7 +153,7 @@ struct Sss {
}
fn (s Sss) str() string {
return '[${s.v1}, ${s.v2:.3f}]'
return '[$s.v1, ${s.v2:.3f}]'
}
fn string_interpolation_str_evaluation() {

View File

@ -1,5 +1,5 @@
import hello as hl
import hello.hello1 as hl1
import v.gen.js.tests.hello as hl
import v.gen.js.tests.hello.hello1 as hl1
const (
i_am_a_const = 21214
@ -71,7 +71,7 @@ fn main() {
arr := [1, 2, 3, 4, 5]
for i in arr {
}
ma := {
ma := map{
'str': 'done'
'ddo': 'baba'
}
@ -91,15 +91,14 @@ fn main() {
propagation() or { println(err) }
}
fn anon_consumer(greeting string, anon fn (message string)) {
fn anon_consumer(greeting string, anon fn (string)) {
anon(greeting)
}
fn async(num int, def string) {
}
[inline]
[deprecated]
[deprecated; inline]
fn hello(game_on int, dummy ...string) (int, int) {
defer {
do := 'not'
@ -130,7 +129,9 @@ fn (it Companies) method() int {
}
fn error_if_even(num int) ?int {
if num % 2 == 0 { return error('number is even') }
if num % 2 == 0 {
return error('number is even')
}
return num
}

View File

@ -1,24 +1,49 @@
fn clear() { JS.console.clear() }
fn clear() {
JS.console.clear()
}
const (w = 30 h = 30)
const (
w = 30
h = 30
)
fn get(game [][]bool, x int, y int) bool {
if y < 0 || x < 0 { return false }
if y >= h || x >= w { return false }
if y < 0 || x < 0 {
return false
}
if y >= h || x >= w {
return false
}
return game[y][x]
}
fn neighbours(game [][]bool, x int, y int) int {
mut count := 0
if get(game, x-1, y-1) { count++ }
if get(game, x, y-1) { count++ }
if get(game, x+1, y-1) { count++ }
if get(game, x-1, y) { count++ }
if get(game, x+1, y) { count++ }
if get(game, x-1, y+1) { count++ }
if get(game, x, y+1) { count++ }
if get(game, x+1, y+1) { count++ }
if get(game, x - 1, y - 1) {
count++
}
if get(game, x, y - 1) {
count++
}
if get(game, x + 1, y - 1) {
count++
}
if get(game, x - 1, y) {
count++
}
if get(game, x + 1, y) {
count++
}
if get(game, x - 1, y + 1) {
count++
}
if get(game, x, y + 1) {
count++
}
if get(game, x + 1, y + 1) {
count++
}
return count
}
@ -38,8 +63,11 @@ fn step(game [][]bool) [][]bool {
fn row_str(row []bool) string {
mut str := ''
for cell in row {
if cell { str += ' ' }
else { str += ' ' }
if cell {
str += ' '
} else {
str += ' '
}
}
return str
}
@ -53,15 +81,18 @@ fn show(game [][]bool) {
// TODO Remove `fn main` once vet supports scripts
fn main() {
mut game := [][]bool{ len: h, init: []bool{ len: w } }
mut game := [][]bool{len: h, init: []bool{len: w}}
game[11][15] = true
game[11][16] = true
game[12][16] = true
game[10][21] = true
game[12][20] = true
game[12][21] = true
game[12][22] = true
game[11][15] = true
game[11][16] = true
game[12][16] = true
game[10][21] = true
game[12][20] = true
game[12][21] = true
game[12][22] = true
JS.setInterval(fn () { show(game) game = step(game) }, 500)
JS.setInterval(fn () {
show(game)
game = step(game)
}, 500)
}

View File

@ -1,28 +1,30 @@
module main
fn main() {
try_propagation() or { println("captured: $err") }
try_propagation() or { println('captured: $err') }
}
fn try_propagation() ? {
try_numbers()?
try_numbers() ?
}
fn try_numbers() ? {
for x in 1 .. 10 {
y := error_if_even(x) or { x + 1 }
println("$x rounded to $y")
error_if_prime(y)?
println('$x rounded to $y')
error_if_prime(y) ?
}
}
fn error_if_even(num int) ?int {
if num % 2 == 0 { return error('number is even') }
if num % 2 == 0 {
return error('number is even')
}
return num
}
fn error_if_prime(num int) ?int {
for i in 2..num {
for i in 2 .. num {
if num % i == 0 {
return error('$num is prime')
}

View File

@ -1,5 +1,5 @@
module main
fn main() {
println("hello world")
println('hello world')
}

View File

@ -33,8 +33,8 @@ fn main() {
b.add(10)
println(b.get()) // 10
use_config(Config{2, 'bar'})
use_config({
use_config(
foo: 2
bar: 'bar'
})
)
}

View File

@ -10,13 +10,12 @@ import v.errors
import v.pref
import term
import strings
import v.table
pub struct Gen {
out_name string
pref &pref.Preferences // Preferences shared from V struct
mut:
table &table.Table
table &ast.Table
buf []byte
sect_header_name_pos int
offset i64
@ -82,7 +81,7 @@ enum Size {
_64
}
pub fn gen(files []ast.File, table &table.Table, out_name string, pref &pref.Preferences) {
pub fn gen(files []ast.File, table &ast.Table, out_name string, pref &pref.Preferences) {
mut g := Gen{
table: table
sect_header_name_pos: 0
@ -776,7 +775,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
sym := g.table.get_type_symbol(right.typ)
// println(sym)
// println(typeof(sym.info))
info := sym.info as table.Struct
info := sym.info as ast.Struct
for field in info.fields {
field_name := name + '.' + field.name
println(field_name)

View File

@ -1,12 +1,12 @@
import v.gen.x64
import v.pref
import v.table
import v.ast
fn test_macho() {
mut g := x64.Gen{
pref: &pref.Preferences{}
out_name: 'test.bin'
table: &table.Table{}
table: &ast.Table{}
}
g.generate_macho_header()
g.generate_macho_footer()

View File

@ -3,12 +3,11 @@
module markused
import v.ast
import v.table
import v.util
import v.pref
// mark_used walks the AST, starting at main() and marks all used fns transitively
pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files []ast.File) {
pub fn mark_used(mut t ast.Table, pref &pref.Preferences, ast_files []ast.File) {
mut all_fns, all_consts := all_fn_and_const(ast_files)
util.timing_start(@METHOD)
@ -103,7 +102,7 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files []
// implicit string builders are generated in auto_eq_methods.v
mut sb_mut_type := ''
if sbfn := the_table.find_fn('strings.new_builder') {
if sbfn := t.find_fn('strings.new_builder') {
sb_mut_type = sbfn.return_type.set_nr_muls(1).str() + '.'
}
@ -141,7 +140,7 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files []
if pref.is_test {
all_fn_root_names << 'main.cb_assertion_ok'
all_fn_root_names << 'main.cb_assertion_failed'
if benched_tests_sym := the_table.find_type('main.BenchedTests') {
if benched_tests_sym := t.find_type('main.BenchedTests') {
bts_type := benched_tests_sym.methods[0].params[0].typ
all_fn_root_names << '${bts_type}.testing_step_start'
all_fn_root_names << '${bts_type}.testing_step_end'
@ -151,7 +150,7 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files []
}
mut walker := Walker{
table: the_table
table: t
files: ast_files
all_fns: all_fns
all_consts: all_consts
@ -181,12 +180,12 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files []
}
}
the_table.used_fns = walker.used_fns.move()
the_table.used_consts = walker.used_consts.move()
t.used_fns = walker.used_fns.move()
t.used_consts = walker.used_consts.move()
$if trace_skip_unused ? {
eprintln('>> the_table.used_fns: $the_table.used_fns.keys()')
eprintln('>> the_table.used_consts: $the_table.used_consts.keys()')
eprintln('>> t.used_fns: $t.used_fns.keys()')
eprintln('>> t.used_consts: $t.used_consts.keys()')
eprintln('>> walker.n_maps: $walker.n_maps')
}
}

View File

@ -5,11 +5,10 @@ module markused
// Walk the entire program starting at fn main and marks used (called) functions.
// Unused functions can be safely skipped by the backends to save CPU time and space.
import v.ast
import v.table
pub struct Walker {
pub mut:
table &table.Table
table &ast.Table
used_fns map[string]bool // used_fns['println'] == true
used_consts map[string]bool // used_consts['os.args'] == true
n_maps int
@ -288,11 +287,10 @@ fn (mut w Walker) expr(node ast.Expr) {
ast.StructInit {
sym := w.table.get_type_symbol(node.typ)
if sym.kind == .struct_ {
info := sym.info as table.Struct
info := sym.info as ast.Struct
for ifield in info.fields {
if ifield.has_default_expr {
defex := ast.fe2ex(ifield.default_expr)
w.expr(defex)
w.expr(ifield.default_expr)
}
}
}
@ -337,7 +335,7 @@ fn (mut w Walker) expr(node ast.Expr) {
w.stmts(branch.stmts)
}
}
ast.Type {}
ast.TypeNode {}
ast.UnsafeExpr {
w.expr(node.expr)
}

View File

@ -4,7 +4,6 @@
module parser
import v.ast
import v.table
fn (mut p Parser) assign_stmt() ast.Stmt {
exprs, comments := p.expr_list()
@ -134,7 +133,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
if p.scope.known_var(lx.name) {
return p.error_with_pos('redefinition of `$lx.name`', lx.pos)
}
mut share := table.ShareType(0)
mut share := ast.ShareType(0)
if lx.info is ast.IdentVar {
iv := lx.info as ast.IdentVar
share = iv.share

View File

@ -6,7 +6,6 @@ module parser
import os
import v.ast
import v.pref
import v.table
import v.token
const (

View File

@ -4,15 +4,14 @@
module parser
import v.ast
import v.table
fn (mut p Parser) array_init() ast.ArrayInit {
first_pos := p.tok.position()
mut last_pos := p.tok.position()
p.check(.lsbr)
// p.warn('array_init() exp=$p.expected_type')
mut array_type := table.void_type
mut elem_type := table.void_type
mut array_type := ast.void_type
mut elem_type := ast.void_type
mut elem_type_pos := first_pos
mut exprs := []ast.Expr{}
mut ecmnts := [][]ast.Comment{}
@ -34,7 +33,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
// this is set here because it's a known type, others could be the
// result of expr so we do those in checker
idx := p.table.find_or_register_array(elem_type)
array_type = table.new_type(idx)
array_type = ast.new_type(idx)
has_type = true
}
last_pos = p.tok.position()
@ -105,7 +104,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
mut has_cap := false
mut len_expr := ast.empty_expr()
mut cap_expr := ast.empty_expr()
if p.tok.kind == .lcbr && exprs.len == 0 && array_type != table.void_type {
if p.tok.kind == .lcbr && exprs.len == 0 && array_type != ast.void_type {
// `[]int{ len: 10, cap: 100}` syntax
p.next()
for p.tok.kind != .rcbr {

View File

@ -4,11 +4,10 @@
module parser
import v.ast
import v.table
import v.token
import v.util
pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExpr {
pub fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr {
first_pos := p.tok.position()
mut fn_name := if language == .c {
'C.$p.check_name()'
@ -34,7 +33,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
}
p.expr_mod = ''
//
mut generic_types := []table.Type{}
mut generic_types := []ast.Type{}
mut generic_list_pos := p.tok.position()
if p.tok.kind == .lt {
// `foo<int>(10)`
@ -69,7 +68,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
p.open_scope()
p.scope.register(ast.Var{
name: 'err'
typ: table.error_type
typ: ast.error_type
pos: p.tok.position()
is_used: true
})
@ -150,7 +149,7 @@ pub fn (mut p Parser) call_args() []ast.CallArg {
comments << p.eat_comments({})
args << ast.CallArg{
is_mut: is_mut
share: table.sharetype_from_flags(is_shared, is_atomic)
share: ast.sharetype_from_flags(is_shared, is_atomic)
expr: expr
comments: comments
pos: pos
@ -166,10 +165,10 @@ struct ReceiverParsingInfo {
mut:
name string
pos token.Position
typ table.Type
typ ast.Type
type_pos token.Position
is_mut bool
language table.Language
language ast.Language
}
fn (mut p Parser) fn_decl() ast.FnDecl {
@ -187,12 +186,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
p.check(.key_fn)
p.open_scope()
// C. || JS.
mut language := table.Language.v
mut language := ast.Language.v
if p.tok.kind == .name && p.tok.lit == 'C' {
is_unsafe = !p.attrs.contains('trusted')
language = table.Language.c
language = ast.Language.c
} else if p.tok.kind == .name && p.tok.lit == 'JS' {
language = table.Language.js
language = ast.Language.js
}
if language != .v {
p.next()
@ -201,11 +200,11 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
}
// Receiver?
mut rec := ReceiverParsingInfo{
typ: table.void_type
typ: ast.void_type
language: language
}
mut is_method := false
mut params := []table.Param{}
mut params := []ast.Param{}
if p.tok.kind == .lpar {
is_method = true
p.fn_receiver(mut params, mut rec) or { return ast.FnDecl{
@ -233,7 +232,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
mut is_duplicate := type_sym.has_method(name)
// make sure this is a normal method and not an interface method
if type_sym.kind == .interface_ && is_duplicate {
if type_sym.info is table.Interface {
if type_sym.info is ast.Interface {
// if the method is in info then its an interface method
is_duplicate = !type_sym.info.has_method(name)
}
@ -254,7 +253,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
}
} else if p.tok.kind in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && p.peek_tok.kind == .lpar {
name = p.tok.kind.str() // op_to_fn_name()
if rec.typ == table.void_type {
if rec.typ == ast.void_type {
p.error_with_pos('cannot use operator overloading with normal functions',
p.tok.position())
}
@ -294,7 +293,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
}
}
// Return type
mut return_type := table.void_type
mut return_type := ast.void_type
// don't confuse token on the next line: fn decl, [attribute]
same_line := p.tok.line_nr == p.prev_tok.line_nr
if (p.tok.kind.is_start_of_type() && (same_line || p.tok.kind != .lsbr))
@ -327,7 +326,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
scope: 0
}
}
type_sym_method_idx = type_sym.register_method(table.Fn{
type_sym_method_idx = type_sym.register_method(ast.Fn{
name: name
params: params
return_type: return_type
@ -355,7 +354,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
if !p.pref.translated && language == .v && name in p.table.fns {
p.table.redefined_fns << name
}
p.table.register_fn(table.Fn{
p.table.register_fn(ast.Fn{
name: name
params: params
return_type: return_type
@ -408,7 +407,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
is_main: is_main
is_test: is_test
is_conditional: is_conditional
receiver: ast.Field{
receiver: ast.StructField{
name: rec.name
typ: rec.typ
}
@ -433,7 +432,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
return fn_decl
}
fn (mut p Parser) fn_receiver(mut params []table.Param, mut rec ReceiverParsingInfo) ? {
fn (mut p Parser) fn_receiver(mut params []ast.Param, mut rec ReceiverParsingInfo) ? {
lpar_pos := p.tok.position()
p.next() // (
is_shared := p.tok.kind == .key_shared
@ -458,7 +457,7 @@ fn (mut p Parser) fn_receiver(mut params []table.Param, mut rec ReceiverParsingI
rec.pos = rec_start_pos.extend(p.tok.position())
is_amp := p.tok.kind == .amp
if p.tok.kind == .name && p.tok.lit == 'JS' {
rec.language = table.Language.js
rec.language = ast.Language.js
}
// if rec.is_mut {
// p.check(.key_mut)
@ -487,14 +486,14 @@ fn (mut p Parser) fn_receiver(mut params []table.Param, mut rec ReceiverParsingI
type_sym := p.table.get_type_symbol(rec.typ)
mut is_auto_rec := false
if type_sym.kind == .struct_ {
info := type_sym.info as table.Struct
info := type_sym.info as ast.Struct
if !rec.is_mut && !rec.typ.is_ptr() && info.fields.len > 8 {
rec.typ = rec.typ.to_ptr()
is_auto_rec = true
}
}
params << table.Param{
params << ast.Param{
pos: rec_start_pos
name: rec.name
is_mut: rec.is_mut
@ -574,7 +573,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
})
}
mut same_line := p.tok.line_nr == p.prev_tok.line_nr
mut return_type := table.void_type
mut return_type := ast.void_type
// lpar: multiple return types
if same_line {
if p.tok.kind.is_start_of_type() {
@ -592,7 +591,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
p.tok.position())
}
mut label_names := []string{}
mut func := table.Fn{
mut func := ast.Fn{
params: args
is_variadic: is_variadic
return_type: return_type
@ -611,7 +610,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
p.close_scope()
func.name = name
idx := p.table.find_or_register_fn_type(p.mod, func, true, false)
typ := table.new_type(idx)
typ := ast.new_type(idx)
// name := p.table.get_type_name(typ)
return ast.AnonFn{
decl: ast.FnDecl{
@ -634,9 +633,9 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
}
// part of fn declaration
fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
p.check(.lpar)
mut args := []table.Param{}
mut args := []ast.Param{}
mut is_variadic := false
// `int, int, string` (no names, just types)
argname := if p.tok.kind == .name && p.tok.lit.len > 0 && p.tok.lit[0].is_capital() {
@ -653,7 +652,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
for p.tok.kind != .rpar {
if p.tok.kind == .eof {
p.error_with_pos('expecting `)`', p.tok.position())
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
is_shared := p.tok.kind == .key_shared
is_atomic := p.tok.kind == .key_atomic
@ -669,7 +668,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
mut arg_type := p.parse_type()
if arg_type == 0 {
// error is added in parse_type
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
if is_mut {
if !arg_type.has_flag(.generic) {
@ -682,7 +681,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
}
} else if is_shared || is_atomic {
p.error_with_pos('generic object cannot be `atomic`or `shared`', pos)
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
// if arg_type.is_ptr() {
// p.error('cannot mut')
@ -697,21 +696,21 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
}
}
if is_variadic {
arg_type = table.new_type(p.table.find_or_register_array(arg_type)).set_flag(.variadic)
arg_type = ast.new_type(p.table.find_or_register_array(arg_type)).set_flag(.variadic)
}
if p.tok.kind == .eof {
p.error_with_pos('expecting `)`', p.prev_tok.position())
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
if p.tok.kind == .comma {
if is_variadic {
p.error_with_pos('cannot use ...(variadic) with non-final parameter no $arg_no',
pos)
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
p.next()
}
args << table.Param{
args << ast.Param{
pos: pos
name: ''
is_mut: is_mut
@ -720,14 +719,14 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
arg_no++
if arg_no > 1024 {
p.error_with_pos('too many args', pos)
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
}
} else {
for p.tok.kind != .rpar {
if p.tok.kind == .eof {
p.error_with_pos('expecting `)`', p.tok.position())
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
is_shared := p.tok.kind == .key_shared
is_atomic := p.tok.kind == .key_atomic
@ -768,7 +767,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
mut typ := p.parse_type()
if typ == 0 {
// error is added in parse_type
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
if is_mut {
if !typ.has_flag(.generic) {
@ -782,7 +781,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
} else if is_shared || is_atomic {
p.error_with_pos('generic object cannot be `atomic` or `shared`',
pos)
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
typ = typ.set_nr_muls(1)
if is_shared {
@ -793,10 +792,10 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
}
}
if is_variadic {
typ = table.new_type(p.table.find_or_register_array(typ)).derive(typ).set_flag(.variadic)
typ = ast.new_type(p.table.find_or_register_array(typ)).derive(typ).set_flag(.variadic)
}
for i, arg_name in arg_names {
args << table.Param{
args << ast.Param{
pos: arg_pos[i]
name: arg_name
is_mut: is_mut
@ -807,12 +806,12 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
if is_variadic && p.tok.kind == .comma {
p.error_with_pos('cannot use ...(variadic) with non-final parameter $arg_name',
arg_pos[i])
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
}
if p.tok.kind == .eof {
p.error_with_pos('expecting `)`', p.prev_tok.position())
return []table.Param{}, false, false
return []ast.Param{}, false, false
}
if p.tok.kind != .rpar {
p.check(.comma)
@ -823,7 +822,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
return args, types_only, is_variadic
}
fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) {
fn (mut p Parser) check_fn_mutable_arguments(typ ast.Type, pos token.Position) {
sym := p.table.get_type_symbol(typ)
if sym.kind in [.array, .array_fixed, .interface_, .map, .placeholder, .struct_, .sum_type] {
return
@ -832,7 +831,7 @@ fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position)
return
}
if sym.kind == .alias {
atyp := (sym.info as table.Alias).parent_type
atyp := (sym.info as ast.Alias).parent_type
p.check_fn_mutable_arguments(atyp, pos)
return
}
@ -842,7 +841,7 @@ fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position)
pos)
}
fn (mut p Parser) check_fn_shared_arguments(typ table.Type, pos token.Position) {
fn (mut p Parser) check_fn_shared_arguments(typ ast.Type, pos token.Position) {
sym := p.table.get_type_symbol(typ)
if sym.kind !in [.array, .struct_, .map, .placeholder] && !typ.is_ptr() {
p.error_with_pos('shared arguments are only allowed for arrays, maps, and structs\n',
@ -850,7 +849,7 @@ fn (mut p Parser) check_fn_shared_arguments(typ table.Type, pos token.Position)
}
}
fn (mut p Parser) check_fn_atomic_arguments(typ table.Type, pos token.Position) {
fn (mut p Parser) check_fn_atomic_arguments(typ ast.Type, pos token.Position) {
sym := p.table.get_type_symbol(typ)
if sym.kind !in [.u32, .int, .u64] {
p.error_with_pos('atomic arguments are only allowed for 32/64 bit integers\n' +

View File

@ -4,7 +4,6 @@
module parser
import v.ast
import v.table
fn (mut p Parser) for_stmt() ast.Stmt {
p.check(.key_for)
@ -120,7 +119,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
}
p.scope.register(ast.Var{
name: key_var_name
typ: table.int_type
typ: ast.int_type
pos: key_var_pos
is_tmp: true
})
@ -144,7 +143,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
high_expr = p.expr(0)
p.scope.register(ast.Var{
name: val_var_name
typ: table.int_type
typ: ast.int_type
pos: val_var_pos
is_tmp: true
})

View File

@ -4,7 +4,6 @@
module parser
import v.ast
import v.table
import v.token
fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
@ -52,7 +51,7 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
if prev_guard {
p.scope.register(ast.Var{
name: 'err'
typ: table.error_type
typ: ast.error_type
pos: p.tok.position()
is_used: true
})
@ -178,16 +177,16 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
is_else = true
p.next()
} else if (p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot)
&& (p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital()
&& (p.tok.lit in ast.builtin_type_names || p.tok.lit[0].is_capital()
|| (p.peek_tok.kind == .dot && p.peek_token(2).lit.len > 0
&& p.peek_token(2).lit[0].is_capital()))) || p.tok.kind == .lsbr {
mut types := []table.Type{}
mut types := []ast.Type{}
for {
// Sum type match
parsed_type := p.parse_type()
ecmnts << p.eat_comments({})
types << parsed_type
exprs << ast.Type{
exprs << ast.TypeNode{
typ: parsed_type
pos: p.prev_tok.position()
}

View File

@ -1,7 +1,6 @@
module parser
import v.ast
import v.table
fn (mut p Parser) lock_expr() ast.LockExpr {
// TODO Handle aliasing sync
@ -20,7 +19,7 @@ fn (mut p Parser) lock_expr() ast.LockExpr {
p.next()
for p.tok.kind == .name {
lockeds << ast.Ident{
language: table.Language.v
language: ast.Language.v
pos: p.tok.position()
mod: p.mod
name: p.tok.lit

View File

@ -3,11 +3,10 @@
// that can be found in the LICENSE file.
module parser
import v.table
import v.util
import v.ast
import v.util
pub fn (mut p Parser) parse_array_type() table.Type {
pub fn (mut p Parser) parse_array_type() ast.Type {
p.check(.lsbr)
// fixed array
if p.tok.kind in [.number, .name] {
@ -44,7 +43,7 @@ pub fn (mut p Parser) parse_array_type() table.Type {
}
// sym := p.table.get_type_symbol(elem_type)
idx := p.table.find_or_register_array_fixed(elem_type, fixed_size)
return table.new_type(idx)
return ast.new_type(idx)
}
// array
p.check(.rsbr)
@ -62,13 +61,13 @@ pub fn (mut p Parser) parse_array_type() table.Type {
nr_dims++
}
idx := p.table.find_or_register_array_with_dims(elem_type, nr_dims)
return table.new_type(idx)
return ast.new_type(idx)
}
pub fn (mut p Parser) parse_map_type() table.Type {
pub fn (mut p Parser) parse_map_type() ast.Type {
p.next()
if p.tok.kind != .lsbr {
return table.map_type
return ast.map_type
}
p.check(.lsbr)
key_type := p.parse_type()
@ -78,12 +77,12 @@ pub fn (mut p Parser) parse_map_type() table.Type {
// error is reported in parse_type
return 0
}
if is_alias && !(key_type in [table.string_type_idx, table.voidptr_type_idx]
if is_alias && !(key_type in [ast.string_type_idx, ast.voidptr_type_idx]
|| ((key_type.is_int() || key_type.is_float()) && !key_type.is_ptr())) {
p.error('cannot use the alias type as the parent type is unsupported')
return 0
}
if !(key_type in [table.string_type_idx, table.voidptr_type_idx]
if !(key_type in [ast.string_type_idx, ast.voidptr_type_idx]
|| key_sym.kind == .enum_ || ((key_type.is_int() || key_type.is_float()
|| is_alias) && !key_type.is_ptr())) {
s := p.table.type_to_str(key_type)
@ -97,29 +96,29 @@ pub fn (mut p Parser) parse_map_type() table.Type {
// error is reported in parse_type
return 0
}
if value_type.idx() == table.void_type_idx {
if value_type.idx() == ast.void_type_idx {
p.error_with_pos('map value type cannot be void', p.tok.position())
return 0
}
idx := p.table.find_or_register_map(key_type, value_type)
return table.new_type(idx)
return ast.new_type(idx)
}
pub fn (mut p Parser) parse_chan_type() table.Type {
pub fn (mut p Parser) parse_chan_type() ast.Type {
if p.peek_tok.kind != .name && p.peek_tok.kind != .key_mut && p.peek_tok.kind != .amp
&& p.peek_tok.kind != .lsbr {
p.next()
return table.chan_type
return ast.chan_type
}
p.register_auto_import('sync')
p.next()
is_mut := p.tok.kind == .key_mut
elem_type := p.parse_type()
idx := p.table.find_or_register_chan(elem_type, is_mut)
return table.new_type(idx)
return ast.new_type(idx)
}
pub fn (mut p Parser) parse_thread_type() table.Type {
pub fn (mut p Parser) parse_thread_type() ast.Type {
is_opt := p.peek_tok.kind == .question
if is_opt {
p.next()
@ -128,12 +127,12 @@ pub fn (mut p Parser) parse_thread_type() table.Type {
&& p.peek_tok.kind != .lsbr {
p.next()
if is_opt {
mut ret_type := table.void_type
mut ret_type := ast.void_type
ret_type = ret_type.set_flag(.optional)
idx := p.table.find_or_register_thread(ret_type)
return table.new_type(idx)
return ast.new_type(idx)
} else {
return table.thread_type
return ast.thread_type
}
}
if !is_opt {
@ -141,12 +140,12 @@ pub fn (mut p Parser) parse_thread_type() table.Type {
}
ret_type := p.parse_type()
idx := p.table.find_or_register_thread(ret_type)
return table.new_type(idx)
return ast.new_type(idx)
}
pub fn (mut p Parser) parse_multi_return_type() table.Type {
pub fn (mut p Parser) parse_multi_return_type() ast.Type {
p.check(.lpar)
mut mr_types := []table.Type{}
mut mr_types := []ast.Type{}
for p.tok.kind != .eof {
mr_type := p.parse_type()
if mr_type.idx() == 0 {
@ -165,20 +164,20 @@ pub fn (mut p Parser) parse_multi_return_type() table.Type {
return mr_types[0]
}
idx := p.table.find_or_register_multi_return(mr_types)
return table.new_type(idx)
return ast.new_type(idx)
}
// given anon name based off signature when `name` is blank
pub fn (mut p Parser) parse_fn_type(name string) table.Type {
pub fn (mut p Parser) parse_fn_type(name string) ast.Type {
// p.warn('parse fn')
p.check(.key_fn)
line_nr := p.tok.line_nr
args, _, is_variadic := p.fn_args()
mut return_type := table.void_type
mut return_type := ast.void_type
if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() {
return_type = p.parse_type()
}
func := table.Fn{
func := ast.Fn{
name: name
params: args
is_variadic: is_variadic
@ -188,10 +187,10 @@ pub fn (mut p Parser) parse_fn_type(name string) table.Type {
// because typedefs get generated after the map struct is generated
has_decl := p.builtin_mod && name.starts_with('Map') && name.ends_with('Fn')
idx := p.table.find_or_register_fn_type(p.mod, func, false, has_decl)
return table.new_type(idx)
return ast.new_type(idx)
}
pub fn (mut p Parser) parse_type_with_mut(is_mut bool) table.Type {
pub fn (mut p Parser) parse_type_with_mut(is_mut bool) ast.Type {
typ := p.parse_type()
if is_mut {
return typ.set_nr_muls(1)
@ -200,13 +199,13 @@ pub fn (mut p Parser) parse_type_with_mut(is_mut bool) table.Type {
}
// Parses any language indicators on a type.
pub fn (mut p Parser) parse_language() table.Language {
pub fn (mut p Parser) parse_language() ast.Language {
language := if p.tok.lit == 'C' {
table.Language.c
ast.Language.c
} else if p.tok.lit == 'JS' {
table.Language.js
ast.Language.js
} else {
table.Language.v
ast.Language.v
}
if language != .v {
p.next()
@ -215,7 +214,7 @@ pub fn (mut p Parser) parse_language() table.Language {
return language
}
pub fn (mut p Parser) parse_type() table.Type {
pub fn (mut p Parser) parse_type() ast.Type {
// optional
mut is_optional := false
if p.tok.kind == .question {
@ -223,7 +222,7 @@ pub fn (mut p Parser) parse_type() table.Type {
p.next()
is_optional = true
if p.tok.line_nr > line_nr {
mut typ := table.void_type
mut typ := ast.void_type
if is_optional {
typ = typ.set_flag(.optional)
}
@ -252,7 +251,7 @@ pub fn (mut p Parser) parse_type() table.Type {
p.next()
}
language := p.parse_language()
mut typ := table.void_type
mut typ := ast.void_type
is_array := p.tok.kind == .lsbr
if p.tok.kind != .lcbr {
pos := p.tok.position()
@ -261,7 +260,7 @@ pub fn (mut p Parser) parse_type() table.Type {
// error is set in parse_type
return 0
}
if typ == table.void_type {
if typ == ast.void_type {
p.error_with_pos('use `?` instead of `?void`', pos)
return 0
}
@ -287,7 +286,7 @@ If you need to modify an array in a function, use a mutable argument instead: `f
return typ
}
pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool, check_dot bool) table.Type {
pub fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_dot bool) ast.Type {
mut name := p.tok.lit
if language == .c {
name = 'C.$name'
@ -358,58 +357,58 @@ pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool, check
}
match name {
'voidptr' {
return table.voidptr_type
return ast.voidptr_type
}
'byteptr' {
return table.byteptr_type
return ast.byteptr_type
}
'charptr' {
return table.charptr_type
return ast.charptr_type
}
'i8' {
return table.i8_type
return ast.i8_type
}
'i16' {
return table.i16_type
return ast.i16_type
}
'int' {
return table.int_type
return ast.int_type
}
'i64' {
return table.i64_type
return ast.i64_type
}
'byte' {
return table.byte_type
return ast.byte_type
}
'u16' {
return table.u16_type
return ast.u16_type
}
'u32' {
return table.u32_type
return ast.u32_type
}
'u64' {
return table.u64_type
return ast.u64_type
}
'f32' {
return table.f32_type
return ast.f32_type
}
'f64' {
return table.f64_type
return ast.f64_type
}
'string' {
return table.string_type
return ast.string_type
}
'char' {
return table.char_type
return ast.char_type
}
'bool' {
return table.bool_type
return ast.bool_type
}
'float_literal' {
return table.float_literal_type
return ast.float_literal_type
}
'int_literal' {
return table.int_literal_type
return ast.int_literal_type
}
else {
if name.len == 1 && name[0].is_capital() {
@ -425,42 +424,42 @@ pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool, check
}
}
pub fn (mut p Parser) parse_enum_or_struct_type(name string, language table.Language) table.Type {
pub fn (mut p Parser) parse_enum_or_struct_type(name string, language ast.Language) ast.Type {
// struct / enum / placeholder
// struct / enum
mut idx := p.table.find_type_idx(name)
if idx > 0 {
return table.new_type(idx)
return ast.new_type(idx)
}
// not found - add placeholder
idx = p.table.add_placeholder_type(name, language)
// println('NOT FOUND: $name - adding placeholder - $idx')
return table.new_type(idx)
return ast.new_type(idx)
}
pub fn (mut p Parser) parse_generic_template_type(name string) table.Type {
pub fn (mut p Parser) parse_generic_template_type(name string) ast.Type {
mut idx := p.table.find_type_idx(name)
if idx > 0 {
return table.new_type(idx).set_flag(.generic)
return ast.new_type(idx).set_flag(.generic)
}
idx = p.table.register_type_symbol(table.TypeSymbol{
idx = p.table.register_type_symbol(ast.TypeSymbol{
name: name
cname: util.no_dots(name)
mod: p.mod
kind: .any
is_public: true
})
return table.new_type(idx).set_flag(.generic)
return ast.new_type(idx).set_flag(.generic)
}
pub fn (mut p Parser) parse_generic_struct_inst_type(name string) table.Type {
pub fn (mut p Parser) parse_generic_struct_inst_type(name string) ast.Type {
mut bs_name := name
mut bs_cname := name
p.next()
p.in_generic_params = true
bs_name += '<'
bs_cname += '_T_'
mut generic_types := []table.Type{}
mut generic_types := []ast.Type{}
mut is_instance := false
for p.tok.kind != .eof {
gt := p.parse_type()
@ -484,28 +483,28 @@ pub fn (mut p Parser) parse_generic_struct_inst_type(name string) table.Type {
if is_instance && generic_types.len > 0 {
mut gt_idx := p.table.find_type_idx(bs_name)
if gt_idx > 0 {
return table.new_type(gt_idx)
return ast.new_type(gt_idx)
}
gt_idx = p.table.add_placeholder_type(bs_name, .v)
mut parent_idx := p.table.type_idxs[name]
if parent_idx == 0 {
parent_idx = p.table.add_placeholder_type(name, .v)
}
idx := p.table.register_type_symbol(table.TypeSymbol{
idx := p.table.register_type_symbol(ast.TypeSymbol{
kind: .generic_struct_inst
name: bs_name
cname: util.no_dots(bs_cname)
mod: p.mod
info: table.GenericStructInst{
info: ast.GenericStructInst{
parent_idx: parent_idx
generic_types: generic_types
}
})
return table.new_type(idx)
return ast.new_type(idx)
} else {
idx := p.table.find_type_idx(name)
if idx != 0 {
return table.new_type(idx).set_flag(.generic)
return ast.new_type(idx).set_flag(.generic)
}
}
return p.parse_enum_or_struct_type(name, .v)

View File

@ -6,7 +6,6 @@ module parser
import v.scanner
import v.ast
import v.token
import v.table
import v.pref
import v.util
import v.vet
@ -20,18 +19,18 @@ const (
pub struct Parser {
pref &pref.Preferences
mut:
file_base string // "hello.v"
file_name string // "/home/user/hello.v"
file_name_dir string // "/home/user"
file_backend_mode table.Language // .c for .c.v|.c.vv|.c.vsh files; .js for .js.v files, .amd64/.rv32/other arches for .amd64.v/.rv32.v/etc. files, .v otherwise.
file_base string // "hello.v"
file_name string // "/home/user/hello.v"
file_name_dir string // "/home/user"
file_backend_mode ast.Language // .c for .c.v|.c.vv|.c.vsh files; .js for .js.v files, .amd64/.rv32/other arches for .amd64.v/.rv32.v/etc. files, .v otherwise.
scanner &scanner.Scanner
comments_mode scanner.CommentsMode = .skip_comments
// see comment in parse_file
tok token.Token
prev_tok token.Token
peek_tok token.Token
table &table.Table
language table.Language
table &ast.Table
language ast.Language
inside_if bool
inside_if_expr bool
inside_ct_if_expr bool
@ -40,12 +39,12 @@ mut:
inside_fn bool // true even with implicit main
inside_unsafe_fn bool
inside_str_interp bool
or_is_handled bool // ignore `or` in this expression
builtin_mod bool // are we in the `builtin` module?
mod string // current module name
is_manualfree bool // true when `[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree
attrs []table.Attr // attributes before next decl stmt
expr_mod string // for constructing full type names in parse_type()
or_is_handled bool // ignore `or` in this expression
builtin_mod bool // are we in the `builtin` module?
mod string // current module name
is_manualfree bool // true when `[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree
attrs []ast.Attr // attributes before next decl stmt
expr_mod string // for constructing full type names in parse_type()
scope &ast.Scope
global_scope &ast.Scope
imports map[string]string // alias => mod_name
@ -77,7 +76,7 @@ mut:
}
// for tests
pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt {
pub fn parse_stmt(text string, table &ast.Table, scope &ast.Scope) ast.Stmt {
mut p := Parser{
scanner: scanner.new_scanner(text, .skip_comments, &pref.Preferences{})
table: table
@ -97,7 +96,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt {
return p.stmt(false)
}
pub fn parse_comptime(text string, table &table.Table, pref &pref.Preferences, scope &ast.Scope, global_scope &ast.Scope) ast.File {
pub fn parse_comptime(text string, table &ast.Table, pref &pref.Preferences, scope &ast.Scope, global_scope &ast.Scope) ast.File {
mut p := Parser{
scanner: scanner.new_scanner(text, .skip_comments, pref)
table: table
@ -110,7 +109,7 @@ pub fn parse_comptime(text string, table &table.Table, pref &pref.Preferences, s
return p.parse()
}
pub fn parse_text(text string, path string, table &table.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File {
pub fn parse_text(text string, path string, table &ast.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File {
mut p := Parser{
scanner: scanner.new_scanner(text, comments_mode, pref)
comments_mode: comments_mode
@ -156,7 +155,7 @@ pub fn (mut p Parser) set_path(path string) {
}
else {
arch := pref.arch_from_string(actual_language) or { pref.Arch._auto }
p.file_backend_mode = table.pref_arch_to_table_language(arch)
p.file_backend_mode = ast.pref_arch_to_table_language(arch)
if arch == ._auto {
p.file_backend_mode = .v
}
@ -164,7 +163,7 @@ pub fn (mut p Parser) set_path(path string) {
}
}
pub fn parse_file(path string, table &table.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File {
pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File {
// NB: when comments_mode == .toplevel_comments,
// the parser gives feedback to the scanner about toplevel statements, so that the scanner can skip
// all the tricky inner comments. This is needed because we do not have a good general solution
@ -190,7 +189,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment
return p.parse()
}
pub fn parse_vet_file(path string, table_ &table.Table, pref &pref.Preferences) (ast.File, []vet.Error) {
pub fn parse_vet_file(path string, table_ &ast.Table, pref &pref.Preferences) (ast.File, []vet.Error) {
global_scope := &ast.Scope{
parent: 0
}
@ -293,7 +292,7 @@ mut:
mu &sync.Mutex
mu2 &sync.Mutex
paths []string
table &table.Table
table &ast.Table
parsed_ast_files []ast.File
pref &pref.Preferences
global_scope &ast.Scope
@ -319,7 +318,7 @@ fn (mut q Queue) run() {
}
}
*/
pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, global_scope &ast.Scope) []ast.File {
pub fn parse_files(paths []string, table &ast.Table, pref &pref.Preferences, global_scope &ast.Scope) []ast.File {
mut timers := util.new_timers(false)
$if time_parsing ? {
timers.should_print = true
@ -585,7 +584,7 @@ pub fn (mut p Parser) top_stmt() ast.Stmt {
is_main: true
stmts: stmts
file: p.file_name
return_type: table.void_type
return_type: ast.void_type
scope: p.scope
label_names: p.label_names
}
@ -867,7 +866,7 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
p.check(.name)
}
p.check_for_impure_v(table.pref_arch_to_table_language(arch), p.prev_tok.position())
p.check_for_impure_v(ast.pref_arch_to_table_language(arch), p.prev_tok.position())
p.check(.lcbr)
p.scope = &ast.Scope{
@ -1454,11 +1453,11 @@ fn (mut p Parser) attributes() {
}
}
fn (mut p Parser) parse_attr() table.Attr {
fn (mut p Parser) parse_attr() ast.Attr {
apos := p.prev_tok.position()
if p.tok.kind == .key_unsafe {
p.next()
return table.Attr{
return ast.Attr{
name: 'unsafe'
pos: apos.extend(p.tok.position())
}
@ -1478,10 +1477,10 @@ fn (mut p Parser) parse_attr() table.Attr {
name = p.check_name()
if name == 'unsafe_fn' {
p.error_with_pos('[unsafe_fn] is obsolete, use `[unsafe]` instead', apos.extend(p.tok.position()))
return table.Attr{}
return ast.Attr{}
} else if name == 'trusted_fn' {
p.error_with_pos('[trusted_fn] is obsolete, use `[trusted]` instead', apos.extend(p.tok.position()))
return table.Attr{}
return ast.Attr{}
} else if name == 'ref_only' {
p.warn_with_pos('[ref_only] is deprecated, use [heap] instead', apos.extend(p.tok.position()))
name = 'heap'
@ -1498,7 +1497,7 @@ fn (mut p Parser) parse_attr() table.Attr {
}
}
}
return table.Attr{
return ast.Attr{
name: name
is_string: is_string
is_comptime_define: is_comptime_define
@ -1508,7 +1507,7 @@ fn (mut p Parser) parse_attr() table.Attr {
}
}
pub fn (mut p Parser) check_for_impure_v(language table.Language, pos token.Position) {
pub fn (mut p Parser) check_for_impure_v(language ast.Language, pos token.Position) {
if language == .v {
// pure V code is always allowed everywhere
return
@ -1698,7 +1697,7 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
}
}
pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident {
pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
// p.warn('name ')
is_shared := p.tok.kind == .key_shared
is_atomic := p.tok.kind == .key_atomic
@ -1748,7 +1747,7 @@ pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident {
info: ast.IdentVar{
is_mut: is_mut
is_static: is_static
share: table.sharetype_from_flags(is_shared, is_atomic)
share: ast.sharetype_from_flags(is_shared, is_atomic)
}
scope: p.scope
}
@ -1817,17 +1816,17 @@ pub fn (mut p Parser) name_expr() ast.Expr {
// get type position before moving to next
type_pos := p.tok.position()
typ := p.parse_type()
return ast.Type{
return ast.TypeNode{
typ: typ
pos: type_pos
}
}
mut language := table.Language.v
mut language := ast.Language.v
if p.tok.lit == 'C' {
language = table.Language.c
language = ast.Language.c
p.check_for_impure_v(language, p.tok.position())
} else if p.tok.lit == 'JS' {
language = table.Language.js
language = ast.Language.js
p.check_for_impure_v(language, p.tok.position())
}
mut mod := ''
@ -1947,7 +1946,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
}
name_w_mod := p.prepend_mod(name)
// type cast. TODO: finish
// if name in table.builtin_type_names {
// if name in ast.builtin_type_names {
if (!known_var && (name in p.table.type_idxs || name_w_mod in p.table.type_idxs)
&& name !in ['C.stat', 'C.sigaction']) || is_mod_cast
|| (language == .v && name[0].is_capital()) {
@ -1969,7 +1968,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
mut has_arg := false
expr = p.expr(0)
// TODO, string(b, len)
if p.tok.kind == .comma && to_typ.idx() == table.string_type_idx {
if p.tok.kind == .comma && to_typ.idx() == ast.string_type_idx {
p.next()
arg = p.expr(0) // len
has_arg = true
@ -2189,7 +2188,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
}
// Method call
// TODO move to fn.v call_expr()
mut generic_types := []table.Type{}
mut generic_types := []ast.Type{}
mut generic_list_pos := p.tok.position()
if is_generic_call {
// `g.foo<int>(10)`
@ -2215,7 +2214,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
p.open_scope()
p.scope.register(ast.Var{
name: 'err'
typ: table.error_type
typ: ast.error_type
pos: p.tok.position()
is_used: true
})
@ -2281,8 +2280,8 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
return sel_expr
}
fn (mut p Parser) parse_generic_type_list() []table.Type {
mut types := []table.Type{}
fn (mut p Parser) parse_generic_type_list() []ast.Type {
mut types := []ast.Type{}
if p.tok.kind != .lt {
return types
}
@ -2325,7 +2324,7 @@ fn (mut p Parser) string_expr() ast.Expr {
node = ast.StringLiteral{
val: val
is_raw: is_raw
language: if is_cstr { table.Language.c } else { table.Language.v }
language: if is_cstr { ast.Language.c } else { ast.Language.v }
pos: pos
}
return node
@ -2443,7 +2442,7 @@ fn (mut p Parser) parse_number_literal() ast.Expr {
}
fn (mut p Parser) module_decl() ast.Module {
mut module_attrs := []table.Attr{}
mut module_attrs := []ast.Attr{}
mut attrs_pos := p.tok.position()
if p.tok.kind == .lsbr {
p.attributes()
@ -2874,12 +2873,12 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
//
')
}
idx := p.table.register_type_symbol(table.TypeSymbol{
idx := p.table.register_type_symbol(ast.TypeSymbol{
kind: .enum_
name: name
cname: util.no_dots(name)
mod: p.mod
info: table.Enum{
info: ast.Enum{
vals: vals
is_flag: is_flag
is_multi_allowed: is_multi_allowed
@ -2963,12 +2962,12 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
}
variant_types := sum_variants.map(it.typ)
prepend_mod_name := p.prepend_mod(name)
typ := p.table.register_type_symbol(table.TypeSymbol{
typ := p.table.register_type_symbol(ast.TypeSymbol{
kind: .sum_type
name: prepend_mod_name
cname: util.no_dots(prepend_mod_name)
mod: p.mod
info: table.SumType{
info: ast.SumType{
variants: variant_types
}
is_public: is_pub
@ -2989,13 +2988,13 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
pidx := parent_type.idx()
p.check_for_impure_v(parent_sym.language, decl_pos)
prepend_mod_name := p.prepend_mod(name)
idx := p.table.register_type_symbol(table.TypeSymbol{
idx := p.table.register_type_symbol(ast.TypeSymbol{
kind: .alias
name: prepend_mod_name
cname: util.no_dots(prepend_mod_name)
mod: p.mod
parent_idx: pidx
info: table.Alias{
info: ast.Alias{
parent_type: parent_type
language: parent_sym.language
}

View File

@ -5,7 +5,6 @@ module parser
import v.ast
import v.vet
import v.table
import v.token
pub fn (mut p Parser) expr(precedence int) ast.Expr {
@ -23,7 +22,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
// Prefix
match p.tok.kind {
.key_mut, .key_shared, .key_atomic, .key_static {
node = p.parse_ident(table.Language.v)
node = p.parse_ident(ast.Language.v)
p.is_stmt_ident = is_stmt_ident
}
.name {
@ -292,7 +291,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
if p.expecting_type {
// Anonymous function type
start_pos := p.tok.position()
return ast.Type{
return ast.TypeNode{
typ: p.parse_type()
pos: start_pos.extend(p.prev_tok.position())
}
@ -460,7 +459,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
p.open_scope()
p.scope.register(ast.Var{
name: 'err'
typ: table.error_type
typ: ast.error_type
pos: p.tok.position()
is_used: true
})
@ -523,7 +522,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
p.open_scope()
p.scope.register(ast.Var{
name: 'err'
typ: table.error_type
typ: ast.error_type
pos: p.tok.position()
is_used: true
})

View File

@ -4,7 +4,6 @@
module parser
import v.ast
import v.table
fn (mut p Parser) sql_expr() ast.Expr {
// `sql db {`
@ -15,10 +14,10 @@ fn (mut p Parser) sql_expr() ast.Expr {
p.check(.key_select)
n := p.check_name()
is_count := n == 'count'
mut typ := table.void_type
mut typ := ast.void_type
if is_count {
p.check_name() // from
typ = table.int_type
typ = ast.int_type
}
table_pos := p.tok.position()
table_type := p.parse_type() // `User`
@ -77,7 +76,7 @@ fn (mut p Parser) sql_expr() ast.Expr {
}
if !query_one && !is_count {
// return an array
typ = table.new_type(p.table.find_or_register_array(table_type))
typ = ast.new_type(p.table.find_or_register_array(table_type))
} else if !is_count {
// return a single object
// TODO optional
@ -100,7 +99,7 @@ fn (mut p Parser) sql_expr() ast.Expr {
has_desc: has_desc
is_array: !query_one
pos: pos.extend(p.prev_tok.position())
table_expr: ast.Type{
table_expr: ast.TypeNode{
typ: table_type
pos: table_pos
}
@ -130,7 +129,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
kind = .update
}
mut inserted_var_name := ''
mut table_type := table.Type(0)
mut table_type := ast.Type(0)
if kind != .delete {
if kind == .update {
table_type = p.parse_type()
@ -189,7 +188,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
pos.last_line = p.prev_tok.line_nr
return ast.SqlStmt{
db_expr: db_expr
table_expr: ast.Type{
table_expr: ast.TypeNode{
typ: table_type
pos: table_pos
}

View File

@ -4,7 +4,6 @@
module parser
import v.ast
import v.table
import v.token
import v.util
@ -25,11 +24,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
p.check(.key_union)
}
language := if p.tok.lit == 'C' && p.peek_tok.kind == .dot {
table.Language.c
ast.Language.c
} else if p.tok.lit == 'JS' && p.peek_tok.kind == .dot {
table.Language.js
ast.Language.js
} else {
table.Language.v
ast.Language.v
}
if language != .v {
p.next() // C || JS
@ -48,7 +47,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
name_pos)
return ast.StructDecl{}
}
mut generic_types := []table.Type{}
mut generic_types := []ast.Type{}
if p.tok.kind == .lt {
p.next()
for {
@ -85,8 +84,8 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
name = p.prepend_mod(name)
}
mut ast_fields := []ast.StructField{}
mut fields := []table.Field{}
mut embed_types := []table.Type{}
mut fields := []ast.StructField{}
mut embed_types := []ast.Type{}
mut embeds := []ast.Embed{}
mut embed_field_names := []string{}
mut mut_pos := -1
@ -181,7 +180,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
|| p.peek_tok.kind == .dot) && language == .v && p.peek_tok.kind != .key_fn
is_on_top := ast_fields.len == 0 && !(is_field_mut || is_field_mut || is_field_global)
mut field_name := ''
mut typ := table.Type(0)
mut typ := ast.Type(0)
mut type_pos := token.Position{}
mut field_pos := token.Position{}
if is_embed {
@ -254,31 +253,33 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
has_default_expr = true
comments << p.eat_comments({})
}
// TODO merge table and ast Fields?
ast_fields << ast.StructField{
name: field_name
typ: typ
pos: field_pos
type_pos: type_pos
typ: typ
comments: comments
default_expr: default_expr
has_default_expr: has_default_expr
attrs: p.attrs
is_public: is_field_pub
is_pub: is_embed || is_field_pub
is_mut: is_embed || is_field_mut
is_global: is_field_global
}
}
is_pub_field := is_embed || is_field_pub
is_mut_field := is_embed || is_field_mut
// save embeds as table fields too, it will be used in generation phase
fields << table.Field{
fields << ast.StructField{
name: field_name
typ: typ
default_expr: ast.ex2fe(default_expr)
pos: field_pos
type_pos: type_pos
comments: comments
default_expr: default_expr
has_default_expr: has_default_expr
is_pub: is_pub_field
is_mut: is_mut_field
is_global: is_field_global
attrs: p.attrs
is_pub: is_embed || is_field_pub
is_mut: is_embed || is_field_mut
is_global: is_field_global
}
p.attrs = []
}
@ -286,13 +287,13 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
last_line = p.tok.line_nr
p.check(.rcbr)
}
t := table.TypeSymbol{
t := ast.TypeSymbol{
kind: .struct_
language: language
name: name
cname: util.no_dots(name)
mod: p.mod
info: table.Struct{
info: ast.Struct{
embeds: embed_types
fields: fields
is_typedef: attrs.contains('typedef')
@ -338,7 +339,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit {
first_pos := p.tok.position()
typ := if short_syntax { table.void_type } else { p.parse_type() }
typ := if short_syntax { ast.void_type } else { p.parse_type() }
p.expr_mod = ''
// sym := p.table.get_type_symbol(typ)
// p.warn('struct init typ=$sym.name')
@ -449,7 +450,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
name: interface_name
cname: util.no_dots(interface_name)
mod: p.mod
info: table.Interface{
info: ast.Interface{
types: []
}
)
@ -458,11 +459,11 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
name_pos)
return ast.InterfaceDecl{}
}
typ := table.new_type(reg_idx)
typ := ast.new_type(reg_idx)
mut ts := p.table.get_type_symbol(typ)
mut info := ts.info as table.Interface
mut info := ts.info as ast.Interface
// if methods were declared before, it's an error, ignore them
ts.methods = []table.Fn{cap: 20}
ts.methods = []ast.Fn{cap: 20}
// Parse fields or methods
mut fields := []ast.StructField{cap: 20}
mut methods := []ast.FnDecl{cap: 20}
@ -496,8 +497,8 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
return ast.InterfaceDecl{}
}
// field_names << name
args2, _, is_variadic := p.fn_args() // TODO merge table.Param and ast.Arg to avoid this
mut args := [table.Param{
args2, _, is_variadic := p.fn_args() // TODO merge ast.Param and ast.Arg to avoid this
mut args := [ast.Param{
name: 'x'
is_mut: is_mut
typ: typ
@ -509,7 +510,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
mod: p.mod
params: args
file: p.file_name
return_type: table.void_type
return_type: ast.void_type
is_variadic: is_variadic
is_pub: true
pos: method_start_pos.extend(p.prev_tok.position())
@ -524,7 +525,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
method.next_comments = mnext_comments
methods << method
// println('register method $name')
tmethod := table.Fn{
tmethod := ast.Fn{
name: name
params: args
return_type: method.return_type
@ -553,9 +554,9 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
type_pos: type_pos
typ: field_typ
comments: comments
is_public: true
is_pub: true
}
info.fields << table.Field{
info.fields << ast.StructField{
name: field_name
typ: field_typ
is_pub: true

View File

@ -3,10 +3,8 @@ module parser
// import v.eval
import v.ast
import v.gen.c
import v.table
import v.checker
import v.pref
import v.scanner
import term
fn test_eval() {
@ -35,7 +33,7 @@ fn test_eval() {
'20',
//
]
table := table.new_table()
table := ast.new_table()
vpref := &pref.Preferences{}
mut scope := &ast.Scope{
start_pos: 0
@ -76,7 +74,7 @@ x := 10
5+7
8+4
'
table := &table.Table{}
table := &ast.Table{}
vpref := &pref.Preferences{}
gscope := &ast.Scope{
parent: 0
@ -95,7 +93,7 @@ fn test_one() {
println('\n\ntest_one()')
input := ['a := 10', 'b := -a', 'c := 20']
expected := 'int a = 10;int b = -a;int c = 20;'
table := table.new_table()
table := ast.new_table()
vpref := &pref.Preferences{}
scope := &ast.Scope{
start_pos: 0
@ -136,7 +134,7 @@ fn test_parse_expr() {
'string s = tos3("hi");', 'x = 11;', 'a += 10;', '1.2 + 3.4;', '4 + 4;', '1 + 2 * 5;',
'-a + 1;', '2 + 2;']
mut e := []ast.Stmt{}
table := table.new_table()
table := ast.new_table()
vpref := &pref.Preferences{}
mut checker := checker.new_checker(table, vpref)
scope := &ast.Scope{
@ -184,7 +182,7 @@ fn test_num_literals() {
'c := -12.',
'd := -a',
]
table := table.new_table()
table := ast.new_table()
mut scope := &ast.Scope{
start_pos: 0
parent: 0
@ -211,7 +209,7 @@ fn test_num_literals() {
}
/*
table := &table.Table{}
table := &ast.Table{}
for s in text_expr {
// print using str method
x := parse_expr(s, table)

View File

@ -76,7 +76,7 @@ pub fn (mut p Preferences) fill_with_defaults() {
// executable on Windows + the precompiled V is more
// optimized.
println('Saving the resulting V executable in `./v2`')
println('Use `v -o v cmd/v` if you want to replace current ' + 'V executable.')
println('Use `v -o v cmd/v` if you want to replace current ' + 'V execuast.')
p.out_name = 'v2'
}
}

View File

@ -561,7 +561,7 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences
must_exist(res.path)
if !res.path.ends_with('.v') && os.is_executable(res.path) && os.is_file(res.path)
&& os.is_file(res.path + '.v') {
eprintln('It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "$res.path" is an executable.')
eprintln('It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "$res.path" is an execuast.')
res.path += '.v'
}
}

View File

@ -1,7 +1,7 @@
module main
// This prelude is loaded in every v program compiled with -live,
// but only for the main executable.
// but only for the main execuast.
import v.live.executable
const (

View File

@ -1,81 +0,0 @@
import v.table
fn test_idx() {
mut t := table.new_type(table.void_type_idx)
assert t.idx() == table.void_type_idx
t = table.new_type(table.i8_type_idx)
assert t.idx() == table.i8_type_idx
}
fn test_muls() {
mut t := table.new_type(table.void_type_idx)
idx := t.idx()
assert t.nr_muls() == 0
for i in 0 .. 32 {
t = t.set_nr_muls(i)
assert t.nr_muls() == i
}
t = t.set_nr_muls(0)
assert t.nr_muls() == 0
assert t.is_ptr() == false
t = t.to_ptr()
assert t.nr_muls() == 1
assert t.is_ptr() == true
t = t.to_ptr()
assert t.nr_muls() == 2
assert t.is_ptr() == true
t = t.deref()
assert t.nr_muls() == 1
assert t.is_ptr() == true
t = t.deref()
assert t.nr_muls() == 0
assert t.is_ptr() == false
assert t.idx() == idx
}
fn test_flags() {
mut t := table.new_type(table.void_type_idx)
idx := t.idx()
nr_muls := t.nr_muls()
t = t.set_flag(table.TypeFlag.optional)
assert t.has_flag(table.TypeFlag.optional) == true
assert t.has_flag(table.TypeFlag.variadic) == false
assert t.has_flag(table.TypeFlag.generic) == false
t = t.set_flag(table.TypeFlag.variadic)
assert t.has_flag(table.TypeFlag.optional) == true
assert t.has_flag(table.TypeFlag.variadic) == true
assert t.has_flag(table.TypeFlag.generic) == false
t = t.set_flag(table.TypeFlag.generic)
assert t.has_flag(table.TypeFlag.optional) == true
assert t.has_flag(table.TypeFlag.variadic) == true
assert t.has_flag(table.TypeFlag.generic) == true
assert t.idx() == idx
assert t.nr_muls() == nr_muls
t = t.clear_flag(table.TypeFlag.optional)
assert t.has_flag(table.TypeFlag.optional) == false
assert t.has_flag(table.TypeFlag.variadic) == true
assert t.has_flag(table.TypeFlag.generic) == true
t = t.clear_flag(table.TypeFlag.variadic)
assert t.has_flag(table.TypeFlag.optional) == false
assert t.has_flag(table.TypeFlag.variadic) == false
assert t.has_flag(table.TypeFlag.generic) == true
t = t.clear_flag(table.TypeFlag.generic)
assert t.has_flag(table.TypeFlag.optional) == false
assert t.has_flag(table.TypeFlag.variadic) == false
assert t.has_flag(table.TypeFlag.generic) == false
assert t.idx() == idx
assert t.nr_muls() == nr_muls
}
fn test_derive() {
mut t := table.new_type(table.i8_type_idx)
t = t.set_flag(table.TypeFlag.generic)
t = t.set_flag(table.TypeFlag.variadic)
t = t.set_nr_muls(10)
mut t2 := table.new_type(table.i16_type_idx)
t2 = t2.derive(t)
assert t2.has_flag(table.TypeFlag.optional) == false
assert t2.has_flag(table.TypeFlag.variadic) == true
assert t2.has_flag(table.TypeFlag.generic) == true
assert t2.nr_muls() == 10
}

View File

@ -16,7 +16,7 @@ fn get_foo() Foo {
}
/*
// TODO: Fix this. It 'works' only with tcc, but is not stable.
// TODO: Fix this. It 'works' only with tcc, but is not sast.
fn test_ref_fn_arg() {
process_foo(get_foo())
println(3434)

View File

@ -18,7 +18,7 @@ fn (p Point) draw() string {
}
// Note: this helper function forced the compiler to generate an
// interface dispatch table. Now, it should not be needed anymore,
// interface dispatch ast. Now, it should not be needed anymore,
// but it is better to test it too, to prevent future interface regressions.
fn (x Point) tointerface() Drawable {
return x

View File

@ -458,7 +458,7 @@ pub fn (kind Kind) is_infix() bool {
.right_shift, .arrow]
}
// Pass table.builtin_type_names
// Pass ast.builtin_type_names
// Note: can't import table here due to circular module dependency
pub fn (tok &Token) can_start_type(builtin_type_names []string) bool {
match tok.kind {