feat(main.rs-parse_tools.rs): added ability to pass arguments

Interpreter now only runs a single script and can passes command line arguments to it
This commit is contained in:
teo3300
2025-04-15 13:45:41 +09:00
5 changed files with 70 additions and 23 deletions

View File

@ -1,23 +1,44 @@
MAL_HOME ?= ${HOME}/.config/mal
BINARY_DIR ?= /usr/local/bin
CONFIG_FILE := ${MAL_HOME}/config.mal
default: build-release
build-release: test
@echo "Build release"
@cargo build --release
@echo "Building release for installation"
@cargo build --release -q
test:
@echo "Test release"
@cargo test --release
@echo "Testing release"
@MAL_HOME=core cargo test --release -q
conf: test
@echo "Copy core and libraries"
@mkdir -p ${HOME}/.config/mal
cp -f core/core.mal ${HOME}/.config/mal/
@mkdir -p ${HOME}/.config/mal/libs
cp -f libs/* ${HOME}/.config/mal/libs/
@echo "Copying config"
@mkdir -p ${MAL_HOME}
@cp -f core/core.mal ${MAL_HOME}/
@mkdir -p ${MAL_HOME}/libs
@cp -f libs/* ${MAL_HOME}/libs/
@touch ${MAL_HOME}/.mal-history
@touch ${MAL_HOME}/config.mal
@test -s ${CONFIG_FILE} || (\
echo ";; Write here your mal config" >> ${MAL_HOME}/config.mal\
&& echo "; (def! BANNER \"\") ; Hide banner at startup" >> ${MAL_HOME}/config.mal\
)
install: build-release test conf
@echo "Install mal"
sudo cp target/release/rust-mal /usr/local/bin/mal
@sudo chown ${USER} /usr/local/bin/mal
@echo "Installing release"
@echo "Provide password for installing \"mal\" to \"${BINARY_DIR}\""
@sudo mkdir -p ${BINARY_DIR}
@sudo cp target/release/rust-mal ${BINARY_DIR}/mal
@sudo chown ${USER} ${BINARY_DIR}/mal
@echo
@echo '***************************************'
@echo '* mal has been successfully installed *'
@echo '***************************************'
@echo IMPORTANT NOTES:
@echo
@echo "Make sure that \"${BINARY_DIR}\" is included into \x24PATH"
@echo "To start mal run:"
@printf "\tmal [path/module.mal ...]\n\n"
@printf "\tmal [path/to/script [args ...]]\n\n"
@echo "To config mal edit:"
@printf "\t${MAL_HOME}/config.mal"

View File

@ -5,3 +5,16 @@ Trying and implementing [mal](https://github.com/kanaka/mal) project from [kanak
## Why
Because I need to improve my knowledge of rust and I also don't know how to use lisp
## Installation
Running `make install` should suffice
### Installation Configuration
Parameters can be set for installation via environment varialbes:
- `MAL_HOME`
- Directory containing the core, libraries and config
- defaults to `~/.config/mal`
- `BINARY_DIR`
- Destination to install the binary, must be included in `PATH` to work properly
- defaults to `/usr/local/bin`

View File

@ -143,7 +143,7 @@
(def! BANNER
(str
"; rust-mal: a toy lisp interpreter written in rust\n"
"; $ mal [filename ...] : load specified files at start\n"
"; $ mal [filename [args ...]] : run mal script with arguments, loaded in \"*ARGV*\"\n"
"; (load-file <name>) : load specified file while mal is running\n"
"; (find [pattern...]) : list symbols matching all patterns\n"
"; (help <symbol>) : print information about a symbol\n"

View File

@ -12,7 +12,7 @@ mod step6_file;
mod types;
use core::ns_init;
use parse_tools::{interactive, load_file, load_home_file, print_banner, set_home_path};
use parse_tools::{interactive, load_file, load_home_file, pre_load, print_banner, set_home_path};
fn main() {
// Initialize ns environment
@ -29,12 +29,21 @@ fn main() {
// based on conf
//load_home_file("config.mal", &reply_env, false);
// load all files passed as arguments
args().collect::<Vec<String>>()[1..].iter().for_each(|f| {
if let Err(e) = load_file(f, &reply_env) {
// load ~~all files~~ first file passed as arguments
//args().collect::<Vec<String>>()[1..].iter().for_each(|f| {
// if let Err(e) = load_file(f, &reply_env) {
// eprintln!("{}", e.message())
// }
//});
{
let argv = args().collect::<Vec<String>>();
pre_load(&argv, &reply_env);
if argv.len() > 1 {
if let Err(e) = load_file(&argv[1], &reply_env) {
eprintln!("{}", e.message())
}
});
}
}
print_banner(&reply_env);

View File

@ -70,6 +70,10 @@ pub fn load_file(filename: &str, env: &Env) -> MalRet {
use rustyline::error::ReadlineError;
use rustyline::DefaultEditor;
pub fn pre_load(argv: &Vec<String>, env: &Env) {
eval_str(format!("(def! *ARGV* '({}))", argv[1..].iter().map(|x| x.to_string() + " ").collect::<String>()).as_str(), &env).unwrap();
}
pub fn interactive(env: Env) {
const HISTORY: &str = ".mal-history";
let home = get_home_path(&env).unwrap();