From 7e77972d71967c65e5446e55673869ef2a8d27bb Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Fri, 12 Aug 2022 17:07:32 +0300 Subject: [PATCH] feat(tvix/eval): add mechanism for emitting warnings from compiler These can be used predominantly to emit warnings about things that the compiler can infer, such as deprecated language features. Change-Id: I3649c625459d7f3f95cdf42d5c651d23d66569ec Reviewed-on: https://cl.tvl.fyi/c/depot/+/6174 Reviewed-by: grfn Tested-by: BuildkiteCI --- tvix/eval/src/compiler.rs | 18 ++++++++++++++++-- tvix/eval/src/eval.rs | 14 +++++++++++--- tvix/eval/src/lib.rs | 1 + tvix/eval/src/warnings.rs | 11 +++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 tvix/eval/src/warnings.rs diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index 1a4e8df1d..9b0530f0f 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -17,12 +17,22 @@ use crate::chunk::Chunk; use crate::errors::EvalResult; use crate::opcode::{CodeIdx, OpCode}; use crate::value::Value; +use crate::warnings::EvalWarning; use rnix; use rnix::types::{BinOpKind, EntryHolder, TokenWrapper, TypedNode, Wrapper}; +/// Represents the result of compiling a piece of Nix code. If +/// compilation was successful, the resulting bytecode can be passed +/// to the VM. +pub struct CompilationResult { + pub chunk: Chunk, + pub warnings: Vec, +} + struct Compiler { chunk: Chunk, + warnings: Vec, } impl Compiler { @@ -573,12 +583,16 @@ impl Compiler { } } -pub fn compile(ast: rnix::AST) -> EvalResult { +pub fn compile(ast: rnix::AST) -> EvalResult { let mut c = Compiler { chunk: Chunk::default(), + warnings: vec![], }; c.compile(ast.node())?; - Ok(c.chunk) + Ok(CompilationResult { + chunk: c.chunk, + warnings: c.warnings, + }) } diff --git a/tvix/eval/src/eval.rs b/tvix/eval/src/eval.rs index a12add48b..31280e4cd 100644 --- a/tvix/eval/src/eval.rs +++ b/tvix/eval/src/eval.rs @@ -14,8 +14,16 @@ pub fn interpret(code: &str) -> EvalResult { println!("{}", ast.root().dump()); } - let code = crate::compiler::compile(ast)?; - println!("code: {:?}", code); + let result = crate::compiler::compile(ast)?; + println!("code: {:?}", result.chunk); - crate::vm::run_chunk(code) + for warning in result.warnings { + eprintln!( + "warning: {:?} at {:?}", + warning.kind, + warning.node.text_range().start() + ) + } + + crate::vm::run_chunk(result.chunk) } diff --git a/tvix/eval/src/lib.rs b/tvix/eval/src/lib.rs index 75cd24642..ba037d6c8 100644 --- a/tvix/eval/src/lib.rs +++ b/tvix/eval/src/lib.rs @@ -5,6 +5,7 @@ mod eval; mod opcode; mod value; mod vm; +mod warnings; #[cfg(test)] mod tests; diff --git a/tvix/eval/src/warnings.rs b/tvix/eval/src/warnings.rs new file mode 100644 index 000000000..4406d0510 --- /dev/null +++ b/tvix/eval/src/warnings.rs @@ -0,0 +1,11 @@ +/// Warnings are emitted in cases where code passed to Tvix exhibits +/// problems that the user could address. + +#[derive(Debug)] +pub enum WarningKind {} + +#[derive(Debug)] +pub struct EvalWarning { + pub node: rnix::SyntaxNode, + pub kind: WarningKind, +}