This commit is contained in:
2026-03-12 17:47:46 +08:00
parent 7a7229d70e
commit 0c9a391618
511 changed files with 234 additions and 12772 deletions

View File

@@ -16,9 +16,6 @@ vim.lsp.config("rust_analyzer", {
settings = {
["rust-analyzer"] = {
cargo = {
features = {
"inspector"
}
}
}
}

1078
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,7 @@
[workspace]
resolver = "3"
members = [
"nix-js",
"nix-js-macros"
"fix"
]
[profile.profiling]

View File

@@ -1,8 +1,7 @@
[package]
name = "nix-js"
name = "fix"
version = "0.1.0"
edition = "2024"
build = "build.rs"
[dependencies]
mimalloc = "0.1"
@@ -35,9 +34,6 @@ itertools = "0.14"
regex = "1.11"
deno_core = "0.385"
deno_error = "0.7"
nix-nar = "0.3"
sha2 = "0.10"
sha1 = "0.10"
@@ -54,7 +50,7 @@ bzip2 = "0.6"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# spec 1.0.0
toml = "0.9.9"
toml = "=0.9.9"
dirs = "6.0"
tempfile = "3.24"
rusqlite = { version = "0.38", features = ["bundled"] }
@@ -62,24 +58,15 @@ rusqlite = { version = "0.38", features = ["bundled"] }
rnix = "0.14"
rowan = "0.16"
nix-js-macros = { path = "../nix-js-macros" }
ere = "0.2.4"
num_enum = "0.7.5"
tap = "1.0.1"
# Inspector (optional)
fastwebsockets = { version = "0.10", features = ["upgrade"], optional = true }
hyper = { version = "1", features = ["http1", "server"], optional = true }
hyper-util = { version = "0.1", features = ["tokio"], optional = true }
http-body-util = { version = "0.1", optional = true }
http = { version = "1", optional = true }
uuid = { version = "1", features = ["v4"], optional = true }
ghost-cell = "0.2.6"
colored = "3.1.1"
[features]
inspector = ["dep:fastwebsockets", "dep:hyper", "dep:hyper-util", "dep:http-body-util", "dep:http", "dep:uuid"]
prof = []
ghost-cell = "0.2"
colored = "3.1"
boxing = "0.1"
gc-arena = { version = "0.5.3", features = ["allocator-api2"] }
allocator-api2 = "0.4.0"
[dev-dependencies]
criterion = { version = "0.8", features = ["html_reports"] }
@@ -96,7 +83,3 @@ harness = false
[[bench]]
name = "thunk_scope"
harness = false
[[bench]]
name = "compile_time"
harness = false

View File

@@ -1,8 +1,8 @@
#![allow(dead_code)]
use nix_js::context::Context;
use nix_js::error::{Result, Source};
use nix_js::value::Value;
use fix::context::Context;
use fix::error::{Result, Source};
use fix::value::Value;
pub fn eval(expr: &str) -> Value {
Context::new()
@@ -16,10 +16,3 @@ pub fn eval_result(expr: &str) -> Result<Value> {
.unwrap()
.eval(Source::new_eval(expr.into()).unwrap())
}
pub fn compile(expr: &str) -> String {
Context::new()
.unwrap()
.compile(Source::new_eval(expr.into()).unwrap())
.unwrap()
}

View File

@@ -30,72 +30,72 @@ pub(crate) trait BytecodeContext {
#[derive(Clone, Copy, TryFromPrimitive)]
#[allow(clippy::enum_variant_names)]
pub enum Op {
PushConst = 0x01,
PushString = 0x02,
PushNull = 0x03,
PushTrue = 0x04,
PushFalse = 0x05,
PushConst,
PushString,
PushNull,
PushTrue,
PushFalse,
LoadLocal = 0x06,
LoadOuter = 0x07,
StoreLocal = 0x08,
AllocLocals = 0x09,
LoadLocal,
LoadOuter,
StoreLocal,
AllocLocals,
MakeThunk = 0x0A,
MakeClosure = 0x0B,
MakePatternClosure = 0x0C,
MakeThunk,
MakeClosure,
MakePatternClosure,
Call = 0x0D,
CallNoSpan = 0x0E,
Call,
CallNoSpan,
MakeAttrs = 0x0F,
MakeAttrsDyn = 0x10,
MakeEmptyAttrs = 0x11,
Select = 0x12,
SelectDefault = 0x13,
HasAttr = 0x14,
MakeAttrs,
MakeAttrsDyn,
MakeEmptyAttrs,
Select,
SelectDefault,
HasAttr,
MakeList = 0x15,
MakeList,
OpAdd = 0x16,
OpSub = 0x17,
OpMul = 0x18,
OpDiv = 0x19,
OpEq = 0x20,
OpNeq = 0x21,
OpLt = 0x22,
OpGt = 0x23,
OpLeq = 0x24,
OpGeq = 0x25,
OpConcat = 0x26,
OpUpdate = 0x27,
OpAdd,
OpSub,
OpMul,
OpDiv,
OpEq,
OpNeq,
OpLt,
OpGt,
OpLeq,
OpGeq,
OpConcat,
OpUpdate,
OpNeg = 0x28,
OpNot = 0x29,
OpNeg,
OpNot,
ForceBool = 0x30,
JumpIfFalse = 0x31,
JumpIfTrue = 0x32,
Jump = 0x33,
ForceBool,
JumpIfFalse,
JumpIfTrue,
Jump,
ConcatStrings = 0x34,
ResolvePath = 0x35,
ConcatStrings,
ResolvePath,
Assert = 0x36,
Assert,
PushWith = 0x37,
PopWith = 0x38,
WithLookup = 0x39,
PushWith,
PopWith,
WithLookup,
LoadBuiltins = 0x40,
LoadBuiltin = 0x41,
LoadBuiltins,
LoadBuiltin,
MkPos = 0x43,
MkPos,
LoadReplBinding = 0x44,
LoadScopedBinding = 0x45,
LoadReplBinding,
LoadScopedBinding,
Return = 0x46,
Return,
}
struct ScopeInfo {
@@ -120,19 +120,6 @@ pub(crate) fn compile_bytecode(ir: RawIrRef<'_>, ctx: &mut impl BytecodeContext)
}
}
pub(crate) fn compile_bytecode_scoped(
ir: RawIrRef<'_>,
ctx: &mut impl BytecodeContext,
) -> Bytecode {
let current_dir = ctx.get_current_dir().to_string_lossy().to_string();
let mut emitter = BytecodeEmitter::new(ctx);
emitter.emit_toplevel_scoped(ir);
Bytecode {
code: emitter.code.into_boxed_slice(),
current_dir,
}
}
impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> {
fn new(ctx: &'a mut Ctx) -> Self {
Self {
@@ -397,37 +384,6 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> {
}
}
fn emit_toplevel_scoped(&mut self, ir: RawIrRef<'_>) {
match ir.deref() {
Ir::TopLevel { body, thunks } => {
let with_thunk_count = self.count_with_thunks(*body);
let total_slots = thunks.len() + with_thunk_count;
let all_thunks = self.collect_all_thunks(thunks, *body);
let thunk_ids: Vec<ThunkId> = all_thunks.iter().map(|&(id, _)| id).collect();
self.push_scope(false, None, &thunk_ids);
if total_slots > 0 {
self.emit_op(Op::AllocLocals);
self.emit_u32(total_slots as u32);
}
self.emit_scope_thunks(thunks);
self.emit_expr(*body);
self.emit_op(Op::Return);
self.pop_scope();
}
_ => {
self.push_scope(false, None, &[]);
self.emit_expr(ir);
self.emit_op(Op::Return);
self.pop_scope();
}
}
}
fn emit_scope_thunks(&mut self, thunks: &[(ThunkId, RawIrRef<'_>)]) {
for &(id, inner) in thunks {
let label = format!("e{}", id.0);

View File

@@ -9,14 +9,10 @@ use rnix::TextRange;
use string_interner::DefaultStringInterner;
use crate::bytecode::{self, Bytecode, BytecodeContext, Constant};
use crate::codegen::{CodegenContext, compile};
use crate::disassembler::{Disassembler, DisassemblerContext};
use crate::downgrade::*;
use crate::error::{Error, Result, Source};
use crate::ir::{ArgId, Ir, IrKey, IrRef, RawIrRef, SymId, ThunkId, ir_content_eq};
#[cfg(feature = "inspector")]
use crate::runtime::inspector::InspectorServer;
use crate::runtime::{ForceMode, Runtime, RuntimeContext};
use crate::store::{DaemonStore, Store, StoreConfig};
use crate::value::{Symbol, Value};
@@ -48,129 +44,27 @@ fn handle_parse_error<'a>(
None
}
pub struct Context {
ctx: Ctx,
runtime: Runtime<Ctx>,
#[cfg(feature = "inspector")]
_inspector_server: Option<InspectorServer>,
}
macro_rules! eval_bc {
($name:ident, $mode:expr) => {
pub fn $name(&mut self, source: Source) -> Result<Value> {
tracing::info!("Starting evaluation");
tracing::debug!("Compiling bytecode");
let bytecode = self.ctx.compile_bytecode(source)?;
tracing::debug!("Executing bytecode");
self.runtime.eval_bytecode(bytecode, &mut self.ctx, $mode)
}
};
}
impl Context {
pub fn new() -> Result<Self> {
let ctx = Ctx::new()?;
#[cfg(feature = "inspector")]
let runtime = Runtime::new(Default::default())?;
#[cfg(not(feature = "inspector"))]
let runtime = Runtime::new()?;
let mut context = Self {
ctx,
runtime,
#[cfg(feature = "inspector")]
_inspector_server: None,
};
context.init()?;
Ok(context)
pub fn eval(&mut self, _source: Source) -> Result<Value> {
todo!()
}
pub fn eval_shallow(&mut self, _source: Source) -> Result<Value> {
todo!()
}
pub fn eval_deep(&mut self, _source: Source) -> Result<Value> {
todo!()
}
#[cfg(feature = "inspector")]
pub fn new_with_inspector(addr: std::net::SocketAddr, wait_for_session: bool) -> Result<Self> {
use crate::runtime::InspectorOptions;
let ctx = Ctx::new()?;
let runtime = Runtime::new(InspectorOptions {
enable: true,
wait: wait_for_session,
})?;
let server = crate::runtime::inspector::InspectorServer::new(addr, "nix-js")
.map_err(|e| Error::internal(e.to_string()))?;
server.register_inspector("nix-js".to_string(), runtime.inspector(), wait_for_session);
let mut context = Self {
ctx,
runtime,
_inspector_server: Some(server),
};
context.init()?;
Ok(context)
}
#[cfg(feature = "inspector")]
pub fn wait_for_inspector_disconnect(&mut self) {
self.runtime.wait_for_inspector_disconnect();
}
fn init(&mut self) -> Result<()> {
const DERIVATION_NIX: &str = include_str!("runtime/corepkgs/derivation.nix");
let source = Source::new_virtual(
"<nix/derivation-internal.nix>".into(),
DERIVATION_NIX.to_string(),
);
let code = self.ctx.compile(source, None)?;
self.runtime.eval(
format!(
"Nix.builtins.set('derivation',({}));Nix.builtins.set('storeDir','{}');{}0n",
code,
self.get_store_dir(),
if std::env::var("NIX_JS_DEBUG_THUNKS").is_ok() {
"Nix.DEBUG_THUNKS.enabled=true;"
} else {
""
}
),
&mut self.ctx,
)?;
Ok(())
}
eval_bc!(eval, ForceMode::Force);
eval_bc!(eval_shallow, ForceMode::ForceShallow);
eval_bc!(eval_deep, ForceMode::ForceDeep);
pub fn eval_repl<'a>(&'a mut self, source: Source, scope: &'a HashSet<SymId>) -> Result<Value> {
tracing::info!("Starting evaluation");
tracing::debug!("Compiling code");
let code = self.ctx.compile(source, Some(Scope::Repl(scope)))?;
tracing::debug!("Executing JavaScript");
self.runtime
.eval(format!("Nix.forceShallow({})", code), &mut self.ctx)
}
pub fn compile(&mut self, source: Source) -> Result<String> {
self.ctx.compile(source, None)
}
pub fn compile_bytecode(&mut self, source: Source) -> Result<Bytecode> {
self.ctx.compile_bytecode(source)
pub fn eval_repl<'a>(&'a mut self, _source: Source, _scope: &'a HashSet<SymId>) -> Result<Value> {
todo!()
}
pub fn disassemble(&self, bytecode: &Bytecode) -> String {
Disassembler::new(bytecode, &self.ctx).disassemble()
Disassembler::new(bytecode, self).disassemble()
}
pub fn disassemble_colored(&self, bytecode: &Bytecode) -> String {
Disassembler::new(bytecode, &self.ctx).disassemble_colored()
}
pub fn get_store_dir(&self) -> &str {
self.ctx.get_store_dir()
Disassembler::new(bytecode, self).disassemble_colored()
}
pub fn add_binding<'a>(
@@ -179,22 +73,11 @@ impl Context {
expr: &str,
scope: &'a mut HashSet<SymId>,
) -> Result<Value> {
let source = Source::new_repl(expr.to_string())?;
let code = self.ctx.compile(source, Some(Scope::Repl(scope)))?;
let sym = self.ctx.symbols.get_or_intern(name);
let eval_and_store = format!(
"(()=>{{const __v=Nix.forceShallow({});Nix.setReplBinding(\"{}\",__v);return __v}})()",
code, name
);
scope.insert(sym);
self.runtime.eval(eval_and_store, &mut self.ctx)
todo!()
}
}
struct Ctx {
pub struct Context {
symbols: DefaultStringInterner,
global: HashMap<SymId, Ir<'static, RawIrRef<'static>>>,
sources: Vec<Source>,
@@ -226,8 +109,8 @@ impl OwnedIr {
}
}
impl Ctx {
fn new() -> Result<Self> {
impl Context {
pub fn new() -> Result<Self> {
let mut symbols = DefaultStringInterner::new();
let mut global = HashMap::new();
let builtins_sym = symbols.get_or_intern("builtins");
@@ -349,33 +232,7 @@ impl Ctx {
})
}
fn compile<'ctx>(
&'ctx mut self,
source: Source,
extra_scope: Option<Scope<'ctx>>,
) -> Result<String> {
let root = self.downgrade(source, extra_scope)?;
tracing::debug!("Generating JavaScript code");
let code = compile::<false>(root.as_ref(), self);
tracing::debug!("Generated code: {}", &code);
Ok(code)
}
fn compile_scoped(&mut self, source: Source, scope: Vec<String>) -> Result<String> {
let scope = Scope::ScopedImport(
scope
.into_iter()
.map(|k| self.symbols.get_or_intern(k))
.collect(),
);
let root = self.downgrade(source, Some(scope))?;
tracing::debug!("Generating JavaScript code for scoped import");
let code = compile::<true>(root.as_ref(), self);
tracing::debug!("Generated scoped code: {}", &code);
Ok(code)
}
fn compile_bytecode(&mut self, source: Source) -> Result<Bytecode> {
pub fn compile_bytecode(&mut self, source: Source) -> Result<Bytecode> {
let root = self.downgrade(source, None)?;
tracing::debug!("Generating bytecode");
let bytecode = bytecode::compile_bytecode(root.as_ref(), self);
@@ -383,47 +240,12 @@ impl Ctx {
Ok(bytecode)
}
fn compile_bytecode_scoped(&mut self, source: Source, scope: Vec<String>) -> Result<Bytecode> {
let scope = Scope::ScopedImport(
scope
.into_iter()
.map(|k| self.symbols.get_or_intern(k))
.collect(),
);
let root = self.downgrade(source, Some(scope))?;
tracing::debug!("Generating bytecode for scoped import");
Ok(bytecode::compile_bytecode_scoped(root.as_ref(), self))
}
}
impl CodegenContext for Ctx {
fn get_sym(&self, id: SymId) -> Symbol<'_> {
self.symbols
.resolve(id)
.expect("SymId out of bounds")
.into()
}
fn get_current_dir(&self) -> &std::path::Path {
self.get_current_dir()
}
fn get_current_source_id(&self) -> usize {
self.sources
.len()
.checked_sub(1)
.expect("current_source not set")
}
fn get_store_dir(&self) -> &str {
pub fn get_store_dir(&self) -> &str {
self.store.get_store_dir()
}
fn register_span(&self, range: rnix::TextRange) -> usize {
let spans = unsafe { &mut *self.spans.get() };
let id = spans.len();
spans.push((self.get_current_source_id(), range));
id
}
}
impl BytecodeContext for Ctx {
impl BytecodeContext for Context {
fn intern_string(&mut self, s: &str) -> u32 {
if let Some(&idx) = self.global_string_map.get(s) {
return idx;
@@ -445,7 +267,16 @@ impl BytecodeContext for Ctx {
}
fn register_span(&self, range: TextRange) -> u32 {
CodegenContext::register_span(self, range) as u32
// FIXME: SAFETY
let spans = unsafe { &mut *self.spans.get() };
let id = spans.len();
let source_id = self
.sources
.len()
.checked_sub(1)
.expect("current_source not set");
spans.push((source_id, range));
id as u32
}
fn get_sym(&self, id: SymId) -> &str {
@@ -453,51 +284,11 @@ impl BytecodeContext for Ctx {
}
fn get_current_dir(&self) -> &Path {
Ctx::get_current_dir(self)
Context::get_current_dir(self)
}
}
impl RuntimeContext for Ctx {
fn get_current_dir(&self) -> &Path {
self.get_current_dir()
}
fn add_source(&mut self, source: Source) {
self.sources.push(source);
}
fn compile(&mut self, source: Source) -> Result<String> {
self.compile(source, None)
}
fn compile_scoped(&mut self, source: Source, scope: Vec<String>) -> Result<String> {
self.compile_scoped(source, scope)
}
fn compile_bytecode(&mut self, source: Source) -> Result<Bytecode> {
self.compile_bytecode(source)
}
fn compile_bytecode_scoped(&mut self, source: Source, scope: Vec<String>) -> Result<Bytecode> {
self.compile_bytecode_scoped(source, scope)
}
fn get_source(&self, id: usize) -> Source {
self.sources.get(id).expect("source not found").clone()
}
fn get_store(&self) -> &DaemonStore {
&self.store
}
fn get_span(&self, id: usize) -> (usize, TextRange) {
let spans = unsafe { &*self.spans.get() };
spans[id]
}
fn get_unsynced(&mut self) -> (&[String], &[Constant], usize, usize) {
let strings_base = self.synced_strings;
let constants_base = self.synced_constants;
let new_strings = &self.global_strings[strings_base..];
let new_constants = &self.global_constants[constants_base..];
self.synced_strings = self.global_strings.len();
self.synced_constants = self.global_constants.len();
(new_strings, new_constants, strings_base, constants_base)
}
}
impl DisassemblerContext for Ctx {
impl DisassemblerContext for Context {
fn lookup_string(&self, id: u32) -> &str {
self.global_strings
.get(id as usize)

View File

@@ -1,14 +1,9 @@
use std::path::{Path, PathBuf};
use std::sync::Arc;
use deno_core::error::JsError;
use deno_error::JsErrorClass as _;
use itertools::Itertools as _;
use miette::{Diagnostic, NamedSource, SourceSpan};
use thiserror::Error;
use crate::runtime::RuntimeContext;
pub type Result<T> = core::result::Result<T, Box<Error>>;
#[derive(Clone, Debug)]
@@ -229,127 +224,3 @@ pub struct StackFrame {
#[source_code]
pub src: NamedSource<Arc<str>>,
}
const MAX_STACK_FRAMES: usize = 20;
const FRAMES_AT_START: usize = 15;
const FRAMES_AT_END: usize = 5;
pub(crate) fn parse_js_error(error: Box<JsError>, ctx: &impl RuntimeContext) -> Error {
let (span, src, frames) = if let Some(stack) = &error.stack {
let mut frames = parse_frames(stack, ctx);
if let Some(last_frame) = frames.pop() {
(
Some(text_range_to_source_span(last_frame.span)),
Some(last_frame.src.into()),
frames,
)
} else {
(None, None, frames)
}
} else {
(None, None, Vec::new())
};
let stack_trace = if std::env::var("NIX_JS_STACK_TRACE").is_ok() {
truncate_stack_trace(frames)
} else {
Vec::new()
};
let message = error.get_message().to_string();
let js_backtrace = error.stack.map(|stack| {
stack
.lines()
.filter(|line| !line.starts_with("NIX_STACK_FRAME:"))
.join("\n")
});
Error::EvalError {
src,
span,
message,
js_backtrace,
stack_trace,
}
}
struct NixStackFrame {
span: rnix::TextRange,
message: String,
src: Source,
}
impl From<NixStackFrame> for StackFrame {
fn from(NixStackFrame { span, message, src }: NixStackFrame) -> Self {
StackFrame {
span: text_range_to_source_span(span),
message,
src: src.into(),
}
}
}
fn parse_frames(stack: &str, ctx: &impl RuntimeContext) -> Vec<NixStackFrame> {
let mut frames = Vec::new();
for line in stack.lines() {
// Format: NIX_STACK_FRAME:span_id:message
let Some(rest) = line.strip_prefix("NIX_STACK_FRAME:") else {
continue;
};
let parts: Vec<&str> = rest.splitn(2, ':').collect();
if parts.is_empty() {
continue;
}
let span_id: usize = match parts[0].parse() {
Ok(id) => id,
Err(_) => continue,
};
let (source_id, span) = ctx.get_span(span_id);
let src = ctx.get_source(source_id);
let message = if parts.len() == 2 {
parts[1].to_string()
} else {
String::new()
};
frames.push(NixStackFrame { span, message, src });
}
frames.dedup_by(|a, b| a.span == b.span && a.message == b.message);
frames
}
fn truncate_stack_trace(frames: Vec<NixStackFrame>) -> Vec<StackFrame> {
let reversed: Vec<_> = frames.into_iter().rev().collect();
let total = reversed.len();
if total <= MAX_STACK_FRAMES {
return reversed.into_iter().map(Into::into).collect();
}
let omitted_count = total - FRAMES_AT_START - FRAMES_AT_END;
reversed
.into_iter()
.enumerate()
.filter_map(|(i, frame)| {
if i < FRAMES_AT_START {
Some(frame.into())
} else if i == FRAMES_AT_START {
Some(StackFrame {
span: text_range_to_source_span(frame.span),
message: format!("... ({} more frames omitted)", omitted_count),
src: frame.src.into(),
})
} else if i >= total - FRAMES_AT_END {
Some(frame.into())
} else {
None
}
})
.collect()
}

View File

@@ -5,8 +5,6 @@ use nix_compat::nixhash::HashAlgo;
use nix_compat::nixhash::NixHash;
use tracing::{debug, info, warn};
use crate::runtime::OpStateExt;
use crate::runtime::RuntimeContext;
use crate::store::Store as _;
mod archive;
@@ -20,7 +18,6 @@ pub use download::Downloader;
pub use metadata_cache::MetadataCache;
use crate::nar;
use crate::runtime::NixRuntimeError;
#[derive(ToV8)]
pub struct FetchUrlResult {
@@ -306,11 +303,3 @@ fn normalize_hash(hash: &str) -> String {
}
hash.to_string()
}
pub fn register_ops<Ctx: RuntimeContext>() -> Vec<deno_core::OpDecl> {
vec![
op_fetch_url::<Ctx>(),
op_fetch_tarball::<Ctx>(),
op_fetch_git::<Ctx>(),
]
}

View File

@@ -10,7 +10,7 @@ impl FetcherCache {
pub fn new() -> Result<Self, std::io::Error> {
let base_dir = dirs::cache_dir()
.unwrap_or_else(|| PathBuf::from("/tmp"))
.join("nix-js")
.join("fix")
.join("fetchers");
fs::create_dir_all(&base_dir)?;

View File

@@ -6,11 +6,10 @@ pub mod logging;
pub mod value;
mod bytecode;
mod codegen;
mod derivation;
mod disassembler;
mod downgrade;
mod fetcher;
// mod fetcher;
mod ir;
mod nar;
mod nix_utils;

View File

@@ -4,22 +4,14 @@ use std::process::exit;
use anyhow::Result;
use clap::{Args, Parser, Subcommand};
use hashbrown::HashSet;
use nix_js::context::Context;
use nix_js::error::Source;
use fix::context::Context;
use fix::error::Source;
use rustyline::DefaultEditor;
use rustyline::error::ReadlineError;
#[derive(Parser)]
#[command(name = "nix-js", about = "Nix expression evaluator")]
struct Cli {
#[cfg(feature = "inspector")]
#[arg(long, value_name = "HOST:PORT", num_args = 0..=1, default_missing_value = "127.0.0.1:9229")]
inspect: Option<String>,
#[cfg(feature = "inspector")]
#[arg(long, value_name = "HOST:PORT", num_args = 0..=1, default_missing_value = "127.0.0.1:9229")]
inspect_brk: Option<String>,
#[command(subcommand)]
command: Command,
}
@@ -48,27 +40,6 @@ struct ExprSource {
file: Option<PathBuf>,
}
fn create_context(#[cfg(feature = "inspector")] cli: &Cli) -> Result<Context> {
#[cfg(feature = "inspector")]
{
let (addr_str, wait) = if let Some(ref addr) = cli.inspect_brk {
(Some(addr.as_str()), true)
} else if let Some(ref addr) = cli.inspect {
(Some(addr.as_str()), false)
} else {
(None, false)
};
if let Some(addr_str) = addr_str {
let addr: std::net::SocketAddr = addr_str
.parse()
.map_err(|e| anyhow::anyhow!("invalid inspector address '{}': {}", addr_str, e))?;
return Ok(Context::new_with_inspector(addr, wait)?);
}
}
Ok(Context::new()?)
}
fn run_compile(context: &mut Context, src: ExprSource, silent: bool) -> Result<()> {
let src = if let Some(expr) = src.expr {
Source::new_eval(expr)?
@@ -88,8 +59,6 @@ fn run_compile(context: &mut Context, src: ExprSource, silent: bool) -> Result<(
exit(1);
}
};
#[cfg(feature = "inspector")]
context.wait_for_inspector_disconnect();
Ok(())
}
@@ -110,8 +79,6 @@ fn run_eval(context: &mut Context, src: ExprSource) -> Result<()> {
exit(1);
}
};
#[cfg(feature = "inspector")]
context.wait_for_inspector_disconnect();
Ok(())
}
@@ -170,14 +137,11 @@ fn run_repl(context: &mut Context) -> Result<()> {
}
fn main() -> Result<()> {
nix_js::logging::init_logging();
fix::logging::init_logging();
let cli = Cli::parse();
let mut context = create_context(
#[cfg(feature = "inspector")]
&cli,
)?;
let mut context = Context::new()?;
match cli.command {
Command::Compile { source, silent } => run_compile(&mut context, source, silent),

View File

@@ -1,4 +1,4 @@
use nix_js::value::Value;
use fix::value::Value;
use crate::utils::{eval, eval_result};

View File

@@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use nix_js::value::{AttrSet, List, Value};
use fix::value::{AttrSet, List, Value};
use crate::utils::eval;

View File

@@ -1,4 +1,4 @@
use nix_js::value::Value;
use fix::value::Value;
use crate::utils::eval_result;

View File

@@ -1,4 +1,4 @@
use nix_js::value::Value;
use fix::value::Value;
use crate::utils::{eval_deep, eval_deep_result};

View File

@@ -1,4 +1,4 @@
use nix_js::value::{List, Value};
use fix::value::{List, Value};
use crate::utils::{eval, eval_result};

View File

@@ -1,4 +1,4 @@
use nix_js::value::Value;
use fix::value::Value;
use crate::utils::{eval, eval_result};

View File

@@ -1,6 +1,6 @@
use nix_js::context::Context;
use nix_js::error::Source;
use nix_js::value::Value;
use fix::context::Context;
use fix::error::Source;
use fix::value::Value;
use crate::utils::{eval, eval_result};

View File

@@ -2,9 +2,9 @@
use std::path::PathBuf;
use nix_js::context::Context;
use nix_js::error::Source;
use nix_js::value::Value;
use fix::context::Context;
use fix::error::Source;
use fix::value::Value;
fn get_lang_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/tests/lang")
@@ -18,7 +18,7 @@ fn eval_file(name: &str) -> Result<(Value, Source), String> {
let mut ctx = Context::new().map_err(|e| e.to_string())?;
let source = Source {
ty: nix_js::error::SourceType::File(nix_path.into()),
ty: fix::error::SourceType::File(nix_path.into()),
src: expr.into(),
};
ctx.eval_deep(source.clone())

Some files were not shown because too many files have changed in this diff Show More