jsgen: fix array push operator

pull/5030/head
spaceface777 2020-05-25 18:34:42 +02:00 committed by GitHub
parent 09dc2eed82
commit f8b237433f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 320 additions and 13 deletions

View File

@ -1196,15 +1196,35 @@ fn (mut g JsGen) gen_index_expr(it ast.IndexExpr) {
} }
fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
g.expr(it.left) l_sym := g.table.get_type_symbol(it.left_type)
r_sym := g.table.get_type_symbol(it.right_type)
mut op := it.op.str() if l_sym.kind == .array && it.op == .left_shift { // arr << 1
// in js == is non-strict & === is strict, always do strict g.expr(it.left)
if op == '==' { op = '===' } g.write('.push(')
else if op == '!=' { op = '!==' } if r_sym.kind == .array { g.write('...') } // arr << [1, 2]
g.expr(it.right)
g.write(')')
} else if it.op == .key_is { // foo is Foo
g.write('/*')
g.expr(it.left)
g.write(' is $r_sym.name')
g.write('*/0')
// TODO
} else {
g.expr(it.left)
g.write(' $op ') // in js == is non-strict & === is strict, always do strict
g.expr(it.right) if it.op == .eq {
g.write(' === ')
} else if it.op == .ne {
g.write(' !== ')
} else {
g.write(' $it.op ')
}
g.expr(it.right)
}
} }

View File

@ -1,5 +1,5 @@
// V_COMMIT_HASH 0de70e8 // V_COMMIT_HASH 0de70e8
// V_CURRENT_COMMIT_HASH 4271eb4 // V_CURRENT_COMMIT_HASH 2eac2a5
// Generated by the V compiler // Generated by the V compiler
"use strict"; "use strict";
@ -70,6 +70,9 @@ const main = (function () {
arr2[0] = 1; arr2[0] = 1;
arr2[0 + 1] = 2; arr2[0 + 1] = 2;
builtin.println(arr2); builtin.println(arr2);
arr2.push(6);
arr2.push(...[7, 8, 9]);
builtin.println(arr2);
/** @type {string} - slice4 */ /** @type {string} - slice4 */
const slice4 = idx1.slice(0, 4); const slice4 = idx1.slice(0, 4);
builtin.println(slice4); builtin.println(slice4);

View File

@ -24,6 +24,15 @@ arr2[0] = 1
arr2[0 + 1] = 2 arr2[0 + 1] = 2
println(arr2) println(arr2)
// TODO: This does not work for now
// arr2[0..1] = arr2[3..4]
// println(arr2)
// Array push operator
arr2 << 6
arr2 << [7, 8, 9]
println(arr2)
// String slices // String slices
slice4 := idx1[..4] slice4 := idx1[..4]
println(slice4) // 'Back' println(slice4) // 'Back'
@ -31,11 +40,6 @@ println(slice4) // 'Back'
// String indexes // String indexes
idx2 := slice4[0] idx2 := slice4[0]
// TODO: This does not work for now
// arr2[0..1] = arr2[3..4]
// println(arr2)
// Maps // Maps
mut m := map[string]string mut m := map[string]string
key := 'key' key := 'key'

View File

@ -0,0 +1,206 @@
// V_COMMIT_HASH 0de70e8
// V_CURRENT_COMMIT_HASH 1c2dbea
// Generated by the V compiler
"use strict";
const _CONSTS = Object.freeze({
/** @type {number} - w */
w: 30,
/** @type {number} - h */
h: 30
});
/** @namespace builtin */
const builtin = (function () {
/**
* @param {any} s
* @returns {void}
* @function
*/
function println(s) {
console.log(s);
}
/**
* @param {any} s
* @returns {void}
* @function
*/
function print(s) {
process.stdout.write(s);
}
/* module exports */
return {
println,
print,
};
})();
/** @namespace main */
const main = (function () {
/**
* @returns {void}
* @function
*/
function clear() {
console.clear();
}
/**
* @param {boolean[]} game
* @param {number} x
* @param {number} y
* @returns {boolean}
* @function
*/
function get(game, x, y) {
if (y < 0 || x < 0) {
return false;
}
if (y >= _CONSTS.h || x >= _CONSTS.w) {
return false;
}
return game[y][x];
}
/**
* @param {boolean[]} game
* @param {number} x
* @param {number} y
* @returns {number}
* @function
*/
function neighbours(game, x, y) {
/** @type {number} - count */
let count = 0;
if (get(game, x - 1, y - 1)) {
count++;
}
if (get(game, x, y - 1)) {
count++;
}
if (get(game, x + 1, y - 1)) {
count++;
}
if (get(game, x - 1, y)) {
count++;
}
if (get(game, x + 1, y)) {
count++;
}
if (get(game, x - 1, y + 1)) {
count++;
}
if (get(game, x, y + 1)) {
count++;
}
if (get(game, x + 1, y + 1)) {
count++;
}
return count;
}
/**
* @param {boolean[]} game
* @returns {boolean[]}
* @function
*/
function step(game) {
/** @type {boolean[]} - new_game */
let new_game = [[]];
for (let y = 0; y < game.length; ++y) {
let row = game[y];
/** @type {boolean[]} - new_row */
let new_row = [];
new_game[y] = new_row;
for (let x = 0; x < row.length; ++x) {
let cell = row[x];
/** @type {number} - count */
const count = neighbours(game, x, y);
new_row[x] = cell && count === 2 || count === 3;
}
}
return new_game;
}
/**
* @param {boolean[]} row
* @returns {string}
* @function
*/
function row_str(row) {
/** @type {string} - str */
let str = "";
for (let _tmp1 = 0; _tmp1 < row.length; ++_tmp1) {
let cell = row[_tmp1];
if (cell) {
str += "◼ ";
} else {
str += "◻ ";
}
}
return str;
}
/**
* @param {boolean[]} game
* @returns {void}
* @function
*/
function show(game) {
clear();
for (let _tmp2 = 0; _tmp2 < game.length; ++_tmp2) {
let row = game[_tmp2];
builtin.println(row_str(row));
}
}
/* program entry point */
(function() {
/** @type {boolean[]} - game */
let game = [[]];
for (let y = 0; y < _CONSTS.h; ++y) {
/** @type {boolean[]} - row */
let row = [];
for (let x = 0; x < _CONSTS.w; ++x) {
row[x] = false;
}
game[y] = row;
}
game[11][15] = true;
game[11][16] = true;
game[12][16] = true;
game[10][21] = true;
game[12][20] = true;
game[12][21] = true;
game[12][22] = true;
setInterval(function () {
show(game);
game = step(game);
}, 500);
})();
/* module exports */
return {};
})();

View File

@ -0,0 +1,74 @@
fn JS.setInterval(f fn (), ms int)
fn JS.console.clear()
fn clear() { JS.console.clear() }
const (w = 30 h = 30)
fn get(game [][]bool, x int, y int) bool {
if y < 0 || x < 0 { return false }
if y >= h || x >= w { return false }
return game[y][x]
}
fn neighbours(game [][]bool, x int, y int) int {
mut count := 0
if get(game, x-1, y-1) { count++ }
if get(game, x, y-1) { count++ }
if get(game, x+1, y-1) { count++ }
if get(game, x-1, y) { count++ }
if get(game, x+1, y) { count++ }
if get(game, x-1, y+1) { count++ }
if get(game, x, y+1) { count++ }
if get(game, x+1, y+1) { count++ }
return count
}
fn step(game [][]bool) [][]bool {
mut new_game := [[]bool{}]
for y, row in game {
mut new_row := []bool{}
new_game[y] = new_row
for x, cell in row {
count := neighbours(game, x, y)
new_row[x] = cell && count == 2 || count == 3 // TODO: count in [2, 3]
}
}
return new_game
}
fn row_str(row []bool) string {
mut str := ''
for cell in row {
if cell { str += ' ' }
else { str += ' ' }
}
return str
}
fn show(game [][]bool) {
clear()
for row in game {
println(row_str(row))
}
}
mut game := [[]bool{}]
for y in 0..h {
mut row := []bool{}
for x in 0..w {
row[x] = false
}
game[y] = row
}
game[11][15] = true
game[11][16] = true
game[12][16] = true
game[10][21] = true
game[12][20] = true
game[12][21] = true
game[12][22] = true
JS.setInterval(fn () { show(game) game = step(game) }, 500)