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

all: new string interpolation "hello {name}!"

This commit is contained in:
Alexander Medvednikov 2022-10-27 11:00:51 +03:00
parent e6fad82b87
commit 18c7da9a5e
26 changed files with 124 additions and 88 deletions

View File

@ -222,6 +222,7 @@ jobs:
git clone --depth 1 https://github.com/vlang/ved
cd ved && ../v -o ved .
../v -autofree .
../v -prod .
cd ..
# - name: Test c2v
# run: |

View File

@ -9,7 +9,7 @@
- [ ] Recursive structs via optionals: `struct Node { next ?Node }`
- [ ] Optional function struct fields
- [ ] Handle function pointers safely, remove `if function == 0 {`
- [ ] Bundle OpenSSL like GC
- [x] Bundle OpenSSL like GC
- [x] Anonymous structs
- [ ] -usecache on by default
- [ ] -skip-unused on by default

View File

@ -112,10 +112,10 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
mut command_for_selfbuilding := ''
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_selfbuilding = './cv.exe -o $vgit_context.vexename {SOURCE}'
command_for_selfbuilding = './cv.exe -o $vgit_context.vexename \{SOURCE}'
} 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_selfbuilding = './cv -o $vgit_context.vexename {SOURCE}'
command_for_selfbuilding = './cv -o $vgit_context.vexename \{SOURCE}'
}
scripting.chdir(vgit_context.workdir)
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(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)
// At this point, there exists a file vgit_context.vexepath
// which should be a valid working V executable.

View File

@ -29,7 +29,7 @@ const (
'hg': 'hg clone'
}
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']
}
supported_vcs_version_cmds = {

View File

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

View File

@ -1663,7 +1663,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))
if node.has_default {
f.write('{init: ')
f.write('\{init: ')
f.expr(node.default_expr)
f.write('}')
} else {

View File

@ -1272,8 +1272,7 @@ fn (mut g Gen) write_chan_push_optional_fns() {
g.channel_definitions.writeln('
static inline ${c.option_name}_void __Option_${styp}_pushval($styp ch, $el_type e) {
if (sync__Channel_try_push_priv(ch, &e, false)) {
return (${c.option_name}_void){ .state = 2, .err = _v_error(_SLIT("channel closed")), .data = {EMPTY_STRUCT_INITIALIZATION} };
}
return (${c.option_name}_void){ .state = 2, .err = _v_error(_SLIT("channel closed")), .data = { EMPTY_STRUCT_INITIALIZATION} }; }
return (${c.option_name}_void){0};
}')
}

View File

@ -802,9 +802,13 @@ fn (mut s Scanner) text_scan() token.Token {
return s.new_token(.rsbr, '', 1)
}
`{` {
// Skip { in `${` in strings
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] == `$` {
// Skip { in `${` in strings
continue
} else {
s.inter_cbr_count++
@ -1225,6 +1229,33 @@ fn (mut s Scanner) ident_string() string {
s.pos -= 2
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] == `}` {
// No } in this string, so it's not a valid `{x}` interpolation
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}")`
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 {
backslash_count = 0
}

View File

@ -18,7 +18,7 @@ pub fn (mut p Pos) free() {
}
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 {