os.shell
This commit is contained in:
@@ -6,7 +6,6 @@ use crate::{
|
||||
};
|
||||
|
||||
pub struct Var {
|
||||
// pub var_type: String,
|
||||
pub stack_offset: usize,
|
||||
}
|
||||
|
||||
@@ -105,7 +104,7 @@ section .text
|
||||
"
|
||||
);
|
||||
|
||||
for name in &["malloc", "realloc", "free", "system", "gethostbyname"] {
|
||||
for name in &["malloc", "realloc", "free", "gethostbyname"] {
|
||||
emit!(&mut self.output, "extern {}", name);
|
||||
emit!(&mut self.output, "c.{} equ {}", name, name);
|
||||
}
|
||||
@@ -156,6 +155,12 @@ _builtin_syscall:
|
||||
mov r9, [rsp+8]
|
||||
syscall
|
||||
ret
|
||||
|
||||
section .text._builtin_environ
|
||||
_builtin_environ:
|
||||
extern environ
|
||||
mov rax, [rel environ]
|
||||
ret
|
||||
"
|
||||
);
|
||||
Ok(())
|
||||
@@ -303,7 +308,7 @@ _builtin_syscall:
|
||||
emit!(&mut self.output, " jmp {}", env.loop_begin_label);
|
||||
}
|
||||
Stmt::Extern(name) => {
|
||||
emit!(&mut self.output, " extern {}", name.lexeme);
|
||||
emit!(&mut self.output, "extern {}", name.lexeme);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -103,6 +103,9 @@ impl Parser {
|
||||
if self.match_token(&[TokenType::KeywordFunc]) {
|
||||
return self.func_declaration();
|
||||
}
|
||||
if self.match_token(&[TokenType::KeywordExtern]) {
|
||||
return self.extern_declaration();
|
||||
}
|
||||
return error!(
|
||||
self.peek().loc,
|
||||
"statements not allowed outside function body"
|
||||
@@ -175,6 +178,12 @@ impl Parser {
|
||||
})
|
||||
}
|
||||
|
||||
fn extern_declaration(&mut self) -> Result<Stmt, ZernError> {
|
||||
Ok(Stmt::Extern(
|
||||
self.consume(TokenType::Identifier, "expected extern name")?,
|
||||
))
|
||||
}
|
||||
|
||||
fn block(&mut self) -> Result<Stmt, ZernError> {
|
||||
self.consume(TokenType::Indent, "expected an indent")?;
|
||||
|
||||
@@ -199,10 +208,6 @@ impl Parser {
|
||||
Ok(Stmt::Break)
|
||||
} else if self.match_token(&[TokenType::KeywordContinue]) {
|
||||
Ok(Stmt::Continue)
|
||||
} else if self.match_token(&[TokenType::KeywordExtern]) {
|
||||
Ok(Stmt::Extern(
|
||||
self.consume(TokenType::Identifier, "expected extern name")?,
|
||||
))
|
||||
} else {
|
||||
Ok(Stmt::Expression(self.expression()?))
|
||||
}
|
||||
|
||||
21
src/std.zr
21
src/std.zr
@@ -430,6 +430,27 @@ func os.time[] : I64
|
||||
mem.free(tv)
|
||||
return seconds * 1000 + microseconds / 1000
|
||||
|
||||
// voodoo magic
|
||||
func os.shell[command: String] : I64
|
||||
let pid: I64 = _builtin_syscall(57) // fork
|
||||
if pid == 0
|
||||
let argv: Array = ["sh", "-c", command, 0]
|
||||
_builtin_syscall(59, "/bin/sh", mem.read64(argv), _builtin_environ()) // execve
|
||||
_builtin_syscall(60, 1) // exit
|
||||
else
|
||||
let status: Ptr = mem.alloc(4)
|
||||
let wp: I64 = _builtin_syscall(61, pid, status, 0, 0) // waitpid
|
||||
if wp == -1
|
||||
mem.free(status)
|
||||
return -1
|
||||
let st: I64 = mem.read32(status)
|
||||
mem.free(status)
|
||||
|
||||
if (st & 0x7f) == 0
|
||||
return (st >> 8) & 0xff
|
||||
else
|
||||
return -(st & 0x7f)
|
||||
|
||||
func os.listdir[path: String] : Array
|
||||
let fd: I64 = _builtin_syscall(2, path, 0, 0) // open
|
||||
if fd < 0
|
||||
|
||||
Reference in New Issue
Block a user