{s}> } } } impl Output { fn display(self) -> Html { html! { <> {maybe_show("Parse errors:", &self.parse_errors)} {maybe_show("Warnings:", &self.warnings)} {maybe_show("Compiler errors:", &self.compiler_errors)} {maybe_show("Bytecode:", &String::from_utf8_lossy(&self.bytecode))} {maybe_show("Runtime errors:", &self.runtime_errors)} {maybe_show("Output:", &self.output)} > } } } fn eval(code: &str) -> Output { let mut out = Output::default(); if code == "" { return out; } let mut codemap = codemap::CodeMap::new(); let file = codemap.add_file("nixbolt".to_string(), code.into()); let parsed = rnix::ast::Root::parse(code); let errors = parsed.errors(); if !errors.is_empty() { for err in errors { writeln!(&mut out.parse_errors, "parse error: {}", err).unwrap(); } return out; } // If we've reached this point, there are no errors. let root_expr = parsed .tree() .expr() .expect("expression should exist if no errors occured"); let mut result = tvix_eval::compiler::compile( root_expr, Some("/nixbolt".into()), &file, tvix_eval::builtins::global_builtins(), Rc::new(codemap), ) .unwrap(); let lambda = Rc::new(result.lambda); tvix_eval::disassembler::disassemble_lambda(&mut out.bytecode, lambda.clone()); out.bytecode.append(&mut result.output); for warning in result.warnings { writeln!( &mut out.warnings, "warning: {:?} at `{}` [line {}]", warning.kind, file.source_slice(warning.span), file.find_line(warning.span.low()) + 1 ) .unwrap(); } if !result.errors.is_empty() { for error in &result.errors { writeln!( &mut out.compiler_errors, "error: {:?} at `{}` [line {}]", error.kind, file.source_slice(error.span), file.find_line(error.span.low()) + 1 ) .unwrap(); } return out; } let result = tvix_eval::vm::run_lambda(lambda); match result { Ok(value) => writeln!(&mut out.output, "{}", value).unwrap(), Err(err) => writeln!(&mut out.runtime_errors, "runtime error: {:?}", err).unwrap(), }; out } fn main() { yew::start_app::