js: fix `rand` build, properly use key values on map, add `rand.string` (#12020)
parent
60ecbec8ea
commit
82f187e5e0
|
@ -1331,8 +1331,8 @@ fn test_struct_array_of_multi_type_in() {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
println(ivan in people)
|
println(ivan in people)
|
||||||
println('TODO: Map eq')
|
// println('TODO: Map eq')
|
||||||
// assert ivan in people
|
assert ivan in people
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_struct_array_of_multi_type_index() {
|
fn test_struct_array_of_multi_type_index() {
|
||||||
|
|
|
@ -2,6 +2,7 @@ module builtin
|
||||||
|
|
||||||
struct map {
|
struct map {
|
||||||
m JS.Map
|
m JS.Map
|
||||||
|
pub:
|
||||||
len int
|
len int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ pub fn (mut m map) delete(key voidptr) {
|
||||||
pub fn (m &map) free() {}
|
pub fn (m &map) free() {}
|
||||||
|
|
||||||
#map.prototype[Symbol.iterator] = function () { return this.map[Symbol.iterator](); }
|
#map.prototype[Symbol.iterator] = function () { return this.map[Symbol.iterator](); }
|
||||||
|
//#Object.defineProperty(map.prototype,"len",{get: function() { return this.map.size; }})
|
||||||
#map.prototype.toString = function () {
|
#map.prototype.toString = function () {
|
||||||
#function fmtKey(key) { return typeof key == 'string' ? '\'' + key + '\'' : key}
|
#function fmtKey(key) { return typeof key == 'string' ? '\'' + key + '\'' : key}
|
||||||
#let res = '{'
|
#let res = '{'
|
||||||
|
|
|
@ -125,3 +125,16 @@ pub fn hex(len int) string {
|
||||||
pub fn ascii(len int) string {
|
pub fn ascii(len int) string {
|
||||||
return string_from_set(ascii_chars, len)
|
return string_from_set(ascii_chars, len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deinit() {
|
||||||
|
unsafe {
|
||||||
|
default_rng.free() // free the implementation
|
||||||
|
free(default_rng) // free the interface wrapper itself
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// init initializes the default RNG.
|
||||||
|
fn init() {
|
||||||
|
default_rng = new_default()
|
||||||
|
C.atexit(deinit)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
module rand
|
||||||
|
|
||||||
|
// init initializes the default RNG.
|
||||||
|
fn init() {
|
||||||
|
default_rng = new_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn string(len int) string {
|
||||||
|
result := ''
|
||||||
|
#
|
||||||
|
#const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
#const charactersLength = characters.length;
|
||||||
|
#for (let i = 0;i < len.val;i++)
|
||||||
|
#result.str += characters.charAt(Math.random() * charactersLength);
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
|
@ -38,19 +38,6 @@ __global (
|
||||||
default_rng &PRNG
|
default_rng &PRNG
|
||||||
)
|
)
|
||||||
|
|
||||||
// init initializes the default RNG.
|
|
||||||
fn init() {
|
|
||||||
default_rng = new_default()
|
|
||||||
C.atexit(deinit)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deinit() {
|
|
||||||
unsafe {
|
|
||||||
default_rng.free() // free the implementation
|
|
||||||
free(default_rng) // free the interface wrapper itself
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance.
|
// new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance.
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn new_default(config config.PRNGConfigStruct) &PRNG {
|
pub fn new_default(config config.PRNGConfigStruct) &PRNG {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import rand
|
||||||
|
|
||||||
|
fn test_string() {
|
||||||
|
res := rand.string(4)
|
||||||
|
assert res.len == 4
|
||||||
|
println(res)
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module wyrand
|
||||||
|
|
||||||
|
pub fn (mut r WyRandRNG) free() {}
|
|
@ -250,9 +250,3 @@ pub fn (mut rng WyRandRNG) f64_in_range(min f64, max f64) f64 {
|
||||||
}
|
}
|
||||||
return min + rng.f64n(max - min)
|
return min + rng.f64n(max - min)
|
||||||
}
|
}
|
||||||
|
|
||||||
// free should be called when the generator is no longer needed
|
|
||||||
[unsafe]
|
|
||||||
pub fn (mut rng WyRandRNG) free() {
|
|
||||||
unsafe { free(rng) }
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
module wyrand
|
||||||
|
|
||||||
|
// free should be called when the generator is no longer needed
|
||||||
|
[unsafe]
|
||||||
|
pub fn (mut rng WyRandRNG) free() {
|
||||||
|
unsafe { free(rng) }
|
||||||
|
}
|
|
@ -589,9 +589,9 @@ fn (mut g JsGen) gen_str_for_map(info ast.Map, styp string, str_fn_name string)
|
||||||
g.definitions.writeln('\tstrings__Builder_write_string(sb, new string("{"));')
|
g.definitions.writeln('\tstrings__Builder_write_string(sb, new string("{"));')
|
||||||
g.definitions.writeln('\tlet i = 0;')
|
g.definitions.writeln('\tlet i = 0;')
|
||||||
g.definitions.writeln('\tfor (let [key,value] of m.map) {')
|
g.definitions.writeln('\tfor (let [key,value] of m.map) {')
|
||||||
|
g.definitions.writeln('\t\tkey = new ${key_styp}(key);')
|
||||||
if key_sym.kind == .string {
|
if key_sym.kind == .string {
|
||||||
g.definitions.writeln('\t\tstrings__Builder_write_string(sb, new string(key));')
|
g.definitions.writeln('\t\tstrings__Builder_write_string(sb, new string("\'" + key.str + "\'"));')
|
||||||
} else if key_sym.kind == .rune {
|
} else if key_sym.kind == .rune {
|
||||||
// tmp_str := str_intp_rune('${key_str_fn_name}(key)')
|
// tmp_str := str_intp_rune('${key_str_fn_name}(key)')
|
||||||
// g.definitions.writeln('\t\tstrings__Builder_write_string(sb, $tmp_str);')
|
// g.definitions.writeln('\t\tstrings__Builder_write_string(sb, $tmp_str);')
|
||||||
|
|
|
@ -300,11 +300,6 @@ fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeConfig) {
|
||||||
g.dec_indent()
|
g.dec_indent()
|
||||||
g.writeln('};\n')
|
g.writeln('};\n')
|
||||||
g.writeln('function ${c.typ_name}__eq(self,other) { return $c.eq; } ')
|
g.writeln('function ${c.typ_name}__eq(self,other) { return $c.eq; } ')
|
||||||
for method in g.method_fn_decls[c.typ_name] {
|
|
||||||
g.inside_def_typ_decl = true
|
|
||||||
g.gen_method_decl(method, .struct_method)
|
|
||||||
g.inside_def_typ_decl = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate builtin type definitions, used for casting and methods.
|
// generate builtin type definitions, used for casting and methods.
|
||||||
|
|
|
@ -294,11 +294,13 @@ fn (mut g JsGen) infix_in_not_in_op(node ast.InfixExpr) {
|
||||||
g.gen_deref_ptr(node.right_type)
|
g.gen_deref_ptr(node.right_type)
|
||||||
g.write('.map.has(')
|
g.write('.map.has(')
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
|
/*
|
||||||
if l_sym.sym.kind == .string {
|
if l_sym.sym.kind == .string {
|
||||||
g.write('.str')
|
g.write('.str')
|
||||||
} else {
|
} else {
|
||||||
g.write('.valueOf()')
|
g.write('.valueOf()')
|
||||||
}
|
}*/
|
||||||
|
g.write('.\$toJS()')
|
||||||
g.write(')')
|
g.write(')')
|
||||||
} else {
|
} else {
|
||||||
g.write('.str.includes(')
|
g.write('.str.includes(')
|
||||||
|
|
|
@ -200,6 +200,18 @@ 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')
|
||||||
|
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 {
|
||||||
|
mod_c_name := util.no_dots(mod_name)
|
||||||
|
init_fn_c_name := '${mod_c_name}__init'
|
||||||
|
g.writeln('${init_fn_c_name}();')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
g.write('js_main();')
|
g.write('js_main();')
|
||||||
g.escape_namespace()
|
g.escape_namespace()
|
||||||
// resolve imports
|
// resolve imports
|
||||||
|
@ -207,6 +219,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
||||||
nodes := deps_resolved.nodes
|
nodes := deps_resolved.nodes
|
||||||
|
|
||||||
mut out := g.definitions.str() + g.hashes()
|
mut out := g.definitions.str() + g.hashes()
|
||||||
|
|
||||||
// equality check for js objects
|
// equality check for js objects
|
||||||
// TODO: Fix msvc bug that's preventing $embed_file('fast_deep_equal.js')
|
// TODO: Fix msvc bug that's preventing $embed_file('fast_deep_equal.js')
|
||||||
// unsafe {
|
// unsafe {
|
||||||
|
@ -221,8 +234,8 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
||||||
out += 'if (typeof module === "object" && module.exports) module.exports = $export;\n'
|
out += 'if (typeof module === "object" && module.exports) module.exports = $export;\n'
|
||||||
}
|
}
|
||||||
out += '\n'
|
out += '\n'
|
||||||
out += g.out.str()
|
|
||||||
|
|
||||||
|
out += g.out.str()
|
||||||
/*
|
/*
|
||||||
TODO(playX): Again add support for these doc comments
|
TODO(playX): Again add support for these doc comments
|
||||||
for node in nodes {
|
for node in nodes {
|
||||||
|
@ -876,12 +889,18 @@ fn (mut g JsGen) expr(node ast.Expr) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
ast.PostfixExpr {
|
ast.PostfixExpr {
|
||||||
|
// match node.expr {
|
||||||
|
// ast.IndexExpr {
|
||||||
|
// g.gen_postfix_index_expr(node.expr,node.op)
|
||||||
|
// } else {
|
||||||
g.expr(node.expr)
|
g.expr(node.expr)
|
||||||
if node.op in [.inc, .dec] {
|
if node.op in [.inc, .dec] {
|
||||||
g.write('.val $node.op')
|
g.write('.val $node.op')
|
||||||
} else {
|
} else {
|
||||||
g.write(node.op.str())
|
g.write(node.op.str())
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
ast.PrefixExpr {
|
ast.PrefixExpr {
|
||||||
if node.op in [.amp, .mul] {
|
if node.op in [.amp, .mul] {
|
||||||
|
@ -1126,6 +1145,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mut array_set := false
|
mut array_set := false
|
||||||
|
mut map_set := false
|
||||||
match left {
|
match left {
|
||||||
ast.IndexExpr {
|
ast.IndexExpr {
|
||||||
g.expr(left.left)
|
g.expr(left.left)
|
||||||
|
@ -1133,11 +1153,17 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||||
g.write('.valueOf()')
|
g.write('.valueOf()')
|
||||||
}
|
}
|
||||||
array_set = true
|
array_set = true
|
||||||
|
|
||||||
if g.table.get_type_symbol(left.left_type).kind == .map {
|
if g.table.get_type_symbol(left.left_type).kind == .map {
|
||||||
g.write('.map.set(')
|
g.write('.map.set(')
|
||||||
|
map_set = true
|
||||||
} else {
|
} else {
|
||||||
g.write('.arr.set(')
|
g.write('.arr.set(')
|
||||||
}
|
}
|
||||||
|
if map_set {
|
||||||
|
g.expr(left.index)
|
||||||
|
g.write('.\$toJS(),')
|
||||||
|
} else {
|
||||||
g.write('new int(')
|
g.write('new int(')
|
||||||
g.cast_stack << ast.int_type_idx
|
g.cast_stack << ast.int_type_idx
|
||||||
g.expr(left.index)
|
g.expr(left.index)
|
||||||
|
@ -1145,6 +1171,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||||
g.cast_stack.delete_last()
|
g.cast_stack.delete_last()
|
||||||
g.write('),')
|
g.write('),')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
g.expr(left)
|
g.expr(left)
|
||||||
}
|
}
|
||||||
|
@ -2308,6 +2335,7 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
} else if left_typ.kind == .map {
|
} else if left_typ.kind == .map {
|
||||||
g.expr(expr.left)
|
g.expr(expr.left)
|
||||||
|
|
||||||
if expr.is_setter {
|
if expr.is_setter {
|
||||||
g.inside_map_set = true
|
g.inside_map_set = true
|
||||||
g.write('.map.set(')
|
g.write('.map.set(')
|
||||||
|
@ -2315,7 +2343,7 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
|
||||||
g.write('.map.get(')
|
g.write('.map.get(')
|
||||||
}
|
}
|
||||||
g.expr(expr.index)
|
g.expr(expr.index)
|
||||||
g.write('.toString()')
|
g.write('.\$toJS()')
|
||||||
if !expr.is_setter {
|
if !expr.is_setter {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
@ -2632,6 +2660,7 @@ fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) {
|
||||||
val := it.vals[i]
|
val := it.vals[i]
|
||||||
g.write('[')
|
g.write('[')
|
||||||
g.expr(key)
|
g.expr(key)
|
||||||
|
g.write('.\$toJS()')
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
g.expr(val)
|
g.expr(val)
|
||||||
g.write(']')
|
g.write(']')
|
||||||
|
@ -2950,3 +2979,95 @@ fn replace_op(s string) string {
|
||||||
else { '' }
|
else { '' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g JsGen) gen_postfix_index_expr(expr ast.IndexExpr, op token.Kind) {
|
||||||
|
left_typ := g.table.get_type_symbol(expr.left_type)
|
||||||
|
// TODO: Handle splice setting if it's implemented
|
||||||
|
if expr.index is ast.RangeExpr {
|
||||||
|
if left_typ.kind == .array {
|
||||||
|
g.write('array_slice(')
|
||||||
|
} else {
|
||||||
|
g.write('string_slice(')
|
||||||
|
}
|
||||||
|
g.expr(expr.left)
|
||||||
|
if expr.left_type.is_ptr() {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
|
g.write(',')
|
||||||
|
|
||||||
|
if expr.index.has_low {
|
||||||
|
g.expr(expr.index.low)
|
||||||
|
} else {
|
||||||
|
g.write('new int(0)')
|
||||||
|
}
|
||||||
|
g.write(', ')
|
||||||
|
if expr.index.has_high {
|
||||||
|
g.expr(expr.index.high)
|
||||||
|
} else {
|
||||||
|
g.expr(expr.left)
|
||||||
|
if expr.left_type.is_ptr() {
|
||||||
|
g.write('.valueOf()')
|
||||||
|
}
|
||||||
|
g.write('.len')
|
||||||
|
}
|
||||||
|
g.write(')')
|
||||||
|
} else if left_typ.kind == .map {
|
||||||
|
g.expr(expr.left)
|
||||||
|
|
||||||
|
if expr.is_setter {
|
||||||
|
g.inside_map_set = true
|
||||||
|
g.write('.map.set(')
|
||||||
|
} else {
|
||||||
|
g.write('.map.get(')
|
||||||
|
}
|
||||||
|
g.expr(expr.index)
|
||||||
|
g.write('.\$toJS()')
|
||||||
|
if !expr.is_setter {
|
||||||
|
g.write(')')
|
||||||
|
} else {
|
||||||
|
g.write(',')
|
||||||
|
lsym := g.table.get_type_symbol(expr.left_type)
|
||||||
|
key_typ := match lsym.info {
|
||||||
|
ast.Map {
|
||||||
|
lsym.info.value_type
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
verror('unreachable')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.write('new ${g.typ(key_typ)}(')
|
||||||
|
|
||||||
|
g.expr(expr.left)
|
||||||
|
g.write('.map.get(')
|
||||||
|
g.expr(expr.index)
|
||||||
|
g.write('.\$toJS())')
|
||||||
|
match op {
|
||||||
|
.inc {
|
||||||
|
g.write('.val + 1)')
|
||||||
|
}
|
||||||
|
.dec {
|
||||||
|
g.write('.val - 1)')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
verror('not yet implemented')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
|
} else if left_typ.kind == .string {
|
||||||
|
if expr.is_setter {
|
||||||
|
// TODO: What's the best way to do this?
|
||||||
|
// 'string'[3] = `o`
|
||||||
|
} else {
|
||||||
|
// 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('.valueOf()')
|
||||||
|
}
|
||||||
|
g.write('.str.charCodeAt(')
|
||||||
|
g.expr(expr.index)
|
||||||
|
g.write('))')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue