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.
[unsafe]
pub fn (mut m map) delete(key voidptr) {
#m.m.delete(key)
#m.map.delete(key)
}
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
// [heap]
[heap]
pub struct Process {
pub:
filename string
@ -41,8 +41,8 @@ pub mut:
// That is done because you may want to customize it first,
// by calling different set_ methods on it.
// In order to start it, call p.run() or p.wait()
pub fn new_process(filename string) Process {
return Process{
pub fn new_process(filename string) &Process {
return &Process{
filename: filename
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() {
#p.pid = $child_process.spawn(
#p.filename+'',
#p.args.arr.map((x) => x.valueOf() + ''),
#p.val.pid = $child_process.spawn(
#p.val.filename+'',
#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
// todo(playX): stderr,stdin
if p.use_stdio_ctl {
#p.pid.stdout.pipe(process.stdout)
#p.pid.stdin.pipe(process.stdin)
#p.pid.stderr.pipe(process.stderr)
#p.val.pid.stdout.pipe(process.stdout)
#p.val.pid.stdin.pipe(process.stdin)
#p.val.pid.stderr.pipe(process.stderr)
}
}
@ -100,7 +100,7 @@ pub fn (mut p Process) signal_kill() {
if p.status !in [.running, .stopped] {
return
}
#p.pid.kill('SIGKILL');
#p.val.pid.kill('SIGKILL');
p.status = .aborted
}
@ -109,7 +109,7 @@ pub fn (mut p Process) signal_stop() {
if p.status !in [.running, .stopped] {
return
}
#p.pid.kill('SIGSTOP');
#p.val.pid.kill('SIGSTOP');
p.status = .aborted
}
@ -118,7 +118,7 @@ pub fn (mut p Process) signal_continue() {
if p.status != .stopped {
return
}
#p.pid.kill('SIGCONT');
#p.val.pid.kill('SIGCONT');
p.status = .running
return
@ -137,7 +137,7 @@ pub fn (mut p Process) wait() {
}
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() {
@ -147,7 +147,7 @@ pub fn (mut p Process) set_redirect_stdio() {
pub fn (mut p Process) stdin_write(s string) {
p.check_redirection_call('stdin_write')
#p.pid.stdin.write(s)
#p.val.pid.stdin.write(s)
}
// 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 {
p.check_redirection_call('stdout_slurp')
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
}

View File

@ -306,7 +306,8 @@ pub fn (mut g JsGen) init() {
g.definitions.writeln('"use strict";')
g.definitions.writeln('')
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 {
g.definitions.writeln('const \$process = {')
g.definitions.writeln(' arch: "js",')
@ -681,10 +682,13 @@ fn (mut g JsGen) expr(node ast.Expr) {
// C pointers/references: ignore them
if node.op == .amp {
type_sym := g.table.get_type_symbol(node.right_type)
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.write(' } ')
g.write(')')
} else {
g.expr(node.right)
}
@ -1111,6 +1115,9 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
if it.kind == .string {
g.write('Array.from(')
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, ')
if g.ns.name == 'builtin' {
g.write('new ')
@ -1118,11 +1125,17 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
g.write('byte($val)])')
} else {
g.expr(it.cond)
if it.cond_type.is_ptr() {
g.write('.valueOf()')
}
g.write('.entries()')
}
} else {
g.write('for (const $val of ')
g.expr(it.cond)
if it.cond_type.is_ptr() {
g.write('.valueOf()')
}
if it.kind == .string {
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 }
g.write('for (let [$key, $val] of ')
g.expr(it.cond)
if it.cond_type.is_ptr() {
g.write('.valueOf()')
}
g.writeln(') {')
g.stmts(it.stmts)
g.writeln('}')
@ -1538,6 +1554,9 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
// TODO: Handle splice setting if it's implemented
if expr.index is ast.RangeExpr {
g.expr(expr.left)
if expr.left_type.is_ptr() {
g.write('.val')
}
g.write('.slice(')
if expr.index.has_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)
} else {
g.expr(expr.left)
if expr.left_type.is_ptr() {
g.write('.val')
}
g.write('.length')
}
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
g.write('new byte(')
g.expr(expr.left)
if expr.left_type.is_ptr() {
g.write('.val')
}
g.write('.str.charCodeAt(')
g.expr(expr.index)
g.write('))')
@ -1580,6 +1605,9 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
} else {
// TODO Does this cover all cases?
g.expr(expr.left)
if expr.left_type.is_ptr() {
g.write('.val')
}
g.write('.arr')
g.write('[')
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) {
g.expr(it.expr)
if it.expr_type.is_ptr() {
g.write('.valueOf()')
}
g.write('.$it.field_name')
}