feat(tvix/compiler): incompletely handle true/false/null literals
These are a bit tricky to implement because Nix technically treats them as identifiers, and only if the identifier is not explicitly overridden within the scope does it yield the expected literal values. Note that weirdness even occurs with scopedImport. Change-Id: Ie55723405ccfcc25da37c5a08fa3332f37cf9ae5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6080 Tested-by: BuildkiteCI Autosubmit: tazjin <tazjin@tvl.su> Reviewed-by: grfn <grfn@gws.fyi>
This commit is contained in:
parent
d431f43f5f
commit
9c5a249b30
2 changed files with 31 additions and 4 deletions
|
@ -6,7 +6,7 @@ use crate::errors::EvalResult;
|
|||
use crate::opcode::OpCode;
|
||||
use crate::value::Value;
|
||||
use rnix;
|
||||
use rnix::types::{TypedNode, Wrapper};
|
||||
use rnix::types::{TokenWrapper, TypedNode, Wrapper};
|
||||
|
||||
struct Compiler {
|
||||
chunk: Chunk,
|
||||
|
@ -41,6 +41,11 @@ impl Compiler {
|
|||
self.compile(node.inner().unwrap())
|
||||
}
|
||||
|
||||
rnix::SyntaxKind::NODE_IDENT => {
|
||||
let node = rnix::types::Ident::cast(node).unwrap();
|
||||
self.compile_ident(node)
|
||||
}
|
||||
|
||||
kind => {
|
||||
println!("visiting unsupported node: {:?}", kind);
|
||||
Ok(())
|
||||
|
@ -98,6 +103,28 @@ impl Compiler {
|
|||
self.chunk.add_op(opcode);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_ident(&mut self, node: rnix::types::Ident) -> EvalResult<()> {
|
||||
match node.as_str() {
|
||||
// TODO(tazjin): Nix technically allows code like
|
||||
//
|
||||
// let null = 1; in null
|
||||
// => 1
|
||||
//
|
||||
// which we do *not* want to check at runtime. Once
|
||||
// scoping is introduced, the compiler should carry some
|
||||
// optimised information about any "weird" stuff that's
|
||||
// happened to the scope (such as overrides of these
|
||||
// literals, or builtins).
|
||||
"true" => self.chunk.add_op(OpCode::OpTrue),
|
||||
"false" => self.chunk.add_op(OpCode::OpFalse),
|
||||
"null" => self.chunk.add_op(OpCode::OpNull),
|
||||
|
||||
_ => todo!("identifier access"),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile(ast: rnix::AST) -> EvalResult<Chunk> {
|
||||
|
|
|
@ -111,9 +111,9 @@ impl VM {
|
|||
self.push(Value::Bool(eq))
|
||||
}
|
||||
|
||||
OpCode::OpNull => todo!("null"),
|
||||
OpCode::OpTrue => todo!("true"),
|
||||
OpCode::OpFalse => todo!("false"),
|
||||
OpCode::OpNull => self.push(Value::Null),
|
||||
OpCode::OpTrue => self.push(Value::Bool(true)),
|
||||
OpCode::OpFalse => self.push(Value::Bool(false)),
|
||||
}
|
||||
|
||||
if self.ip == self.chunk.code.len() {
|
||||
|
|
Loading…
Reference in a new issue