1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

js: os now compiles to the JS backend, more builtins & minor codegen fixes (#11302)

This commit is contained in:
playX
2021-08-25 14:40:53 +03:00
committed by GitHub
parent f257a23313
commit 109d5d5847
15 changed files with 479 additions and 369 deletions

View File

@ -32,12 +32,38 @@ struct Option {
err Error
}
// IError holds information about an error instance
pub interface IError {
msg string
code int
}
// Error is the default implementation of IError, that is returned by e.g. `error()`
pub struct Error {
pub:
msg string
code int
}
const none__ = IError(&None__{})
struct None__ {
msg string
code int
}
fn (_ None__) str() string {
return 'none'
}
pub fn (err IError) str() string {
return match err {
None__ { 'none' }
Error { err.msg }
else { '$err.type_name(): $err.msg' }
}
}
pub fn (o Option) str() string {
if o.state == 0 {
return 'Option{ ok }'
@ -48,21 +74,28 @@ pub fn (o Option) str() string {
return 'Option{ error: "$o.err" }'
}
pub fn error(s string) Option {
return Option{
state: 2
err: Error{
msg: s
}
[if trace_error ?]
fn trace_error(x string) {
eprintln('> ${@FN} | $x')
}
// error returns a default error instance containing the error given in `message`.
// Example: `if ouch { return error('an error occurred') }`
[inline]
pub fn error(message string) IError {
trace_error(message)
return &Error{
msg: message
}
}
pub fn error_with_code(s string, code int) Option {
return Option{
state: 2
err: Error{
msg: s
code: code
}
// error_with_code returns a default error instance containing the given `message` and error `code`.
// `if ouch { return error_with_code('an error occurred', 1) }`
[inline]
pub fn error_with_code(message string, code int) IError {
// trace_error('$message | code: $code')
return &Error{
msg: message
code: code
}
}

View File

@ -2,7 +2,15 @@ module builtin
pub fn (b byte) is_space() bool {
mut result := false
#result = /^\s*$/.test(String.fromCharCode(b))
#result.val = /^\s*$/.test(String.fromCharCode(b))
return result
}
pub fn (c byte) is_letter() bool {
result := false
#result.val = (c.val >= `a`.charCodeAt() && c.val <= `z`.charCodeAt()) || (c.val >= `A`.charCodeAt() && c.val <= `Z`.charCodeAt())
return result
}

View File

@ -541,3 +541,168 @@ pub fn (s string) split_nth(delim string, nth int) []string {
}
}
}
struct RepIndex {
idx int
val_idx int
}
// replace_each replaces all occurences of the string pairs given in `vals`.
// Example: assert 'ABCD'.replace_each(['B','C/','C','D','D','C']) == 'AC/DC'
[direct_array_access]
pub fn (s string) replace_each(vals []string) string {
if s.len == 0 || vals.len == 0 {
return s.clone()
}
if vals.len % 2 != 0 {
eprintln('string.replace_each(): odd number of strings')
return s.clone()
}
// `rep` - string to replace
// `with_` - string to replace with_
// Remember positions of all rep strings, and calculate the length
// of the new string to do just one allocation.
mut idxs := []RepIndex{}
mut idx := 0
s_ := s.clone()
#function setCharAt(str,index,chr) {
#if(index > str.length-1) return str;
#return str.substring(0,index) + chr + str.substring(index+1);
#}
for rep_i := 0; rep_i < vals.len; rep_i += 2 {
rep := vals[rep_i]
mut with_ := vals[rep_i + 1]
with_ = with_
for {
idx = s_.index_after(rep, idx)
if idx == -1 {
break
}
for i in 0 .. rep.len {
mut j_ := i
j_ = j_
#s_.str = setCharAt(s_.str,idx + i, String.fromCharCode(127))
}
idxs << RepIndex{
idx: idx
val_idx: rep_i
}
idx += rep.len
}
}
if idxs.len == 0 {
return s.clone()
}
idxs.sort(a.idx < b.idx)
mut b := ''
mut idx_pos := 0
mut cur_idx := idxs[idx_pos]
mut b_i := 0
for i := 0; i < s.len; i++ {
if i == cur_idx.idx {
rep := vals[cur_idx.val_idx]
with_ := vals[cur_idx.val_idx + 1]
for j in 0 .. with_.len {
mut j_ := j
j_ = j_
#b.str = setCharAt(b.str,b_i, with_.str[j])
//#b.str[b_i] = with_.str[j]
b_i++
}
i += rep.len - 1
idx_pos++
if idx_pos < idxs.len {
cur_idx = idxs[idx_pos]
}
} else {
#b.str = setCharAt(b.str,b_i,s.str[i]) //b.str[b_i] = s.str[i]
b_i++
}
}
return b
}
// last_index returns the position of the last occurence of the input string.
fn (s string) last_index_(p string) int {
if p.len > s.len || p.len == 0 {
return -1
}
mut i := s.len - p.len
for i >= 0 {
mut j := 0
for j < p.len && s[i + j] == p[j] {
j++
}
if j == p.len {
return i
}
i--
}
return -1
}
// last_index returns the position of the last occurence of the input string.
pub fn (s string) last_index(p string) ?int {
idx := s.last_index_(p)
if idx == -1 {
return none
}
return idx
}
pub fn (s string) trim_space() string {
res := ''
#res.str = s.str.trim()
return res
}
pub fn (s string) index_after(p string, start int) int {
if p.len > s.len {
return -1
}
mut strt := start
if start < 0 {
strt = 0
}
if start >= s.len {
return -1
}
mut i := strt
for i < s.len {
mut j := 0
mut ii := i
for j < p.len && s[ii] == p[j] {
j++
ii++
}
if j == p.len {
return i
}
i++
}
return -1
}
pub fn (s string) split_into_lines() []string {
mut res := []string{}
#let i = 0
#s.str.split('\n').forEach((str) => {
#res.arr[i] = new string(str);
#})
return res
}