Getty Ritter il y a 2 ans
Parent
commit
bb079b9fc4
6 fichiers modifiés avec 54 ajouts et 66 suppressions
  1. 31 33
      src/interp.rs
  2. 2 4
      src/lexer.rs
  3. 1 1
      src/lib.rs
  4. 4 13
      src/main.rs
  5. 15 14
      src/repl.rs
  6. 1 1
      tools/regenerate.rs

+ 31 - 33
src/interp.rs

@@ -47,8 +47,7 @@ impl Value {
                 buf.push_str(">");
                 f(&buf)
             }
-            Value::Builtin(func) =>
-                f(&format!("#<builtin {}>", func.name)),
+            Value::Builtin(func) => f(&format!("#<builtin {}>", func.name)),
         }
     }
 
@@ -89,9 +88,8 @@ const BUILTINS: &[BuiltinFunc] = &[
             let num = state.eval(&args[0])?.as_num()?;
             let rep = (0..num).map(|_| args[1].clone()).collect();
             state.eval(&Expr::Cat(rep))
-        }
+        },
     },
-
     BuiltinFunc {
         name: "length",
         callback: &|_state: &mut State, expr: &Expr| -> Result<Value, Error> {
@@ -100,23 +98,21 @@ const BUILTINS: &[BuiltinFunc] = &[
                 _ => bail!("`length`: expected tuple"),
             };
             Ok(Value::Lit(Literal::Num(args.len() as i64)))
-        }
+        },
     },
-
     BuiltinFunc {
         name: "to-upper",
         callback: &|state: &mut State, expr: &Expr| -> Result<Value, Error> {
             let s = state.eval(expr)?;
             Ok(Value::Lit(Literal::Str(s.as_str()?.to_uppercase())))
-        }
+        },
     },
-
     BuiltinFunc {
         name: "to-lower",
         callback: &|state: &mut State, expr: &Expr| -> Result<Value, Error> {
             let s = state.eval(expr)?;
             Ok(Value::Lit(Literal::Str(s.as_str()?.to_lowercase())))
-        }
+        },
     },
 ];
 
@@ -143,10 +139,8 @@ impl State {
             rand: rand::thread_rng(),
         };
         for builtin in BUILTINS {
-            s.scope.insert(
-                builtin.name.to_string(),
-                NamedItem::Builtin(builtin),
-            );
+            s.scope
+                .insert(builtin.name.to_string(), NamedItem::Builtin(builtin));
         }
         s
     }
@@ -173,14 +167,19 @@ impl State {
                 println!("{}", val.to_string());
             }
             Stmt::Assn(name, expr) => {
-                self.scope.insert(name.to_string(), NamedItem::Expr(expr.clone()));
+                self.scope
+                    .insert(name.to_string(), NamedItem::Expr(expr.clone()));
             }
             Stmt::LitAssn(name, strs) => {
-                let choices = strs.iter().map(|s| Choice {
-                    weight: None,
-                    value: Expr::Lit(Literal::Str(s.clone())),
-                }).collect();
-                self.scope.insert(name.to_string(), NamedItem::Expr(Expr::Chc(choices)));
+                let choices = strs
+                    .iter()
+                    .map(|s| Choice {
+                        weight: None,
+                        value: Expr::Lit(Literal::Str(s.clone())),
+                    })
+                    .collect();
+                self.scope
+                    .insert(name.to_string(), NamedItem::Expr(Expr::Chc(choices)));
             }
             _ => bail!("unimplemented"),
         })
@@ -191,12 +190,9 @@ impl State {
             Expr::Lit(l) => Ok(Value::Lit(l.clone())),
             Expr::Var(v) => {
                 let e = match self.scope.get(v) {
-                    Some(NamedItem::Expr(e)) =>
-                        e.clone(),
-                    Some(NamedItem::Builtin(b)) =>
-                        return Ok(Value::Builtin(b)),
-                    None =>
-                        bail!("no such thing: {}", v),
+                    Some(NamedItem::Expr(e)) => e.clone(),
+                    Some(NamedItem::Builtin(b)) => return Ok(Value::Builtin(b)),
+                    None => bail!("no such thing: {}", v),
                 };
                 self.eval(&e)
             }
@@ -219,14 +215,16 @@ impl State {
                     self.choose(choices)
                 }
             }
-            Expr::Tup(values) =>
-                Ok(Value::Tup(values.iter().map(|v| self.eval(v)).collect::<Result<Vec<Value>, Error>>()?)),
-            Expr::Ap(fun, arg) => {
-                match self.eval(fun)? {
-                    Value::Builtin(builtin) => (builtin.callback)(self, arg),
-                    _ => bail!("bad function: {:?}", fun),
-                }
-            }
+            Expr::Tup(values) => Ok(Value::Tup(
+                values
+                    .iter()
+                    .map(|v| self.eval(v))
+                    .collect::<Result<Vec<Value>, Error>>()?,
+            )),
+            Expr::Ap(fun, arg) => match self.eval(fun)? {
+                Value::Builtin(builtin) => (builtin.callback)(self, arg),
+                _ => bail!("bad function: {:?}", fun),
+            },
             Expr::Range(from, to) => {
                 let from = self.eval(from)?.as_num()?;
                 let to = self.eval(to)?.as_num()?;

+ 2 - 4
src/lexer.rs

@@ -94,7 +94,7 @@ pub enum Token<'a> {
     #[error]
     #[regex(r"[ \t\n\f]+", logos::skip)]
     #[regex(r"\(\*([^*]|\*[^)])*\*\)", logos::skip)]
-    Error
+    Error,
 }
 
 #[derive(Debug)]
@@ -102,9 +102,7 @@ pub struct LexerError;
 
 pub type Spanned<Tok, Loc, Error> = Result<(Loc, Tok, Loc), Error>;
 
-pub fn tokens(
-    source: &str,
-) -> impl Iterator<Item = Spanned<Token<'_>, usize, LexerError>> {
+pub fn tokens(source: &str) -> impl Iterator<Item = Spanned<Token<'_>, usize, LexerError>> {
     Token::lexer(source)
         .spanned()
         .map(move |(token, range)| match token {

+ 1 - 1
src/lib.rs

@@ -1,9 +1,9 @@
 #[macro_use]
 extern crate lalrpop_util;
 
-pub mod lexer;
 pub mod ast;
 pub mod interp;
+pub mod lexer;
 pub mod repl;
 
 #[cfg(test)]

+ 4 - 13
src/main.rs

@@ -22,17 +22,13 @@ fn run_repl() -> Result<(), Box<dyn std::error::Error>> {
         "{}",
         ansi_term::Colour::Blue.bold().paint("matzo interpreter"),
     );
-    println!(
-        "{}",
-        ansi_term::Colour::Blue.paint("(work-in-progress)"),
-    );
+    println!("{}", ansi_term::Colour::Blue.paint("(work-in-progress)"),);
 
     loop {
         let line = match rl.readline(">>> ") {
             Ok(ln) => ln,
-            Err(rustyline::error::ReadlineError::Eof) |
-            Err(rustyline::error::ReadlineError::Interrupted) =>
-                return Ok(()),
+            Err(rustyline::error::ReadlineError::Eof)
+            | Err(rustyline::error::ReadlineError::Interrupted) => return Ok(()),
             err => err?,
         };
         let lexed = tokens(&line);
@@ -49,12 +45,7 @@ fn run_repl() -> Result<(), Box<dyn std::error::Error>> {
                     Err(_) => {
                         // that didn't fix it, so report the
                         // _original_ parse error, not the new one
-                        eprintln!(
-                            "{}",
-                            ansi_term::Colour::Red.paint(
-                                format!("{:?}", err)
-                            ),
-                        );
+                        eprintln!("{}", ansi_term::Colour::Red.paint(format!("{:?}", err)),);
                         continue;
                     }
                 }

+ 15 - 14
src/repl.rs

@@ -1,9 +1,5 @@
 use rustyline::{
-    Helper,
-    completion::Completer,
-    hint::Hinter,
-    highlight::Highlighter,
-    validate::Validator,
+    completion::Completer, highlight::Highlighter, hint::Hinter, validate::Validator, Helper,
 };
 use std::cell::RefCell;
 use std::rc::Rc;
@@ -21,8 +17,13 @@ impl Repl {
 impl Completer for Repl {
     type Candidate = String;
 
-    fn complete(&self, line: &str, pos: usize, _ctx: &rustyline::Context<'_>) -> rustyline::Result<(usize, Vec<String>)> {
-        if let Some(c) = line.chars().nth(pos-1) {
+    fn complete(
+        &self,
+        line: &str,
+        pos: usize,
+        _ctx: &rustyline::Context<'_>,
+    ) -> rustyline::Result<(usize, Vec<String>)> {
+        if let Some(c) = line.chars().nth(pos - 1) {
             if c.is_alphabetic() {
                 // this means we're looking at maybe something
                 // alphabetic; let's see what the current typed thing
@@ -38,7 +39,10 @@ impl Completer for Repl {
                 }
                 // we've now found the current fragment
                 let so_far = &line[str_start..pos];
-                return Ok((str_start, self.state.borrow().autocomplete(so_far, str_start == 0)))
+                return Ok((
+                    str_start,
+                    self.state.borrow().autocomplete(so_far, str_start == 0),
+                ));
             }
         }
         Ok((pos, Vec::new()))
@@ -49,11 +53,8 @@ impl Hinter for Repl {
     type Hint = String;
 }
 
-impl Highlighter for Repl {
-}
+impl Highlighter for Repl {}
 
-impl Validator for Repl {
-}
+impl Validator for Repl {}
 
-impl Helper for Repl {
-}
+impl Helper for Repl {}

+ 1 - 1
tools/regenerate.rs

@@ -1,5 +1,5 @@
-use matzo::lexer;
 use matzo::grammar;
+use matzo::lexer;
 
 use std::io::Write;