C string literals (c'str'); bare builtin module; bare println()
parent
0b3b241258
commit
96cde10696
|
@ -0,0 +1,28 @@
|
|||
module builtin
|
||||
|
||||
pub fn syscall5(number, arg1, arg2, arg3, arg4, arg5 voidptr) voidptr
|
||||
|
||||
// TODO no pub => error
|
||||
pub fn write(fd int, data voidptr, nbytes int) int {
|
||||
return syscall5(
|
||||
1, // SYS_write
|
||||
fd,
|
||||
data,
|
||||
nbytes,
|
||||
0, // ignored
|
||||
0 // ignored
|
||||
)
|
||||
}
|
||||
|
||||
pub fn println(s string) {
|
||||
write(1, s.str, s.len)
|
||||
}
|
||||
|
||||
pub fn panic(s string) {
|
||||
write(1, s.str, s.len)
|
||||
}
|
||||
|
||||
pub fn malloc(n int) voidptr {
|
||||
return syscall5(0,0,0,0,0,0)
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
module builtin
|
||||
|
||||
pub struct string {
|
||||
pub:
|
||||
str byteptr
|
||||
len int
|
||||
}
|
||||
|
||||
pub fn strlen(s byteptr) int {
|
||||
mut i := 0
|
||||
for i = 0; s[i] != 0; i++ {
|
||||
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
pub fn tos(s byteptr, len int) string {
|
||||
if s == 0 {
|
||||
panic('tos(): nil string')
|
||||
}
|
||||
return string {
|
||||
str: s
|
||||
len: len
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tos_clone(s byteptr) string {
|
||||
if s == 0 {
|
||||
panic('tos: nil string')
|
||||
}
|
||||
return tos2(s).clone()
|
||||
}
|
||||
|
||||
// Same as `tos`, but calculates the length. Called by `string(bytes)` casts.
|
||||
// Used only internally.
|
||||
pub fn tos2(s byteptr) string {
|
||||
if s == 0 {
|
||||
panic('tos2: nil string')
|
||||
}
|
||||
return string {
|
||||
str: s
|
||||
len: strlen(s)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tos3(s *C.char) string {
|
||||
if s == 0 {
|
||||
panic('tos3: nil string')
|
||||
}
|
||||
return string {
|
||||
str: byteptr(s)
|
||||
len: strlen(byteptr(s))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (a string) clone() string {
|
||||
mut b := string {
|
||||
len: a.len
|
||||
str: malloc(a.len + 1)
|
||||
}
|
||||
for i := 0; i < a.len; i++ {
|
||||
b[i] = a[i]
|
||||
}
|
||||
b[a.len] = `\0`
|
||||
return b
|
||||
}
|
|
@ -161,7 +161,7 @@ fn (p mut Parser) name_expr() string {
|
|||
|
||||
mut name := p.lit
|
||||
// Raw string (`s := r'hello \n ')
|
||||
if name == 'r' && p.peek() == .str {
|
||||
if (name == 'r' || name == 'c') && p.peek() == .str {
|
||||
p.string_expr()
|
||||
return 'string'
|
||||
}
|
||||
|
|
|
@ -579,7 +579,7 @@ pub fn (v &V) v_files_from_dir(dir string) []string {
|
|||
pub fn (v mut V) add_v_files_to_compile() {
|
||||
mut builtin_files := v.get_builtin_files()
|
||||
if v.pref.is_bare {
|
||||
builtin_files = []
|
||||
//builtin_files = []
|
||||
}
|
||||
// Builtin cache exists? Use it.
|
||||
builtin_vh := '$v_modules_path${os.path_separator}vlib${os.path_separator}builtin.vh'
|
||||
|
@ -651,6 +651,9 @@ pub fn (v mut V) add_v_files_to_compile() {
|
|||
|
||||
pub fn (v &V) get_builtin_files() []string {
|
||||
// .vh cache exists? Use it
|
||||
if v.pref.is_bare {
|
||||
return v.v_files_from_dir(filepath.join(v.vroot, 'vlib', 'builtin', 'bare'))
|
||||
}
|
||||
$if js {
|
||||
return v.v_files_from_dir('$v.vroot${os.path_separator}vlib${os.path_separator}builtin${os.path_separator}js')
|
||||
}
|
||||
|
|
|
@ -2125,7 +2125,8 @@ fn format_str(_str string) string {
|
|||
|
||||
fn (p mut Parser) string_expr() {
|
||||
is_raw := p.tok == .name && p.lit == 'r'
|
||||
if is_raw {
|
||||
is_cstr := p.tok == .name && p.lit == 'c'
|
||||
if is_raw || is_cstr {
|
||||
p.next()
|
||||
}
|
||||
str := p.lit
|
||||
|
@ -2137,7 +2138,7 @@ fn (p mut Parser) string_expr() {
|
|||
Calling a C function sometimes requires a call to a string method
|
||||
C.fun('ssss'.to_wide()) => fun(string_to_wide(tos3("ssss")))
|
||||
*/
|
||||
if (p.calling_c && p.peek() != .dot) || p.pref.is_bare || (p.pref.translated && p.mod == 'main') {
|
||||
if (p.calling_c && p.peek() != .dot) || is_cstr || (p.pref.translated && p.mod == 'main') {
|
||||
p.gen('"$f"')
|
||||
}
|
||||
else if p.is_sql {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.intel_syntax noprefix
|
||||
.text
|
||||
.globl _start, main__syscall5
|
||||
.globl _start, syscall5
|
||||
|
||||
_start:
|
||||
xor rbp,rbp
|
||||
|
@ -16,7 +16,7 @@
|
|||
ret /* should never be reached, but if the OS somehow fails
|
||||
to kill us, it will cause a segmentation fault */
|
||||
|
||||
main__syscall5:
|
||||
syscall5:
|
||||
mov rax,rdi
|
||||
mov rdi,rsi
|
||||
mov rsi,rdx
|
||||
|
|
|
@ -1,16 +1,4 @@
|
|||
fn syscall5(number, arg1, arg2, arg3, arg4, arg5 voidptr) voidptr
|
||||
|
||||
fn write(fd int, data voidptr, nbytes u64) int {
|
||||
return syscall5(
|
||||
1, // SYS_write
|
||||
fd,
|
||||
data,
|
||||
nbytes,
|
||||
0, // ignored
|
||||
0 // ignored
|
||||
)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
write(1, "hallo\n", 6)
|
||||
write(1, c'Hello!\n', 7)
|
||||
println('println test\n')
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue