v.gen.js: fix references and add iterator to map (#10938)

pull/10922/head
playX 2021-07-24 15:35:17 +03:00 committed by GitHub
parent 45a15755b8
commit f51fa7e665
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 21 deletions

View File

@ -8,7 +8,9 @@ struct map {
// Removes the mapping of a particular key from the map. // Removes the mapping of a particular key from the map.
[unsafe] [unsafe]
pub fn (mut m map) delete(key voidptr) { pub fn (mut m map) delete(key voidptr) {
#m.m.delete(key) #m.map.delete(key)
} }
pub fn (m &map) free() {} pub fn (m &map) free() {}
#map.prototype[Symbol.iterator] = function () { return this.map[Symbol.iterator](); }

View File

@ -18,7 +18,7 @@ pub enum ProcessState {
} }
// todo(playX): fix reference member access in JS backend // todo(playX): fix reference member access in JS backend
// [heap] [heap]
pub struct Process { pub struct Process {
pub: pub:
filename string filename string
@ -41,8 +41,8 @@ pub mut:
// That is done because you may want to customize it first, // That is done because you may want to customize it first,
// by calling different set_ methods on it. // by calling different set_ methods on it.
// In order to start it, call p.run() or p.wait() // In order to start it, call p.run() or p.wait()
pub fn new_process(filename string) Process { pub fn new_process(filename string) &Process {
return Process{ return &Process{
filename: filename filename: filename
stdio_fd: [-1, -1, -1]! stdio_fd: [-1, -1, -1]!
} }
@ -71,20 +71,20 @@ pub fn (mut p Process) set_environment(envs map[string]string) {
} }
fn (mut p Process) spawn_internal() { fn (mut p Process) spawn_internal() {
#p.pid = $child_process.spawn( #p.val.pid = $child_process.spawn(
#p.filename+'', #p.val.filename+'',
#p.args.arr.map((x) => x.valueOf() + ''), #p.val.args.arr.map((x) => x.valueOf() + ''),
#{ #{
#env: (p.env_is_custom ? p.env : $process.env), #env: (p.val.env_is_custom ? p.val.env : $process.env),
#}) #})
#p.pid.on('error', function (err) { builtin.panic('Failed to start subprocess') }) #p.val.pid.on('error', function (err) { builtin.panic('Failed to start subprocess') })
p.status = .running p.status = .running
// todo(playX): stderr,stdin // todo(playX): stderr,stdin
if p.use_stdio_ctl { if p.use_stdio_ctl {
#p.pid.stdout.pipe(process.stdout) #p.val.pid.stdout.pipe(process.stdout)
#p.pid.stdin.pipe(process.stdin) #p.val.pid.stdin.pipe(process.stdin)
#p.pid.stderr.pipe(process.stderr) #p.val.pid.stderr.pipe(process.stderr)
} }
} }
@ -100,7 +100,7 @@ pub fn (mut p Process) signal_kill() {
if p.status !in [.running, .stopped] { if p.status !in [.running, .stopped] {
return return
} }
#p.pid.kill('SIGKILL'); #p.val.pid.kill('SIGKILL');
p.status = .aborted p.status = .aborted
} }
@ -109,7 +109,7 @@ pub fn (mut p Process) signal_stop() {
if p.status !in [.running, .stopped] { if p.status !in [.running, .stopped] {
return return
} }
#p.pid.kill('SIGSTOP'); #p.val.pid.kill('SIGSTOP');
p.status = .aborted p.status = .aborted
} }
@ -118,7 +118,7 @@ pub fn (mut p Process) signal_continue() {
if p.status != .stopped { if p.status != .stopped {
return return
} }
#p.pid.kill('SIGCONT'); #p.val.pid.kill('SIGCONT');
p.status = .running p.status = .running
return return
@ -137,7 +137,7 @@ pub fn (mut p Process) wait() {
} }
fn (mut p Process) wait_internal() { fn (mut p Process) wait_internal() {
#p.pid.on('exit', function (code) { console.log(code) }) #p.val.pid.on('exit', function (code) { console.log(code) })
} }
pub fn (mut p Process) set_redirect_stdio() { pub fn (mut p Process) set_redirect_stdio() {
@ -147,7 +147,7 @@ pub fn (mut p Process) set_redirect_stdio() {
pub fn (mut p Process) stdin_write(s string) { pub fn (mut p Process) stdin_write(s string) {
p.check_redirection_call('stdin_write') p.check_redirection_call('stdin_write')
#p.pid.stdin.write(s) #p.val.pid.stdin.write(s)
} }
// todo(playX): probably does not work // todo(playX): probably does not work
@ -157,7 +157,7 @@ pub fn (mut p Process) stdin_write(s string) {
pub fn (mut p Process) stdout_slurp() string { pub fn (mut p Process) stdout_slurp() string {
p.check_redirection_call('stdout_slurp') p.check_redirection_call('stdout_slurp')
mut res := '' mut res := ''
#p.pid.stdout.on('data', function (data) { res = new builtin.string(data) }) #p.val.pid.stdout.on('data', function (data) { res = new builtin.string(data) })
return res return res
} }

View File

@ -306,7 +306,8 @@ pub fn (mut g JsGen) init() {
g.definitions.writeln('"use strict";') g.definitions.writeln('"use strict";')
g.definitions.writeln('') g.definitions.writeln('')
g.definitions.writeln('var \$global = (new Function("return this"))();') g.definitions.writeln('var \$global = (new Function("return this"))();')
g.definitions.writeln('function \$ref(value) { this.val = value; } ')
g.definitions.writeln('\$ref.prototype.valueOf = function() { return this.val; } ')
if g.pref.backend != .js_node { if g.pref.backend != .js_node {
g.definitions.writeln('const \$process = {') g.definitions.writeln('const \$process = {')
g.definitions.writeln(' arch: "js",') g.definitions.writeln(' arch: "js",')
@ -681,10 +682,13 @@ fn (mut g JsGen) expr(node ast.Expr) {
// C pointers/references: ignore them // C pointers/references: ignore them
if node.op == .amp { if node.op == .amp {
type_sym := g.table.get_type_symbol(node.right_type) type_sym := g.table.get_type_symbol(node.right_type)
if !type_sym.is_primitive() && !node.right_type.is_pointer() { if !type_sym.is_primitive() && !node.right_type.is_pointer() {
g.write('{ val: ') // kind of weird way to handle references but it allows us to access type methods easily.
g.write('(function(x) {')
g.write(' return { val: x, __proto__: Object.getPrototypeOf(x), valueOf: function() { return this.val; } }})( ')
g.expr(node.right) g.expr(node.right)
g.write(' } ') g.write(')')
} else { } else {
g.expr(node.right) g.expr(node.right)
} }
@ -1111,6 +1115,9 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
if it.kind == .string { if it.kind == .string {
g.write('Array.from(') g.write('Array.from(')
g.expr(it.cond) g.expr(it.cond)
if it.cond_type.is_ptr() {
g.write('.valueOf()')
}
g.write('.str.split(\'\').entries(), ([$it.key_var, $val]) => [$it.key_var, ') g.write('.str.split(\'\').entries(), ([$it.key_var, $val]) => [$it.key_var, ')
if g.ns.name == 'builtin' { if g.ns.name == 'builtin' {
g.write('new ') g.write('new ')
@ -1118,11 +1125,17 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
g.write('byte($val)])') g.write('byte($val)])')
} else { } else {
g.expr(it.cond) g.expr(it.cond)
if it.cond_type.is_ptr() {
g.write('.valueOf()')
}
g.write('.entries()') g.write('.entries()')
} }
} else { } else {
g.write('for (const $val of ') g.write('for (const $val of ')
g.expr(it.cond) g.expr(it.cond)
if it.cond_type.is_ptr() {
g.write('.valueOf()')
}
if it.kind == .string { if it.kind == .string {
g.write(".str.split('')") g.write(".str.split('')")
} }
@ -1146,6 +1159,9 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
val := if it.val_var in ['', '_'] { '' } else { it.val_var } val := if it.val_var in ['', '_'] { '' } else { it.val_var }
g.write('for (let [$key, $val] of ') g.write('for (let [$key, $val] of ')
g.expr(it.cond) g.expr(it.cond)
if it.cond_type.is_ptr() {
g.write('.valueOf()')
}
g.writeln(') {') g.writeln(') {')
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
@ -1538,6 +1554,9 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
// TODO: Handle splice setting if it's implemented // TODO: Handle splice setting if it's implemented
if expr.index is ast.RangeExpr { if expr.index is ast.RangeExpr {
g.expr(expr.left) g.expr(expr.left)
if expr.left_type.is_ptr() {
g.write('.val')
}
g.write('.slice(') g.write('.slice(')
if expr.index.has_low { if expr.index.has_low {
g.expr(expr.index.low) g.expr(expr.index.low)
@ -1549,6 +1568,9 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
g.expr(expr.index.high) g.expr(expr.index.high)
} else { } else {
g.expr(expr.left) g.expr(expr.left)
if expr.left_type.is_ptr() {
g.write('.val')
}
g.write('.length') g.write('.length')
} }
g.write(')') g.write(')')
@ -1573,6 +1595,9 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
// TODO: Maybe use u16 there? JS String returns values up to 2^16-1 // TODO: Maybe use u16 there? JS String returns values up to 2^16-1
g.write('new byte(') g.write('new byte(')
g.expr(expr.left) g.expr(expr.left)
if expr.left_type.is_ptr() {
g.write('.val')
}
g.write('.str.charCodeAt(') g.write('.str.charCodeAt(')
g.expr(expr.index) g.expr(expr.index)
g.write('))') g.write('))')
@ -1580,6 +1605,9 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
} else { } else {
// TODO Does this cover all cases? // TODO Does this cover all cases?
g.expr(expr.left) g.expr(expr.left)
if expr.left_type.is_ptr() {
g.write('.val')
}
g.write('.arr') g.write('.arr')
g.write('[') g.write('[')
g.cast_stack << ast.int_type_idx g.cast_stack << ast.int_type_idx
@ -1756,6 +1784,9 @@ fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) {
fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) { fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) {
g.expr(it.expr) g.expr(it.expr)
if it.expr_type.is_ptr() {
g.write('.valueOf()')
}
g.write('.$it.field_name') g.write('.$it.field_name')
} }