Kaynağa Gözat

exploring read function

ada 5 yıl önce
ebeveyn
işleme
5153df63c1
1 değiştirilmiş dosya ile 72 ekleme ve 46 silme
  1. 72 46
      lisp/lisp.rs

+ 72 - 46
lisp/lisp.rs

@@ -63,36 +63,42 @@ struct RispEnv<'a> {
 
 
 struct InPort {
 struct InPort {
     line: String,
     line: String,
-    lines: Vec<String>, 
-    cur_line: usize
+    lines: Vec<String>,
+    cur_line: usize,
 }
 }
 
 
 impl InPort {
 impl InPort {
-
     fn init(filename: String) -> InPort {
     fn init(filename: String) -> InPort {
         let file = File::open(filename).unwrap();
         let file = File::open(filename).unwrap();
-        let reader = io::BufReader::new(file).lines().map(|s| s.ok().unwrap().to_string()).collect();
-        InPort { 
-            line : String::new(),
+        let reader = io::BufReader::new(file)
+            .lines()
+            .map(|s| s.ok().unwrap().to_string())
+            .collect();
+        InPort {
+            line: String::new(),
             lines: reader,
             lines: reader,
-            cur_line: 0
+            cur_line: 0,
         }
         }
     }
     }
 
 
     pub fn next_token(&mut self) -> String {
     pub fn next_token(&mut self) -> String {
         loop {
         loop {
-           if self.line.is_empty() {
-               self.line = self.lines.get(self.cur_line).unwrap_or(&"#<eof-object>".to_string()).to_string();
-               self.cur_line = self.cur_line + 1;
-           }
-           if self.line.is_empty() {
-               return "#<eof-object>".to_string();
-           }
-           let (token, rest) = InPort::tokenize(self.line.clone());
-           self.line = rest;
-           if !token.is_empty() {
-               return token;
-           }
+            if self.line.is_empty() {
+                self.line = self
+                    .lines
+                    .get(self.cur_line)
+                    .unwrap_or(&"#<eof-object>".to_string())
+                    .to_string();
+                self.cur_line = self.cur_line + 1;
+            }
+            if self.line.is_empty() {
+                return "#<eof-object>".to_string();
+            }
+            let (token, rest) = InPort::tokenize(self.line.clone());
+            self.line = rest;
+            if !token.is_empty() {
+                return token;
+            }
         }
         }
     }
     }
 
 
@@ -103,7 +109,7 @@ impl InPort {
         let captures = result
         let captures = result
             .expect("Error running regex")
             .expect("Error running regex")
             .expect("No match found");
             .expect("No match found");
-//        println!("{}", captures.get(0).unwrap().as_str().to_string());
+        //        println!("{}", captures.get(0).unwrap().as_str().to_string());
         (
         (
             captures.get(1).unwrap().as_str().to_string(),
             captures.get(1).unwrap().as_str().to_string(),
             captures.get(2).unwrap().as_str().to_string(),
             captures.get(2).unwrap().as_str().to_string(),
@@ -111,27 +117,48 @@ impl InPort {
     }
     }
 }
 }
 
 
-// TODO change return type to Symbol
-fn read(inport: InPort) -> String {
-    fn read_ahead(token: String) {
-        match token {
-            "(" => {
-                let L = Vec::new();
-                loop {
-                    let token = inport.next_token();
-                    if token == ")" { 
-                        return L;
+fn read_ahead(inport: &InPort, token: String) -> String {
+    match token.as_str() {
+        "(" => {
+            let mut L = Vec::new();
+            loop {
+                let t = &inport.next_token();
+                if t.to_string() == ")" {
+                        return L.into_iter().collect();
                     } else {
                     } else {
-                        L.append(read_ahead(token));
+                        L.push(read_ahead(&inport, t.to_string()));
                     }
                     }
                 }
                 }
-            },
-            _ => { println!("{}", token); }
+            }
+        _ => {
+            println!("{}", token);
+            return token;
         }
         }
     }
     }
-    let token1 = inport.next_token();
-    if token1 == "#<eof-object>".to_string() {
+}
+
+fn read_seq<'a>(tokens: &'a [String]) -> Result<(RispExp, &'a [String]), RispErr> {
+    let mut res: Vec<RispExp> = vec![];
+    let mut xs = tokens;
+    loop {
+        let (next_token, rest) = xs
+            .split_first()
+            .ok_or(RispErr::Reason("could not find closing `)`".to_string()))?;
+        if next_token == ")" {
+            return Ok((RispExp::List(res), rest)); // skip `)`, head to the token after
+        }
+        let (exp, new_xs) = parse(&xs)?;
+        res.push(exp);
+        xs = new_xs;
+    }
+}
+// TODO change return type to Symbol
+fn read(inport: &InPort) -> String {
+    let token1 = &inport.next_token().as_str();
+    if token1.to_string() == "#<eof-object>".to_string() {
         return "#<eof-object>".to_string();
         return "#<eof-object>".to_string();
+    } else {
+        return read_ahead(&inport, token1.to_string());
     }
     }
 }
 }
 
 
@@ -402,22 +429,21 @@ fn eval(exp: &RispExp, env: &mut RispEnv) -> Result<RispExp, RispErr> {
     }
     }
 }
 }
 
 
-
 fn main() {
 fn main() {
     let env = &mut default_env();
     let env = &mut default_env();
     let mut reader = InPort::init("new.lisp".to_string());
     let mut reader = InPort::init("new.lisp".to_string());
     let mut token = String::new();
     let mut token = String::new();
-    read(reader); 
+    read(&reader);
     // read from file
     // read from file
-//    let file = File::open("new.lisp").unwrap();
-//    let lines = io::BufReader::new(file).lines();
-//    let mut cur_line = String::new();
-//    let mut token = String::new();
-//    for line in lines {
-//        let (token, cur_line) = tokenize(line.ok().unwrap().as_str().to_string());
-//        println!("token {:?}", token);
-//        println!("line {:?}", cur_line);
- //   }
+    //    let file = File::open("new.lisp").unwrap();
+    //    let lines = io::BufReader::new(file).lines();
+    //    let mut cur_line = String::new();
+    //    let mut token = String::new();
+    //    for line in lines {
+    //        let (token, cur_line) = tokenize(line.ok().unwrap().as_str().to_string());
+    //        println!("token {:?}", token);
+    //        println!("line {:?}", cur_line);
+    //   }
 
 
     /*
     /*
     loop {
     loop {