mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
This commit is contained in:
parent
1d80cb9157
commit
667f65bb5f
34 changed files with 138 additions and 86 deletions
|
@ -131,7 +131,7 @@ fn json(file string) string {
|
|||
pref: pref_
|
||||
}
|
||||
// parse file with comment
|
||||
ast_file := parser.parse_file(file, t.table, .parse_comments, t.pref)
|
||||
ast_file := parser.parse_file(file, mut t.table, .parse_comments, t.pref)
|
||||
t.root = t.ast_file(ast_file)
|
||||
// generate the ast string
|
||||
s := json_print(t.root)
|
||||
|
@ -140,10 +140,10 @@ fn json(file string) string {
|
|||
|
||||
// the ast tree
|
||||
struct Tree {
|
||||
table &ast.Table = unsafe { nil }
|
||||
pref &pref.Preferences = unsafe { nil }
|
||||
pref &pref.Preferences = unsafe { nil }
|
||||
mut:
|
||||
root Node // the root of tree
|
||||
table &ast.Table = unsafe { nil }
|
||||
root Node // the root of tree
|
||||
}
|
||||
|
||||
// tree node
|
||||
|
|
|
@ -160,10 +160,10 @@ fn (foptions &FormatOptions) vlog(msg string) {
|
|||
|
||||
fn (foptions &FormatOptions) format_file(file string) {
|
||||
foptions.vlog('vfmt2 running fmt.fmt over file: ${file}')
|
||||
prefs, table := setup_preferences_and_table()
|
||||
file_ast := parser.parse_file(file, table, .parse_comments, prefs)
|
||||
prefs, mut table := setup_preferences_and_table()
|
||||
file_ast := parser.parse_file(file, mut table, .parse_comments, prefs)
|
||||
// checker.new_checker(table, prefs).check(file_ast)
|
||||
formatted_content := fmt.fmt(file_ast, table, prefs, foptions.is_debug)
|
||||
formatted_content := fmt.fmt(file_ast, mut table, prefs, foptions.is_debug)
|
||||
file_name := os.file_name(file)
|
||||
ulid := rand.ulid()
|
||||
vfmt_output_path := os.join_path(vtmp_folder, 'vfmt_${ulid}_${file_name}')
|
||||
|
@ -174,11 +174,13 @@ fn (foptions &FormatOptions) format_file(file string) {
|
|||
|
||||
fn (foptions &FormatOptions) format_pipe() {
|
||||
foptions.vlog('vfmt2 running fmt.fmt over stdin')
|
||||
prefs, table := setup_preferences_and_table()
|
||||
prefs, mut table := setup_preferences_and_table()
|
||||
input_text := os.get_raw_lines_joined()
|
||||
file_ast := parser.parse_text(input_text, '', table, .parse_comments, prefs)
|
||||
file_ast := parser.parse_text(input_text, '', mut table, .parse_comments, prefs)
|
||||
// checker.new_checker(table, prefs).check(file_ast)
|
||||
formatted_content := fmt.fmt(file_ast, table, prefs, foptions.is_debug, source_text: input_text)
|
||||
formatted_content := fmt.fmt(file_ast, mut table, prefs, foptions.is_debug,
|
||||
source_text: input_text
|
||||
)
|
||||
print(formatted_content)
|
||||
flush_stdout()
|
||||
foptions.vlog('fmt.fmt worked and ${formatted_content.len} bytes were written to stdout.')
|
||||
|
|
|
@ -56,7 +56,8 @@ fn main() {
|
|||
time.sleep(ms * time.millisecond)
|
||||
exit(ecode_timeout)
|
||||
}(context.timeout_ms)
|
||||
_ := parser.parse_text(source, context.path, context.table, .skip_comments, context.pref)
|
||||
_ := parser.parse_text(source, context.path, mut context.table, .skip_comments,
|
||||
context.pref)
|
||||
context.log('> worker ${pid:5} finished parsing ${context.path}')
|
||||
exit(0)
|
||||
} else {
|
||||
|
|
|
@ -103,9 +103,9 @@ fn (mut vt Vet) vet_file(path string) {
|
|||
mut prefs := pref.new_preferences()
|
||||
prefs.is_vet = true
|
||||
prefs.is_vsh = path.ends_with('.vsh')
|
||||
table := ast.new_table()
|
||||
mut table := ast.new_table()
|
||||
vt.vprintln("vetting file '${path}'...")
|
||||
_, errors, notices := parser.parse_vet_file(path, table, prefs)
|
||||
_, errors, notices := parser.parse_vet_file(path, mut table, prefs)
|
||||
// Transfer errors from scanner and parser
|
||||
vt.errors << errors
|
||||
vt.notices << notices
|
||||
|
|
|
@ -4943,7 +4943,7 @@ struct MyStruct {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
m := MyStruct{}
|
||||
mut m := MyStruct{}
|
||||
mut r := RefStruct{
|
||||
r: &m
|
||||
}
|
||||
|
@ -5046,7 +5046,7 @@ fn use_stack() {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
m := MyStruct{}
|
||||
mut m := MyStruct{}
|
||||
mut r := RefStruct{
|
||||
r: &m
|
||||
}
|
||||
|
|
|
@ -35,9 +35,9 @@ fn test_type_size() {
|
|||
mut b := builder.new_builder(pref_)
|
||||
mut files := b.get_builtin_files()
|
||||
b.set_module_lookup_paths()
|
||||
parser.parse_files(files, b.table, b.pref)
|
||||
parser.parse_files(files, mut b.table, b.pref)
|
||||
b.parse_imports()
|
||||
parser.parse_file(@FILE, b.table, .parse_comments, b.pref)
|
||||
parser.parse_file(@FILE, mut b.table, .parse_comments, b.pref)
|
||||
|
||||
mut t := b.table
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ import v.parser
|
|||
import v.pref
|
||||
|
||||
fn parse_text(text string) &ast.File {
|
||||
tbl := ast.new_table()
|
||||
mut tbl := ast.new_table()
|
||||
prefs := pref.new_preferences()
|
||||
return parser.parse_text(text, '', tbl, .skip_comments, prefs)
|
||||
return parser.parse_text(text, '', mut tbl, .skip_comments, prefs)
|
||||
}
|
||||
|
||||
struct NodeByOffset {
|
||||
|
|
|
@ -89,8 +89,8 @@ pub fn new_builder(pref_ &pref.Preferences) Builder {
|
|||
}
|
||||
|
||||
pub fn (mut b Builder) interpret_text(code string, v_files []string) ! {
|
||||
b.parsed_files = parser.parse_files(v_files, b.table, b.pref)
|
||||
b.parsed_files << parser.parse_text(code, '', b.table, .skip_comments, b.pref)
|
||||
b.parsed_files = parser.parse_files(v_files, mut b.table, b.pref)
|
||||
b.parsed_files << parser.parse_text(code, '', mut b.table, .skip_comments, b.pref)
|
||||
b.parse_imports()
|
||||
|
||||
if b.pref.only_check_syntax {
|
||||
|
@ -109,7 +109,7 @@ pub fn (mut b Builder) front_stages(v_files []string) ! {
|
|||
util.timing_start('PARSE')
|
||||
|
||||
util.timing_start('Builder.front_stages.parse_files')
|
||||
b.parsed_files = parser.parse_files(v_files, b.table, b.pref)
|
||||
b.parsed_files = parser.parse_files(v_files, mut b.table, b.pref)
|
||||
timers.show('Builder.front_stages.parse_files')
|
||||
|
||||
b.parse_imports()
|
||||
|
@ -144,7 +144,7 @@ pub fn (mut b Builder) middle_stages() ! {
|
|||
//
|
||||
b.table.complete_interface_check()
|
||||
if b.pref.skip_unused {
|
||||
markused.mark_used(mut b.table, b.pref, b.parsed_files)
|
||||
markused.mark_used(mut b.table, mut b.pref, b.parsed_files)
|
||||
}
|
||||
if b.pref.show_callgraph {
|
||||
callgraph.show(mut b.table, b.pref, b.parsed_files)
|
||||
|
@ -222,7 +222,7 @@ pub fn (mut b Builder) parse_imports() {
|
|||
}
|
||||
// eprintln('>> ast_file.path: $ast_file.path , done: $done_imports, `import $mod` => $v_files')
|
||||
// Add all imports referenced by these libs
|
||||
parsed_files := parser.parse_files(v_files, b.table, b.pref)
|
||||
parsed_files := parser.parse_files(v_files, mut b.table, b.pref)
|
||||
for file in parsed_files {
|
||||
mut name := file.mod.name
|
||||
if name == '' {
|
||||
|
|
|
@ -73,7 +73,7 @@ pub fn gen_c(mut b builder.Builder, v_files []string) string {
|
|||
}
|
||||
|
||||
util.timing_start('C GEN')
|
||||
header, res, out_str, out_fn_start_pos := c.gen(b.parsed_files, b.table, b.pref)
|
||||
header, res, out_str, out_fn_start_pos := c.gen(b.parsed_files, mut b.table, b.pref)
|
||||
util.timing_measure('C GEN')
|
||||
|
||||
if b.pref.parallel_cc {
|
||||
|
|
|
@ -36,6 +36,6 @@ pub fn build_golang(mut b builder.Builder, v_files []string, out_file string) {
|
|||
}
|
||||
b.front_and_middle_stages(nvf) or { return }
|
||||
util.timing_start('Golang GEN')
|
||||
b.stats_lines, b.stats_bytes = golang.gen(b.parsed_files, b.table, out_file, b.pref)
|
||||
b.stats_lines, b.stats_bytes = golang.gen(b.parsed_files, mut b.table, out_file, b.pref)
|
||||
util.timing_measure('Golang GEN')
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ pub fn build_js(mut b builder.Builder, v_files []string, out_file string) {
|
|||
pub fn gen_js(mut b builder.Builder, v_files []string) string {
|
||||
b.front_and_middle_stages(v_files) or { return '' }
|
||||
util.timing_start('JS GEN')
|
||||
res := js.gen(b.parsed_files, b.table, b.pref)
|
||||
res := js.gen(b.parsed_files, mut b.table, b.pref)
|
||||
util.timing_measure('JS GEN')
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -58,6 +58,6 @@ pub fn build_native(mut b builder.Builder, v_files []string, out_file string) {
|
|||
eprintln('Error: Only arm64 and amd64 are supported by V')
|
||||
}
|
||||
}
|
||||
b.stats_lines, b.stats_bytes = native.gen(b.parsed_files, b.table, out_file, b.pref)
|
||||
b.stats_lines, b.stats_bytes = native.gen(b.parsed_files, mut b.table, out_file, b.pref)
|
||||
util.timing_measure('Native GEN')
|
||||
}
|
||||
|
|
|
@ -31,6 +31,6 @@ pub fn compile_wasm(mut b builder.Builder) {
|
|||
pub fn build_wasm(mut b builder.Builder, v_files []string, out_file string) {
|
||||
b.front_and_middle_stages(v_files) or { return }
|
||||
util.timing_start('WebAssembly GEN')
|
||||
wasm.gen(b.parsed_files, b.table, out_file, b.pref)
|
||||
wasm.gen(b.parsed_files, mut b.table, out_file, b.pref)
|
||||
util.timing_measure('WebAssembly GEN')
|
||||
}
|
||||
|
|
|
@ -223,11 +223,31 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if mut left is ast.Ident && mut right is ast.Ident {
|
||||
if !c.inside_unsafe && left_type.is_ptr() && left.is_mut() && right_type.is_ptr()
|
||||
&& !right.is_mut() {
|
||||
if left is ast.Ident && left.is_mut() && !c.inside_unsafe {
|
||||
if left_type.is_ptr() && mut right is ast.Ident && !right.is_mut()
|
||||
&& right_type.is_ptr() {
|
||||
c.error('`${right.name}` is immutable, cannot have a mutable reference to an immutable object',
|
||||
right.pos)
|
||||
} else if mut right is ast.StructInit {
|
||||
typ_sym := c.table.sym(right.typ)
|
||||
for init_field in right.init_fields {
|
||||
if field_info := c.table.find_field_with_embeds(typ_sym, init_field.name) {
|
||||
if field_info.is_mut {
|
||||
if init_field.expr is ast.Ident && !init_field.expr.is_mut()
|
||||
&& init_field.typ.is_ptr() {
|
||||
c.note('`${init_field.expr.name}` is immutable, cannot have a mutable reference to an immutable object',
|
||||
init_field.pos)
|
||||
} else if init_field.expr is ast.PrefixExpr {
|
||||
if init_field.expr.op == .amp
|
||||
&& init_field.expr.right is ast.Ident
|
||||
&& !init_field.expr.right.is_mut() {
|
||||
c.note('`${init_field.expr.right.name}` is immutable, cannot have a mutable reference to an immutable object',
|
||||
init_field.expr.right.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
vlib/v/checker/tests/assign_immutable_reference_struct_field_err.vv:13:29: notice: `parent` is immutable, cannot have a mutable reference to an immutable object
|
||||
11 | }
|
||||
12 | // taking a reference of `parent` and putting it under a `mut:` struct field
|
||||
13 | mut child := Tree{parent: &parent}
|
||||
| ~~~~~~
|
||||
14 |
|
||||
15 | // unwrap the reference of `parent`, but declare it as `mut`
|
|
@ -0,0 +1,19 @@
|
|||
struct Tree {
|
||||
mut:
|
||||
garbage int
|
||||
parent ?&Tree
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// `parent` is not declared as mutable!
|
||||
parent := Tree{
|
||||
garbage: 11
|
||||
}
|
||||
// taking a reference of `parent` and putting it under a `mut:` struct field
|
||||
mut child := Tree{parent: &parent}
|
||||
|
||||
// unwrap the reference of `parent`, but declare it as `mut`
|
||||
mut inner_parent := child.parent?
|
||||
inner_parent.garbage = 777 // !we can mutate `parent` freely!
|
||||
println(parent.garbage) // 777
|
||||
}
|
|
@ -453,7 +453,7 @@ pub fn (mut d Doc) generate() ! {
|
|||
if i == 0 {
|
||||
d.parent_mod_name = get_parent_mod(d.base_path) or { '' }
|
||||
}
|
||||
file_asts << parser.parse_file(file_path, d.table, comments_mode, d.prefs)
|
||||
file_asts << parser.parse_file(file_path, mut d.table, comments_mode, d.prefs)
|
||||
}
|
||||
return d.file_asts(mut file_asts)
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ fn get_parent_mod(input_dir string) !string {
|
|||
}
|
||||
return error('No V files found.')
|
||||
}
|
||||
tbl := ast.new_table()
|
||||
file_ast := parser.parse_file(v_files[0], tbl, .skip_comments, prefs)
|
||||
mut tbl := ast.new_table()
|
||||
file_ast := parser.parse_file(v_files[0], mut tbl, .skip_comments, prefs)
|
||||
if file_ast.mod.name == 'main' {
|
||||
return ''
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@ const max_len = [0, 35, 60, 85, 93, 100]
|
|||
|
||||
@[minify]
|
||||
pub struct Fmt {
|
||||
pref &pref.Preferences = unsafe { nil }
|
||||
pub mut:
|
||||
file ast.File
|
||||
table &ast.Table = unsafe { nil }
|
||||
pref &pref.Preferences = unsafe { nil }
|
||||
table &ast.Table = unsafe { nil }
|
||||
is_debug bool
|
||||
out strings.Builder
|
||||
out_imports strings.Builder
|
||||
|
@ -62,7 +62,7 @@ pub struct FmtOptions {
|
|||
source_text string
|
||||
}
|
||||
|
||||
pub fn fmt(file ast.File, table &ast.Table, pref_ &pref.Preferences, is_debug bool, options FmtOptions) string {
|
||||
pub fn fmt(file ast.File, mut table ast.Table, pref_ &pref.Preferences, is_debug bool, options FmtOptions) string {
|
||||
mut f := Fmt{
|
||||
file: file
|
||||
table: table
|
||||
|
|
|
@ -26,9 +26,9 @@ fn test_bin2v_formatting() {
|
|||
}
|
||||
prepare_bin2v_file()
|
||||
|
||||
table := ast.new_table()
|
||||
file_ast := parser.parse_file(b2v_keep_path, table, .parse_comments, fpref)
|
||||
result_ocontent := fmt.fmt(file_ast, table, fpref, false)
|
||||
mut table := ast.new_table()
|
||||
file_ast := parser.parse_file(b2v_keep_path, mut table, .parse_comments, fpref)
|
||||
result_ocontent := fmt.fmt(file_ast, mut table, fpref, false)
|
||||
eprintln('> the file ${b2v_keep_path} can be formatted.')
|
||||
expected_ocontent := os.read_file(b2v_keep_path)!
|
||||
if expected_ocontent != result_ocontent {
|
||||
|
|
|
@ -50,9 +50,9 @@ fn test_fmt() {
|
|||
eprintln(fmt_bench.step_message_fail('cannot read from ${vrelpath}'))
|
||||
continue
|
||||
}
|
||||
table := ast.new_table()
|
||||
file_ast := parser.parse_file(ipath, table, .parse_comments, fpref)
|
||||
result_ocontent := fmt.fmt(file_ast, table, fpref, false)
|
||||
mut table := ast.new_table()
|
||||
file_ast := parser.parse_file(ipath, mut table, .parse_comments, fpref)
|
||||
result_ocontent := fmt.fmt(file_ast, mut table, fpref, false)
|
||||
if expected_ocontent != result_ocontent {
|
||||
fmt_bench.fail()
|
||||
eprintln(fmt_bench.step_message_fail('file ${vrelpath} after formatting, does not look as expected.'))
|
||||
|
|
|
@ -46,9 +46,9 @@ fn test_fmt() {
|
|||
eprintln(fmt_bench.step_message_fail('cannot read from ${opath}'))
|
||||
continue
|
||||
}
|
||||
table := ast.new_table()
|
||||
file_ast := parser.parse_file(ipath, table, .parse_comments, fpref)
|
||||
result_ocontent := fmt.fmt(file_ast, table, fpref, false)
|
||||
mut table := ast.new_table()
|
||||
file_ast := parser.parse_file(ipath, mut table, .parse_comments, fpref)
|
||||
result_ocontent := fmt.fmt(file_ast, mut table, fpref, false)
|
||||
if expected_ocontent != result_ocontent {
|
||||
fmt_bench.fail()
|
||||
eprintln(fmt_bench.step_message_fail('file ${ipath} after formatting, does not look as expected.'))
|
||||
|
|
|
@ -44,9 +44,9 @@ fn test_vlib_fmt() {
|
|||
eprintln(fmt_bench.step_message_fail('cannot read from ${opath}'))
|
||||
continue
|
||||
}
|
||||
table := ast.new_table()
|
||||
file_ast := parser.parse_file(ipath, table, .parse_comments, fpref)
|
||||
result_ocontent := fmt.fmt(file_ast, table, fpref, false)
|
||||
mut table := ast.new_table()
|
||||
file_ast := parser.parse_file(ipath, mut table, .parse_comments, fpref)
|
||||
result_ocontent := fmt.fmt(file_ast, mut table, fpref, false)
|
||||
if expected_ocontent != result_ocontent {
|
||||
fmt_bench.fail()
|
||||
eprintln(fmt_bench.step_message_fail('file ${ipath} after formatting, does not look as expected.'))
|
||||
|
|
|
@ -261,7 +261,7 @@ struct GlobalConstDef {
|
|||
is_precomputed bool // can be declared as a const in C: primitive, and a simple definition
|
||||
}
|
||||
|
||||
pub fn gen(files []&ast.File, table &ast.Table, pref_ &pref.Preferences) (string, string, string, []int) {
|
||||
pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (string, string, string, []int) {
|
||||
mut module_built := ''
|
||||
if pref_.build_mode == .build_module {
|
||||
for file in files {
|
||||
|
@ -313,7 +313,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref_ &pref.Preferences) (string
|
|||
module_built: module_built
|
||||
timers_should_print: timers_should_print
|
||||
timers: util.new_timers(should_print: timers_should_print, label: 'global_cgen')
|
||||
inner_loop: &ast.empty_stmt
|
||||
inner_loop: unsafe { &ast.empty_stmt }
|
||||
field_data_type: ast.Type(table.find_type_idx('FieldData'))
|
||||
enum_data_type: ast.Type(table.find_type_idx('EnumData'))
|
||||
is_cc_msvc: pref_.ccompiler == 'msvc'
|
||||
|
|
|
@ -12,9 +12,9 @@ import os
|
|||
const bs = '\\'
|
||||
|
||||
pub struct Gen {
|
||||
pref &pref.Preferences = unsafe { nil }
|
||||
pub mut:
|
||||
table &ast.Table = unsafe { nil }
|
||||
pref &pref.Preferences = unsafe { nil }
|
||||
table &ast.Table = unsafe { nil }
|
||||
// is_debug bool
|
||||
out strings.Builder
|
||||
out_imports strings.Builder
|
||||
|
@ -45,7 +45,7 @@ pub mut:
|
|||
nlines int
|
||||
}
|
||||
|
||||
pub fn gen(files []&ast.File, table &ast.Table, out_file string, pref_ &pref.Preferences) (int, int) {
|
||||
pub fn gen(files []&ast.File, mut table ast.Table, out_file string, pref_ &pref.Preferences) (int, int) {
|
||||
mut g := Gen{
|
||||
table: table
|
||||
pref: pref_
|
||||
|
|
|
@ -97,7 +97,7 @@ fn (mut g JsGen) write_tests_definitions() {
|
|||
g.definitions.writeln('globalThis.g_test_fails = 0;')
|
||||
}
|
||||
|
||||
pub fn gen(files []&ast.File, table &ast.Table, pref_ &pref.Preferences) string {
|
||||
pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) string {
|
||||
mut g := &JsGen{
|
||||
definitions: strings.new_builder(100)
|
||||
table: table
|
||||
|
|
|
@ -327,7 +327,7 @@ fn get_backend(arch pref.Arch, target_os pref.OS) !CodeGen {
|
|||
return error('unsupported architecture')
|
||||
}
|
||||
|
||||
pub fn gen(files []&ast.File, table &ast.Table, out_name string, pref_ &pref.Preferences) (int, int) {
|
||||
pub fn gen(files []&ast.File, mut table ast.Table, out_name string, pref_ &pref.Preferences) (int, int) {
|
||||
exe_name := if pref_.os == .windows && !out_name.ends_with('.exe') {
|
||||
out_name + '.exe'
|
||||
} else {
|
||||
|
|
|
@ -1283,7 +1283,7 @@ pub fn (mut g Gen) calculate_enum_fields() {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn gen(files []&ast.File, table &ast.Table, out_name string, w_pref &pref.Preferences) {
|
||||
pub fn gen(files []&ast.File, mut table ast.Table, out_name string, w_pref &pref.Preferences) {
|
||||
stack_top := w_pref.wasm_stack_top
|
||||
mut g := &Gen{
|
||||
table: table
|
||||
|
|
|
@ -7,7 +7,7 @@ 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 table ast.Table, pref_ &pref.Preferences, ast_files []&ast.File) {
|
||||
pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&ast.File) {
|
||||
mut all_fns, all_consts, all_globals := all_fn_const_and_global(ast_files)
|
||||
util.timing_start(@METHOD)
|
||||
defer {
|
||||
|
|
|
@ -282,7 +282,7 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
|
|||
// the tmpl inherits all parent scopes. previous functionality was just to
|
||||
// inherit the scope from which the comptime call was made and no parents.
|
||||
// this is much simpler and allows access to globals. can be changed if needed.
|
||||
mut file := parse_comptime(tmpl_path, v_code, p.table, p.pref, p.scope)
|
||||
mut file := parse_comptime(tmpl_path, v_code, mut p.table, p.pref, mut p.scope)
|
||||
file.path = tmpl_path
|
||||
return ast.ComptimeCall{
|
||||
scope: unsafe { nil }
|
||||
|
|
|
@ -116,7 +116,7 @@ pub mut:
|
|||
__global codegen_files = unsafe { []&ast.File{} }
|
||||
|
||||
// for tests
|
||||
pub fn parse_stmt(text string, table &ast.Table, scope &ast.Scope) ast.Stmt {
|
||||
pub fn parse_stmt(text string, mut table ast.Table, mut scope ast.Scope) ast.Stmt {
|
||||
$if trace_parse_stmt ? {
|
||||
eprintln('> ${@MOD}.${@FN} text: ${text}')
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ pub fn parse_stmt(text string, table &ast.Table, scope &ast.Scope) ast.Stmt {
|
|||
return p.stmt(false)
|
||||
}
|
||||
|
||||
pub fn parse_comptime(tmpl_path string, text string, table &ast.Table, pref_ &pref.Preferences, scope &ast.Scope) &ast.File {
|
||||
pub fn parse_comptime(tmpl_path string, text string, mut table ast.Table, pref_ &pref.Preferences, mut scope ast.Scope) &ast.File {
|
||||
$if trace_parse_comptime ? {
|
||||
eprintln('> ${@MOD}.${@FN} text: ${text}')
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ pub fn parse_comptime(tmpl_path string, text string, table &ast.Table, pref_ &pr
|
|||
return res
|
||||
}
|
||||
|
||||
pub fn parse_text(text string, path string, table &ast.Table, comments_mode scanner.CommentsMode, pref_ &pref.Preferences) &ast.File {
|
||||
pub fn parse_text(text string, path string, mut table ast.Table, comments_mode scanner.CommentsMode, pref_ &pref.Preferences) &ast.File {
|
||||
$if trace_parse_text ? {
|
||||
eprintln('> ${@MOD}.${@FN} comments_mode: ${comments_mode:-20} | path: ${path:-20} | text: ${text}')
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ pub fn (mut p Parser) set_path(path string) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsMode, pref_ &pref.Preferences) &ast.File {
|
||||
pub fn parse_file(path string, mut table ast.Table, comments_mode scanner.CommentsMode, pref_ &pref.Preferences) &ast.File {
|
||||
// Note: 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
|
||||
|
@ -258,7 +258,7 @@ pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsM
|
|||
return res
|
||||
}
|
||||
|
||||
pub fn parse_vet_file(path string, table_ &ast.Table, pref_ &pref.Preferences) (&ast.File, []vet.Error, []vet.Error) {
|
||||
pub fn parse_vet_file(path string, mut table_ ast.Table, pref_ &pref.Preferences) (&ast.File, []vet.Error, []vet.Error) {
|
||||
$if trace_parse_vet_file ? {
|
||||
eprintln('> ${@MOD}.${@FN} path: ${path}')
|
||||
}
|
||||
|
@ -367,7 +367,8 @@ pub fn (mut p Parser) parse() &ast.File {
|
|||
// codegen
|
||||
if p.codegen_text.len > 0 && !p.pref.is_fmt {
|
||||
ptext := 'module ' + p.mod.all_after_last('.') + '\n' + p.codegen_text
|
||||
codegen_files << parse_text(ptext, p.file_name, p.table, p.comments_mode, p.pref)
|
||||
codegen_files << parse_text(ptext, p.file_name, mut p.table, p.comments_mode,
|
||||
p.pref)
|
||||
}
|
||||
|
||||
return &ast.File{
|
||||
|
@ -427,7 +428,7 @@ fn (mut q Queue) run() {
|
|||
}
|
||||
}
|
||||
*/
|
||||
pub fn parse_files(paths []string, table &ast.Table, pref_ &pref.Preferences) []&ast.File {
|
||||
pub fn parse_files(paths []string, mut table ast.Table, pref_ &pref.Preferences) []&ast.File {
|
||||
mut timers := util.new_timers(should_print: false, label: 'parse_files: ${paths}')
|
||||
$if time_parsing ? {
|
||||
timers.should_print = true
|
||||
|
@ -459,7 +460,7 @@ pub fn parse_files(paths []string, table &ast.Table, pref_ &pref.Preferences) []
|
|||
mut files := []&ast.File{cap: paths.len}
|
||||
for path in paths {
|
||||
timers.start('parse_file ${path}')
|
||||
files << parse_file(path, table, .skip_comments, pref_)
|
||||
files << parse_file(path, mut table, .skip_comments, pref_)
|
||||
timers.show('parse_file ${path}')
|
||||
}
|
||||
if codegen_files.len > 0 {
|
||||
|
|
|
@ -79,9 +79,9 @@ fn main() {
|
|||
ff(8+x)
|
||||
}
|
||||
'
|
||||
table := ast.new_table()
|
||||
mut table := ast.new_table()
|
||||
vpref := &pref.Preferences{}
|
||||
mut prog := parse_text(source_text, '', table, .skip_comments, vpref)
|
||||
mut prog := parse_text(source_text, '', mut table, .skip_comments, vpref)
|
||||
mut checker_ := checker.new_checker(table, vpref)
|
||||
checker_.check(mut prog)
|
||||
}
|
||||
|
@ -93,14 +93,14 @@ fn test_one() {
|
|||
println(@LOCATION)
|
||||
input := ['a := 10', 'b := -a', 'c := 20']
|
||||
expected := 'int a = 10;int b = -a;int c = 20;'
|
||||
table := ast.new_table()
|
||||
mut table := ast.new_table()
|
||||
vpref := &pref.Preferences{}
|
||||
scope := &ast.Scope{
|
||||
mut scope := &ast.Scope{
|
||||
start_pos: 0
|
||||
}
|
||||
mut e := []ast.Stmt{}
|
||||
for line in input {
|
||||
e << parse_stmt(line, table, scope)
|
||||
e << parse_stmt(line, mut table, mut scope)
|
||||
}
|
||||
mut program := &ast.File{
|
||||
stmts: e
|
||||
|
@ -109,7 +109,7 @@ fn test_one() {
|
|||
}
|
||||
mut checker_ := checker.new_checker(table, vpref)
|
||||
checker_.check(mut program)
|
||||
mut res, _, _, _ := c.gen([program], table, vpref)
|
||||
mut res, _, _, _ := c.gen([program], mut table, vpref)
|
||||
res = res.replace('\n', '').trim_space().after('#endif')
|
||||
println(res)
|
||||
ok := expected == res
|
||||
|
@ -136,15 +136,15 @@ 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 := ast.new_table()
|
||||
mut table := ast.new_table()
|
||||
vpref := &pref.Preferences{}
|
||||
mut chk := checker.new_checker(table, vpref)
|
||||
scope := &ast.Scope{
|
||||
mut scope := &ast.Scope{
|
||||
start_pos: 0
|
||||
}
|
||||
for s in input {
|
||||
println('\n\nst="${s}"')
|
||||
e << parse_stmt(s, table, scope)
|
||||
e << parse_stmt(s, mut table, mut scope)
|
||||
}
|
||||
mut program := &ast.File{
|
||||
stmts: e
|
||||
|
@ -152,7 +152,7 @@ fn test_parse_expr() {
|
|||
global_scope: scope
|
||||
}
|
||||
chk.check(mut program)
|
||||
mut res, _, _, _ := c.gen([program], table, vpref)
|
||||
mut res, _, _, _ := c.gen([program], mut table, vpref)
|
||||
res = res.after('#endif')
|
||||
println('========')
|
||||
println(res)
|
||||
|
@ -185,13 +185,13 @@ fn test_num_literals() {
|
|||
'c := -12.',
|
||||
'd := -a',
|
||||
]
|
||||
table := ast.new_table()
|
||||
mut table := ast.new_table()
|
||||
mut scope := &ast.Scope{
|
||||
start_pos: 0
|
||||
}
|
||||
mut rhs_types := []string{}
|
||||
for input in inputs {
|
||||
stmt := parse_stmt(input, table, scope)
|
||||
stmt := parse_stmt(input, mut table, mut scope)
|
||||
r := (stmt as ast.AssignStmt).right
|
||||
match r[0] {
|
||||
ast.IntegerLiteral { rhs_types << 'int literal' }
|
||||
|
@ -297,8 +297,8 @@ fn parse(output_mode pref.OutputMode) ! {
|
|||
pref_.output_mode = output_mode
|
||||
for idx, f in files {
|
||||
// eprintln('> parsing in mode: ${output_mode}, ${idx+1:5}/${files.len} $f ...')
|
||||
table := ast.new_table()
|
||||
p := parse_file(f, table, .parse_comments, pref_)
|
||||
mut table := ast.new_table()
|
||||
p := parse_file(f, mut table, .parse_comments, pref_)
|
||||
assert !isnil(p), 'failed to parse `${f}` in mode: ${output_mode}'
|
||||
assert p.errors.len == 0, 'file ${f} should have been parsed with 0 errors'
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ fn test_main() {
|
|||
nr_elems: 11
|
||||
}
|
||||
mut child := Tree{
|
||||
parent: &parent
|
||||
parent: unsafe { &parent }
|
||||
}
|
||||
child.set_nr_elems('Buzz', 123)
|
||||
assert child.parent or { return }.nr_elems == 123
|
||||
|
|
|
@ -3,11 +3,13 @@ import v.parser
|
|||
import v.pref
|
||||
|
||||
fn test_parser_map_type() {
|
||||
result := parser.parse_text('a := map[*Node]bool', '', ast.new_table(), .parse_comments,
|
||||
&pref.Preferences{
|
||||
mut table := ast.new_table()
|
||||
pref_ := pref.Preferences{
|
||||
output_mode: .silent
|
||||
is_fmt: true
|
||||
})
|
||||
}
|
||||
result := parser.parse_text('a := map[*Node]bool', '', mut table, .parse_comments,
|
||||
pref_)
|
||||
println(result)
|
||||
assert true
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue