rust runtime
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
use std::{io::{stdout, Write}};
|
||||
|
||||
const scm_tc3_cons: u64 = 0;
|
||||
const scm_tc2_int: u64 = 2;
|
||||
|
||||
|
||||
type scm_bits = u64;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct SCM {
|
||||
n : scm_bits
|
||||
}
|
||||
|
||||
fn scm_pack (bits : scm_bits) -> SCM {
|
||||
SCM {n: bits}
|
||||
}
|
||||
|
||||
fn scm_unpack (x : SCM) -> scm_bits {
|
||||
x.n
|
||||
}
|
||||
|
||||
fn scm_unpack_pointer (x : SCM) -> *mut scm_bits {
|
||||
x.n as *mut scm_bits
|
||||
}
|
||||
|
||||
fn scm_pack_pointer (x : *const scm_bits) -> SCM {
|
||||
SCM {n: x as scm_bits}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn scm_cell_object (x: SCM, n: usize) -> SCM {
|
||||
let p = scm_unpack_pointer (x) as *mut SCM;
|
||||
unsafe {
|
||||
*(p.wrapping_add (n))
|
||||
}
|
||||
}
|
||||
|
||||
fn scm_cell_word (x: SCM, n: usize) -> scm_bits {
|
||||
scm_unpack (scm_cell_object (x, n))
|
||||
}
|
||||
|
||||
fn is_immediate (x: SCM) -> bool {
|
||||
6 & scm_unpack (x) != 0
|
||||
}
|
||||
|
||||
fn scm_cell_type (x: SCM) -> scm_bits {
|
||||
scm_cell_word (x, 0)
|
||||
}
|
||||
|
||||
fn is_cons (x: SCM) -> bool {
|
||||
! is_immediate (x) && (1 & scm_cell_type (x)) == 0
|
||||
}
|
||||
|
||||
fn is_small_int (x: SCM) -> bool {
|
||||
3 & scm_unpack (x) == scm_tc2_int
|
||||
}
|
||||
|
||||
fn get_small_int (x: SCM) -> scm_bits {
|
||||
scm_unpack (x) >> 2
|
||||
}
|
||||
|
||||
fn scm_car (x: SCM) -> SCM {
|
||||
scm_cell_object (x, 0)
|
||||
}
|
||||
|
||||
fn scm_cdr (x: SCM) -> SCM {
|
||||
scm_cell_object (x, 1)
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn scm_write (x: SCM) -> SCM {
|
||||
if is_small_int (x) {
|
||||
print! ("{:?}", get_small_int (x));
|
||||
} else if is_cons (x) {
|
||||
print! ("(");
|
||||
scm_write (scm_car (x));
|
||||
print! (" . ");
|
||||
scm_write (scm_cdr (x));
|
||||
print! (")");
|
||||
} else {
|
||||
let ty = if is_immediate (x) { "immediate" } else { "heap object" };
|
||||
print! ("#<{ty} {:#016x}>", scm_unpack (x));
|
||||
}
|
||||
stdout ().flush ();
|
||||
return scm_pack (0);
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn scm_from_utf8_string (s: scm_bits, len: scm_bits) -> scm_bits {
|
||||
println! ("scm_from_utf8_string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn add (left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works () {
|
||||
let result = add (2, 2);
|
||||
assert_eq! (result, 4);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user