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 default: build-release
build-release: test build-release: test
@echo "Build release" @echo "Building release for installation"
@cargo build --release @cargo build --release -q
test: test:
@echo "Test release" @echo "Testing release"
@cargo test --release @MAL_HOME=core cargo test --release -q
conf: test conf: test
@echo "Copy core and libraries" @echo "Copying config"
@mkdir -p ${HOME}/.config/mal @mkdir -p ${MAL_HOME}
cp -f core/core.mal ${HOME}/.config/mal/ @cp -f core/core.mal ${MAL_HOME}/
@mkdir -p ${HOME}/.config/mal/libs @mkdir -p ${MAL_HOME}/libs
cp -f libs/* ${HOME}/.config/mal/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 install: build-release test conf
@echo "Install mal" @echo "Installing release"
sudo cp target/release/rust-mal /usr/local/bin/mal @echo "Provide password for installing \"mal\" to \"${BINARY_DIR}\""
@sudo chown ${USER} /usr/local/bin/mal @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:" @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 ## Why
Because I need to improve my knowledge of rust and I also don't know how to use lisp 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,10 +143,10 @@
(def! BANNER (def! BANNER
(str (str
"; rust-mal: a toy lisp interpreter written in rust\n" "; 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" "; (load-file <name>) : load specified file while mal is running\n"
"; (find [pattern...]) : list symbols matching all patterns\n" "; (find [pattern...]) : list symbols matching all patterns\n"
"; (help <symbol>) : print information about a symbol\n" "; (help <symbol>) : print information about a symbol\n"
";\n" ";\n"
"; enjoy ^.^\n")) "; enjoy ^.^\n"))

View File

@ -12,7 +12,7 @@ mod step6_file;
mod types; mod types;
use core::ns_init; 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() { fn main() {
// Initialize ns environment // Initialize ns environment
@ -29,12 +29,21 @@ fn main() {
// based on conf // based on conf
//load_home_file("config.mal", &reply_env, false); //load_home_file("config.mal", &reply_env, false);
// load all files passed as arguments // load ~~all files~~ first file passed as arguments
args().collect::<Vec<String>>()[1..].iter().for_each(|f| { //args().collect::<Vec<String>>()[1..].iter().for_each(|f| {
if let Err(e) = load_file(f, &reply_env) { // if let Err(e) = load_file(f, &reply_env) {
eprintln!("{}", e.message()) // 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); 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::error::ReadlineError;
use rustyline::DefaultEditor; 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) { pub fn interactive(env: Env) {
const HISTORY: &str = ".mal-history"; const HISTORY: &str = ".mal-history";
let home = get_home_path(&env).unwrap(); let home = get_home_path(&env).unwrap();