Просмотр исходного кода

zkas: Implement interactive semantic analyzer.

parazyd 4 лет назад
Родитель
Сommit
882f1e931a
2 измененных файлов с 74 добавлено и 2 удалено
  1. 66 1
      zkas/src/analyzer.rs
  2. 8 1
      zkas/src/main.rs

+ 66 - 1
zkas/src/analyzer.rs

@@ -1,4 +1,9 @@
-use std::{io, io::Write, process, str::Chars};
+use std::{
+    io,
+    io::{stdin, stdout, Read, Write},
+    process,
+    str::Chars,
+};
 
 use termion::{color, style};
 
@@ -179,6 +184,57 @@ impl Analyzer {
     }
 
     pub fn analyze_semantic(&mut self) {
+        let mut stack = vec![];
+
+        println!("Loading constants...\n-----");
+        for i in &self.constants {
+            println!("Adding `{}` to stack", i.name);
+            stack.push(&i.name);
+            Analyzer::pause();
+        }
+        println!("Stack:\n{:#?}\n-----", stack);
+
+        println!("Loading witnesses...\n-----");
+        for i in &self.witnesses {
+            println!("Adding `{}` to stack", i.name);
+            stack.push(&i.name);
+            Analyzer::pause();
+        }
+        println!("Stack:\n{:#?}\n-----", stack);
+
+        println!("Loading circuit...");
+        for i in &self.statements {
+            let argnames: Vec<String> = i.args.iter().map(|x| x.name.clone()).collect();
+            println!("Executing: {:?}({:?})", i.opcode, argnames);
+            Analyzer::pause();
+
+            for arg in &i.args {
+                print!("Looking up `{}` on the stack... ", arg.name);
+                if let Some(index) = stack.iter().position(|&r| r == &arg.name) {
+                    println!("Found at stack index {}", index);
+                } else {
+                    self.error(
+                        format!("Could not find `{}` on the stack", arg.name),
+                        arg.line,
+                        arg.column,
+                    );
+                }
+                Analyzer::pause();
+            }
+
+            match i.typ {
+                StatementType::Assignment => {
+                    println!("Pushing result as `{}` to stack", &i.variable.as_ref().unwrap().name);
+                    stack.push(&i.variable.as_ref().unwrap().name);
+                    println!("Stack:\n{:#?}\n-----", stack);
+                }
+                StatementType::Call => {
+                    println!("-----");
+                }
+                _ => unreachable!(),
+            }
+        }
+
         // println!("{:#?}", self.constants);
         // println!("{:#?}", self.witnesses);
         // println!("{:#?}", self.statements);
@@ -251,4 +307,13 @@ impl Analyzer {
         handle.flush().unwrap();
         process::exit(1);
     }
+
+    fn pause() {
+        let msg = b"[Press Enter to continue]\r";
+        let mut stdout = stdout();
+        let _ = stdout.write(msg).unwrap();
+        stdout.flush().unwrap();
+        let _ = stdin().read(&mut [0]).unwrap();
+        write!(stdout, "{}{}\r", termion::cursor::Up(1), termion::clear::CurrentLine).unwrap();
+    }
 }

+ 8 - 1
zkas/src/main.rs

@@ -24,6 +24,10 @@ struct Cli {
     #[clap(short)]
     evaluate: bool,
 
+    /// Interactive semantic analysis
+    #[clap(short)]
+    interactive: bool,
+
     /// Examine decoded bytecode
     #[clap(long)]
     examine: bool,
@@ -46,7 +50,10 @@ fn main() -> Result<()> {
 
     let mut analyzer = Analyzer::new(filename, source.chars(), constants, witnesses, statements);
     analyzer.analyze_types();
-    analyzer.analyze_semantic();
+
+    if cli.interactive {
+        analyzer.analyze_semantic();
+    }
 
     if cli.evaluate {
         println!("{:#?}", analyzer.constants);