Skip to content

parser, fmt, gen: support js"string literal"#24653

Merged
spytheman merged 11 commits into
vlang:masterfrom
StunxFS:implement-js-strings
Jun 9, 2025
Merged

parser, fmt, gen: support js"string literal"#24653
spytheman merged 11 commits into
vlang:masterfrom
StunxFS:implement-js-strings

Conversation

@StunxFS

@StunxFS StunxFS commented Jun 4, 2025

Copy link
Copy Markdown
Contributor

This PR aims to add native JS string support to the compiler. It will now be possible to write js"Hello" just like you would write c"Hello".

This test ran successfully locally (using JS Browser):

fn test_js_string() {
	s := js'hello V'
	assert s.charAt(0) == js'h'
	assert s.charAt(6) == js'V'
	assert s.charCodeAt(0) == JS.Number(104)
	assert s.toUpperCase() == js'HELLO V'
	assert s.toLowerCase() == js'hello v'
	assert s.concat(js' from JS') == js'hello V from JS'
	assert s.includes(js' ') == JS.Boolean(true)
	assert s.startsWith(js'hello') == JS.Boolean(true)
	assert s.endsWith(js'V') == JS.Boolean(true)
}

@huly-for-github

Copy link
Copy Markdown

Connected to Huly®: V_0.6-23012

@StunxFS StunxFS marked this pull request as ready for review June 4, 2025 16:48
@enghitalo

Copy link
Copy Markdown
Contributor

What is a JS string?

@JalonSolov

Copy link
Copy Markdown
Collaborator

JavaScript has 2 types of strings - primitive strings and String objects. Primitive strings do not have any methods or properties, while String objects have multiples of both.

Basically, it is the same as the difference between C strings and V strings.

Comment thread vlib/v/checker/checker.v Outdated
Comment thread vlib/v/checker/checker.v Outdated
Comment thread vlib/builtin/js/string_test.js.v Outdated
Comment on lines +987 to +988
/*
TODO(StunxFS): Uncomment when the PR is merged

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why uncomment it later, and not now?
V is bootstrapped in the PR, and the test should be runnable imho as it is?

@spytheman spytheman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work.
@medvednikov what do you think about it (adding syntax support for js'strings') ?

Comment thread vlib/v/checker/checker.v
v_current_commit_hash string // same as old C.V_CURRENT_COMMIT_HASH
assign_stmt_attr string // for `x := [1,2,3] @[freed]`

js_string ast.Type = ast.void_type // when `js"string literal"` is used, `js_string` will be equal to `JS.String`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to have the default value ast.void_type

@StunxFS StunxFS marked this pull request as draft June 5, 2025 17:03
@StunxFS

StunxFS commented Jun 5, 2025

Copy link
Copy Markdown
Contributor Author

For some strange reason, test_js_string fails with v test. The error it throws is the following:

>> compilation failed:
jsgen error: could not generate string method voidptr_str for type 'voidptr'

If I generate .js from a normal file with the same content, everything compiles and runs perfectly:

$ cat main.v
fn main() {
        s := js'hello V'
        assert s.charAt(0) == js'h'
        assert s.charAt(6) == js'V'
        assert s.charCodeAt(0) == JS.Number(104)
        assert s.toUpperCase() == js'HELLO V'
        assert s.toLowerCase() == js'hello v'
        assert s.concat(js' from JS') == js'hello V from JS'
        assert s.includes(js' ') == JS.Boolean(true)
        assert s.startsWith(js'hello') == JS.Boolean(true)
        assert s.endsWith(js'V') == JS.Boolean(true)
}
$ v -b js main.v
$ node main.js
$ 

@JalonSolov

Copy link
Copy Markdown
Collaborator

First impression... it's related to line 152 in checker.v, where you explicitly set the type to ast.void_type.

@StunxFS

StunxFS commented Jun 5, 2025

Copy link
Copy Markdown
Contributor Author

@JalonSolov

First impression... it's related to line 152 in checker.v, where you explicitly set the type to ast.void_type.

If I remove the default value from the field, V panics:

V panic: table.sym: invalid type (typ=ast.Type(0x0 = 0) idx=0). Compiler bug. This should never happen. Please report the bug using `v bug file.v`.

@medvednikov

Copy link
Copy Markdown
Member

Looks good to me. A simple change.

@StunxFS StunxFS marked this pull request as ready for review June 9, 2025 00:29
@spytheman spytheman merged commit 921e001 into vlang:master Jun 9, 2025
74 of 75 checks passed
@StunxFS StunxFS deleted the implement-js-strings branch June 9, 2025 10:07
@westtrade

Copy link
Copy Markdown

Looks cool, but for what purposes is this necessary?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants