js: support running `.js.v` tests in `v test-self`, fixes for array methods & codegen (#12011)
parent
4ff061927b
commit
4333a53f28
|
@ -268,7 +268,18 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
|
||||||
tls_bench.no_cstep = true
|
tls_bench.no_cstep = true
|
||||||
mut relative_file := os.real_path(p.get_item<string>(idx))
|
mut relative_file := os.real_path(p.get_item<string>(idx))
|
||||||
mut cmd_options := [ts.vargs]
|
mut cmd_options := [ts.vargs]
|
||||||
if relative_file.contains('global') && !ts.vargs.contains('fmt') {
|
mut run_js := false
|
||||||
|
|
||||||
|
is_fmt := ts.vargs.contains('fmt')
|
||||||
|
|
||||||
|
if relative_file.ends_with('js.v') {
|
||||||
|
if !is_fmt {
|
||||||
|
cmd_options << ' -b js'
|
||||||
|
}
|
||||||
|
run_js = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if relative_file.contains('global') && !is_fmt {
|
||||||
cmd_options << ' -enable-globals'
|
cmd_options << ' -enable-globals'
|
||||||
}
|
}
|
||||||
if ts.root_relative {
|
if ts.root_relative {
|
||||||
|
@ -279,8 +290,10 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
|
||||||
// Ensure that the generated binaries will be stored in the temporary folder.
|
// Ensure that the generated binaries will be stored in the temporary folder.
|
||||||
// Remove them after a test passes/fails.
|
// Remove them after a test passes/fails.
|
||||||
fname := os.file_name(file)
|
fname := os.file_name(file)
|
||||||
generated_binary_fname := if os.user_os() == 'windows' {
|
generated_binary_fname := if os.user_os() == 'windows' && !run_js {
|
||||||
fname.replace('.v', '.exe')
|
fname.replace('.v', '.exe')
|
||||||
|
} else if !run_js {
|
||||||
|
fname.replace('.v', '')
|
||||||
} else {
|
} else {
|
||||||
fname.replace('.v', '')
|
fname.replace('.v', '')
|
||||||
}
|
}
|
||||||
|
@ -290,6 +303,7 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
|
||||||
os.rm(generated_binary_fpath) or {}
|
os.rm(generated_binary_fpath) or {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ts.vargs.contains('fmt') {
|
if !ts.vargs.contains('fmt') {
|
||||||
cmd_options << ' -o "$generated_binary_fpath"'
|
cmd_options << ' -o "$generated_binary_fpath"'
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ const (
|
||||||
'vlib/net/http/header_test.v',
|
'vlib/net/http/header_test.v',
|
||||||
'vlib/net/http/server_test.v',
|
'vlib/net/http/server_test.v',
|
||||||
'vlib/net/http/response_test.v',
|
'vlib/net/http/response_test.v',
|
||||||
|
'vlib/builtin/js/array_test.js.v',
|
||||||
]
|
]
|
||||||
skip_on_linux = [
|
skip_on_linux = [
|
||||||
'do_not_remove',
|
'do_not_remove',
|
||||||
|
@ -142,7 +143,8 @@ fn main() {
|
||||||
args_string := args[1..].join(' ')
|
args_string := args[1..].join(' ')
|
||||||
cmd_prefix := args_string.all_before('test-self')
|
cmd_prefix := args_string.all_before('test-self')
|
||||||
title := 'testing vlib'
|
title := 'testing vlib'
|
||||||
all_test_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.v')
|
mut all_test_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.v')
|
||||||
|
all_test_files << os.walk_ext(os.join_path(vroot, 'vlib'), '_test.js.v')
|
||||||
testing.eheader(title)
|
testing.eheader(title)
|
||||||
mut tsession := testing.new_test_session(cmd_prefix, true)
|
mut tsession := testing.new_test_session(cmd_prefix, true)
|
||||||
tsession.files << all_test_files.filter(!it.contains('testdata' + os.path_separator))
|
tsession.files << all_test_files.filter(!it.contains('testdata' + os.path_separator))
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
module builtin
|
module builtin
|
||||||
|
|
||||||
|
import strings
|
||||||
/// Internal representation of `array` type. It is used to implement slices and to make slices behave correctly
|
/// Internal representation of `array` type. It is used to implement slices and to make slices behave correctly
|
||||||
/// it simply stores reference to original array and to index them properly it does index array relative to `index_start`.
|
/// it simply stores reference to original array and to index them properly it does index array relative to `index_start`.
|
||||||
|
|
||||||
struct array_buffer {
|
struct array_buffer {
|
||||||
arr JS.Array
|
arr JS.Array
|
||||||
index_start int
|
index_start int
|
||||||
|
@ -43,6 +45,7 @@ fn (mut a array_buffer) set(ix int, val voidptr) {
|
||||||
#array_buffer.prototype.set = function(ix,val) { array_buffer_set(this,ix,val); }
|
#array_buffer.prototype.set = function(ix,val) { array_buffer_set(this,ix,val); }
|
||||||
|
|
||||||
struct array {
|
struct array {
|
||||||
|
mut:
|
||||||
arr array_buffer
|
arr array_buffer
|
||||||
pub:
|
pub:
|
||||||
len int
|
len int
|
||||||
|
@ -175,8 +178,9 @@ pub fn (a array) index(v string) int {
|
||||||
pub fn (a array) slice(start int, end int) array {
|
pub fn (a array) slice(start int, end int) array {
|
||||||
mut result := a
|
mut result := a
|
||||||
#let slice = a.arr.arr.slice(start,end)
|
#let slice = a.arr.arr.slice(start,end)
|
||||||
#result = new array(new array_buffer({arr: a.arr.arr, len: new int(slice.length),cap: new int(slice.length),index_start: new int(start)}))
|
#result = new array(new array_buffer({arr: a.arr.arr, len: new int(slice.length),cap: new int(slice.length),index_start: new int(start),has_slice: new bool(true)}))
|
||||||
#a.arr.has_slice = true
|
#a.arr.has_slice = true
|
||||||
|
//#v_makeSlice(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -199,7 +203,10 @@ pub fn (mut a array) join(separator string) string {
|
||||||
|
|
||||||
fn (mut a array) push(val voidptr) {
|
fn (mut a array) push(val voidptr) {
|
||||||
#a.val.arr.make_copy()
|
#a.val.arr.make_copy()
|
||||||
|
#if (arguments[2] && arguments[2].valueOf()) {a.val.arr.arr.push(...val)} else {
|
||||||
#a.val.arr.arr.push(val)
|
#a.val.arr.arr.push(val)
|
||||||
|
#}
|
||||||
|
#a.val.arr.len.val += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn v_filter(arr array, callback fn (voidptr) bool) array {
|
fn v_filter(arr array, callback fn (voidptr) bool) array {
|
||||||
|
@ -271,6 +278,12 @@ pub fn (mut a array) delete(i int) {
|
||||||
a.delete_many(i, 1)
|
a.delete_many(i, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn arr_copy(mut dst array, src array, count int) {
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
dst.arr.set(i, src.arr.get(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// delete_many deletes `size` elements beginning with index `i`
|
// delete_many deletes `size` elements beginning with index `i`
|
||||||
pub fn (mut a array) delete_many(i int, size int) {
|
pub fn (mut a array) delete_many(i int, size int) {
|
||||||
#a.val.arr.make_copy()
|
#a.val.arr.make_copy()
|
||||||
|
@ -301,6 +314,11 @@ pub fn (mut a array) reverse_in_place() {
|
||||||
|
|
||||||
#array.prototype.$includes = function (elem) { return this.arr.arr.find(function(e) { return vEq(elem,e); }) !== undefined;}
|
#array.prototype.$includes = function (elem) { return this.arr.arr.find(function(e) { return vEq(elem,e); }) !== undefined;}
|
||||||
|
|
||||||
|
pub fn (mut a array) clear() {
|
||||||
|
#a.val.arr.make_copy()
|
||||||
|
#a.val.arr.arr.clear()
|
||||||
|
}
|
||||||
|
|
||||||
// reduce executes a given reducer function on each element of the array,
|
// reduce executes a given reducer function on each element of the array,
|
||||||
// resulting in a single output value.
|
// resulting in a single output value.
|
||||||
pub fn (a array) reduce(iter fn (int, int) int, accum_start int) int {
|
pub fn (a array) reduce(iter fn (int, int) int, accum_start int) int {
|
||||||
|
@ -319,6 +337,7 @@ pub fn (mut a array) pop() voidptr {
|
||||||
mut res := voidptr(0)
|
mut res := voidptr(0)
|
||||||
#a.val.arr.make_copy()
|
#a.val.arr.make_copy()
|
||||||
#res = a.val.arr.arr.pop()
|
#res = a.val.arr.arr.pop()
|
||||||
|
#a.val.arr.len.val -= 1
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -361,7 +380,6 @@ pub fn (a array) bytestr() string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn (a []string) str() string {
|
pub fn (a []string) str() string {
|
||||||
mut sb := strings.new_builder(a.len * 3)
|
mut sb := strings.new_builder(a.len * 3)
|
||||||
sb.write_string('[')
|
sb.write_string('[')
|
||||||
|
@ -377,4 +395,4 @@ pub fn (a []string) str() string {
|
||||||
sb.write_string(']')
|
sb.write_string(']')
|
||||||
res := sb.str()
|
res := sb.str()
|
||||||
return res
|
return res
|
||||||
}*/
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -121,7 +121,7 @@ fn (mut b Builder) run_compiled_executable_and_exit() {
|
||||||
mut exefile := os.real_path(b.pref.out_name)
|
mut exefile := os.real_path(b.pref.out_name)
|
||||||
mut cmd := '"$exefile"'
|
mut cmd := '"$exefile"'
|
||||||
if b.pref.backend.is_js() {
|
if b.pref.backend.is_js() {
|
||||||
exefile = os.real_path('${b.pref.out_name}.js')
|
exefile = os.real_path('${b.pref.out_name}.js').replace('.js.js', '.js')
|
||||||
cmd = 'node "$exefile"'
|
cmd = 'node "$exefile"'
|
||||||
}
|
}
|
||||||
for arg in b.pref.run_args {
|
for arg in b.pref.run_args {
|
||||||
|
|
|
@ -180,20 +180,20 @@ fn (mut g JsGen) gen_array_contains_method(left_type ast.Type) string {
|
||||||
fn_builder.writeln('function ${fn_name}(a,v) {')
|
fn_builder.writeln('function ${fn_name}(a,v) {')
|
||||||
fn_builder.writeln('\tfor (let i = 0; i < a.len; ++i) {')
|
fn_builder.writeln('\tfor (let i = 0; i < a.len; ++i) {')
|
||||||
if elem_sym.kind == .string {
|
if elem_sym.kind == .string {
|
||||||
fn_builder.writeln('\t\tif (a.arr.arr[i].str == v.str) {')
|
fn_builder.writeln('\t\tif (a.arr.get(new int(i)).str == v.str) {')
|
||||||
} else if elem_sym.kind == .array && left_info.elem_type.nr_muls() == 0 {
|
} else if elem_sym.kind == .array && left_info.elem_type.nr_muls() == 0 {
|
||||||
ptr_typ := g.gen_array_equality_fn(left_info.elem_type)
|
ptr_typ := g.gen_array_equality_fn(left_info.elem_type)
|
||||||
fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(a.arr.arr[i],v)) {')
|
fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(a.arr.get(new int(i)),v).val) {')
|
||||||
} else if elem_sym.kind == .function {
|
} else if elem_sym.kind == .function {
|
||||||
fn_builder.writeln('\t\tif (a.arr.arr[i] == v) {')
|
fn_builder.writeln('\t\tif (a.arr.get(new int(i)) == v) {')
|
||||||
} else if elem_sym.kind == .map && left_info.elem_type.nr_muls() == 0 {
|
} else if elem_sym.kind == .map && left_info.elem_type.nr_muls() == 0 {
|
||||||
ptr_typ := g.gen_map_equality_fn(left_info.elem_type)
|
ptr_typ := g.gen_map_equality_fn(left_info.elem_type)
|
||||||
fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(a.arr.arr[i],v)) {')
|
fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(a.arr.get(new int(i)),v).val) {')
|
||||||
} else if elem_sym.kind == .struct_ && left_info.elem_type.nr_muls() == 0 {
|
} else if elem_sym.kind == .struct_ && left_info.elem_type.nr_muls() == 0 {
|
||||||
ptr_typ := g.gen_struct_equality_fn(left_info.elem_type)
|
ptr_typ := g.gen_struct_equality_fn(left_info.elem_type)
|
||||||
fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(a.arr.arr[i],v)) {')
|
fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(a.arr.get(new int(i)),v).val) {')
|
||||||
} else {
|
} else {
|
||||||
fn_builder.writeln('\t\tif (vEq(a.arr.arr[i],v)) {')
|
fn_builder.writeln('\t\tif (vEq(a.arr.get(new int(i)),v)) {')
|
||||||
}
|
}
|
||||||
fn_builder.writeln('\t\t\treturn new bool(true);')
|
fn_builder.writeln('\t\t\treturn new bool(true);')
|
||||||
fn_builder.writeln('\t\t}')
|
fn_builder.writeln('\t\t}')
|
||||||
|
|
|
@ -237,22 +237,22 @@ fn (mut g JsGen) gen_fixed_array_equality_fn(left_type ast.Type) string {
|
||||||
fn_builder.writeln('\t\tif (a.arr.get(new int(i)).str != b.arr.get(new int(i)).str) {')
|
fn_builder.writeln('\t\tif (a.arr.get(new int(i)).str != b.arr.get(new int(i)).str) {')
|
||||||
} else if elem.sym.kind == .sum_type && !elem.typ.is_ptr() {
|
} else if elem.sym.kind == .sum_type && !elem.typ.is_ptr() {
|
||||||
eq_fn := g.gen_sumtype_equality_fn(elem.typ)
|
eq_fn := g.gen_sumtype_equality_fn(elem.typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_sumtype_eq(a.arr.get(new int(i)), b.arr.get(new int(i)))) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_sumtype_eq(a.arr.get(new int(i)), b.arr.get(new int(i))).val) {')
|
||||||
} else if elem.sym.kind == .struct_ && !elem.typ.is_ptr() {
|
} else if elem.sym.kind == .struct_ && !elem.typ.is_ptr() {
|
||||||
eq_fn := g.gen_struct_equality_fn(elem.typ)
|
eq_fn := g.gen_struct_equality_fn(elem.typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_struct_eq(a.arr.get(new int(i)), b.arr.get(new int(i)))) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_struct_eq(a.arr.get(new int(i)), b.arr.get(new int(i))).val) {')
|
||||||
} else if elem.sym.kind == .array && !elem.typ.is_ptr() {
|
} else if elem.sym.kind == .array && !elem.typ.is_ptr() {
|
||||||
eq_fn := g.gen_array_equality_fn(elem.typ)
|
eq_fn := g.gen_array_equality_fn(elem.typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_arr_eq(a.arr.get(new int(i)), b.arr.get(new int(i)))) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_arr_eq(a.arr.get(new int(i)), b.arr.get(new int(i))).val) {')
|
||||||
} else if elem.sym.kind == .array_fixed && !elem.typ.is_ptr() {
|
} else if elem.sym.kind == .array_fixed && !elem.typ.is_ptr() {
|
||||||
eq_fn := g.gen_fixed_array_equality_fn(elem.typ)
|
eq_fn := g.gen_fixed_array_equality_fn(elem.typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_arr_eq(a.arr.get(new int(i)), b.arr.get(new int(i)))) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_arr_eq(a.arr.get(new int(i)), b.arr.get(new int(i))).val) {')
|
||||||
} else if elem.sym.kind == .map && !elem.typ.is_ptr() {
|
} else if elem.sym.kind == .map && !elem.typ.is_ptr() {
|
||||||
eq_fn := g.gen_map_equality_fn(elem.typ)
|
eq_fn := g.gen_map_equality_fn(elem.typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(a.arr.get(new int(i)), b.arr.get(new int(i)))) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(a.arr.get(new int(i)), b.arr.get(new int(i))).val) {')
|
||||||
} else if elem.sym.kind == .alias && !elem.typ.is_ptr() {
|
} else if elem.sym.kind == .alias && !elem.typ.is_ptr() {
|
||||||
eq_fn := g.gen_alias_equality_fn(elem.typ)
|
eq_fn := g.gen_alias_equality_fn(elem.typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq(a.arr.get(new int(i)), b.arr.get(new int(i)))) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq(a.arr.get(new int(i)), b.arr.get(new int(i))).val) {')
|
||||||
} else if elem.sym.kind == .function {
|
} else if elem.sym.kind == .function {
|
||||||
fn_builder.writeln('\t\tif (a.arr.get(new int(i)) != b.arr.get(new int(i))) {')
|
fn_builder.writeln('\t\tif (a.arr.get(new int(i)) != b.arr.get(new int(i))) {')
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -6,6 +6,102 @@ import v.ast
|
||||||
import v.util
|
import v.util
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
|
struct StrType {
|
||||||
|
styp string
|
||||||
|
mut:
|
||||||
|
typ ast.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) get_str_fn(typ ast.Type) string {
|
||||||
|
mut unwrapped := g.unwrap_generic(typ).set_nr_muls(0).clear_flag(.variadic)
|
||||||
|
if g.pref.nofloat {
|
||||||
|
if typ == ast.f32_type {
|
||||||
|
unwrapped = ast.u32_type
|
||||||
|
} else if typ == ast.f64_type {
|
||||||
|
unwrapped = ast.u64_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if typ.has_flag(.optional) {
|
||||||
|
unwrapped.set_flag(.optional)
|
||||||
|
}
|
||||||
|
styp := g.typ(unwrapped)
|
||||||
|
mut sym := g.table.get_type_symbol(unwrapped)
|
||||||
|
mut str_fn_name := styp_to_str_fn_name(styp)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.str_types << StrType{
|
||||||
|
typ: unwrapped
|
||||||
|
styp: styp
|
||||||
|
}
|
||||||
|
return str_fn_name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) final_gen_str(typ StrType) {
|
||||||
|
if typ in g.generated_str_fns {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.generated_str_fns << typ
|
||||||
|
sym := g.table.get_type_symbol(typ.typ)
|
||||||
|
if sym.has_method('str') && !typ.typ.has_flag(.optional) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
styp := typ.styp
|
||||||
|
str_fn_name := styp_to_str_fn_name(styp)
|
||||||
|
if typ.typ.has_flag(.optional) {
|
||||||
|
g.gen_str_for_option(typ.typ, styp, str_fn_name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
match mut sym.info {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast.Array {
|
||||||
|
g.gen_str_for_array(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.ArrayFixed {
|
||||||
|
g.gen_str_for_array_fixed(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.Enum {
|
||||||
|
g.gen_str_for_enum(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.FnType {
|
||||||
|
g.gen_str_for_fn_type(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.Struct {
|
||||||
|
g.gen_str_for_struct(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.Map {
|
||||||
|
g.gen_str_for_map(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.MultiReturn {
|
||||||
|
g.gen_str_for_multi_return(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.SumType {
|
||||||
|
g.gen_str_for_union_sum_type(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.Interface {
|
||||||
|
g.gen_str_for_interface(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.Chan {
|
||||||
|
g.gen_str_for_chan(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
ast.Thread {
|
||||||
|
g.gen_str_for_thread(sym.info, styp, str_fn_name)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
verror("could not generate string method $str_fn_name for type '$styp'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum StrIntpType {
|
pub enum StrIntpType {
|
||||||
si_no_str = 0 // no parameter to print only fix string
|
si_no_str = 0 // no parameter to print only fix string
|
||||||
si_c
|
si_c
|
||||||
|
@ -116,85 +212,11 @@ fn (mut g JsGen) gen_str_default(sym ast.TypeSymbol, styp string, str_fn_name st
|
||||||
g.definitions.writeln('}')
|
g.definitions.writeln('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) 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 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sym_has_str_method, str_method_expects_ptr, str_nr_args := sym.str_method_info()
|
|
||||||
already_generated_key := '$styp:$str_fn_name'
|
|
||||||
if !sym_has_str_method && already_generated_key !in g.str_types && !typ.has_flag(.optional) {
|
|
||||||
$if debugautostr ? {
|
|
||||||
eprintln('> gen_str_for_type: |typ: ${typ:5}, ${sym.name:20}|has_str: ${sym_has_str_method:5}|expects_ptr: ${str_method_expects_ptr:5}|nr_args: ${str_nr_args:1}|fn_name: ${str_fn_name:20}')
|
|
||||||
}
|
|
||||||
g.str_types << already_generated_key
|
|
||||||
match mut sym.info {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast.Array {
|
|
||||||
g.gen_str_for_array(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.ArrayFixed {
|
|
||||||
g.gen_str_for_array_fixed(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.Enum {
|
|
||||||
g.gen_str_for_enum(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.FnType {
|
|
||||||
g.gen_str_for_fn_type(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.Struct {
|
|
||||||
g.gen_str_for_struct(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.Map {
|
|
||||||
g.gen_str_for_map(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.MultiReturn {
|
|
||||||
g.gen_str_for_multi_return(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.SumType {
|
|
||||||
g.gen_str_for_union_sum_type(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.Interface {
|
|
||||||
g.gen_str_for_interface(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.Chan {
|
|
||||||
g.gen_str_for_chan(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
ast.Thread {
|
|
||||||
g.gen_str_for_thread(sym.info, styp, str_fn_name)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
panic("could not generate string method $str_fn_name for type '$styp'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typ.has_flag(.optional) {
|
|
||||||
option_already_generated_key := 'option_$already_generated_key'
|
|
||||||
if option_already_generated_key !in g.str_types {
|
|
||||||
g.gen_str_for_option(typ, styp, str_fn_name)
|
|
||||||
g.str_types << option_already_generated_key
|
|
||||||
}
|
|
||||||
return str_fn_name
|
|
||||||
}
|
|
||||||
return str_fn_name
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g JsGen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string) {
|
fn (mut g JsGen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string) {
|
||||||
parent_type := typ.clear_flag(.optional)
|
parent_type := typ.clear_flag(.optional)
|
||||||
sym := g.table.get_type_symbol(parent_type)
|
sym := g.table.get_type_symbol(parent_type)
|
||||||
sym_has_str_method, _, _ := sym.str_method_info()
|
sym_has_str_method, _, _ := sym.str_method_info()
|
||||||
parent_str_fn_name := g.gen_str_for_type(parent_type)
|
parent_str_fn_name := g.get_str_fn(parent_type)
|
||||||
|
|
||||||
g.definitions.writeln('function ${str_fn_name}(it) { return indent_${str_fn_name}(it, 0); }')
|
g.definitions.writeln('function ${str_fn_name}(it) { return indent_${str_fn_name}(it, 0); }')
|
||||||
g.definitions.writeln('function indent_${str_fn_name}(it, indent_count) {')
|
g.definitions.writeln('function indent_${str_fn_name}(it, indent_count) {')
|
||||||
|
@ -219,7 +241,7 @@ fn (mut g JsGen) gen_str_for_option(typ ast.Type, styp string, str_fn_name strin
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string) {
|
fn (mut g JsGen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string) {
|
||||||
parent_str_fn_name := g.gen_str_for_type(info.parent_type)
|
parent_str_fn_name := g.get_str_fn(info.parent_type)
|
||||||
g.definitions.writeln('function ${str_fn_name}(it) { return indent_${str_fn_name}(it, 0); }')
|
g.definitions.writeln('function ${str_fn_name}(it) { return indent_${str_fn_name}(it, 0); }')
|
||||||
|
|
||||||
g.definitions.writeln('function indent_${str_fn_name}(it, indent_count) {')
|
g.definitions.writeln('function indent_${str_fn_name}(it, indent_count) {')
|
||||||
|
@ -239,7 +261,7 @@ fn (mut g JsGen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str
|
||||||
sym := g.table.get_type_symbol(typ)
|
sym := g.table.get_type_symbol(typ)
|
||||||
is_arg_ptr := typ.is_ptr()
|
is_arg_ptr := typ.is_ptr()
|
||||||
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
arg_str_fn_name := g.gen_str_for_type(typ)
|
arg_str_fn_name := g.get_str_fn(typ)
|
||||||
|
|
||||||
if should_use_indent_func(sym.kind) && !sym_has_str_method {
|
if should_use_indent_func(sym.kind) && !sym_has_str_method {
|
||||||
fn_builder.writeln('\tstrings__Builder_write_string(sb, ${arg_str_fn_name}(a.arg$i));')
|
fn_builder.writeln('\tstrings__Builder_write_string(sb, ${arg_str_fn_name}(a.arg$i));')
|
||||||
|
@ -323,7 +345,7 @@ fn (mut g JsGen) gen_str_for_interface(info ast.Interface, styp string, str_fn_n
|
||||||
fn_builder.writeln('function indent_${str_fn_name}(x,indent_count) { /* gen_str_for_interface */')
|
fn_builder.writeln('function indent_${str_fn_name}(x,indent_count) { /* gen_str_for_interface */')
|
||||||
for typ in info.types {
|
for typ in info.types {
|
||||||
subtype := g.table.get_type_symbol(typ)
|
subtype := g.table.get_type_symbol(typ)
|
||||||
mut func_name := g.gen_str_for_type(typ)
|
mut func_name := g.get_str_fn(typ)
|
||||||
sym_has_str_method, _, _ := subtype.str_method_info()
|
sym_has_str_method, _, _ := subtype.str_method_info()
|
||||||
if should_use_indent_func(subtype.kind) && !sym_has_str_method {
|
if should_use_indent_func(subtype.kind) && !sym_has_str_method {
|
||||||
func_name = 'indent_$func_name'
|
func_name = 'indent_$func_name'
|
||||||
|
@ -431,7 +453,7 @@ fn (mut g JsGen) gen_str_for_array(info ast.Array, styp string, str_fn_name stri
|
||||||
}
|
}
|
||||||
is_elem_ptr := typ.is_ptr()
|
is_elem_ptr := typ.is_ptr()
|
||||||
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
mut elem_str_fn_name := g.gen_str_for_type(typ)
|
mut elem_str_fn_name := g.get_str_fn(typ)
|
||||||
if sym.kind == .byte {
|
if sym.kind == .byte {
|
||||||
elem_str_fn_name = elem_str_fn_name + '_escaped'
|
elem_str_fn_name = elem_str_fn_name + '_escaped'
|
||||||
}
|
}
|
||||||
|
@ -490,7 +512,7 @@ fn (mut g JsGen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_f
|
||||||
}
|
}
|
||||||
is_elem_ptr := typ.is_ptr()
|
is_elem_ptr := typ.is_ptr()
|
||||||
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
elem_str_fn_name := g.gen_str_for_type(typ)
|
elem_str_fn_name := g.get_str_fn(typ)
|
||||||
|
|
||||||
g.definitions.writeln('function ${str_fn_name}(a) { return indent_${str_fn_name}(a, 0);}')
|
g.definitions.writeln('function ${str_fn_name}(a) { return indent_${str_fn_name}(a, 0);}')
|
||||||
|
|
||||||
|
@ -545,7 +567,7 @@ fn (mut g JsGen) gen_str_for_map(info ast.Map, styp string, str_fn_name string)
|
||||||
key_styp := g.typ(key_typ)
|
key_styp := g.typ(key_typ)
|
||||||
key_str_fn_name := key_styp.replace('*', '') + '_str'
|
key_str_fn_name := key_styp.replace('*', '') + '_str'
|
||||||
if !key_sym.has_method('str') {
|
if !key_sym.has_method('str') {
|
||||||
g.gen_str_for_type(key_typ)
|
g.get_str_fn(key_typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
mut val_typ := info.value_type
|
mut val_typ := info.value_type
|
||||||
|
@ -557,7 +579,7 @@ fn (mut g JsGen) gen_str_for_map(info ast.Map, styp string, str_fn_name string)
|
||||||
val_styp := g.typ(val_typ)
|
val_styp := g.typ(val_typ)
|
||||||
elem_str_fn_name := val_styp.replace('*', '') + '_str'
|
elem_str_fn_name := val_styp.replace('*', '') + '_str'
|
||||||
if !val_sym.has_method('str') {
|
if !val_sym.has_method('str') {
|
||||||
g.gen_str_for_type(val_typ)
|
g.get_str_fn(val_typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
g.definitions.writeln('function ${str_fn_name}(m) { return indent_${str_fn_name}(m, 0);}')
|
g.definitions.writeln('function ${str_fn_name}(m) { return indent_${str_fn_name}(m, 0);}')
|
||||||
|
@ -701,7 +723,7 @@ fn (mut g JsGen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name st
|
||||||
field_styp_fn_name := if has_custom_str {
|
field_styp_fn_name := if has_custom_str {
|
||||||
'${field_styp}_str'
|
'${field_styp}_str'
|
||||||
} else {
|
} else {
|
||||||
g.gen_str_for_type(field.typ)
|
g.get_str_fn(field.typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
mut func := struct_auto_str_func1(mut g, sym, field.typ, field_styp_fn_name, field.name)
|
mut func := struct_auto_str_func1(mut g, sym, field.typ, field_styp_fn_name, field.name)
|
||||||
|
|
|
@ -406,7 +406,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
|
||||||
typ_name: typ_name
|
typ_name: typ_name
|
||||||
val_name: 'arr'
|
val_name: 'arr'
|
||||||
default_value: 'new array_buffer({})'
|
default_value: 'new array_buffer({})'
|
||||||
constructor: 'this.arr = arr\nif (arr.index_start.val != 0) { v_makeSlice(this); } '
|
constructor: 'this.arr = arr\nif (arr.index_start.val != 0 || arr.has_slice.val) { v_makeSlice(this); } '
|
||||||
value_of: 'this'
|
value_of: 'this'
|
||||||
to_string: 'JSON.stringify(this.arr.map(it => it.valueOf()))'
|
to_string: 'JSON.stringify(this.arr.map(it => it.valueOf()))'
|
||||||
eq: 'new bool(vEq(self, other))'
|
eq: 'new bool(vEq(self, other))'
|
||||||
|
|
|
@ -96,6 +96,10 @@ fn (mut g JsGen) js_method_call(node ast.CallExpr) {
|
||||||
fn (mut g JsGen) method_call(node ast.CallExpr) {
|
fn (mut g JsGen) method_call(node ast.CallExpr) {
|
||||||
g.call_stack << node
|
g.call_stack << node
|
||||||
it := node
|
it := node
|
||||||
|
if it.name == 'str' {
|
||||||
|
g.gen_expr_to_string(node.left, node.left_type)
|
||||||
|
return
|
||||||
|
}
|
||||||
call_return_is_optional := it.return_type.has_flag(.optional)
|
call_return_is_optional := it.return_type.has_flag(.optional)
|
||||||
if call_return_is_optional {
|
if call_return_is_optional {
|
||||||
g.writeln('(function(){')
|
g.writeln('(function(){')
|
||||||
|
@ -104,6 +108,13 @@ fn (mut g JsGen) method_call(node ast.CallExpr) {
|
||||||
g.inc_indent()
|
g.inc_indent()
|
||||||
g.write('return builtin.unwrap(')
|
g.write('return builtin.unwrap(')
|
||||||
}
|
}
|
||||||
|
if node.name == 'str' {
|
||||||
|
mut rec_type := node.receiver_type
|
||||||
|
if rec_type.has_flag(.shared_f) {
|
||||||
|
rec_type = rec_type.clear_flag(.shared_f).set_nr_muls(0)
|
||||||
|
}
|
||||||
|
g.get_str_fn(rec_type)
|
||||||
|
}
|
||||||
mut unwrapped_rec_type := node.receiver_type
|
mut unwrapped_rec_type := node.receiver_type
|
||||||
if g.table.cur_fn.generic_names.len > 0 {
|
if g.table.cur_fn.generic_names.len > 0 {
|
||||||
unwrapped_rec_type = g.unwrap_generic(node.receiver_type)
|
unwrapped_rec_type = g.unwrap_generic(node.receiver_type)
|
||||||
|
|
|
@ -89,6 +89,9 @@ fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.gen_deref_ptr(node.right_type)
|
g.gen_deref_ptr(node.right_type)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
if node.op == .ne {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
} else if left.typ.idx() == right.typ.idx()
|
} else if left.typ.idx() == right.typ.idx()
|
||||||
&& left.sym.kind in [.array, .array_fixed, .alias, .map, .struct_, .sum_type] {
|
&& left.sym.kind in [.array, .array_fixed, .alias, .map, .struct_, .sum_type] {
|
||||||
match left.sym.kind {
|
match left.sym.kind {
|
||||||
|
@ -104,6 +107,9 @@ fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.gen_deref_ptr(node.right_type)
|
g.gen_deref_ptr(node.right_type)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
if node.op == .ne {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.array {
|
.array {
|
||||||
ptr_typ := g.gen_array_equality_fn(left.unaliased.clear_flag(.shared_f))
|
ptr_typ := g.gen_array_equality_fn(left.unaliased.clear_flag(.shared_f))
|
||||||
|
@ -117,6 +123,9 @@ fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.gen_deref_ptr(node.right_type)
|
g.gen_deref_ptr(node.right_type)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
if node.op == .ne {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.array_fixed {
|
.array_fixed {
|
||||||
ptr_typ := g.gen_fixed_array_equality_fn(left.unaliased)
|
ptr_typ := g.gen_fixed_array_equality_fn(left.unaliased)
|
||||||
|
@ -130,6 +139,9 @@ fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.gen_deref_ptr(node.right_type)
|
g.gen_deref_ptr(node.right_type)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
if node.op == .ne {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.map {
|
.map {
|
||||||
ptr_typ := g.gen_map_equality_fn(left.unaliased)
|
ptr_typ := g.gen_map_equality_fn(left.unaliased)
|
||||||
|
@ -143,6 +155,9 @@ fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.gen_deref_ptr(node.right_type)
|
g.gen_deref_ptr(node.right_type)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
if node.op == .ne {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.struct_ {
|
.struct_ {
|
||||||
ptr_typ := g.gen_struct_equality_fn(left.unaliased)
|
ptr_typ := g.gen_struct_equality_fn(left.unaliased)
|
||||||
|
@ -156,6 +171,9 @@ fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.gen_deref_ptr(node.right_type)
|
g.gen_deref_ptr(node.right_type)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
if node.op == .ne {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.sum_type {
|
.sum_type {
|
||||||
ptr_typ := g.gen_sumtype_equality_fn(left.unaliased)
|
ptr_typ := g.gen_sumtype_equality_fn(left.unaliased)
|
||||||
|
@ -170,6 +188,9 @@ fn (mut g JsGen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.gen_deref_ptr(node.right_type)
|
g.gen_deref_ptr(node.right_type)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
if node.op == .ne {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
|
@ -231,22 +252,22 @@ fn (mut g JsGen) infix_expr_left_shift_op(node ast.InfixExpr) {
|
||||||
if left.unaliased_sym.kind == .array {
|
if left.unaliased_sym.kind == .array {
|
||||||
// arr << val
|
// arr << val
|
||||||
array_info := left.unaliased_sym.info as ast.Array
|
array_info := left.unaliased_sym.info as ast.Array
|
||||||
g.write('Array.prototype.push.call(')
|
g.write('array_push(')
|
||||||
//&& array_info.elem_type != g.unwrap_generic(node.right_type)
|
//&& array_info.elem_type != g.unwrap_generic(node.right_type)
|
||||||
if right.unaliased_sym.kind == .array && array_info.elem_type != right.typ {
|
if right.unaliased_sym.kind == .array && array_info.elem_type != right.typ {
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.gen_deref_ptr(left.typ)
|
g.gen_deref_ptr(left.typ)
|
||||||
g.write('.arr.arr,...')
|
g.write(',')
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.gen_deref_ptr(right.typ)
|
g.gen_deref_ptr(right.typ)
|
||||||
g.write('.arr.arr')
|
g.write('.arr.arr')
|
||||||
g.write(')')
|
g.write(',true)')
|
||||||
} else {
|
} else {
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.gen_deref_ptr(left.typ)
|
g.gen_deref_ptr(left.typ)
|
||||||
g.write('.arr.arr,')
|
g.write(',')
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(')')
|
g.write(',false)')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g.gen_plain_infix_expr(node)
|
g.gen_plain_infix_expr(node)
|
||||||
|
|
|
@ -64,7 +64,8 @@ mut:
|
||||||
stmt_start_pos int
|
stmt_start_pos int
|
||||||
defer_stmts []ast.DeferStmt
|
defer_stmts []ast.DeferStmt
|
||||||
fn_decl &ast.FnDecl // pointer to the FnDecl we are currently inside otherwise 0
|
fn_decl &ast.FnDecl // pointer to the FnDecl we are currently inside otherwise 0
|
||||||
str_types []string // types that need automatic str() generation
|
generated_str_fns []StrType
|
||||||
|
str_types []StrType // types that need automatic str() generation
|
||||||
array_fn_definitions []string // array equality functions that have been defined
|
array_fn_definitions []string // array equality functions that have been defined
|
||||||
map_fn_definitions []string // map equality functions that have been defined
|
map_fn_definitions []string // map equality functions that have been defined
|
||||||
struct_fn_definitions []string // struct equality functions that have been defined
|
struct_fn_definitions []string // struct equality functions that have been defined
|
||||||
|
@ -156,6 +157,9 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
||||||
// store the current namespace
|
// store the current namespace
|
||||||
g.escape_namespace()
|
g.escape_namespace()
|
||||||
}
|
}
|
||||||
|
for i := 0; i < g.str_types.len; i++ {
|
||||||
|
g.final_gen_str(g.str_types[i])
|
||||||
|
}
|
||||||
if g.pref.is_test {
|
if g.pref.is_test {
|
||||||
g.gen_js_main_for_tests()
|
g.gen_js_main_for_tests()
|
||||||
}
|
}
|
||||||
|
@ -1031,10 +1035,10 @@ fn (mut g JsGen) gen_assert_single_expr(expr ast.Expr, typ ast.Type) {
|
||||||
g.write('$sym.name')
|
g.write('$sym.name')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g.writeln(unknown_value)
|
g.write(unknown_value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.write(' /* typeof: ' + expr.type_name() + ' type: ' + typ.str() + ' */ ')
|
// g.writeln(' /* typeof: ' + expr.type_name() + ' type: ' + typ.str() + ' */ ')
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -1150,6 +1154,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||||
is_ptr = true
|
is_ptr = true
|
||||||
g.write('.val')
|
g.write('.val')
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.inside_map_set && op == .assign {
|
if g.inside_map_set && op == .assign {
|
||||||
g.inside_map_set = false
|
g.inside_map_set = false
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
|
@ -1160,6 +1165,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
} else {
|
} else {
|
||||||
if is_assign && array_set {
|
if is_assign && array_set {
|
||||||
|
g.write('new ${styp}(')
|
||||||
g.expr(left)
|
g.expr(left)
|
||||||
if l_sym.kind == .string {
|
if l_sym.kind == .string {
|
||||||
g.write('.str')
|
g.write('.str')
|
||||||
|
@ -1272,6 +1278,9 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
g.cast_stack.delete_last()
|
g.cast_stack.delete_last()
|
||||||
}
|
}
|
||||||
|
if is_assign && array_set {
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if array_set {
|
if array_set {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
@ -1741,7 +1750,13 @@ fn (mut g JsGen) gen_array_init_expr(it ast.ArrayInit) {
|
||||||
g.expr(it.exprs[0])
|
g.expr(it.exprs[0])
|
||||||
g.write(')')
|
g.write(')')
|
||||||
} else {
|
} else {
|
||||||
c := g.gen_array_init_values(it.exprs)
|
styp := g.typ(it.elem_type)
|
||||||
|
|
||||||
|
c := if styp in js.v_types {
|
||||||
|
g.gen_array_init_values_prim(it.exprs, styp)
|
||||||
|
} else {
|
||||||
|
g.gen_array_init_values(it.exprs)
|
||||||
|
}
|
||||||
g.write(', len: new int($c), cap: new int($c)')
|
g.write(', len: new int($c), cap: new int($c)')
|
||||||
}
|
}
|
||||||
g.dec_indent()
|
g.dec_indent()
|
||||||
|
@ -1762,6 +1777,22 @@ fn (mut g JsGen) gen_array_init_values(exprs []ast.Expr) int {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) gen_array_init_values_prim(exprs []ast.Expr, typ string) int {
|
||||||
|
g.write('[')
|
||||||
|
mut c := 0
|
||||||
|
for i, expr in exprs {
|
||||||
|
g.write('new ${typ}(')
|
||||||
|
g.expr(expr)
|
||||||
|
g.write(')')
|
||||||
|
if i < exprs.len - 1 {
|
||||||
|
g.write(', ')
|
||||||
|
}
|
||||||
|
c++
|
||||||
|
}
|
||||||
|
g.write(']')
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g JsGen) gen_ident(node ast.Ident) {
|
fn (mut g JsGen) gen_ident(node ast.Ident) {
|
||||||
mut name := g.js_name(node.name)
|
mut name := g.js_name(node.name)
|
||||||
if node.kind == .blank_ident || name in ['', '_'] {
|
if node.kind == .blank_ident || name in ['', '_'] {
|
||||||
|
@ -2258,10 +2289,11 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
|
||||||
g.write('.valueOf()')
|
g.write('.valueOf()')
|
||||||
}
|
}
|
||||||
g.write(',')
|
g.write(',')
|
||||||
|
|
||||||
if expr.index.has_low {
|
if expr.index.has_low {
|
||||||
g.expr(expr.index.low)
|
g.expr(expr.index.low)
|
||||||
} else {
|
} else {
|
||||||
g.write('0')
|
g.write('new int(0)')
|
||||||
}
|
}
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
if expr.index.has_high {
|
if expr.index.has_high {
|
||||||
|
@ -2407,7 +2439,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
} else if l_sym.kind == .array && it.op == .left_shift { // arr << 1
|
} else if l_sym.kind == .array && it.op == .left_shift { // arr << 1
|
||||||
g.write('Array.prototype.push.call(')
|
g.write('array_push(')
|
||||||
g.expr(it.left)
|
g.expr(it.left)
|
||||||
mut ltyp := it.left_type
|
mut ltyp := it.left_type
|
||||||
for ltyp.is_ptr() {
|
for ltyp.is_ptr() {
|
||||||
|
|
|
@ -2,6 +2,7 @@ module js
|
||||||
|
|
||||||
import v.ast
|
import v.ast
|
||||||
|
|
||||||
|
/*
|
||||||
fn (mut g JsGen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
fn (mut g JsGen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
||||||
is_shared := etype.has_flag(.shared_f)
|
is_shared := etype.has_flag(.shared_f)
|
||||||
mut typ := etype
|
mut typ := etype
|
||||||
|
@ -72,4 +73,75 @@ fn (mut g JsGen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
||||||
}
|
}
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
fn (mut g JsGen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
||||||
|
is_shared := etype.has_flag(.shared_f)
|
||||||
|
mut typ := etype
|
||||||
|
if is_shared {
|
||||||
|
typ = typ.clear_flag(.shared_f).set_nr_muls(0)
|
||||||
|
}
|
||||||
|
mut sym := g.table.get_type_symbol(typ)
|
||||||
|
// when type is alias, print the aliased value
|
||||||
|
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
|
||||||
|
sym = parent_sym
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
|
if typ.has_flag(.variadic) {
|
||||||
|
str_fn_name := g.get_str_fn(typ)
|
||||||
|
g.write('${str_fn_name}(')
|
||||||
|
g.expr(expr)
|
||||||
|
g.write(')')
|
||||||
|
} else if typ == ast.string_type {
|
||||||
|
g.expr(expr)
|
||||||
|
} else if typ == ast.bool_type {
|
||||||
|
g.expr(expr)
|
||||||
|
g.write('.valueOf() ? new string("true") : new string("false")')
|
||||||
|
} else if sym.kind == .none_ {
|
||||||
|
g.write('new string("<none>")')
|
||||||
|
} else if sym.kind == .enum_ {
|
||||||
|
if expr !is ast.EnumVal {
|
||||||
|
str_fn_name := g.get_str_fn(typ)
|
||||||
|
g.write('${str_fn_name}(')
|
||||||
|
g.expr(expr)
|
||||||
|
g.write(')')
|
||||||
|
} else {
|
||||||
|
g.write('new string("')
|
||||||
|
g.expr(expr)
|
||||||
|
g.write('")')
|
||||||
|
}
|
||||||
|
} else if sym_has_str_method
|
||||||
|
|| sym.kind in [.array, .array_fixed, .map, .struct_, .multi_return, .sum_type, .interface_] {
|
||||||
|
is_ptr := typ.is_ptr()
|
||||||
|
is_var_mut := expr.is_auto_deref_var()
|
||||||
|
str_fn_name := g.get_str_fn(typ)
|
||||||
|
g.write('${str_fn_name}(')
|
||||||
|
if str_method_expects_ptr && !is_ptr {
|
||||||
|
g.write('new \$ref(')
|
||||||
|
}
|
||||||
|
|
||||||
|
g.expr(expr)
|
||||||
|
if (!str_method_expects_ptr && is_ptr && !is_shared) || is_var_mut {
|
||||||
|
g.write('.val')
|
||||||
|
}
|
||||||
|
g.write(')')
|
||||||
|
if str_method_expects_ptr && !is_ptr {
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str_fn_name := g.get_str_fn(typ)
|
||||||
|
g.write('${str_fn_name}(')
|
||||||
|
|
||||||
|
if sym.kind != .function {
|
||||||
|
g.expr(expr)
|
||||||
|
}
|
||||||
|
if expr.is_auto_deref_var() {
|
||||||
|
g.write('.val')
|
||||||
|
}
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,302 +0,0 @@
|
||||||
3
|
|
||||||
1
|
|
||||||
2
|
|
||||||
4
|
|
||||||
255
|
|
||||||
256
|
|
||||||
2
|
|
||||||
4
|
|
||||||
131
|
|
||||||
4
|
|
||||||
1
|
|
||||||
2
|
|
||||||
3
|
|
||||||
5
|
|
||||||
4
|
|
||||||
4
|
|
||||||
[1, 5, 2, 3, 4]
|
|
||||||
5
|
|
||||||
4
|
|
||||||
5
|
|
||||||
[1, 5, 2, 3, 4]
|
|
||||||
[5, 2, 3, 4]
|
|
||||||
4
|
|
||||||
[5, 3, 4]
|
|
||||||
3
|
|
||||||
[5, 3]
|
|
||||||
2
|
|
||||||
[2.5, 3.25, 4.5, 5.75]
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
1
|
|
||||||
2
|
|
||||||
3
|
|
||||||
10000
|
|
||||||
234
|
|
||||||
0
|
|
||||||
1
|
|
||||||
0
|
|
||||||
1
|
|
||||||
3
|
|
||||||
[1, 3]
|
|
||||||
3
|
|
||||||
2
|
|
||||||
3
|
|
||||||
4
|
|
||||||
1
|
|
||||||
4
|
|
||||||
5
|
|
||||||
2
|
|
||||||
5
|
|
||||||
0
|
|
||||||
1
|
|
||||||
1.1
|
|
||||||
[1, 2, 3, 4]
|
|
||||||
[1, 5, 6, 2, 3, 4]
|
|
||||||
0
|
|
||||||
1
|
|
||||||
1
|
|
||||||
0
|
|
||||||
1
|
|
||||||
1.1
|
|
||||||
[1, 2, 3, 4]
|
|
||||||
[5, 6, 1, 2, 3, 4]
|
|
||||||
5
|
|
||||||
true
|
|
||||||
1.1
|
|
||||||
1.1
|
|
||||||
1.1
|
|
||||||
-123
|
|
||||||
-123
|
|
||||||
-123
|
|
||||||
123
|
|
||||||
123
|
|
||||||
123
|
|
||||||
1.1
|
|
||||||
1.1
|
|
||||||
1.1
|
|
||||||
1
|
|
||||||
2
|
|
||||||
1
|
|
||||||
2
|
|
||||||
1
|
|
||||||
abc
|
|
||||||
1
|
|
||||||
abc
|
|
||||||
0
|
|
||||||
abc
|
|
||||||
2
|
|
||||||
3
|
|
||||||
2
|
|
||||||
3
|
|
||||||
1
|
|
||||||
2
|
|
||||||
1
|
|
||||||
2
|
|
||||||
2
|
|
||||||
1
|
|
||||||
4
|
|
||||||
6
|
|
||||||
1
|
|
||||||
4
|
|
||||||
6
|
|
||||||
[]
|
|
||||||
0
|
|
||||||
[0, 0, 0, 0]
|
|
||||||
[0, 7, 0, 0]
|
|
||||||
0
|
|
||||||
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
|
|
||||||
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
|
|
||||||
[2, 4, 6, 8, 10]
|
|
||||||
2
|
|
||||||
[1, 2]
|
|
||||||
0
|
|
||||||
1
|
|
||||||
-1
|
|
||||||
0
|
|
||||||
3
|
|
||||||
-1
|
|
||||||
0
|
|
||||||
2
|
|
||||||
-1
|
|
||||||
1
|
|
||||||
2
|
|
||||||
-1
|
|
||||||
2
|
|
||||||
3
|
|
||||||
1
|
|
||||||
3
|
|
||||||
6
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
false
|
|
||||||
false
|
|
||||||
false
|
|
||||||
false
|
|
||||||
true
|
|
||||||
true
|
|
||||||
15
|
|
||||||
20
|
|
||||||
14
|
|
||||||
-6
|
|
||||||
-7
|
|
||||||
[2, 4, 6]
|
|
||||||
[is, awesome]
|
|
||||||
[2, 3, 4, 6, 8, 9, 10]
|
|
||||||
[4, 5, 6]
|
|
||||||
[5, 10]
|
|
||||||
[2, 4]
|
|
||||||
[2, 4]
|
|
||||||
[1, 2, 3, 4, 5, 6]
|
|
||||||
[v, is, awesome]
|
|
||||||
[0, 0, 0, 0, 0, 0]
|
|
||||||
0
|
|
||||||
[10, 20, 30, 40, 50, 60]
|
|
||||||
[1, 4, 9, 16, 25, 36]
|
|
||||||
[1, 2, 3, 4, 5, 6]
|
|
||||||
[false, true, false, true, false, true]
|
|
||||||
[V, IS, AWESOME]
|
|
||||||
[false, false, true]
|
|
||||||
[true, true, false]
|
|
||||||
[7, 7, 7]
|
|
||||||
[1, 4, 9, 16, 25, 36]
|
|
||||||
[3, 4, 5, 6, 7, 8]
|
|
||||||
[3, 9, 4, 6, 12, 7]
|
|
||||||
[]
|
|
||||||
[true, true, true, true, true, true]
|
|
||||||
[1a, 2a, 3a, 4a, 5a, 6a]
|
|
||||||
[2, 3, 4, 5, 6, 7]
|
|
||||||
[2, 3, 8]
|
|
||||||
[1v, 2is, 3awesome]
|
|
||||||
[1, 4, 9, 16, 25, 36]
|
|
||||||
[1, 25, 100]
|
|
||||||
[1, 2, 3, 4, 5, 6]
|
|
||||||
[v, is, awesome]
|
|
||||||
[2, 3, 4]
|
|
||||||
[2, 3, 4]
|
|
||||||
[3, 4, 5]
|
|
||||||
[2, 3, 4]
|
|
||||||
[1, 2, 3]
|
|
||||||
[1, 2, 3]
|
|
||||||
[[1, 2, 3], [4, 5, 6]]
|
|
||||||
false
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
false
|
|
||||||
[1, 3, 5, hi]
|
|
||||||
[-3, 7, 42, 67, 108]
|
|
||||||
0
|
|
||||||
1
|
|
||||||
79
|
|
||||||
[0, 1, 15, 27, 38, 50, 79]
|
|
||||||
[0, 1, 15, 27, 38, 50, 79]
|
|
||||||
2
|
|
||||||
[14, 2, 3]
|
|
||||||
test b
|
|
||||||
[true, false, true]
|
|
||||||
1,1
|
|
||||||
2,2
|
|
||||||
3,3
|
|
||||||
4,4
|
|
||||||
1,1
|
|
||||||
2,2
|
|
||||||
3,3
|
|
||||||
4,4
|
|
||||||
{ val: 0 }
|
|
||||||
6
|
|
||||||
[2, 0, 2, 2]
|
|
||||||
[[1, 0, 0], [0, 0, 0]]
|
|
||||||
[[1, 0, 0], [1, 0, 0]]
|
|
||||||
[abc]
|
|
||||||
[0, 0, 0, 0]
|
|
||||||
[2, 2]
|
|
||||||
[1, 2, 3, 4]
|
|
||||||
[4, 3, 2, 1]
|
|
||||||
[c, b, a]
|
|
||||||
[[5, 6], [3, 4], [1, 2]]
|
|
||||||
5,5
|
|
||||||
4
|
|
||||||
1
|
|
||||||
xyz
|
|
||||||
def
|
|
||||||
abc
|
|
||||||
3
|
|
||||||
1
|
|
||||||
abc
|
|
||||||
a
|
|
||||||
3
|
|
||||||
4
|
|
||||||
def
|
|
||||||
a
|
|
||||||
11
|
|
||||||
33
|
|
||||||
[21, 24, 14, 20]
|
|
||||||
2
|
|
||||||
3
|
|
||||||
4
|
|
||||||
123
|
|
||||||
123
|
|
||||||
[[1, 2, 3]]
|
|
||||||
[[1, 2, 3]]
|
|
||||||
[[1, 2, 3]]
|
|
||||||
[[1, 2, 3]]
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
false
|
|
||||||
false
|
|
||||||
true
|
|
||||||
true
|
|
||||||
false
|
|
||||||
true
|
|
||||||
0
|
|
||||||
`exists`: true and `not exists`: false
|
|
||||||
[[], [], [], []]
|
|
||||||
[[], [], [123], []]
|
|
||||||
[{}, {}, {}, {}]
|
|
||||||
[{}, {}, {123: 123}, {}]
|
|
||||||
Numbers{
|
|
||||||
odds: [1, 3, 5]
|
|
||||||
evens: [2, 4]
|
|
||||||
}
|
|
||||||
Numbers{
|
|
||||||
odds: [3, 5, 7]
|
|
||||||
evens: [2, 6, 10]
|
|
||||||
}
|
|
||||||
[[10, 10, 10], [10, 10, 10], [10, 10, 10]]
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue