1#![cfg_attr(all(doc, not(doctest)), feature(doc_cfg))]
4#![no_std]
5
6#[cfg(feature = "std")]
7#[doc(hidden)]
8pub extern crate std;
9
10#[doc(hidden)]
11pub mod __private {
12 #[cfg(feature = "std")]
13 pub use clap;
14 #[cfg(feature = "libc")]
15 pub use libc;
16 #[cfg(feature = "std")]
17 pub use main_error;
18 pub use stak_configuration;
19 pub use stak_device;
20 pub use stak_file;
21 #[cfg(feature = "libc")]
22 pub use stak_libc;
23 pub use stak_macro;
24 pub use stak_process_context;
25 pub use stak_r7rs;
26 pub use stak_time;
27 pub use stak_vm;
28 #[cfg(feature = "std")]
29 pub use std;
30}
31
32#[cfg(feature = "std")]
47#[macro_export]
48macro_rules! main {
49 ($path:expr) => {
50 $crate::main!(
51 $path,
52 $crate::__private::stak_configuration::DEFAULT_HEAP_SIZE
53 );
54 };
55 ($path:expr, $heap_size:expr) => {
56 use $crate::__private::{
57 clap::{self, Parser},
58 main_error::MainError,
59 stak_device::StdioDevice,
60 stak_file::OsFileSystem,
61 stak_macro::include_r7rs,
62 stak_process_context::OsProcessContext,
63 stak_r7rs::SmallPrimitiveSet,
64 stak_time::OsClock,
65 stak_vm::Vm,
66 };
67
68 #[derive(clap::Parser)]
69 #[command(disable_help_flag = true, ignore_errors = true, version)]
70 struct Arguments {
71 #[arg()]
72 arguments: Vec<String>,
73 #[arg(short = 's', long, default_value_t = $heap_size)]
74 heap_size: usize,
75 }
76
77 fn main() -> Result<(), MainError> {
78 let arguments = Arguments::parse();
79
80 let mut heap = vec![Default::default(); arguments.heap_size];
81 let mut vm = Vm::new(
82 &mut heap,
83 SmallPrimitiveSet::new(
84 StdioDevice::new(),
85 OsFileSystem::new(),
86 OsProcessContext::new(),
87 OsClock::new(),
88 ),
89 )?;
90
91 vm.initialize(include_r7rs!($path).iter().copied())?;
92
93 Ok(vm.run()?)
94 }
95 };
96}
97
98#[cfg(feature = "libc")]
105#[macro_export]
106macro_rules! libc_main {
107 ($path:expr) => {
108 $crate::libc_main!(
109 $path,
110 $crate::__private::stak_configuration::DEFAULT_HEAP_SIZE
111 );
112 };
113 ($path:expr, $heap_size:expr) => {
114 use $crate::__private::{
115 libc::exit,
116 stak_device::libc::{ReadWriteDevice, Stderr, Stdin, Stdout},
117 stak_file::LibcFileSystem,
118 stak_libc::Heap,
119 stak_macro::include_r7rs,
120 stak_process_context::LibcProcessContext,
121 stak_r7rs::SmallPrimitiveSet,
122 stak_time::LibcClock,
123 stak_vm::Vm,
124 };
125
126 #[cfg(not(test))]
127 #[panic_handler]
128 fn panic(_info: &core::panic::PanicInfo) -> ! {
129 unsafe { exit(1) }
130 }
131
132 #[cfg_attr(not(test), unsafe(no_mangle))]
133 unsafe extern "C" fn main(argc: isize, argv: *const *const i8) -> isize {
134 let mut heap = Heap::new($heap_size, Default::default);
135 let mut vm = Vm::new(
136 heap.as_slice_mut(),
137 SmallPrimitiveSet::new(
138 ReadWriteDevice::new(Stdin::new(), Stdout::new(), Stderr::new()),
139 LibcFileSystem::new(),
140 LibcProcessContext::new(argc, argv),
141 LibcClock::new(),
142 ),
143 )
144 .unwrap();
145
146 vm.initialize(include_r7rs!($path).iter().copied()).unwrap();
147 vm.run().unwrap();
148
149 0
150 }
151 };
152}