From 4ffc5299c015a0c8e0237ab8c0f710b586640fd4 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Mon, 25 Apr 2016 23:29:26 -0400 Subject: rust: compiled-in prelude --- rust/spectrum.rs | 63 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/rust/spectrum.rs b/rust/spectrum.rs index 3a0362f..18080f3 100644 --- a/rust/spectrum.rs +++ b/rust/spectrum.rs @@ -7,7 +7,7 @@ * Intentended to work with Rust 1.8 (stable from Spring 2016) */ -use std::{io, env}; +use std::{io, env, str}; use std::io::{Write, Read}; use std::fs::File; use std::path::Path; @@ -716,6 +716,21 @@ fn repl(verbose: bool, top_env: &mut HashMap) { } } +/* This loads and evals the hard-coded prelude file (which is just scheme expressions compiled into + * the executable), saving the resulting defines in top_env. + */ +fn import_prelude(top_env: &mut HashMap) -> Result<(), String> { + + let raw_prelude = include_bytes!("prelude.scm"); + let contents = str::from_utf8(raw_prelude).unwrap(); + let tokens = try!(scheme_tokenize(contents)); + let (ast_list, _) = try!(scheme_parse(&tokens, 0)); + for ast in ast_list.iter() { + try!(scheme_eval(&ast, top_env)); + }; + Ok(()) +} + fn import_file(fpath: &Path, top_env: &mut HashMap) -> Result<(), String> { let mut raw_bytes: Vec = Vec::new(); @@ -736,25 +751,29 @@ fn import_file(fpath: &Path, top_env: &mut HashMap) -> Resul } fn usage() { - println!("usage:\tspectrum [-h] [-v] [--no-repl] []"); + println!("usage:\tspectrum [-h] [-v] [--no-repl] [--no-prelude] []"); println!(""); println!("Files will be loaded in order, then drop to REPL (unless \"--no-repl\" is passed)."); - println!("Verbose flag (\"-v\") will result in lexed tokens and parsed AST being dumped to stdout (when on REPL)"); + println!("Verbose flag (\"-v\") will result in lexed tokens and parsed AST \ + being dumped to stdout (when on REPL)."); + println!("A \"prelude\" of common Scheme/LISP functions (eg, cdaddr) will \ + be loaded before any files (unless \"--no-prelude\" is passed)."); } fn main() { let mut verbose: bool = false; let mut no_repl: bool = false; + let mut no_prelude: bool = false; let mut top_env = HashMap::::new(); - let prelude_path = Path::new("../prelude.scm"); - import_file(&prelude_path, &mut top_env).unwrap(); + let mut file_list = Vec::::new(); for arg in env::args().skip(1) { match &*arg { "-v" | "--verbose" => { verbose = true; }, "--no-repl" => { no_repl = true; }, + "--no-prelude" => { no_prelude = true; }, "-h" | "--help" => { usage(); return; }, _ if arg.starts_with("-") => { println!("Unknown option: {}", arg); @@ -763,23 +782,31 @@ fn main() { return; }, _ => { - let arg_path = Path::new(&arg); - println!("Loading {}...", arg); - if !arg_path.is_file() { - println!("File not found (or not file): {}", arg); - return; - } - match import_file(&arg_path, &mut top_env) { - Err(e) => { - println!("Error loading file: {}\n {}", arg, e); - return; - }, - Ok(_) => () - } + file_list.push(arg.clone()); } } } + if !no_prelude { + import_prelude(&mut top_env).unwrap(); + } + + for fname in file_list { + let fpath = Path::new(&fname); + if !fpath.is_file() { + println!("File not found (or not file): {}", fname); + return; + } + println!("Loading {}...", fname); + match import_file(&fpath, &mut top_env) { + Err(e) => { + println!("Error loading file: {}\n {}", fname, e); + return; + }, + Ok(_) => () + } + } + if !no_repl { repl(verbose, &mut top_env); } -- cgit v1.2.3