js: codegen & vlib fixes, replace the Game of Life CLI example (#12272)
parent
8a4756819a
commit
864d6eae6b
|
@ -1,25 +1,85 @@
|
|||
module main
|
||||
|
||||
import term
|
||||
import rand
|
||||
import time
|
||||
import automaton
|
||||
|
||||
fn print_automaton(a &automaton.Automaton) {
|
||||
for y := 1; y < a.field.maxy; y++ {
|
||||
mut s := ' '
|
||||
for x := 1; x < a.field.maxx; x++ {
|
||||
cell := a.field.get(x, y)
|
||||
s += if cell == 1 { '@' } else { '.' }
|
||||
const (
|
||||
cell = '█'
|
||||
nothing = ' '
|
||||
switches = {
|
||||
cell: nothing
|
||||
nothing: cell
|
||||
}
|
||||
println(s)
|
||||
transformers = [nothing, cell]
|
||||
)
|
||||
|
||||
struct Game {
|
||||
mut:
|
||||
grid [][]string
|
||||
}
|
||||
|
||||
fn (g Game) get_surrounding_alive_count(x int, y int) int {
|
||||
mut count := 0
|
||||
for i := x - 1; i <= x + 1; i++ {
|
||||
for j := y - 1; j <= y + 1; j++ {
|
||||
if (i != x || j != y) && i >= 0 && j >= 0 && i < g.grid.len && j < g.grid[x].len {
|
||||
if g.grid[i][j] == cell {
|
||||
count++
|
||||
}
|
||||
println('')
|
||||
}
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
fn (mut g Game) evolve() {
|
||||
mut temp_grid := [][]string{}
|
||||
for x in 0 .. g.grid.len {
|
||||
temp_grid << []string{}
|
||||
for y in 0 .. g.grid[x].len {
|
||||
count := g.get_surrounding_alive_count(x, y)
|
||||
if count == 3 || ((g.grid[x][y] == cell) && count == 2) {
|
||||
temp_grid[x] << cell
|
||||
} else {
|
||||
temp_grid[x] << nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.grid = temp_grid
|
||||
}
|
||||
|
||||
fn (mut g Game) display() {
|
||||
for y in 0 .. g.grid[0].len {
|
||||
mut line := ''
|
||||
for x in 0 .. g.grid.len {
|
||||
line += g.grid[x][y]
|
||||
}
|
||||
println(line)
|
||||
}
|
||||
}
|
||||
|
||||
fn new_game() Game {
|
||||
w, h := term.get_terminal_size()
|
||||
mut grid := [][]string{}
|
||||
for x in 0 .. w {
|
||||
grid << []string{}
|
||||
for _ in 0 .. h {
|
||||
is_live := rand.f64() > 0.82
|
||||
icon := transformers[int(is_live)]
|
||||
grid[x] << icon
|
||||
}
|
||||
}
|
||||
return Game{grid}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut a := automaton.gun()
|
||||
mut g := new_game()
|
||||
|
||||
g.display()
|
||||
for {
|
||||
a.update()
|
||||
print_automaton(a)
|
||||
g.evolve()
|
||||
term.erase_clear()
|
||||
g.display()
|
||||
time.sleep(100 * time.millisecond)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,10 @@ pub const (
|
|||
args = []string{}
|
||||
)
|
||||
|
||||
$if js_node {
|
||||
fn init() {
|
||||
$if js_node {
|
||||
#$process.argv.forEach(function(val,index) { os__args.arr[index] = new string(val); })
|
||||
}
|
||||
}
|
||||
|
||||
// real_path returns the full absolute path for fpath, with all relative ../../, symlinks and so on resolved.
|
||||
|
|
|
@ -4,7 +4,7 @@ module constants
|
|||
pub const (
|
||||
lower_mask = u64(0x00000000FFFFFFFF)
|
||||
max_u32 = 0xFFFFFFFF
|
||||
max_u64 = 0xFFFFFFFFFFFFFFFF
|
||||
max_u64 = u64(0xFFFFFFFFFFFFFFFF)
|
||||
max_u32_as_f32 = f32(max_u32) + 1
|
||||
max_u64_as_f64 = f64(max_u64) + 1
|
||||
u31_mask = u32(0x7FFFFFFF)
|
||||
|
|
|
@ -36,3 +36,9 @@ pub fn (t Time) local() Time {
|
|||
// if it is not we should try to use Intl for getting local time.
|
||||
return t
|
||||
}
|
||||
|
||||
pub fn sleep(dur Duration) {
|
||||
#let now = new Date().getTime()
|
||||
#let toWait = BigInt(dur.val) / BigInt(time__millisecond)
|
||||
#while (new Date().getTime() < now + Number(toWait)) {}
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
|
|||
typ_name: typ_name
|
||||
default_value: 'new Number(0)'
|
||||
// mask <=32 bit numbers with 0xffffffff
|
||||
constructor: 'this.val = Number(val) & 0xffffffff'
|
||||
constructor: 'this.val = Math.round(Number(val)) & 0xffffffff'
|
||||
value_of: 'Number(this.val)'
|
||||
to_string: 'this.valueOf().toString()'
|
||||
eq: 'new bool(self.valueOf() === other.valueOf())'
|
||||
|
@ -359,7 +359,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
|
|||
g.gen_builtin_prototype(
|
||||
typ_name: typ_name
|
||||
default_value: 'new Number(0)'
|
||||
constructor: 'if (typeof(val) == "string") { this.val = val.charCodeAt() } else if (val instanceof string) { this.val = val.str.charCodeAt(); } else { this.val = val | 0 }'
|
||||
constructor: 'if (typeof(val) == "string") { this.val = val.charCodeAt() } else if (val instanceof string) { this.val = val.str.charCodeAt(); } else { this.val = Math.round(val) }'
|
||||
value_of: 'this.val | 0'
|
||||
to_string: 'new string(this.val + "")'
|
||||
eq: 'new bool(self.valueOf() === other.valueOf())'
|
||||
|
|
|
@ -86,6 +86,7 @@ mut:
|
|||
array_sort_fn map[string]bool
|
||||
wasm_export map[string][]string
|
||||
wasm_import map[string][]string
|
||||
init_global map[string]map[string]ast.Expr // initializers for constants or globals, should be invoked before module init.
|
||||
}
|
||||
|
||||
fn (mut g JsGen) write_tests_definitions() {
|
||||
|
@ -204,6 +205,11 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
|||
|
||||
for mod_name in g.table.modules {
|
||||
g.writeln('// Initializations for module $mod_name')
|
||||
for global, expr in g.init_global[mod_name] {
|
||||
g.write('$global = ')
|
||||
g.expr(expr)
|
||||
g.writeln(';')
|
||||
}
|
||||
init_fn_name := '${mod_name}.init'
|
||||
if initfn := g.table.find_fn(init_fn_name) {
|
||||
if initfn.return_type == ast.void_type && initfn.params.len == 0 {
|
||||
|
@ -213,6 +219,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !g.pref.is_shared {
|
||||
g.write('loadRoutine().then(_ => js_main());')
|
||||
}
|
||||
|
@ -1214,7 +1221,7 @@ fn (mut g JsGen) gen_assert_stmt(orig_node ast.AssertStmt) {
|
|||
fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||
if stmt.left.len > stmt.right.len {
|
||||
// multi return
|
||||
g.write('const [')
|
||||
g.write('let [')
|
||||
for i, left in stmt.left {
|
||||
if !left.is_blank_ident() {
|
||||
g.expr(left)
|
||||
|
@ -1469,8 +1476,17 @@ fn (mut g JsGen) gen_const_decl(it ast.ConstDecl) {
|
|||
if field.is_pub {
|
||||
g.push_pub_var(field.name)
|
||||
}
|
||||
|
||||
if field.expr is ast.StringInterLiteral || field.expr is ast.StringLiteral
|
||||
|| field.expr is ast.IntegerLiteral || field.expr is ast.FloatLiteral
|
||||
|| field.expr is ast.BoolLiteral {
|
||||
g.write('const ${g.js_name(field.name)} = ')
|
||||
g.expr(field.expr)
|
||||
} else {
|
||||
g.write('let ${g.js_name(field.name)} = ')
|
||||
g.write('undefined')
|
||||
g.init_global[g.ns.name][g.js_name(field.name)] = field.expr
|
||||
}
|
||||
g.writeln(';')
|
||||
}
|
||||
g.writeln('')
|
||||
|
|
Loading…
Reference in New Issue