v.gen.js: fix references and add iterator to map (#10938)
parent
45a15755b8
commit
f51fa7e665
|
@ -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](); }
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue