Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,183 @@
|
||||
module builtin
|
||||
|
||||
// used to generate JS throw statements.
|
||||
|
||||
$if js_node {
|
||||
#var $fs = require('fs');
|
||||
}
|
||||
|
||||
@[noreturn]
|
||||
pub fn js_throw(s any) {
|
||||
#throw s
|
||||
|
||||
for {}
|
||||
}
|
||||
|
||||
#let globalPrint, globalWrite;
|
||||
$if js_freestanding {
|
||||
#globalPrint = globalThis.print
|
||||
#globalWrite = (typeof globalThis.write === 'function')? write: globalThis.print
|
||||
}
|
||||
|
||||
pub fn flush_stdout() {
|
||||
// needed for parity with builtin.c.v
|
||||
}
|
||||
|
||||
pub fn flush_stderr() {
|
||||
// needed for parity with builtin.c.v
|
||||
}
|
||||
|
||||
pub fn println(s string) {
|
||||
$if js_freestanding {
|
||||
#globalPrint(s.str)
|
||||
} $else {
|
||||
#console.log(s.str)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print(s string) {
|
||||
$if js_node {
|
||||
#$process.stdout.write(s.str)
|
||||
} $else $if js_freestanding {
|
||||
#globalWrite(s.str)
|
||||
} $else {
|
||||
panic('Cannot `print` in a browser, use `println` instead')
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eprintln(s string) {
|
||||
$if js_freestanding {
|
||||
#globalPrint(s.str)
|
||||
} $else {
|
||||
#console.error(s.str)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eprint(s string) {
|
||||
$if js_node {
|
||||
#$process.stderr.write(s.str)
|
||||
} $else {
|
||||
panic('Cannot `eprint` in a browser, use `println` instead')
|
||||
}
|
||||
}
|
||||
|
||||
// input_character gives back a single character, read from the standard input.
|
||||
// It returns -1 on error (when the input is finished (EOF), on a broken pipe etc).
|
||||
pub fn input_character() int {
|
||||
$if js_node {
|
||||
mut ch := -1
|
||||
#try {
|
||||
#const read_buffer = Buffer.alloc(1)
|
||||
#const nbytes = $fs.readSync(0, read_buffer, 0, 1, null)
|
||||
#if (nbytes > 0) { ch.val = read_buffer[0] }
|
||||
#} catch (e) {}
|
||||
|
||||
return ch
|
||||
} $else {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// print_character writes the single character `ch` to the standard output.
|
||||
// It returns the written character value, or panics if the active JS runtime
|
||||
// does not support stdout writes.
|
||||
pub fn print_character(ch u8) int {
|
||||
print(ch.ascii_str())
|
||||
return ch
|
||||
}
|
||||
|
||||
// Exits the process in node, and halts execution in the browser
|
||||
// because `process.exit` is undefined. Workaround for not having
|
||||
// a 'real' way to exit in the browser.
|
||||
@[noreturn]
|
||||
pub fn exit(c int) {
|
||||
JS.process.exit(c)
|
||||
js_throw('exit(${c})')
|
||||
}
|
||||
|
||||
fn opt_ok(data voidptr, option Option) {
|
||||
#option.state = 0
|
||||
#option.err = none__
|
||||
#option.data = data
|
||||
}
|
||||
|
||||
pub fn unwrap(opt string) string {
|
||||
mut o := Option{}
|
||||
#o = opt
|
||||
if o.state != 0 {
|
||||
js_throw(o.err)
|
||||
}
|
||||
|
||||
mut res := ''
|
||||
#res = opt.data
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
fn js_stacktrace() string {
|
||||
stacktrace := ''
|
||||
#let err = new TypeError();
|
||||
#err.name = 'stacktrace: '
|
||||
#stacktrace.str = err.stack
|
||||
|
||||
return stacktrace
|
||||
}
|
||||
|
||||
// v_clone_value preserves standalone JS semantics for V clone methods.
|
||||
#function v_clone_value(value) {
|
||||
#if (value === null || value === undefined) return value;
|
||||
#if (value instanceof $ref) return new $ref(v_clone_value(value.val));
|
||||
#if (value instanceof array) return array_clone(value);
|
||||
#if (value instanceof map) {
|
||||
#let cloned = {}
|
||||
#for (const key in value.map) cloned[key] = { key: v_clone_value(value.map[key].key), val: v_clone_value(value.map[key].val) }
|
||||
#return new map(cloned);
|
||||
#}
|
||||
#if (typeof value !== 'object') return value;
|
||||
#if (typeof value.$toJS === 'function') {
|
||||
#let cloned = Object.create(Object.getPrototypeOf(value) || Object.prototype);
|
||||
#for (const key of Object.keys(value)) cloned[key] = v_clone_value(value[key]);
|
||||
#return cloned;
|
||||
#}
|
||||
#let cloned;
|
||||
#try {
|
||||
#cloned = typeof value.constructor === 'function' ? new value.constructor({}) : Object.create(Object.getPrototypeOf(value));
|
||||
#} catch (e) {
|
||||
#cloned = Object.create(Object.getPrototypeOf(value) || Object.prototype);
|
||||
#}
|
||||
#for (const key of Object.keys(value)) cloned[key] = v_clone_value(value[key]);
|
||||
#return cloned;
|
||||
#}
|
||||
|
||||
pub fn print_backtrace() {
|
||||
println(js_stacktrace())
|
||||
}
|
||||
|
||||
pub fn (a array) clone() array {
|
||||
mut res := empty_array()
|
||||
#const source = a instanceof $ref ? a.val : a
|
||||
#const cloned = source.arr.arr.slice(source.arr.index_start.valueOf(), source.arr.index_start.valueOf() + source.len.valueOf()).map(v_clone_value)
|
||||
#res = new array(new array_buffer({arr: cloned, len: new int(cloned.length), cap: new int(cloned.length), index_start: new int(0), has_slice: new bool(false)}))
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// Check for nil value
|
||||
pub fn isnil(val voidptr) bool {
|
||||
res := false
|
||||
// This one is kinda weird. In C and native backend we can cast booleans and integers to pointers
|
||||
// so we just check *for* all possible NULL-like values here.
|
||||
#if (typeof val == 'function') { res.val = false; } else {
|
||||
#val = val instanceof voidptr ? val.valueOf().val : val;
|
||||
#res.val = val === null || val === undefined || val === false || val === 0 || val === BigInt(0) || (val instanceof int ? val.val == 0 : false)
|
||||
#}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (f float_literal) str() string {
|
||||
res := ''
|
||||
#res.str += f.valueOf()
|
||||
|
||||
return res
|
||||
}
|
||||
Reference in new issue
Block a user