v.gen.js: refactor code, fix alias codegen, `-stats` now again works with tests on the JS backend (#11512)
parent
ead5e66afd
commit
c175b4fd48
|
@ -2,6 +2,7 @@ module os
|
|||
|
||||
#const $fs = require('fs');
|
||||
#const $path = require('path');
|
||||
#const tty = require('tty')
|
||||
|
||||
pub const (
|
||||
path_delimiter = '/'
|
||||
|
@ -95,3 +96,10 @@ pub fn execute(cmd string) Result {
|
|||
output: stdout
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_atty(fd int) int {
|
||||
res := 0
|
||||
#res.val = +tty.isatty(fd.val)
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -258,6 +258,9 @@ pub fn (v &Builder) get_user_files() []string {
|
|||
if v.pref.is_test && v.pref.is_stats {
|
||||
user_files << os.join_path(preludes_path, 'tests_with_stats.v')
|
||||
}
|
||||
if v.pref.backend.is_js() && v.pref.is_stats && v.pref.is_test {
|
||||
user_files << os.join_path(preludes_path, 'stats_import.js.v')
|
||||
}
|
||||
if v.pref.is_prof {
|
||||
user_files << os.join_path(preludes_path, 'profiled_program.v')
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ fn (mut g JsGen) gen_sumtype_equality_fn(left_type ast.Type) string {
|
|||
g.sumtype_fn_definitions << ptr_styp
|
||||
info := left.sym.sumtype_info()
|
||||
mut fn_builder := strings.new_builder(512)
|
||||
defer {
|
||||
g.definitions.writeln(fn_builder.str())
|
||||
}
|
||||
fn_builder.writeln('function ${ptr_styp}_sumtype_eq(a,b) {')
|
||||
fn_builder.writeln('\tlet aProto = Object.getPrototypeOf(a);')
|
||||
fn_builder.writeln('\tlet bProto = Object.getPrototypeOf(b);')
|
||||
|
@ -48,7 +51,7 @@ fn (mut g JsGen) gen_sumtype_equality_fn(left_type ast.Type) string {
|
|||
}
|
||||
fn_builder.writeln('\treturn new bool(false);')
|
||||
fn_builder.writeln('}')
|
||||
g.definitions.writeln(fn_builder.str())
|
||||
|
||||
return ptr_styp
|
||||
}
|
||||
|
||||
|
|
|
@ -120,10 +120,11 @@ pub fn (mut g JsGen) base_type(t ast.Type) string {
|
|||
}
|
||||
|
||||
pub fn (mut g JsGen) typ(t ast.Type) string {
|
||||
sym := g.table.get_type_symbol(t)
|
||||
sym := g.table.get_final_type_symbol(t)
|
||||
if sym.kind == .voidptr {
|
||||
return 'any'
|
||||
}
|
||||
|
||||
styp := g.base_type(t)
|
||||
return styp
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ module js
|
|||
import v.ast
|
||||
import v.util
|
||||
import v.parser
|
||||
import strings
|
||||
|
||||
fn (mut g JsGen) js_mname(name_ string) string {
|
||||
mut is_js := false
|
||||
|
@ -348,3 +349,178 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
|
|||
}
|
||||
g.call_stack.delete_last()
|
||||
}
|
||||
|
||||
enum FnGenType {
|
||||
function
|
||||
struct_method
|
||||
alias_method
|
||||
iface_method
|
||||
}
|
||||
|
||||
fn (g &JsGen) fn_gen_type(it &ast.FnDecl) FnGenType {
|
||||
if it.is_method && g.table.get_type_symbol(it.params[0].typ).kind == .alias {
|
||||
return .alias_method
|
||||
} else if it.is_method && g.table.get_type_symbol(it.params[0].typ).kind == .interface_ {
|
||||
return .iface_method
|
||||
} else if it.is_method || it.no_body {
|
||||
return .struct_method
|
||||
} else {
|
||||
return .function
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_fn_decl(it ast.FnDecl) {
|
||||
res := g.fn_gen_type(it)
|
||||
if it.language == .js {
|
||||
return
|
||||
}
|
||||
if g.inside_builtin {
|
||||
g.builtin_fns << it.name
|
||||
}
|
||||
cur_fn_decl := g.fn_decl
|
||||
g.gen_method_decl(it, res)
|
||||
g.fn_decl = cur_fn_decl
|
||||
}
|
||||
|
||||
fn fn_has_go(node ast.FnDecl) bool {
|
||||
mut has_go := false
|
||||
for stmt in node.stmts {
|
||||
if stmt is ast.ExprStmt {
|
||||
if stmt.expr is ast.GoExpr {
|
||||
has_go = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return has_go
|
||||
}
|
||||
|
||||
fn (mut g JsGen) generic_fn_name(types []ast.Type, before string, is_decl bool) string {
|
||||
if types.len == 0 {
|
||||
return before
|
||||
}
|
||||
|
||||
mut name := before + '_T'
|
||||
for typ in types {
|
||||
name += '_' + strings.repeat_string('__ptr__', typ.nr_muls()) + g.typ(typ.set_nr_muls(0))
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_method_decl(it ast.FnDecl, typ FnGenType) {
|
||||
unsafe {
|
||||
g.fn_decl = &it
|
||||
}
|
||||
cur_fn_save := g.table.cur_fn
|
||||
defer {
|
||||
g.table.cur_fn = cur_fn_save
|
||||
}
|
||||
unsafe {
|
||||
g.table.cur_fn = &it
|
||||
}
|
||||
node := it
|
||||
mut name := it.name
|
||||
if name in ['+', '-', '*', '/', '%', '<', '=='] {
|
||||
name = util.replace_op(name)
|
||||
}
|
||||
|
||||
if node.is_method {
|
||||
unwrapped_rec_sym := g.table.get_type_symbol(g.unwrap_generic(node.receiver.typ))
|
||||
if unwrapped_rec_sym.kind == .placeholder {
|
||||
return
|
||||
}
|
||||
name = g.cc_type(node.receiver.typ, false) + '_' + name
|
||||
}
|
||||
|
||||
name = g.js_name(name)
|
||||
|
||||
name = g.generic_fn_name(g.table.cur_concrete_types, name, true)
|
||||
if name in parser.builtin_functions {
|
||||
name = 'builtin__$name'
|
||||
}
|
||||
has_go := fn_has_go(it)
|
||||
if it.is_pub && !it.is_method {
|
||||
g.push_pub_var(name)
|
||||
}
|
||||
is_main := it.name == 'main.main'
|
||||
g.gen_attrs(it.attrs)
|
||||
if is_main {
|
||||
// there is no concept of main in JS but we do have iife
|
||||
g.writeln('/* program entry point */')
|
||||
|
||||
// g.write('(')
|
||||
if has_go {
|
||||
g.write('async ')
|
||||
}
|
||||
g.write('function js_main(')
|
||||
} else if it.is_anon {
|
||||
g.write('function (')
|
||||
} else {
|
||||
c := name[0]
|
||||
if c in [`+`, `-`, `*`, `/`] {
|
||||
name = util.replace_op(name)
|
||||
}
|
||||
// type_name := g.typ(it.return_type)
|
||||
// generate jsdoc for the function
|
||||
g.doc.gen_fn(it)
|
||||
if has_go {
|
||||
g.write('async ')
|
||||
}
|
||||
|
||||
g.write('function ')
|
||||
|
||||
g.write('${name}(')
|
||||
if it.is_pub && !it.is_method {
|
||||
g.push_pub_var(name)
|
||||
}
|
||||
}
|
||||
mut args := it.params
|
||||
|
||||
g.fn_args(args, it.is_variadic)
|
||||
g.write(') {')
|
||||
for i, arg in args {
|
||||
is_varg := i == args.len - 1 && it.is_variadic
|
||||
arg_name := g.js_name(arg.name)
|
||||
if is_varg {
|
||||
g.writeln('$arg_name = new array($arg_name);')
|
||||
} else {
|
||||
if arg.typ.is_ptr() || arg.is_mut {
|
||||
g.writeln('$arg_name = new \$ref($arg_name)')
|
||||
}
|
||||
}
|
||||
}
|
||||
g.stmts(it.stmts)
|
||||
g.writeln('}')
|
||||
|
||||
if is_main {
|
||||
// g.write(')')
|
||||
}
|
||||
g.writeln('')
|
||||
|
||||
for attr in it.attrs {
|
||||
match attr.name {
|
||||
'export' {
|
||||
g.writeln('globalThis.$attr.arg = ${g.js_name(it.name)};')
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
||||
g.fn_decl = voidptr(0)
|
||||
}
|
||||
|
||||
fn (mut g JsGen) fn_args(args []ast.Param, is_variadic bool) {
|
||||
for i, arg in args {
|
||||
name := g.js_name(arg.name)
|
||||
is_varg := i == args.len - 1 && is_variadic
|
||||
if is_varg {
|
||||
g.write('...$name')
|
||||
} else {
|
||||
g.write(name)
|
||||
}
|
||||
// if its not the last argument
|
||||
if i < args.len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,6 @@ import v.util.version
|
|||
import v.depgraph
|
||||
import encoding.base64
|
||||
import v.gen.js.sourcemap
|
||||
import v.parser
|
||||
|
||||
struct MutArg {
|
||||
tmp_var string
|
||||
expr ast.Expr = ast.empty_expr()
|
||||
}
|
||||
|
||||
const (
|
||||
// https://ecma-international.org/ecma-262/#sec-reserved-words
|
||||
|
@ -285,24 +279,24 @@ pub fn (mut g JsGen) gen_js_main_for_tests() {
|
|||
g.writeln('')
|
||||
g.writeln('globalThis.VTEST=1')
|
||||
if g.pref.is_stats {
|
||||
g.writeln('let bt = start_testing($all_tfuncs.len, "$g.pref.path")')
|
||||
g.writeln('let bt = main__start_testing(new int($all_tfuncs.len), new string("$g.pref.path"))')
|
||||
}
|
||||
for tname in all_tfuncs {
|
||||
tcname := g.js_name(tname)
|
||||
|
||||
if g.pref.is_stats {
|
||||
g.writeln('bt.testing_step_start("$tcname")')
|
||||
g.writeln('main__BenchedTests_testing_step_start(bt,new string("$tcname"))')
|
||||
}
|
||||
|
||||
g.writeln('try { ${tcname}(); } catch (_e) {} ')
|
||||
if g.pref.is_stats {
|
||||
g.writeln('bt.testing_step_end();')
|
||||
g.writeln('main__BenchedTests_testing_step_end(bt);')
|
||||
}
|
||||
}
|
||||
|
||||
g.writeln('')
|
||||
if g.pref.is_stats {
|
||||
g.writeln('bt.end_testing();')
|
||||
g.writeln('main__BenchedTests_end_testing(bt);')
|
||||
}
|
||||
g.dec_indent()
|
||||
g.writeln('}')
|
||||
|
@ -489,62 +483,6 @@ fn (mut g JsGen) get_alias(name string) string {
|
|||
}
|
||||
|
||||
fn (mut g JsGen) js_name(name_ string) string {
|
||||
/*
|
||||
mut is_js := false
|
||||
is_overload := ['+', '-', '*', '/', '==', '<', '>']
|
||||
mut name := name_
|
||||
if name.starts_with('JS.') {
|
||||
name = name[3..]
|
||||
is_js = true
|
||||
}
|
||||
ns := get_ns(name)
|
||||
name = if name in is_overload {
|
||||
match name {
|
||||
'+' {
|
||||
'\$add'
|
||||
}
|
||||
'-' {
|
||||
'\$sub'
|
||||
}
|
||||
'/' {
|
||||
'\$div'
|
||||
}
|
||||
'*' {
|
||||
'\$mul'
|
||||
}
|
||||
'%' {
|
||||
'\$mod'
|
||||
}
|
||||
'==' {
|
||||
'eq'
|
||||
}
|
||||
'>' {
|
||||
'\$gt'
|
||||
}
|
||||
'<' {
|
||||
'\$lt'
|
||||
}
|
||||
else {
|
||||
''
|
||||
}
|
||||
}
|
||||
} else if g.ns == 0 {
|
||||
name
|
||||
} else if ns == g.ns.name {
|
||||
name.split('.').last()
|
||||
} else {
|
||||
g.get_alias(name)
|
||||
}
|
||||
mut parts := name.split('.')
|
||||
if !is_js {
|
||||
for i, p in parts {
|
||||
if p in js.js_reserved {
|
||||
parts[i] = 'v_$p'
|
||||
}
|
||||
}
|
||||
}
|
||||
return parts.join('.')*/
|
||||
|
||||
mut name := name_
|
||||
if name.starts_with('JS.') {
|
||||
name = name[3..]
|
||||
|
@ -558,11 +496,9 @@ fn (mut g JsGen) js_name(name_ string) string {
|
|||
}
|
||||
|
||||
fn (mut g JsGen) stmts(stmts []ast.Stmt) {
|
||||
g.inc_indent()
|
||||
for stmt in stmts {
|
||||
g.stmt(stmt)
|
||||
}
|
||||
g.dec_indent()
|
||||
}
|
||||
|
||||
[inline]
|
||||
|
@ -619,6 +555,11 @@ fn (mut g JsGen) gen_global_decl(node ast.GlobalDecl) {
|
|||
}
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_alias_type_decl(node ast.AliasTypeDecl) {
|
||||
name := if g.ns.name == 'builtin' { node.name } else { '${g.js_name(g.ns.name)}__$node.name' }
|
||||
g.writeln('function ${name}(val) { return val; }')
|
||||
}
|
||||
|
||||
fn (mut g JsGen) stmt_no_semi(node ast.Stmt) {
|
||||
g.stmt_start_pos = g.out.len
|
||||
match node {
|
||||
|
@ -822,7 +763,12 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
|||
g.gen_struct_decl(node)
|
||||
}
|
||||
ast.TypeDecl {
|
||||
// skip JS has no typedecl
|
||||
match node {
|
||||
ast.AliasTypeDecl {
|
||||
g.gen_alias_type_decl(node)
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1275,7 +1221,9 @@ fn (mut g JsGen) gen_attrs(attrs []ast.Attr) {
|
|||
|
||||
fn (mut g JsGen) gen_block(it ast.Block) {
|
||||
g.writeln('{')
|
||||
g.inc_indent()
|
||||
g.stmts(it.stmts)
|
||||
g.dec_indent()
|
||||
g.writeln('}')
|
||||
}
|
||||
|
||||
|
@ -1338,59 +1286,9 @@ fn (mut g JsGen) gen_expr_stmt_no_semi(it ast.ExprStmt) {
|
|||
g.expr(it.expr)
|
||||
}
|
||||
|
||||
enum FnGenType {
|
||||
function
|
||||
struct_method
|
||||
alias_method
|
||||
iface_method
|
||||
}
|
||||
|
||||
fn (g &JsGen) fn_gen_type(it &ast.FnDecl) FnGenType {
|
||||
if it.is_method && g.table.get_type_symbol(it.params[0].typ).kind == .alias {
|
||||
return .alias_method
|
||||
} else if it.is_method && g.table.get_type_symbol(it.params[0].typ).kind == .interface_ {
|
||||
return .iface_method
|
||||
} else if it.is_method || it.no_body {
|
||||
return .struct_method
|
||||
} else {
|
||||
return .function
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_fn_decl(it ast.FnDecl) {
|
||||
res := g.fn_gen_type(it)
|
||||
if it.language == .js {
|
||||
return
|
||||
}
|
||||
/*
|
||||
if res == .struct_method {
|
||||
// Struct methods are handled by class generation code.
|
||||
return
|
||||
}*/
|
||||
if g.inside_builtin {
|
||||
g.builtin_fns << it.name
|
||||
}
|
||||
cur_fn_decl := g.fn_decl
|
||||
g.gen_method_decl(it, res)
|
||||
g.fn_decl = cur_fn_decl
|
||||
}
|
||||
|
||||
fn fn_has_go(node ast.FnDecl) bool {
|
||||
mut has_go := false
|
||||
for stmt in node.stmts {
|
||||
if stmt is ast.ExprStmt {
|
||||
if stmt.expr is ast.GoExpr {
|
||||
has_go = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return has_go
|
||||
}
|
||||
|
||||
// cc_type whether to prefix 'struct' or not (C__Foo -> struct Foo)
|
||||
fn (mut g JsGen) cc_type(typ ast.Type, is_prefix_struct bool) string {
|
||||
sym := g.table.get_type_symbol(g.unwrap_generic(typ))
|
||||
sym := g.table.get_final_type_symbol(g.unwrap_generic(typ))
|
||||
mut styp := sym.cname
|
||||
match mut sym.info {
|
||||
ast.Struct, ast.Interface, ast.SumType {
|
||||
|
@ -1408,231 +1306,6 @@ fn (mut g JsGen) cc_type(typ ast.Type, is_prefix_struct bool) string {
|
|||
return styp
|
||||
}
|
||||
|
||||
fn (mut g JsGen) generic_fn_name(types []ast.Type, before string, is_decl bool) string {
|
||||
if types.len == 0 {
|
||||
return before
|
||||
}
|
||||
|
||||
mut name := before + '_T'
|
||||
for typ in types {
|
||||
name += '_' + strings.repeat_string('__ptr__', typ.nr_muls()) + g.typ(typ.set_nr_muls(0))
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_method_decl(it ast.FnDecl, typ FnGenType) {
|
||||
unsafe {
|
||||
g.fn_decl = &it
|
||||
}
|
||||
cur_fn_save := g.table.cur_fn
|
||||
defer {
|
||||
g.table.cur_fn = cur_fn_save
|
||||
}
|
||||
unsafe {
|
||||
g.table.cur_fn = &it
|
||||
}
|
||||
node := it
|
||||
mut name := it.name
|
||||
if name in ['+', '-', '*', '/', '%', '<', '=='] {
|
||||
name = util.replace_op(name)
|
||||
}
|
||||
|
||||
if node.is_method {
|
||||
unwrapped_rec_sym := g.table.get_type_symbol(g.unwrap_generic(node.receiver.typ))
|
||||
if unwrapped_rec_sym.kind == .placeholder {
|
||||
return
|
||||
}
|
||||
name = g.cc_type(node.receiver.typ, false) + '_' + name
|
||||
}
|
||||
|
||||
name = g.js_name(name)
|
||||
|
||||
name = g.generic_fn_name(g.table.cur_concrete_types, name, true)
|
||||
if name in parser.builtin_functions {
|
||||
name = 'builtin__$name'
|
||||
}
|
||||
has_go := fn_has_go(it)
|
||||
if it.is_pub && !it.is_method {
|
||||
g.push_pub_var(name)
|
||||
}
|
||||
is_main := it.name == 'main.main'
|
||||
g.gen_attrs(it.attrs)
|
||||
if is_main {
|
||||
// there is no concept of main in JS but we do have iife
|
||||
g.writeln('/* program entry point */')
|
||||
|
||||
// g.write('(')
|
||||
if has_go {
|
||||
g.write('async ')
|
||||
}
|
||||
g.write('function js_main(')
|
||||
} else if it.is_anon {
|
||||
g.write('function (')
|
||||
} else {
|
||||
c := name[0]
|
||||
if c in [`+`, `-`, `*`, `/`] {
|
||||
name = util.replace_op(name)
|
||||
}
|
||||
// type_name := g.typ(it.return_type)
|
||||
// generate jsdoc for the function
|
||||
g.doc.gen_fn(it)
|
||||
if has_go {
|
||||
g.write('async ')
|
||||
}
|
||||
|
||||
g.write('function ')
|
||||
|
||||
g.write('${name}(')
|
||||
if it.is_pub && !it.is_method {
|
||||
g.push_pub_var(name)
|
||||
}
|
||||
}
|
||||
mut args := it.params
|
||||
|
||||
g.fn_args(args, it.is_variadic)
|
||||
g.write(') {')
|
||||
for i, arg in args {
|
||||
is_varg := i == args.len - 1 && it.is_variadic
|
||||
arg_name := g.js_name(arg.name)
|
||||
if is_varg {
|
||||
g.writeln('$arg_name = new array($arg_name);')
|
||||
} else {
|
||||
if arg.typ.is_ptr() || arg.is_mut {
|
||||
g.writeln('$arg_name = new \$ref($arg_name)')
|
||||
}
|
||||
}
|
||||
}
|
||||
g.stmts(it.stmts)
|
||||
g.writeln('}')
|
||||
|
||||
if is_main {
|
||||
// g.write(')')
|
||||
}
|
||||
g.writeln('')
|
||||
|
||||
for attr in it.attrs {
|
||||
match attr.name {
|
||||
'export' {
|
||||
g.writeln('globalThis.$attr.arg = ${g.js_name(it.name)};')
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
/*
|
||||
if typ == .alias_method || typ == .iface_method {
|
||||
sym := g.table.get_final_type_symbol(it.params[0].typ.set_nr_muls(0))
|
||||
name := g.js_name(sym.name)
|
||||
if name in js.v_types {
|
||||
g.writeln('')
|
||||
}
|
||||
g.writeln('${name}.prototype.$it.name = function ')
|
||||
}
|
||||
has_go := fn_has_go(it)
|
||||
is_main := it.name == 'main.main'
|
||||
g.gen_attrs(it.attrs)
|
||||
if is_main {
|
||||
// there is no concept of main in JS but we do have iife
|
||||
g.writeln('/* program entry point */')
|
||||
|
||||
g.write('(')
|
||||
if has_go {
|
||||
g.write('async ')
|
||||
}
|
||||
g.write('function(')
|
||||
} else if it.is_anon {
|
||||
g.write('function (')
|
||||
} else {
|
||||
mut name := g.js_name(it.name)
|
||||
c := name[0]
|
||||
if c in [`+`, `-`, `*`, `/`] {
|
||||
name = util.replace_op(name)
|
||||
}
|
||||
// type_name := g.typ(it.return_type)
|
||||
// generate jsdoc for the function
|
||||
g.doc.gen_fn(it)
|
||||
if has_go {
|
||||
g.write('async ')
|
||||
}
|
||||
if !it.is_method {
|
||||
g.write('function ')
|
||||
} else {
|
||||
if it.attrs.contains('js_getter') {
|
||||
g.write('get ')
|
||||
} else if it.attrs.contains('js_setter') {
|
||||
g.write('set ')
|
||||
}
|
||||
}
|
||||
g.write('${name}(')
|
||||
if it.is_pub && !it.is_method {
|
||||
g.push_pub_var(name)
|
||||
}
|
||||
}
|
||||
mut args := it.params
|
||||
if it.is_method {
|
||||
args = args[1..]
|
||||
}
|
||||
g.fn_args(args, it.is_variadic)
|
||||
if it.is_method {
|
||||
if args.len > 0 {
|
||||
g.write(', ')
|
||||
}
|
||||
if it.params[0].is_mut || it.params[0].typ.is_ptr() {
|
||||
g.write('${it.params[0].name} = new \$ref(this)')
|
||||
} else {
|
||||
g.write('${it.params[0].name} = this')
|
||||
}
|
||||
}
|
||||
g.writeln(') {')
|
||||
for i, arg in args {
|
||||
is_varg := i == args.len - 1 && it.is_variadic
|
||||
name := g.js_name(arg.name)
|
||||
if is_varg {
|
||||
g.writeln('$name = new array($name);')
|
||||
} else {
|
||||
if arg.typ.is_ptr() || arg.is_mut {
|
||||
g.writeln('$name = new \$ref($name)')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.stmts(it.stmts)
|
||||
g.writeln('}')
|
||||
for attr in it.attrs {
|
||||
match attr.name {
|
||||
'export' {
|
||||
g.writeln('globalThis.$attr.arg = ${g.js_name(it.name)};')
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
if is_main {
|
||||
g.write(')();')
|
||||
} else if typ != .struct_method {
|
||||
// g.write(';')
|
||||
}
|
||||
if typ == .struct_method || typ == .alias_method || typ == .iface_method {
|
||||
g.writeln('\n')
|
||||
}
|
||||
*/
|
||||
g.fn_decl = voidptr(0)
|
||||
}
|
||||
|
||||
fn (mut g JsGen) fn_args(args []ast.Param, is_variadic bool) {
|
||||
for i, arg in args {
|
||||
name := g.js_name(arg.name)
|
||||
is_varg := i == args.len - 1 && is_variadic
|
||||
if is_varg {
|
||||
g.write('...$name')
|
||||
} else {
|
||||
g.write(name)
|
||||
}
|
||||
// if its not the last argument
|
||||
if i < args.len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_for_c_stmt(it ast.ForCStmt) {
|
||||
g.inside_loop = true
|
||||
g.write('for (')
|
||||
|
@ -1918,11 +1591,6 @@ fn (mut g JsGen) gen_struct_decl(node ast.StructDecl) {
|
|||
g.writeln('};\n')
|
||||
g.dec_indent()
|
||||
|
||||
/*
|
||||
for cfn in fns {
|
||||
g.gen_method_decl(cfn, .struct_method)
|
||||
}*/
|
||||
|
||||
if node.is_pub {
|
||||
g.push_pub_var(name)
|
||||
}
|
||||
|
@ -2553,11 +2221,12 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
|
|||
g.write('.valueOf()')
|
||||
}
|
||||
g.write('.arr')
|
||||
g.write('[+')
|
||||
g.write('[Number(')
|
||||
g.cast_stack << ast.int_type_idx
|
||||
g.expr(expr.index)
|
||||
g.write('.valueOf()')
|
||||
g.cast_stack.delete_last()
|
||||
g.write(']')
|
||||
g.write(')]')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2617,37 +2286,6 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
|
|||
g.write('.valueOf()')
|
||||
g.write(')')
|
||||
} else if it.op == .eq || it.op == .ne {
|
||||
/*
|
||||
has_operator_overloading := g.table.type_has_method(l_sym, '==')
|
||||
if has_operator_overloading {
|
||||
g.expr(it.left)
|
||||
g.gen_deref_ptr(it.left_type)
|
||||
g.write('.eq(')
|
||||
g.expr(it.right)
|
||||
g.gen_deref_ptr(it.right_type)
|
||||
g.write(')')
|
||||
// Shallow equatables
|
||||
} else if l_sym.kind in js.shallow_equatables && r_sym.kind in js.shallow_equatables {
|
||||
// wrap left expr in parens so binary operations will work correctly.
|
||||
g.write('(')
|
||||
g.expr(it.left)
|
||||
g.gen_deref_ptr(it.left_type)
|
||||
g.write(')')
|
||||
g.write('.eq(')
|
||||
g.cast_stack << int(l_sym.kind)
|
||||
g.expr(it.right)
|
||||
g.gen_deref_ptr(it.right_type)
|
||||
g.cast_stack.delete_last()
|
||||
g.write(')')
|
||||
} else {
|
||||
g.write('vEq(')
|
||||
g.expr(it.left)
|
||||
g.gen_deref_ptr(it.left_type)
|
||||
g.write(', ')
|
||||
g.expr(it.right)
|
||||
g.gen_deref_ptr(it.right_type)
|
||||
g.write(')')
|
||||
}*/
|
||||
node := it
|
||||
left := g.unwrap(node.left_type)
|
||||
right := g.unwrap(node.right_type)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
module stats_import
|
Loading…
Reference in New Issue