1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
use crate::parse::Parser; use crate::print::Printer; use crate::session::{LibrarySpec, Session}; use crate::value::Value; use std::env; use std::fmt::Debug; use std::io; use std::io::{Read, Write}; use std::path::PathBuf; pub struct Config<'a> { pub session: &'a mut Session, pub path: Option<PathBuf>, } impl<'a> Config<'a> { pub fn read_ast(&self) -> Option<Vec<Value>> { return self.path.as_ref().map(|path| { Parser { input: &mut self.session.read_ast(path.as_path()), } .collect() }); } } pub trait LibProcessError: Debug + From<io::Error> { fn unknown_function(name: String) -> Self; fn invalid_num_args(fun: String, expected: usize, actual: usize) -> Self; fn invalid_arg_types(actual: Vec<Value>, expected: String) -> Self; fn not_function(value: Value) -> Self; fn unsupported(reason: String) -> Self; } pub trait LibProcess { type Error: LibProcessError; fn dependencies() -> Vec<LibrarySpec>; fn configure(&mut self, config: Config); fn call_fun(&mut self, fun: String, args: Vec<Value>) -> Result<Value, Self::Error>; fn run<R: Read, W: Write>(&mut self, input: &mut R, output: &mut W) -> Result<(), Self::Error> { let mut parser = Parser { input: input }; let mut printer = Printer { output: output }; while let Some(fun_val) = parser.scan_value() { if let Value::Record { head: fun, props: args, } = fun_val { let res = self.call_fun(fun, args)?; printer .print_value(res) .map_err(|err| Self::Error::from(err))?; } else { return Err(Self::Error::not_function(fun_val)); } } return Ok(()); } fn run_main(&mut self) { let args: Vec<String> = env::args().collect(); let mut session = Session::new(Self::dependencies()); let path: Option<PathBuf>; match args.len() { 1 => path = None, 2 => path = Some(PathBuf::from(args[1].clone())), _ => panic!( "invalid number of arguments - expected 0 or 1, got {}", args.len() - 1 ), }; session.start(&path); self.configure(Config { session: &mut session, path: path, }); self .run(&mut io::stdin(), &mut io::stdout()) .expect("server error"); session.stop(); } } #[derive(Debug)] pub enum BasicLibProcessError { UnknownFunction(String), InvalidNumArgs { fun: String, expected: usize, actual: usize, }, InvalidArgTypes { actual: Vec<Value>, expected: String, }, NotFunction(Value), Unsupported(String), IOError(io::Error), } impl From<io::Error> for BasicLibProcessError { fn from(err: io::Error) -> BasicLibProcessError { return BasicLibProcessError::IOError(err); } } impl LibProcessError for BasicLibProcessError { fn unknown_function(name: String) -> BasicLibProcessError { return BasicLibProcessError::UnknownFunction(name); } fn invalid_num_args(fun: String, expected: usize, actual: usize) -> BasicLibProcessError { return BasicLibProcessError::InvalidNumArgs { fun: fun, expected: expected, actual: actual, }; } fn invalid_arg_types(actual: Vec<Value>, expected: String) -> Self { return BasicLibProcessError::InvalidArgTypes { actual: actual, expected: expected, }; } fn not_function(value: Value) -> BasicLibProcessError { return BasicLibProcessError::NotFunction(value); } fn unsupported(reason: String) -> BasicLibProcessError { return BasicLibProcessError::Unsupported(reason); } }