1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

all: rollback to old interpolation (step 3) (#16380)

This commit is contained in:
shove 2022-11-10 20:05:34 +08:00 committed by GitHub
parent bbae7a705f
commit 26d643fc5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 91 additions and 108 deletions

View File

@ -169,10 +169,10 @@ pub fn (mut ws WebhookServer) genhook() {
ws.gen_vc.generate() ws.gen_vc.generate()
// error in generate // error in generate
if ws.gen_vc.gen_error { if ws.gen_vc.gen_error {
ws.json('{ status: "failed" }') ws.json('{status: "failed"}')
return return
} }
ws.json('{ status: "ok" }') ws.json('{status: "ok"}')
} }
pub fn (ws &WebhookServer) reset() { pub fn (ws &WebhookServer) reset() {

View File

@ -112,10 +112,10 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
mut command_for_selfbuilding := '' mut command_for_selfbuilding := ''
if 'windows' == os.user_os() { if 'windows' == os.user_os() {
command_for_building_v_from_c_source = '$vgit_context.cc -std=c99 -I ./thirdparty/stdatomic/win -municode -w -o cv.exe "$vgit_context.path_vc/v_win.c" ' command_for_building_v_from_c_source = '$vgit_context.cc -std=c99 -I ./thirdparty/stdatomic/win -municode -w -o cv.exe "$vgit_context.path_vc/v_win.c" '
command_for_selfbuilding = './cv.exe -o $vgit_context.vexename \{SOURCE}' command_for_selfbuilding = './cv.exe -o $vgit_context.vexename {SOURCE}'
} else { } else {
command_for_building_v_from_c_source = '$vgit_context.cc -std=gnu11 -I ./thirdparty/stdatomic/nix -w -o cv "$vgit_context.path_vc/v.c" -lm -lpthread' command_for_building_v_from_c_source = '$vgit_context.cc -std=gnu11 -I ./thirdparty/stdatomic/nix -w -o cv "$vgit_context.path_vc/v.c" -lm -lpthread'
command_for_selfbuilding = './cv -o $vgit_context.vexename \{SOURCE}' command_for_selfbuilding = './cv -o $vgit_context.vexename {SOURCE}'
} }
scripting.chdir(vgit_context.workdir) scripting.chdir(vgit_context.workdir)
clone_or_pull(vgit_context.v_repo_url, vgit_context.path_v) clone_or_pull(vgit_context.v_repo_url, vgit_context.path_v)
@ -146,7 +146,7 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
scripting.run('make fresh_tcc') scripting.run('make fresh_tcc')
} }
scripting.run(command_for_building_v_from_c_source) scripting.run(command_for_building_v_from_c_source)
build_cmd := command_for_selfbuilding.replace('\{SOURCE}', vgit_context.vvlocation) build_cmd := command_for_selfbuilding.replace('{SOURCE}', vgit_context.vvlocation)
scripting.run(build_cmd) scripting.run(build_cmd)
// At this point, there exists a file vgit_context.vexepath // At this point, there exists a file vgit_context.vexepath
// which should be a valid working V executable. // which should be a valid working V executable.

View File

@ -165,8 +165,8 @@ fn (mut context Context) parse_options() ! {
context.verbose = fp.bool('verbose', `v`, false, 'Be more verbose.') context.verbose = fp.bool('verbose', `v`, false, 'Be more verbose.')
context.fail_on_maxtime = fp.int('max_time', `m`, max_time, 'Fail with exit code 2, when first cmd takes above M milliseconds (regression).') context.fail_on_maxtime = fp.int('max_time', `m`, max_time, 'Fail with exit code 2, when first cmd takes above M milliseconds (regression).')
context.fail_on_regress_percent = fp.int('fail_percent', `f`, max_fail_percent, 'Fail with exit code 3, when first cmd is X% slower than the rest (regression).') context.fail_on_regress_percent = fp.int('fail_percent', `f`, max_fail_percent, 'Fail with exit code 3, when first cmd is X% slower than the rest (regression).')
context.cmd_template = fp.string('template', `t`, r'{T}', r'Command template. {T} will be substituted with the current command.') context.cmd_template = fp.string('template', `t`, '{T}', 'Command template. {T} will be substituted with the current command.')
cmd_params := fp.string_multi('parameter', `p`, r'A parameter substitution list. `{p}=val1,val2,val2` means that {p} in the template, will be substituted with each of val1, val2, val3.') cmd_params := fp.string_multi('parameter', `p`, 'A parameter substitution list. `{p}=val1,val2,val2` means that {p} in the template, will be substituted with each of val1, val2, val3.')
context.nmins = fp.int('nmins', `i`, 0, 'Ignore the BOTTOM X results (minimum execution time). Makes the results more robust to performance flukes.') context.nmins = fp.int('nmins', `i`, 0, 'Ignore the BOTTOM X results (minimum execution time). Makes the results more robust to performance flukes.')
context.nmaxs = fp.int('nmaxs', `a`, 1, 'Ignore the TOP X results (maximum execution time). Makes the results more robust to performance flukes.') context.nmaxs = fp.int('nmaxs', `a`, 1, 'Ignore the TOP X results (maximum execution time). Makes the results more robust to performance flukes.')
for p in cmd_params { for p in cmd_params {
@ -212,7 +212,7 @@ fn (mut context Context) clear_line() {
fn (mut context Context) expand_all_commands(commands []string) []string { fn (mut context Context) expand_all_commands(commands []string) []string {
mut all_commands := []string{} mut all_commands := []string{}
for cmd in commands { for cmd in commands {
maincmd := context.cmd_template.replace(r'{T}', cmd) maincmd := context.cmd_template.replace('{T}', cmd)
mut substituted_commands := []string{} mut substituted_commands := []string{}
substituted_commands << maincmd substituted_commands << maincmd
for paramk, paramlist in context.cmd_params { for paramk, paramlist in context.cmd_params {

View File

@ -141,7 +141,7 @@ $vdoctor_output
**What did you do?** **What did you do?**
`v -g -o vdbg cmd/v && vdbg $file_path` `v -g -o vdbg cmd/v && vdbg $file_path`
\{file_content} {file_content}
**What did you expect to see?** **What did you expect to see?**
@ -150,11 +150,11 @@ $expected_result
**What did you see instead?** **What did you see instead?**
``` ```
$build_output```' $build_output```'
mut encoded_body := urllib.query_escape(raw_body.replace_once(r'{file_content}', '```v\n$file_content\n```')) mut encoded_body := urllib.query_escape(raw_body.replace_once('{file_content}', '```v\n$file_content\n```'))
mut generated_uri := 'https://github.com/vlang/v/issues/new?labels=Bug&body=$encoded_body' mut generated_uri := 'https://github.com/vlang/v/issues/new?labels=Bug&body=$encoded_body'
if generated_uri.len > 8192 { if generated_uri.len > 8192 {
// GitHub doesn't support URLs longer than 8192 characters // GitHub doesn't support URLs longer than 8192 characters
encoded_body = urllib.query_escape(raw_body.replace_once(r'{file_content}', 'See attached file `$file_path`')) encoded_body = urllib.query_escape(raw_body.replace_once('{file_content}', 'See attached file `$file_path`'))
generated_uri = 'https://github.com/vlang/v/issues/new?labels=Bug&body=$encoded_body' generated_uri = 'https://github.com/vlang/v/issues/new?labels=Bug&body=$encoded_body'
println('Your file is too big to be submitted. Head over to the following URL and attach your file.') println('Your file is too big to be submitted. Head over to the following URL and attach your file.')
println(generated_uri) println(generated_uri)

View File

@ -72,7 +72,7 @@ fn (mut a App) collect_info() {
os_details += ' (WSL)' os_details += ' (WSL)'
} }
// From https://unix.stackexchange.com/a/14346 // From https://unix.stackexchange.com/a/14346
awk_cmd := '[ "$(awk \'\$5=="/" { print \$1 }\' </proc/1/mountinfo)" != "$(awk \'\$5=="/" { print \$1 }\' </proc/$$/mountinfo)" ] ; echo \$?' awk_cmd := '[ "$(awk \'\$5=="/" {print \$1}\' </proc/1/mountinfo)" != "$(awk \'\$5=="/" {print \$1}\' </proc/$$/mountinfo)" ] ; echo \$?'
if a.cmd(command: awk_cmd) == '0' { if a.cmd(command: awk_cmd) == '0' {
os_details += ' (chroot)' os_details += ' (chroot)'
} }

View File

@ -29,7 +29,7 @@ const (
'hg': 'hg clone' 'hg': 'hg clone'
} }
supported_vcs_outdated_steps = { supported_vcs_outdated_steps = {
'git': ['git fetch', 'git rev-parse @', 'git rev-parse @\{u}'] 'git': ['git fetch', 'git rev-parse @', 'git rev-parse @{u}']
'hg': ['hg incoming'] 'hg': ['hg incoming']
} }
supported_vcs_version_cmds = { supported_vcs_version_cmds = {

View File

@ -516,7 +516,7 @@ fn test_struct_print() {
} }
a.b << b a.b << b
a.b << b a.b << b
assert a.str() == '\{Test [{1 2}, {1 2}]}' assert a.str() == '{Test [{1 2}, {1 2}]}'
assert b.str() == '{1 2}' assert b.str() == '{1 2}'
assert a.b.str() == '[{1 2}, {1 2}]' assert a.b.str() == '[{1 2}, {1 2}]'
} }

View File

@ -504,7 +504,7 @@ fn test_struct_print() {
} }
a.b << b a.b << b
a.b << b a.b << b
assert a.str() == r'{Test [{1 2}, {1 2}]}' assert a.str() == '{Test [{1 2}, {1 2}]}'
assert b.str() == '{1 2}' assert b.str() == '{1 2}'
assert a.b.str() == '[{1 2}, {1 2}]' assert a.b.str() == '[{1 2}, {1 2}]'
} }

View File

@ -687,22 +687,22 @@ pub const (
[inline] [inline]
pub fn str_intp_sq(in_str string) string { pub fn str_intp_sq(in_str string) string {
return 'str_intp(2, _MOV((StrIntpData[]){{ _SLIT("\'"), $si_s_code, {.d_s = $in_str}},{ _SLIT("\'"), 0, {.d_c = 0 }}}))' return 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("\'"), $si_s_code, {.d_s = $in_str}},{_SLIT("\'"), 0, {.d_c = 0 }}}))'
} }
[inline] [inline]
pub fn str_intp_rune(in_str string) string { pub fn str_intp_rune(in_str string) string {
return 'str_intp(2, _MOV((StrIntpData[]){{ _SLIT("\`"), $si_s_code, {.d_s = $in_str}},{ _SLIT("\`"), 0, {.d_c = 0 }}}))' return 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("\`"), $si_s_code, {.d_s = $in_str}},{_SLIT("\`"), 0, {.d_c = 0 }}}))'
} }
[inline] [inline]
pub fn str_intp_g32(in_str string) string { pub fn str_intp_g32(in_str string) string {
return 'str_intp(1, _MOV((StrIntpData[]){{ _SLIT0, $si_g32_code, {.d_f32 = $in_str }}}))' return 'str_intp(1, _MOV((StrIntpData[]){{_SLIT0, $si_g32_code, {.d_f32 = $in_str }}}))'
} }
[inline] [inline]
pub fn str_intp_g64(in_str string) string { pub fn str_intp_g64(in_str string) string {
return 'str_intp(1, _MOV((StrIntpData[]){{ _SLIT0, $si_g64_code, {.d_f64 = $in_str }}}))' return 'str_intp(1, _MOV((StrIntpData[]){{_SLIT0, $si_g64_code, {.d_f64 = $in_str }}}))'
} }
// replace %% with the in_str // replace %% with the in_str
@ -718,12 +718,12 @@ pub fn str_intp_sub(base_str string, in_str string) string {
st_str := base_str[..index] st_str := base_str[..index]
if index + 2 < base_str.len { if index + 2 < base_str.len {
en_str := base_str[index + 2..] en_str := base_str[index + 2..]
res_str := 'str_intp(2, _MOV((StrIntpData[]){{ _SLIT("$st_str"), $si_s_code, {.d_s = $in_str }},{ _SLIT("$en_str"), 0, {.d_c = 0}}}))' res_str := 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("$st_str"), $si_s_code, {.d_s = $in_str }},{_SLIT("$en_str"), 0, {.d_c = 0}}}))'
st_str.free() st_str.free()
en_str.free() en_str.free()
return res_str return res_str
} }
res2_str := 'str_intp(1, _MOV((StrIntpData[]){{ _SLIT("$st_str"), $si_s_code, { .d_s = $in_str }}}))' res2_str := 'str_intp(1, _MOV((StrIntpData[]){{_SLIT("$st_str"), $si_s_code, {.d_s = $in_str }}}))'
st_str.free() st_str.free()
return res2_str return res2_str
} }

View File

@ -849,11 +849,6 @@ fn test_raw_inter() {
assert s.contains('$') assert s.contains('$')
} }
fn test_new_inter() {
// world := 'world'
// assert 'hello {world}' == 'hello world'
}
fn test_c_r() { fn test_c_r() {
// This used to break because of r'' and c'' // This used to break because of r'' and c''
c := 42 c := 42

View File

@ -95,8 +95,8 @@ fn test_parse_form() {
'a': 'b' 'a': 'b'
'c': ' d ' 'c': ' d '
} }
assert parse_form(r'{json}') == { assert parse_form('{json}') == {
'json': r'{json}' 'json': '{json}'
} }
assert parse_form('{ assert parse_form('{
"_id": "76c", "_id": "76c",

View File

@ -68,7 +68,7 @@ pub fn default() string {
} }
} }
} }
mut fm := os.execute("fc-match --format='%\{file}\n' -s") mut fm := os.execute("fc-match --format='%{file}\n' -s")
if fm.exit_code == 0 { if fm.exit_code == 0 {
lines := fm.output.split('\n') lines := fm.output.split('\n')
for l in lines { for l in lines {

View File

@ -71,9 +71,9 @@ const expected_string_outputs = [
fn test_find_between_pair_family() { fn test_find_between_pair_family() {
assert strings.find_between_pair_rune('xxokyy', ``, ``) == 'ok' assert strings.find_between_pair_rune('xxokyy', ``, ``) == 'ok'
assert strings.find_between_pair_u8('xx\{ok}yy', `{`, `}`) == 'ok' assert strings.find_between_pair_u8('xx{ok}yy', `{`, `}`) == 'ok'
assert strings.find_between_pair_string('xx/*ok*/yy', '/*', '*/') == 'ok' assert strings.find_between_pair_string('xx/*ok*/yy', '/*', '*/') == 'ok'
assert strings.find_between_pair_u8('xx\{ok}yy', `{`, `}`) == 'ok' assert strings.find_between_pair_u8('xx{ok}yy', `{`, `}`) == 'ok'
assert strings.find_between_pair_string('xxxxokyyyy', 'xxx', 'yyy') == 'xok' assert strings.find_between_pair_string('xxxxokyyyy', 'xxx', 'yyy') == 'xok'
for i, tstr in test_rune_and_byte { for i, tstr in test_rune_and_byte {

View File

@ -4,31 +4,52 @@ vlib/v/checker/tests/str_interpol_invalid_err.vv:8:13: error: illegal format spe
8 | _ = '${[1]:x}' 8 | _ = '${[1]:x}'
| ^ | ^
9 | _ = '${[1]!:x}' 9 | _ = '${[1]!:x}'
10 | // _ = '${Foo{}:x}' 10 | _ = '${Foo{}:x}'
vlib/v/checker/tests/str_interpol_invalid_err.vv:9:14: error: illegal format specifier `x` for type `[1]int` vlib/v/checker/tests/str_interpol_invalid_err.vv:9:14: error: illegal format specifier `x` for type `[1]int`
7 | fn main() { 7 | fn main() {
8 | _ = '${[1]:x}' 8 | _ = '${[1]:x}'
9 | _ = '${[1]!:x}' 9 | _ = '${[1]!:x}'
| ^ | ^
10 | // _ = '${Foo{}:x}' 10 | _ = '${Foo{}:x}'
11 | _ = '${[1]:f}' 11 | _ = '${[1]:f}'
vlib/v/checker/tests/str_interpol_invalid_err.vv:10:15: error: illegal format specifier `x` for type `Foo`
8 | _ = '${[1]:x}'
9 | _ = '${[1]!:x}'
10 | _ = '${Foo{}:x}'
| ^
11 | _ = '${[1]:f}'
12 | _ := '${none:F}'
vlib/v/checker/tests/str_interpol_invalid_err.vv:11:13: error: illegal format specifier `f` for type `[]int` vlib/v/checker/tests/str_interpol_invalid_err.vv:11:13: error: illegal format specifier `f` for type `[]int`
9 | _ = '${[1]!:x}' 9 | _ = '${[1]!:x}'
10 | // _ = '${Foo{}:x}' 10 | _ = '${Foo{}:x}'
11 | _ = '${[1]:f}' 11 | _ = '${[1]:f}'
| ^ | ^
12 | _ := '${none:F}' 12 | _ := '${none:F}'
13 | // _ = '${{"a": "b"}:x}' 13 | _ = '${{"a": "b"}:x}'
vlib/v/checker/tests/str_interpol_invalid_err.vv:12:15: error: illegal format specifier `F` for type `none` vlib/v/checker/tests/str_interpol_invalid_err.vv:12:15: error: illegal format specifier `F` for type `none`
10 | // _ = '${Foo{}:x}' 10 | _ = '${Foo{}:x}'
11 | _ = '${[1]:f}' 11 | _ = '${[1]:f}'
12 | _ := '${none:F}' 12 | _ := '${none:F}'
| ^ | ^
13 | // _ = '${{"a": "b"}:x}' 13 | _ = '${{"a": "b"}:x}'
14 | // _ = '${Alias(Foo{}):x}' 14 | _ = '${Alias(Foo{}):x}'
vlib/v/checker/tests/str_interpol_invalid_err.vv:13:20: error: illegal format specifier `x` for type `map[string]string`
11 | _ = '${[1]:f}'
12 | _ := '${none:F}'
13 | _ = '${{"a": "b"}:x}'
| ^
14 | _ = '${Alias(Foo{}):x}'
15 | _ = '${SumType(int(5)):o}'
vlib/v/checker/tests/str_interpol_invalid_err.vv:14:22: error: illegal format specifier `x` for type `Alias`
12 | _ := '${none:F}'
13 | _ = '${{"a": "b"}:x}'
14 | _ = '${Alias(Foo{}):x}'
| ^
15 | _ = '${SumType(int(5)):o}'
16 | }
vlib/v/checker/tests/str_interpol_invalid_err.vv:15:25: error: illegal format specifier `o` for type `SumType` vlib/v/checker/tests/str_interpol_invalid_err.vv:15:25: error: illegal format specifier `o` for type `SumType`
13 | // _ = '${{"a": "b"}:x}' 13 | _ = '${{"a": "b"}:x}'
14 | // _ = '${Alias(Foo{}):x}' 14 | _ = '${Alias(Foo{}):x}'
15 | _ = '${SumType(int(5)):o}' 15 | _ = '${SumType(int(5)):o}'
| ^ | ^
16 | } 16 | }

View File

@ -7,10 +7,10 @@ type SumType = Alias | int
fn main() { fn main() {
_ = '${[1]:x}' _ = '${[1]:x}'
_ = '${[1]!:x}' _ = '${[1]!:x}'
// _ = '${Foo{}:x}' _ = '${Foo{}:x}'
_ = '${[1]:f}' _ = '${[1]:f}'
_ := '${none:F}' _ := '${none:F}'
// _ = '${{"a": "b"}:x}' _ = '${{"a": "b"}:x}'
// _ = '${Alias(Foo{}):x}' _ = '${Alias(Foo{}):x}'
_ = '${SumType(int(5)):o}' _ = '${SumType(int(5)):o}'
} }

View File

@ -10,10 +10,10 @@ module eval
import v.token import v.token
import v.ast import v.ast
fn(e Eval)infix_expr(left Object,right Object,op token.Kind,expecting ast.Type)Object{match op{' fn(e Eval)infix_expr(left Object,right Object,op token.Kind,expecting ast.Type)Object{match op{'
footer = "else{ e.error('unknown infix expression: \$op')}}return empty // should e.error before this anyway footer = "else{e.error('unknown infix expression: \$op')}}return empty // should e.error before this anyway
} }
" "
uk_expect_footer = "else{ e.error('unknown infix expectation: \${e.table.sym(expecting).str()}')}}" uk_expect_footer = "else{e.error('unknown infix expectation: \${e.table.sym(expecting).str()}')}}"
comparison = { comparison = {
'gt': '>' 'gt': '>'
'lt': '<' 'lt': '<'
@ -46,7 +46,7 @@ fn main() {
for lt2 in literal_types { for lt2 in literal_types {
b.write_string('$lt2{return left.val${op}right}') b.write_string('$lt2{return left.val${op}right}')
} }
b.write_string("else{ e.error('invalid operands to $op: $ct and \$right.type_name()')}}}") b.write_string("else{e.error('invalid operands to $op: $ct and \$right.type_name()')}}}")
} }
for lt in literal_types { for lt in literal_types {
b.write_string('$lt {match right{') b.write_string('$lt {match right{')
@ -61,9 +61,9 @@ fn main() {
b.write_string(" literal and \$right.type_name()')}}}") b.write_string(" literal and \$right.type_name()')}}}")
} }
if op in ['==', '!='] { if op in ['==', '!='] {
b.write_string('string{ match right{ string{ return left${op}right}else{ e.error(\'invalid operands to $op: string and \$right.type_name()\')}}}') b.write_string('string{match right{string{return left${op}right}else{e.error(\'invalid operands to $op: string and \$right.type_name()\')}}}')
} }
b.write_string("else { e.error('invalid operands to $op: \$left.type_name() and \$right.type_name()')}}}") b.write_string("else {e.error('invalid operands to $op: \$left.type_name() and \$right.type_name()')}}}")
} }
for math, op in math_ops { for math, op in math_ops {
b.write_string('.$math{match left{') b.write_string('.$math{match left{')
@ -77,9 +77,9 @@ fn main() {
continue continue
} }
unsafe_start, unsafe_end := if op in ['<<', '>>'] { 'unsafe{', '}' } else { '', '' } unsafe_start, unsafe_end := if op in ['<<', '>>'] { 'unsafe{', '}' } else { '', '' }
b.write_string('$ct2{ if expecting in ast.signed_integer_type_idxs{ return Int{ i64(left.val)${op}i64(right.val),i8(e.type_to_size(expecting))}}else if expecting in ast.unsigned_integer_type_idxs{ return Uint{ u64(left.val)${op}u64(right.val),i8(e.type_to_size(expecting))}}else if expecting==ast.int_literal_type_idx{${unsafe_start}return i64(i64(left.val)${op}i64(right.val))$unsafe_end}') b.write_string('$ct2{if expecting in ast.signed_integer_type_idxs{return Int{i64(left.val)${op}i64(right.val),i8(e.type_to_size(expecting))}}else if expecting in ast.unsigned_integer_type_idxs{return Uint{u64(left.val)${op}u64(right.val),i8(e.type_to_size(expecting))}}else if expecting==ast.int_literal_type_idx{${unsafe_start}return i64(i64(left.val)${op}i64(right.val))$unsafe_end}')
if op !in ['<<', '>>'] { if op !in ['<<', '>>'] {
b.write_string('else if expecting in ast.float_type_idxs{ return Float{ f64(left.val)${op}f64(right.val),i8(e.type_to_size(expecting))}}else if expecting==ast.float_literal_type_idx{ return f64(f64(left.val)${op}f64(right.val))}') b.write_string('else if expecting in ast.float_type_idxs{return Float{f64(left.val)${op}f64(right.val), i8(e.type_to_size(expecting))}}else if expecting==ast.float_literal_type_idx{return f64(f64(left.val)${op}f64(right.val))}')
} }
b.write_string(uk_expect_footer) b.write_string(uk_expect_footer)
} }
@ -88,13 +88,13 @@ fn main() {
continue continue
} }
unsafe_start, unsafe_end := if op in ['<<', '>>'] { 'unsafe{', '}' } else { '', '' } unsafe_start, unsafe_end := if op in ['<<', '>>'] { 'unsafe{', '}' } else { '', '' }
b.write_string('$lt2{ if expecting in ast.signed_integer_type_idxs{ return Int{ i64(left.val)${op}i64(right),i8(e.type_to_size(expecting))}}else if expecting in ast.unsigned_integer_type_idxs{ return Uint{ u64(left.val)${op}u64(right),i8(e.type_to_size(expecting))}}else if expecting==ast.int_literal_type_idx{${unsafe_start}return i64(i64(left.val)${op}i64(right))$unsafe_end}') b.write_string('$lt2{if expecting in ast.signed_integer_type_idxs{return Int{i64(left.val)${op}i64(right),i8(e.type_to_size(expecting))}}else if expecting in ast.unsigned_integer_type_idxs{return Uint{u64(left.val)${op}u64(right),i8(e.type_to_size(expecting))}}else if expecting==ast.int_literal_type_idx{${unsafe_start}return i64(i64(left.val)${op}i64(right))$unsafe_end}')
if op !in ['<<', '>>'] { if op !in ['<<', '>>'] {
b.write_string('else if expecting in ast.float_type_idxs{ return Float{ f64(left.val)${op}f64(right), i8(e.type_to_size(expecting))}}else if expecting==ast.float_literal_type_idx{ return f64(f64(left.val)${op}f64(right))}') b.write_string('else if expecting in ast.float_type_idxs{return Float{f64(left.val)${op}f64(right), i8(e.type_to_size(expecting))}}else if expecting==ast.float_literal_type_idx{return f64(f64(left.val)${op}f64(right))}')
} }
b.write_string(uk_expect_footer) b.write_string(uk_expect_footer)
} }
b.write_string("else { e.error('invalid operands to $op: $ct and \$right.type_name()')}}}") b.write_string("else {e.error('invalid operands to $op: $ct and \$right.type_name()')}}}")
} }
for lt in literal_types { for lt in literal_types {
if op in ['<<', '>>'] && lt == 'f64' { if op in ['<<', '>>'] && lt == 'f64' {
@ -106,9 +106,9 @@ fn main() {
continue continue
} }
unsafe_start, unsafe_end := if op in ['<<', '>>'] { 'unsafe{', '}' } else { '', '' } unsafe_start, unsafe_end := if op in ['<<', '>>'] { 'unsafe{', '}' } else { '', '' }
b.write_string('$ct2{ if expecting in ast.signed_integer_type_idxs{ return Int{ i64(left)${op}i64(right.val),i8(e.type_to_size(expecting))}}else if expecting in ast.unsigned_integer_type_idxs{ return Uint{ u64(left)${op}u64(right.val),i8(e.type_to_size(expecting))}}else if expecting==ast.int_literal_type_idx{${unsafe_start}return i64(i64(left)${op}i64(right.val))$unsafe_end}') b.write_string('$ct2{if expecting in ast.signed_integer_type_idxs{return Int{i64(left)${op}i64(right.val),i8(e.type_to_size(expecting))}}else if expecting in ast.unsigned_integer_type_idxs{return Uint{u64(left)${op}u64(right.val),i8(e.type_to_size(expecting))}}else if expecting==ast.int_literal_type_idx{${unsafe_start}return i64(i64(left)${op}i64(right.val))$unsafe_end}')
if op !in ['<<', '>>'] { if op !in ['<<', '>>'] {
b.write_string('else if expecting in ast.float_type_idxs{ return Float{ f64(left)${op}f64(right.val), i8(e.type_to_size(expecting))}}else if expecting==ast.float_literal_type_idx{ return f64(f64(left)${op}f64(right.val))}') b.write_string('else if expecting in ast.float_type_idxs{return Float{f64(left)${op}f64(right.val), i8(e.type_to_size(expecting))}}else if expecting==ast.float_literal_type_idx{return f64(f64(left)${op}f64(right.val))}')
} }
b.write_string(uk_expect_footer) b.write_string(uk_expect_footer)
} }
@ -117,9 +117,9 @@ fn main() {
continue continue
} }
unsafe_start, unsafe_end := if op in ['<<', '>>'] { 'unsafe{', '}' } else { '', '' } unsafe_start, unsafe_end := if op in ['<<', '>>'] { 'unsafe{', '}' } else { '', '' }
b.write_string('$lt2{if expecting in ast.signed_integer_type_idxs{ return Int{ i64(left)${op}i64(right),i8(e.type_to_size(expecting))}}else if expecting in ast.unsigned_integer_type_idxs{ return Uint{ u64(left)${op}u64(right),i8(e.type_to_size(expecting))}}else if expecting==ast.int_literal_type_idx{${unsafe_start}return i64(i64(left)${op}i64(right))$unsafe_end}') b.write_string('$lt2{if expecting in ast.signed_integer_type_idxs{return Int{i64(left)${op}i64(right),i8(e.type_to_size(expecting))}}else if expecting in ast.unsigned_integer_type_idxs{return Uint{u64(left)${op}u64(right),i8(e.type_to_size(expecting))}}else if expecting==ast.int_literal_type_idx{${unsafe_start}return i64(i64(left)${op}i64(right))$unsafe_end}')
if op !in ['<<', '>>'] { if op !in ['<<', '>>'] {
b.write_string('else if expecting in ast.float_type_idxs{ return Float{ f64(left)${op}f64(right), i8(e.type_to_size(expecting))}}else if expecting==ast.float_literal_type_idx{ return f64(f64(left)${op}f64(right))}') b.write_string('else if expecting in ast.float_type_idxs{return Float{f64(left)${op}f64(right), i8(e.type_to_size(expecting))}}else if expecting==ast.float_literal_type_idx{return f64(f64(left)${op}f64(right))}')
} }
b.write_string(uk_expect_footer) b.write_string(uk_expect_footer)
} }
@ -127,7 +127,7 @@ fn main() {
b.write_string(if lt == 'i64' { 'int' } else { 'float' }) b.write_string(if lt == 'i64' { 'int' } else { 'float' })
b.write_string(" literal and \$right.type_name()')}}}") b.write_string(" literal and \$right.type_name()')}}}")
} }
b.write_string("else { e.error('invalid operands to $op: \$left.type_name() and \$right.type_name()')}}}") b.write_string("else {e.error('invalid operands to $op: \$left.type_name() and \$right.type_name()')}}}")
} }
b.write_string(footer) b.write_string(footer)

View File

@ -1685,7 +1685,7 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
} }
f.write(f.table.type_to_str_using_aliases(node.elem_type, f.mod2alias)) f.write(f.table.type_to_str_using_aliases(node.elem_type, f.mod2alias))
if node.has_default { if node.has_default {
f.write('\{init: ') f.write('{init: ')
f.expr(node.default_expr) f.expr(node.default_expr)
f.write('}') f.write('}')
} else { } else {

View File

@ -209,7 +209,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
g.expr(val) g.expr(val)
} else { } else {
if left_sym.kind == .function { if left_sym.kind == .function {
g.write('{ void* _ = ') g.write('{void* _ = ')
} else { } else {
g.write('{$styp _ = ') g.write('{$styp _ = ')
} }

View File

@ -102,7 +102,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
is_var_mut := expr.is_auto_deref_var() is_var_mut := expr.is_auto_deref_var()
str_fn_name := g.get_str_fn(typ) str_fn_name := g.get_str_fn(typ)
if is_ptr && !is_var_mut { if is_ptr && !is_var_mut {
g.write('str_intp(1, _MOV((StrIntpData[]){{ _SLIT("&"), $si_s_code ,{.d_s = isnil(') g.write('str_intp(1, _MOV((StrIntpData[]){{_SLIT("&"), $si_s_code ,{.d_s = isnil(')
g.expr(expr) g.expr(expr)
g.write(') ? _SLIT("nil") : ') g.write(') ? _SLIT("nil") : ')
} }

View File

@ -215,9 +215,9 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
escaped_val := util.smart_quote(val, false) escaped_val := util.smart_quote(val, false)
if escaped_val.len > 0 { if escaped_val.len > 0 {
g.write('{ _SLIT("$escaped_val"), ') g.write('{_SLIT("$escaped_val"), ')
} else { } else {
g.write('{ _SLIT0, ') g.write('{_SLIT0, ')
} }
if i >= node.exprs.len { if i >= node.exprs.len {

View File

@ -812,18 +812,18 @@ fn struct_auto_str_func(mut g JsGen, sym &ast.TypeSymbol, field_type ast.Type, f
// ptr int can be "nil", so this needs to be casted to a string // ptr int can be "nil", so this needs to be casted to a string
if sym.kind == .f32 { if sym.kind == .f32 {
return 'str_intp(1, _MOV((StrIntpData[]){ return 'str_intp(1, _MOV((StrIntpData[]){
{ _SLIT0, $si_g32_code, {.d_f32 = *$method_str }} {_SLIT0, $si_g32_code, {.d_f32 = *$method_str }}
}))' }))'
} else if sym.kind == .f64 { } else if sym.kind == .f64 {
return 'str_intp(1, _MOV((StrIntpData[]){ return 'str_intp(1, _MOV((StrIntpData[]){
{ _SLIT0, $si_g64_code, {.d_f64 = *$method_str }} {_SLIT0, $si_g64_code, {.d_f64 = *$method_str }}
}))' }))'
} else if sym.kind == .u64 { } else if sym.kind == .u64 {
fmt_type := StrIntpType.si_u64 fmt_type := StrIntpType.si_u64
return 'str_intp(1, _MOV((StrIntpData[]){{ _SLIT0, ${u32(fmt_type) | 0xfe00}, {.d_u64 = *$method_str }}}))' return 'str_intp(1, _MOV((StrIntpData[]){{_SLIT0, ${u32(fmt_type) | 0xfe00}, {.d_u64 = *$method_str }}}))'
} }
fmt_type := StrIntpType.si_i32 fmt_type := StrIntpType.si_i32
return 'str_intp(1, _MOV((StrIntpData[]){{ _SLIT0, ${u32(fmt_type) | 0xfe00}, {.d_i32 = *$method_str }}}))' return 'str_intp(1, _MOV((StrIntpData[]){{_SLIT0, ${u32(fmt_type) | 0xfe00}, {.d_i32 = *$method_str }}}))'
} }
return method_str return method_str
} }

View File

@ -683,7 +683,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl, typ FnGenType) {
is_varg := i == args.len - 1 && it.is_variadic is_varg := i == args.len - 1 && it.is_variadic
arg_name := g.js_name(arg.name) arg_name := g.js_name(arg.name)
if is_varg { if is_varg {
g.writeln('$arg_name = new array(new array_buffer({ arr: $arg_name,len: new int(${arg_name}.length),index_start: new int(0)}));') g.writeln('$arg_name = new array(new array_buffer({arr: $arg_name,len: new int(${arg_name}.length),index_start: new int(0)}));')
} else { } else {
asym := g.table.sym(arg.typ) asym := g.table.sym(arg.typ)
if asym.kind != .interface_ && asym.language != .js { if asym.kind != .interface_ && asym.language != .js {

View File

@ -152,9 +152,9 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
// builtin types // builtin types
if g.file.mod.name == 'builtin' && !g.generated_builtin { if g.file.mod.name == 'builtin' && !g.generated_builtin {
g.gen_builtin_type_defs() g.gen_builtin_type_defs()
g.writeln('Object.defineProperty(array.prototype,"len", { get: function() { return new int(this.arr.arr.length);}, set: function(l) { this.arr.arr.length = l.valueOf(); } }); ') g.writeln('Object.defineProperty(array.prototype,"len", { get: function() {return new int(this.arr.arr.length);}, set: function(l) { this.arr.arr.length = l.valueOf(); } }); ')
g.writeln('Object.defineProperty(map.prototype,"len", { get: function() { return new int(this.length);}, set: function(l) { } }); ') g.writeln('Object.defineProperty(map.prototype,"len", { get: function() {return new int(this.length);}, set: function(l) { } }); ')
g.writeln('Object.defineProperty(array.prototype,"length", { get: function() { return new int(this.arr.arr.length);}, set: function(l) { this.arr.arr.length = l.valueOf(); } }); ') g.writeln('Object.defineProperty(array.prototype,"length", { get: function() {return new int(this.arr.arr.length);}, set: function(l) { this.arr.arr.length = l.valueOf(); } }); ')
g.generated_builtin = true g.generated_builtin = true
} }
if g.is_test && !tests_inited { if g.is_test && !tests_inited {

View File

@ -3,7 +3,7 @@ module sourcemap
fn test_simple() { fn test_simple() {
mut sg := generate_empty_map() mut sg := generate_empty_map()
mut sm := sg.add_map('hello.js', '/', true, 0, 0) mut sm := sg.add_map('hello.js', '/', true, 0, 0)
sm.set_source_content('hello.v', "fn main(){ nprintln('Hello World! Helo \$a')\n}") sm.set_source_content('hello.v', "fn main(){nprintln('Hello World! Helo \$a')\n}")
mlist := [ mlist := [
MappingInput{ MappingInput{
@ -132,7 +132,7 @@ fn test_simple() {
json_data := sm.to_json() json_data := sm.to_json()
expected := '{"version":3,"file":"hello.js","sourceRoot":"\\/","sources":["hello.v"],"sourcesContent":["fn main(){ nprintln(\'Hello World! Helo \$a\')\\n}"],"names":["hello_name"],"mappings":"AAAA;AAAA,EAAA,OAAO,CAACA,GAAR,CAAY,aAAZ,CAAA,CAAA;AAAA"}' expected := '{"version":3,"file":"hello.js","sourceRoot":"\\/","sources":["hello.v"],"sourcesContent":["fn main(){nprintln(\'Hello World! Helo \$a\')\\n}"],"names":["hello_name"],"mappings":"AAAA;AAAA,EAAA,OAAO,CAACA,GAAR,CAAY,aAAZ,CAAA,CAAA;AAAA"}'
assert json_data.str() == expected assert json_data.str() == expected
} }

View File

@ -802,13 +802,9 @@ fn (mut s Scanner) text_scan() token.Token {
return s.new_token(.rsbr, '', 1) return s.new_token(.rsbr, '', 1)
} }
`{` { `{` {
// Skip { in `${` in strings
if s.is_inside_string { if s.is_inside_string {
// Handle new `hello {name}` string interpolation
if !s.text[s.pos + 1].is_space() && s.text[s.pos - 1] != `$` {
return s.new_token(.str_dollar, '', 1)
}
if s.text[s.pos - 1] == `$` { if s.text[s.pos - 1] == `$` {
// Skip { in `${` in strings
continue continue
} else { } else {
s.inter_cbr_count++ s.inter_cbr_count++
@ -1229,32 +1225,6 @@ fn (mut s Scanner) ident_string() string {
s.pos -= 2 s.pos -= 2
break break
} }
// {var} (ignore in vfmt mode) (skip \{)
if c == `{` && util.is_name_char(s.text[s.pos + 1]) && prevc != `$` && !is_raw
&& s.count_symbol_before(s.pos - 1, scanner.backslash) % 2 == 0 {
// Detect certain strings with "{" that are not interpolation:
// e.g. "{init: " (no "}" at the end)
mut is_valid_inter := true
for i := s.pos + 1; i < s.text.len; i++ {
if s.text[i] == `}` {
break
}
if s.text[i] in [`=`, `:`, `\n`, s.inter_quote] {
// We reached the end of the line or string without reaching "}".
// Also if there's "=", there's no way it's a valid interpolation expression:
// e.g. `println("{a.b = 42}")` `println('{foo:bar}')`
is_valid_inter = false
break
}
}
if is_valid_inter {
s.is_inside_string = true
s.is_enclosed_inter = true
// so that s.pos points to $ at the next step
s.pos -= 1
break
}
}
if c != scanner.backslash { if c != scanner.backslash {
backslash_count = 0 backslash_count = 0
} }

View File

@ -9,12 +9,9 @@ fn test_string_interpolation_inner_cbr() {
println(s1) println(s1)
assert s1 == '22' assert s1 == '22'
/*
XTODO
s2 := '${St{}}' s2 := '${St{}}'
println(s2) println(s2)
assert s2 == 'St{}' assert s2 == 'St{}'
*/
s3 := '${{ s3 := '${{
'a': 1 'a': 1

View File

@ -18,7 +18,7 @@ pub fn (mut p Pos) free() {
} }
pub fn (p Pos) line_str() string { pub fn (p Pos) line_str() string {
return '\{l: ${p.line_nr + 1:5}, c: ${p.col:3}, p: ${p.pos:5}, ll: ${p.last_line + 1:5}}' return '{l: ${p.line_nr + 1:5}, c: ${p.col:3}, p: ${p.pos:5}, ll: ${p.last_line + 1:5}}'
} }
pub fn (pos Pos) extend(end Pos) Pos { pub fn (pos Pos) extend(end Pos) Pos {