all: a massive merge of ast and table modules
parent
043f6420f7
commit
7385f8e56b
|
@ -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 (
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/',
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
346
vlib/v/ast/ast.v
346
vlib/v/ast/ast.v
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())'
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// import v.table
|
||||
// import v.ast
|
||||
import v.doc
|
||||
|
||||
// fn test_generate_with_pos() {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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('&')
|
||||
|
|
|
@ -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 := ''
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {')
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(')
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
|
|
|
@ -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_ {
|
||||
|
|
|
@ -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 {}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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('*/')
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -69,4 +69,4 @@ function vEq(a, b) {
|
|||
return a!==a && b!==b;
|
||||
};
|
||||
"
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()!'
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module main
|
||||
|
||||
fn main() {
|
||||
println("hello world")
|
||||
println('hello world')
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,7 +6,6 @@ module parser
|
|||
import os
|
||||
import v.ast
|
||||
import v.pref
|
||||
import v.table
|
||||
import v.token
|
||||
|
||||
const (
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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' +
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue