about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-10-13T15·22+0300
committertazjin <tazjin@tvl.su>2022-10-16T12·26+0000
commite6d9be32a2dc6c7752f658f5c8fe4e33024bc2d3 (patch)
tree78e61021c4c4d59e6266a9af65e971a14ac629d8
parent0abc66ad91b8bcc25aeb7f3d086fcc52529ec8e8 (diff)
feat(tvixbolt): add toggle for displaying pretty-printed AST r/5144
This uses the JSON serialisation of the AST introduced earlier to
display a text box with the serialised AST to users. Useful for
debugging.

Change-Id: Ibc400eaf5ca87fa5072d5c044942505331c3bb40
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7005
Autosubmit: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Reviewed-by: Adam Joseph <adam@westernsemico.com>
Reviewed-by: tazjin <tazjin@tvl.su>
-rw-r--r--corp/tvixbolt/src/main.rs28
1 files changed, 26 insertions, 2 deletions
diff --git a/corp/tvixbolt/src/main.rs b/corp/tvixbolt/src/main.rs
index e6dda736f4a4..6cef4851a59f 100644
--- a/corp/tvixbolt/src/main.rs
+++ b/corp/tvixbolt/src/main.rs
@@ -15,12 +15,14 @@ use yew_router::{prelude::*, AnyRoute};
 enum Msg {
     CodeChange(String),
     ToggleTrace(bool),
+    ToggleDisplayAst(bool),
 }
 
 #[derive(Clone, Serialize, Deserialize)]
 struct Model {
     code: String,
     trace: bool,
+    display_ast: bool,
 }
 
 fn tvixbolt_overview() -> Html {
@@ -99,6 +101,7 @@ impl Component for Model {
             .unwrap_or_else(|_| Self {
                 code: String::new(),
                 trace: false,
+                display_ast: false,
             })
     }
 
@@ -108,6 +111,10 @@ impl Component for Model {
                 self.trace = trace;
             }
 
+            Msg::ToggleDisplayAst(display_ast) => {
+                self.display_ast = display_ast;
+            }
+
             Msg::CodeChange(new_code) => {
                 self.code = new_code;
             }
@@ -152,6 +159,17 @@ impl Component for Model {
                        })}
                        />
                     </div>
+
+                    <div class="form-group">
+                      <label for="display-ast">{"Display parsed AST:"}</label>
+                      <input
+                       id="display-ast" type="checkbox" checked={self.display_ast}
+                       onchange={link.callback(|e: Event| {
+                           let trace = e.target_unchecked_into::<HtmlInputElement>().checked();
+                           Msg::ToggleDisplayAst(trace)
+                       })}
+                       />
+                    </div>
                   </fieldset>
                 </form>
                 <hr />
@@ -179,7 +197,7 @@ impl Model {
         html! {
             <>
               <h2>{"Result:"}</h2>
-              {eval(self.trace, &self.code).display()}
+            {eval(self.trace, self.display_ast, &self.code).display()}
             </>
         }
     }
@@ -194,6 +212,7 @@ struct Output {
     output: String,
     bytecode: Vec<u8>,
     trace: Vec<u8>,
+    ast: String,
 }
 
 fn maybe_show(title: &str, s: &str) -> Html {
@@ -220,12 +239,13 @@ impl Output {
             {maybe_show("Bytecode:", &String::from_utf8_lossy(&self.bytecode))}
             {maybe_show("Runtime errors:", &self.runtime_errors)}
             {maybe_show("Runtime trace:", &String::from_utf8_lossy(&self.trace))}
+            {maybe_show("Parsed AST:", &self.ast)}
             </>
         }
     }
 }
 
-fn eval(trace: bool, code: &str) -> Output {
+fn eval(trace: bool, display_ast: bool, code: &str) -> Output {
     let mut out = Output::default();
 
     if code.is_empty() {
@@ -249,6 +269,10 @@ fn eval(trace: bool, code: &str) -> Output {
         .expr()
         .expect("expression should exist if no errors occured");
 
+    if display_ast {
+        out.ast = tvix_eval::pretty_print_expr(&root_expr);
+    }
+
     let source = SourceCode::new();
     let file = source.add_file("nixbolt".to_string(), code.into());