js: fix string.bytes codegen, readline, add tests for `strings` (#12060)
parent
e94e08475d
commit
8d1ba52d0c
|
@ -45,9 +45,9 @@ fn (mut a array_buffer) set(ix int, val voidptr) {
|
||||||
#array_buffer.prototype.set = function(ix,val) { array_buffer_set(this,ix,val); }
|
#array_buffer.prototype.set = function(ix,val) { array_buffer_set(this,ix,val); }
|
||||||
|
|
||||||
struct array {
|
struct array {
|
||||||
mut:
|
pub mut:
|
||||||
arr array_buffer
|
arr array_buffer
|
||||||
pub:
|
|
||||||
len int
|
len int
|
||||||
cap int
|
cap int
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,14 @@ fn v_sort(mut arr array, comparator fn (voidptr, voidptr) int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trim trims the array length to "index" without modifying the allocated data. If "index" is greater
|
||||||
|
// than len nothing will be changed.
|
||||||
|
pub fn (mut a array) trim(index int) {
|
||||||
|
if index < a.len {
|
||||||
|
a.len = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#function flatIntoArray(target, source, sourceLength, targetIndex, depth) {
|
#function flatIntoArray(target, source, sourceLength, targetIndex, depth) {
|
||||||
#"use strict";
|
#"use strict";
|
||||||
#
|
#
|
||||||
|
@ -368,7 +376,7 @@ pub fn (a &array) free() {
|
||||||
// todo: once (a []byte) will work rewrite this
|
// todo: once (a []byte) will work rewrite this
|
||||||
pub fn (a array) bytestr() string {
|
pub fn (a array) bytestr() string {
|
||||||
res := ''
|
res := ''
|
||||||
#a.arr.arr.forEach((item) => res.str += String.fromCharCode(+item))
|
#for (let i = 0;i < a.arr.len.valueOf();i++) res.str += String.fromCharCode(a.arr.get(new int(i)))
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ pub fn (s string) split(dot string) []string {
|
||||||
pub fn (s string) bytes() []byte {
|
pub fn (s string) bytes() []byte {
|
||||||
sep := ''
|
sep := ''
|
||||||
mut arr := s.str.split(sep.str).map(it.charCodeAt(0))
|
mut arr := s.str.split(sep.str).map(it.charCodeAt(0))
|
||||||
#arr = new array(arr)
|
#arr = new array(new array_buffer({arr,index_start: new int(0),len: new int(arr.length)}))
|
||||||
|
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
@ -735,11 +735,21 @@ pub fn (s string) index_after(p string, start int) int {
|
||||||
|
|
||||||
pub fn (s string) split_into_lines() []string {
|
pub fn (s string) split_into_lines() []string {
|
||||||
mut res := []string{}
|
mut res := []string{}
|
||||||
#let i = 0
|
if s.len == 0 {
|
||||||
#s.str.split('\n').forEach((str) => {
|
return res
|
||||||
#res.arr[i] = new string(str);
|
}
|
||||||
#})
|
mut start := 0
|
||||||
|
mut end := 0
|
||||||
|
for i := 0; i < s.len; i++ {
|
||||||
|
if s[i] == 10 {
|
||||||
|
end = if i > 0 && s[i - 1] == 13 { i - 1 } else { i }
|
||||||
|
res << if start == end { '' } else { s[start..end] }
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if start < s.len {
|
||||||
|
res << s[start..]
|
||||||
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
module readline
|
||||||
|
|
||||||
|
#const $readline = require('readline')
|
||||||
|
|
||||||
|
struct Termios {}
|
||||||
|
|
||||||
|
// Only use standard os.get_line
|
||||||
|
// Need implementation for readline capabilities
|
||||||
|
//
|
||||||
|
// read_line_utf8 blocks execution in a loop and awaits user input
|
||||||
|
// characters from a terminal until `EOF` or `Enter` key is encountered
|
||||||
|
// in the input stream.
|
||||||
|
// read_line_utf8 returns the complete input line as an UTF-8 encoded `[]rune` or
|
||||||
|
// an error if the line is empty.
|
||||||
|
// The `prompt` `string` is output as a prefix text for the input capturing.
|
||||||
|
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
||||||
|
|
||||||
|
pub fn (mut r Readline) read_line(prompt string) ?string {
|
||||||
|
res := ''
|
||||||
|
print(prompt)
|
||||||
|
#const rl = $readline.createInterface({input: $process.stdin,output: $process.stdout,prompt: prompt.str})
|
||||||
|
#rl.prompt()
|
||||||
|
#rl.on('line', function (ans) { rl.prompt(); res.str = ans; rl.close();})
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_line(prompt string) ?string {
|
||||||
|
mut r := Readline{}
|
||||||
|
s := r.read_line(prompt) ?
|
||||||
|
return s
|
||||||
|
}
|
|
@ -17,4 +17,4 @@ fn test_struct_readline() {
|
||||||
// eprintln('methods: $methods')
|
// eprintln('methods: $methods')
|
||||||
assert 'read_line_utf8' in methods
|
assert 'read_line_utf8' in methods
|
||||||
assert 'read_line' in methods
|
assert 'read_line' in methods
|
||||||
}
|
}
|
|
@ -3,32 +3,37 @@
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module strings
|
module strings
|
||||||
|
|
||||||
|
/*
|
||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
mut:
|
mut:
|
||||||
buf []byte
|
buf []byte
|
||||||
pub mut:
|
pub mut:
|
||||||
len int
|
len int
|
||||||
initial_size int = 1
|
initial_size int = 1
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
pub type Builder = []byte
|
||||||
|
|
||||||
pub fn new_builder(initial_size int) Builder {
|
pub fn new_builder(initial_size int) Builder {
|
||||||
return Builder{[]byte{cap: initial_size}, 0, initial_size}
|
return []byte{cap: initial_size}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut b Builder) write_b(data byte) {
|
pub fn (mut b Builder) write_b(data byte) {
|
||||||
b.buf << data
|
b << data
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut b Builder) write(data []byte) ?int {
|
pub fn (mut b Builder) write(data []byte) ?int {
|
||||||
if data.len == 0 {
|
if data.len == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
b.buf << data
|
b << data
|
||||||
return data.len
|
return data.len
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (b &Builder) byte_at(n int) byte {
|
pub fn (b &Builder) byte_at(n int) byte {
|
||||||
return b.buf[n]
|
unsafe {
|
||||||
|
return b[n]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut b Builder) write_string(s string) {
|
pub fn (mut b Builder) write_string(s string) {
|
||||||
|
@ -37,7 +42,7 @@ pub fn (mut b Builder) write_string(s string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for c in s {
|
for c in s {
|
||||||
b.buf << c
|
b << c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,14 +51,41 @@ pub fn (mut b Builder) writeln(s string) {
|
||||||
b.write_string(s)
|
b.write_string(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.buf << 10
|
b << 10
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut b Builder) str() string {
|
pub fn (mut b Builder) str() string {
|
||||||
s := ''
|
s := ''
|
||||||
|
|
||||||
#for (const c of b.val.buf.arr.arr)
|
#for (const c of b.val.arr.arr)
|
||||||
#s.str += String.fromCharCode(+c)
|
#s.str += String.fromCharCode(+c)
|
||||||
|
b.trim(0)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (mut b Builder) cut_last(n int) string {
|
||||||
|
cut_pos := b.len - n
|
||||||
|
x := b[cut_pos..]
|
||||||
|
res := x.bytestr()
|
||||||
|
b.trim(cut_pos)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut b Builder) go_back_to(pos int) {
|
||||||
|
b.trim(pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// go_back discards the last `n` bytes from the buffer
|
||||||
|
pub fn (mut b Builder) go_back(n int) {
|
||||||
|
b.trim(b.len - n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cut_to cuts the string after `pos` and returns it.
|
||||||
|
// if `pos` is superior to builder length, returns an empty string
|
||||||
|
// and cancel further operations
|
||||||
|
pub fn (mut b Builder) cut_to(pos int) string {
|
||||||
|
if pos > b.len {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return b.cut_last(b.len - pos)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
import strings
|
||||||
|
|
||||||
|
type MyInt = int
|
||||||
|
|
||||||
|
const maxn = 100000
|
||||||
|
|
||||||
|
fn test_sb() {
|
||||||
|
mut sb := strings.new_builder(100)
|
||||||
|
sb.write_string('hi')
|
||||||
|
sb.write_string('!')
|
||||||
|
sb.write_string('hello')
|
||||||
|
assert sb.len == 8
|
||||||
|
sb_end := sb.str()
|
||||||
|
assert sb_end == 'hi!hello'
|
||||||
|
assert sb.len == 0
|
||||||
|
///
|
||||||
|
sb = strings.new_builder(10)
|
||||||
|
sb.write_string('a')
|
||||||
|
sb.write_string('b')
|
||||||
|
assert sb.len == 2
|
||||||
|
assert sb.str() == 'ab'
|
||||||
|
// Test interpolation optimization
|
||||||
|
sb = strings.new_builder(10)
|
||||||
|
x := 10
|
||||||
|
y := MyInt(20)
|
||||||
|
sb.writeln('x = $x y = $y')
|
||||||
|
res := sb.str()
|
||||||
|
assert res[res.len - 1] == `\n`
|
||||||
|
println('"$res"')
|
||||||
|
assert res.trim_space() == 'x = 10 y = 20'
|
||||||
|
//
|
||||||
|
sb = strings.new_builder(10)
|
||||||
|
sb.write_string('x = $x y = $y')
|
||||||
|
assert sb.str() == 'x = 10 y = 20'
|
||||||
|
//$if !windows {
|
||||||
|
sb = strings.new_builder(10)
|
||||||
|
sb.write_string('123456')
|
||||||
|
last_2 := sb.cut_last(2)
|
||||||
|
assert last_2 == '56'
|
||||||
|
final_sb := sb.str()
|
||||||
|
assert final_sb == '1234'
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_big_sb() {
|
||||||
|
mut sb := strings.new_builder(100)
|
||||||
|
mut sb2 := strings.new_builder(10000)
|
||||||
|
for i in 0 .. maxn {
|
||||||
|
sb.writeln(i.str())
|
||||||
|
sb2.write_string('+')
|
||||||
|
}
|
||||||
|
s := sb.str()
|
||||||
|
lines := s.split_into_lines()
|
||||||
|
assert lines.len == maxn
|
||||||
|
assert lines[0] == '0'
|
||||||
|
assert lines[1] == '1'
|
||||||
|
assert lines[777] == '777'
|
||||||
|
assert lines[98765] == '98765'
|
||||||
|
println(sb2.len)
|
||||||
|
assert sb2.len == maxn
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_byte_write() {
|
||||||
|
mut sb := strings.new_builder(100)
|
||||||
|
temp_str := 'byte testing'
|
||||||
|
mut count := 0
|
||||||
|
for word in temp_str {
|
||||||
|
sb.write_b(word)
|
||||||
|
count++
|
||||||
|
assert count == sb.len
|
||||||
|
}
|
||||||
|
sb_final := sb.str()
|
||||||
|
assert sb_final == temp_str
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strings_builder_reuse() {
|
||||||
|
mut sb := strings.new_builder(256)
|
||||||
|
sb.write_string('world')
|
||||||
|
assert sb.str() == 'world'
|
||||||
|
sb.write_string('hello')
|
||||||
|
assert sb.str() == 'hello'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_cut_to() {
|
||||||
|
mut sb := strings.new_builder(16)
|
||||||
|
sb.write_string('hello')
|
||||||
|
assert sb.cut_to(3) == 'lo'
|
||||||
|
assert sb.len == 3
|
||||||
|
assert sb.cut_to(3) == ''
|
||||||
|
assert sb.len == 3
|
||||||
|
assert sb.cut_to(0) == 'hel'
|
||||||
|
assert sb.cut_to(32) == ''
|
||||||
|
assert sb.len == 0
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import strings
|
||||||
|
|
||||||
|
fn test_levenshtein_distance() {
|
||||||
|
assert strings.levenshtein_distance('', '') == 0
|
||||||
|
assert strings.levenshtein_distance('one', 'one') == 0
|
||||||
|
assert strings.levenshtein_distance('', 'two') == 3
|
||||||
|
assert strings.levenshtein_distance('three', '') == 5
|
||||||
|
assert strings.levenshtein_distance('bananna', '') == 7
|
||||||
|
assert strings.levenshtein_distance('cats', 'hats') == 1
|
||||||
|
assert strings.levenshtein_distance('hugs', 'shrugs') == 2
|
||||||
|
assert strings.levenshtein_distance('broom', 'shroom') == 2
|
||||||
|
assert strings.levenshtein_distance('flomax', 'volmax') == 3
|
||||||
|
}
|
|
@ -9,10 +9,8 @@ pub fn repeat(c byte, n int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn repeat_string(s string, n int) string {
|
pub fn repeat_string(s string, n int) string {
|
||||||
return ''
|
res := ''
|
||||||
/*
|
#res.str = s.str.repeat(n.valueOf())
|
||||||
// TODO: uncomment this. It is commented for now, so that `v doc strings` works
|
|
||||||
res := # s.repeat(n)
|
|
||||||
return res
|
return res
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import strings
|
||||||
|
|
||||||
|
fn test_repeat() {
|
||||||
|
assert strings.repeat(`x`, 10) == 'xxxxxxxxxx'
|
||||||
|
assert strings.repeat(`a`, 1) == 'a'
|
||||||
|
assert strings.repeat(`a`, 0) == ''
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_repeat_string() {
|
||||||
|
assert strings.repeat_string('abc', 3) == 'abcabcabc'
|
||||||
|
assert strings.repeat_string('abc', 1) == 'abc'
|
||||||
|
assert strings.repeat_string('abc', 0) == ''
|
||||||
|
assert strings.repeat_string('', 200) == ''
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
import strings.textscanner
|
||||||
|
|
||||||
|
fn test_remaining() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.remaining() == 3
|
||||||
|
s.next()
|
||||||
|
s.next()
|
||||||
|
assert s.remaining() == 1
|
||||||
|
s.next()
|
||||||
|
assert s.remaining() == 0
|
||||||
|
s.next()
|
||||||
|
s.next()
|
||||||
|
assert s.remaining() == 0
|
||||||
|
s.reset()
|
||||||
|
assert s.remaining() == 3
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_next() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.next() == `a`
|
||||||
|
assert s.next() == `b`
|
||||||
|
assert s.next() == `c`
|
||||||
|
assert s.next() == -1
|
||||||
|
assert s.next() == -1
|
||||||
|
assert s.next() == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_skip() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.next() == `a`
|
||||||
|
s.skip()
|
||||||
|
assert s.next() == `c`
|
||||||
|
assert s.next() == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_skip_n() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
s.skip_n(2)
|
||||||
|
assert s.next() == `c`
|
||||||
|
assert s.next() == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_peek() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.peek() == `a`
|
||||||
|
assert s.peek() == `a`
|
||||||
|
assert s.peek() == `a`
|
||||||
|
//
|
||||||
|
assert s.next() == `a`
|
||||||
|
assert s.next() == `b`
|
||||||
|
assert s.next() == `c`
|
||||||
|
assert s.next() == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_peek_n() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.peek_n(0) == `a`
|
||||||
|
assert s.peek_n(1) == `b`
|
||||||
|
assert s.peek_n(2) == `c`
|
||||||
|
assert s.peek_n(3) == -1
|
||||||
|
assert s.peek_n(4) == -1
|
||||||
|
//
|
||||||
|
assert s.next() == `a`
|
||||||
|
assert s.next() == `b`
|
||||||
|
assert s.next() == `c`
|
||||||
|
assert s.next() == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_back() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.next() == `a`
|
||||||
|
s.back()
|
||||||
|
assert s.next() == `a`
|
||||||
|
assert s.next() == `b`
|
||||||
|
s.back()
|
||||||
|
assert s.next() == `b`
|
||||||
|
assert s.next() == `c`
|
||||||
|
assert s.next() == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_back_n() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.next() == `a`
|
||||||
|
s.back_n(10)
|
||||||
|
assert s.next() == `a`
|
||||||
|
assert s.next() == `b`
|
||||||
|
assert s.next() == `c`
|
||||||
|
s.back_n(2)
|
||||||
|
assert s.next() == `b`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_peek_back() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.next() == `a`
|
||||||
|
assert s.next() == `b`
|
||||||
|
// check that calling .peek_back() multiple times
|
||||||
|
// does not change the state:
|
||||||
|
assert s.peek_back() == `a`
|
||||||
|
assert s.peek_back() == `a`
|
||||||
|
assert s.peek_back() == `a`
|
||||||
|
// advance, then peek_back again:
|
||||||
|
assert s.next() == `c`
|
||||||
|
assert s.peek_back() == `b`
|
||||||
|
// peeking before the start:
|
||||||
|
s.reset()
|
||||||
|
assert s.peek_back() == -1
|
||||||
|
// peeking right at the end:
|
||||||
|
s.goto_end()
|
||||||
|
assert s.peek_back() == `b`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_peek_back_n() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
s.goto_end()
|
||||||
|
assert s.peek_back_n(0) == `c`
|
||||||
|
assert s.peek_back_n(1) == `b`
|
||||||
|
assert s.peek_back_n(2) == `a`
|
||||||
|
assert s.peek_back_n(3) == -1
|
||||||
|
assert s.peek_back_n(4) == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_reset() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.next() == `a`
|
||||||
|
s.next()
|
||||||
|
s.next()
|
||||||
|
assert s.next() == -1
|
||||||
|
s.reset()
|
||||||
|
assert s.next() == `a`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_current() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
assert s.current() == -1
|
||||||
|
assert s.next() == `a`
|
||||||
|
assert s.current() == `a`
|
||||||
|
assert s.current() == `a`
|
||||||
|
assert s.peek_back() == -1
|
||||||
|
assert s.next() == `b`
|
||||||
|
assert s.current() == `b`
|
||||||
|
assert s.current() == `b`
|
||||||
|
assert s.peek_back() == `a`
|
||||||
|
assert s.next() == `c`
|
||||||
|
assert s.current() == `c`
|
||||||
|
assert s.next() == -1
|
||||||
|
assert s.current() == `c`
|
||||||
|
assert s.next() == -1
|
||||||
|
assert s.current() == `c`
|
||||||
|
s.reset()
|
||||||
|
assert s.current() == -1
|
||||||
|
assert s.next() == `a`
|
||||||
|
assert s.current() == `a`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_goto_end() {
|
||||||
|
mut s := textscanner.new('abc')
|
||||||
|
s.goto_end()
|
||||||
|
assert s.current() == `c`
|
||||||
|
}
|
|
@ -111,10 +111,18 @@ fn (mut g JsGen) sym_to_js_typ(sym ast.TypeSymbol) string {
|
||||||
return styp
|
return styp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn (mut g JsGen) base_type(t ast.Type) string {
|
pub fn (mut g JsGen) base_type(t ast.Type) string {
|
||||||
mut styp := g.cc_type(t, true)
|
mut styp := g.cc_type(t, true)
|
||||||
return styp
|
return styp
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
fn (mut g JsGen) base_type(_t ast.Type) string {
|
||||||
|
t := g.unwrap_generic(_t)
|
||||||
|
share := t.share()
|
||||||
|
mut styp := if share == .atomic_t { t.atomic_typename() } else { g.cc_type(t, true) }
|
||||||
|
return styp
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut g JsGen) typ(t ast.Type) string {
|
pub fn (mut g JsGen) typ(t ast.Type) string {
|
||||||
sym := g.table.get_final_type_symbol(t)
|
sym := g.table.get_final_type_symbol(t)
|
||||||
|
|
|
@ -106,7 +106,7 @@ fn (mut g JsGen) method_call(node ast.CallExpr) {
|
||||||
g.inc_indent()
|
g.inc_indent()
|
||||||
g.writeln('try {')
|
g.writeln('try {')
|
||||||
g.inc_indent()
|
g.inc_indent()
|
||||||
g.write('return builtin.unwrap(')
|
g.write('return unwrap(')
|
||||||
}
|
}
|
||||||
if node.name == 'str' {
|
if node.name == 'str' {
|
||||||
mut rec_type := node.receiver_type
|
mut rec_type := node.receiver_type
|
||||||
|
|
|
@ -8,7 +8,8 @@ fn (mut g JsGen) gen_plain_infix_expr(node ast.InfixExpr) {
|
||||||
l_sym := g.table.get_final_type_symbol(it.left_type)
|
l_sym := g.table.get_final_type_symbol(it.left_type)
|
||||||
r_sym := g.table.get_final_type_symbol(it.right_type)
|
r_sym := g.table.get_final_type_symbol(it.right_type)
|
||||||
greater_typ := g.greater_typ(it.left_type, it.right_type)
|
greater_typ := g.greater_typ(it.left_type, it.right_type)
|
||||||
g.write('new ${g.typ(greater_typ)}( ')
|
cast_ty := if greater_typ == it.left_type { l_sym.cname } else { r_sym.cname }
|
||||||
|
g.write('new ${g.js_name(cast_ty)}( ')
|
||||||
g.cast_stack << greater_typ
|
g.cast_stack << greater_typ
|
||||||
if (l_sym.kind == .i64 || l_sym.kind == .u64) || (r_sym.kind == .i64 || r_sym.kind == .u64) {
|
if (l_sym.kind == .i64 || l_sym.kind == .u64) || (r_sym.kind == .i64 || r_sym.kind == .u64) {
|
||||||
g.write('BigInt(')
|
g.write('BigInt(')
|
||||||
|
|
|
@ -1398,7 +1398,7 @@ fn (mut g JsGen) gen_expr_stmt_no_semi(it ast.ExprStmt) {
|
||||||
|
|
||||||
// cc_type whether to prefix 'struct' or not (C__Foo -> struct Foo)
|
// cc_type whether to prefix 'struct' or not (C__Foo -> struct Foo)
|
||||||
fn (mut g JsGen) cc_type(typ ast.Type, is_prefix_struct bool) string {
|
fn (mut g JsGen) cc_type(typ ast.Type, is_prefix_struct bool) string {
|
||||||
sym := g.table.get_final_type_symbol(g.unwrap_generic(typ))
|
sym := g.table.get_type_symbol(g.unwrap_generic(typ))
|
||||||
mut styp := sym.cname
|
mut styp := sym.cname
|
||||||
match mut sym.info {
|
match mut sym.info {
|
||||||
ast.Struct, ast.Interface, ast.SumType {
|
ast.Struct, ast.Interface, ast.SumType {
|
||||||
|
@ -2306,10 +2306,10 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
|
||||||
left_typ := g.table.get_type_symbol(expr.left_type)
|
left_typ := g.table.get_type_symbol(expr.left_type)
|
||||||
// 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 {
|
||||||
if left_typ.kind == .array {
|
if left_typ.kind == .string {
|
||||||
g.write('array_slice(')
|
|
||||||
} else {
|
|
||||||
g.write('string_slice(')
|
g.write('string_slice(')
|
||||||
|
} else {
|
||||||
|
g.write('array_slice(')
|
||||||
}
|
}
|
||||||
g.expr(expr.left)
|
g.expr(expr.left)
|
||||||
if expr.left_type.is_ptr() {
|
if expr.left_type.is_ptr() {
|
||||||
|
|
Loading…
Reference in New Issue