difftreelog
feat(macro) pass call location to builtins
in: master
8 files changed
cmds/jrsonnet-fmt/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/cmds/jrsonnet-fmt/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "jrsonnet-fmt"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+dprint-core = "0.47.1"
+jrsonnet-parser = { path = "../../crates/jrsonnet-parser" }
cmds/jrsonnet-fmt/src/main.rsdiffbeforeafterbothno changes
crates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -5,14 +5,13 @@
equals,
error::{Error::*, Result},
operator::evaluate_mod_op,
- parse_args, primitive_equals, push_frame, throw, with_state, ArrValue, Context, FuncVal,
+ primitive_equals, push_frame, throw, with_state, ArrValue, Context, FuncVal,
IndexableVal, Val,
};
use format::{format_arr, format_obj};
use gcmodule::Cc;
use jrsonnet_interner::IStr;
use jrsonnet_parser::{ArgsDesc, ExprLocation};
-use jrsonnet_types::ty;
use serde::Deserialize;
use serde_yaml::DeserializingQuirks;
use std::{
@@ -466,19 +465,19 @@
Ok(format!("{:x}", md5::compute(&str.as_bytes())))
}
-fn builtin_trace(context: Context, loc: &ExprLocation, args: &ArgsDesc) -> Result<Val> {
- parse_args!(context, "trace", args, 2, [
- 0, str: ty!(string) => Val::Str;
- 1, rest: ty!(any);
- ], {
- eprint!("TRACE:");
- with_state(|s|{
- let locs = s.map_source_locations(&loc.0, &[loc.1]);
- eprint!(" {}:{}", loc.0.file_name().unwrap().to_str().unwrap(), locs[0].line);
- });
- eprintln!(" {}", str);
- Ok(rest)
- })
+#[jrsonnet_macros::builtin]
+fn builtin_trace(#[location] loc: &ExprLocation, str: IStr, rest: Any) -> Result<Any> {
+ eprint!("TRACE:");
+ with_state(|s| {
+ let locs = s.map_source_locations(&loc.0, &[loc.1]);
+ eprint!(
+ " {}:{}",
+ loc.0.file_name().unwrap().to_str().unwrap(),
+ locs[0].line
+ );
+ });
+ eprintln!(" {}", str);
+ Ok(rest) as Result<Any>
}
#[jrsonnet_macros::builtin]
crates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -16,8 +16,6 @@
pub enum Error {
#[error("intrinsic not found: {0}")]
IntrinsicNotFound(IStr),
- #[error("argument reordering in intrisics not supported yet")]
- IntrinsicArgumentReorderingIsNotSupportedYet,
#[error("operator {0} does not operate on type {1}")]
UnaryOperatorDoesNotOperateOnType(UnaryOpType, ValType),
crates/jrsonnet-evaluator/src/function.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function.rs
+++ b/crates/jrsonnet-evaluator/src/function.rs
@@ -311,45 +311,3 @@
Ok(body_ctx.extend(out, None, None, None))
}
-
-#[macro_export]
-macro_rules! parse_args {
- ($ctx: expr, $fn_name: expr, $args: expr, $total_args: expr, [
- $($id: expr, $name: ident: $ty: expr $(=>$match: path)?);+ $(;)?
- ], $handler:block) => {{
- use $crate::{error::Error::*, throw, evaluate, push_description_frame, typed::CheckType};
-
- let args = $args;
- if args.unnamed.len() + args.named.len() > $total_args {
- throw!(TooManyArgsFunctionHas($total_args));
- }
- $(
- if args.unnamed.len() + args.named.len() <= $id {
- throw!(FunctionParameterNotBoundInCall(stringify!($name).into()));
- }
- // Is named
- let $name = if $id >= $args.unnamed.len() {
- let named = &args.named[$id - $args.unnamed.len()];
- if &named.0 != stringify!($name) {
- throw!(IntrinsicArgumentReorderingIsNotSupportedYet);
- }
- &named.1
- } else {
- &$args.unnamed[$id]
- };
- let $name = push_description_frame(|| format!("evaluating builtin argument {}", stringify!($name)), || {
- let value = evaluate($ctx.clone(), &$name)?;
- $ty.check(&value)?;
- Ok(value)
- })?;
- $(
- let $name = if let $match(v) = $name {
- v
- } else {
- unreachable!();
- };
- )?
- )+
- ($handler as crate::Result<_>)
- }};
-}
crates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -1,6 +1,10 @@
use proc_macro2::Span;
use quote::quote;
-use syn::{parse_macro_input, FnArg, Ident, ItemFn, Pat};
+use syn::{parse_macro_input, FnArg, Ident, ItemFn, Pat, PatType};
+
+fn is_location_arg(t: &PatType) -> bool {
+ t.attrs.iter().any(|a| a.path.is_ident("location"))
+}
#[proc_macro_attribute]
pub fn builtin(
@@ -8,14 +12,11 @@
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
// syn::ItemFn::parse(input)
- let fun: ItemFn = parse_macro_input!(item);
+ let mut fun: ItemFn = parse_macro_input!(item);
- let inner_name = Ident::new("inner", Span::call_site());
- let mut inner_fun = fun.clone();
- inner_fun.sig.ident = inner_name.clone();
let result = match fun.sig.output {
syn::ReturnType::Default => panic!("builtin should return something"),
- syn::ReturnType::Type(_, ty) => ty,
+ syn::ReturnType::Type(_, ref ty) => ty.clone(),
};
let params = fun
@@ -26,6 +27,7 @@
FnArg::Receiver(_) => unreachable!(),
FnArg::Typed(t) => t,
})
+ .filter(|a| !is_location_arg(a))
.map(|t| {
let ident = match &t.pat as &Pat {
Pat::Ident(i) => i.ident.to_string(),
@@ -39,38 +41,53 @@
has_default: #optional,
}
}
- });
+ })
+ .collect::<Vec<_>>();
let args = fun
.sig
.inputs
- .iter()
+ .iter_mut()
.map(|i| match i {
FnArg::Receiver(_) => unreachable!(),
FnArg::Typed(t) => t,
})
.map(|t| {
- let ident = match &t.pat as &Pat {
- Pat::Ident(i) => i.ident.to_string(),
- _ => panic!("only idents supported yet"),
- };
- let ty = &t.ty;
- quote! {{
- let value = parsed.get(#ident).unwrap();
+ let count_before = t.attrs.len();
+ t.attrs.retain(|a| !a.path.is_ident("location"));
+ let count_after = t.attrs.len();
+ let is_location = count_before != count_after;
+ if is_location {
+ quote! {{
+ loc
+ }}
+ } else {
+ let ident = match &t.pat as &Pat {
+ Pat::Ident(i) => i.ident.to_string(),
+ _ => panic!("only idents supported yet"),
+ };
+ let ty = &t.ty;
+ quote! {{
+ let value = parsed.get(#ident).unwrap();
- jrsonnet_evaluator::push_description_frame(
- || format!("argument <{}> evaluation", #ident),
- || <#ty>::try_from(value.evaluate()?),
- )?
- }}
- });
+ jrsonnet_evaluator::push_description_frame(
+ || format!("argument <{}> evaluation", #ident),
+ || <#ty>::try_from(value.evaluate()?),
+ )?
+ }}
+ }
+ }).collect::<Vec<_>>();
+
+ let inner_name = Ident::new("inner", Span::call_site());
+ let mut inner_fun = fun.clone();
+ inner_fun.sig.ident = inner_name.clone();
let attrs = &fun.attrs;
let vis = &fun.vis;
let name = &fun.sig.ident;
(quote! {
#(#attrs)*
- #vis fn #name(context: Context, _loc: &ExprLocation, args: &ArgsDesc) -> Result<Val> {
+ #vis fn #name(context: Context, loc: &ExprLocation, args: &ArgsDesc) -> Result<Val> {
#inner_fun
use jrsonnet_evaluator::function::BuiltinParam;
const PARAMS: &'static [BuiltinParam] = &[
crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-types/src/lib.rs
+++ b/crates/jrsonnet-types/src/lib.rs
@@ -191,9 +191,9 @@
write!(f, "}}")?;
}
ComplexValType::Union(v) => write_union(f, true, v.iter())?,
- ComplexValType::UnionRef(v) => write_union(f, true, v.iter().map(|v| *v))?,
+ ComplexValType::UnionRef(v) => write_union(f, true, v.iter().copied())?,
ComplexValType::Sum(v) => write_union(f, false, v.iter())?,
- ComplexValType::SumRef(v) => write_union(f, false, v.iter().map(|v| *v))?,
+ ComplexValType::SumRef(v) => write_union(f, false, v.iter().copied())?,
};
Ok(())
}
flake.nixdiffbeforeafterboth--- a/flake.nix
+++ b/flake.nix
@@ -1,21 +1,59 @@
{
- description = "Rust jsonnet implementation";
-
- inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
- inputs.flake-utils.url = "github:numtide/flake-utils";
-
- outputs = { self, nixpkgs, flake-utils }:
+ description = "Dotfiles manager";
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs";
+ flake-utils.url = "github:numtide/flake-utils";
+ naersk.url = "github:nix-community/naersk";
+ rust-overlay.url = "github:oxalica/rust-overlay";
+ pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
+ };
+ outputs = { self, nixpkgs, flake-utils, rust-overlay, pre-commit-hooks, naersk }:
flake-utils.lib.eachDefaultSystem (system:
let
- pkgs = nixpkgs.legacyPackages.${system};
- jrsonnet = pkgs.rustPlatform.buildRustPackage rec {
- pname = "jrsonnet";
- version = "0.1.0";
- src = self;
- cargoSha256 = "sha256-cez8pJ/uwj+PHAPQwpSB4CKaxcP8Uvv8xguOrVXR2xE=";
+ pkgs = import nixpkgs
+ {
+ inherit system;
+ overlays = [ rust-overlay.overlay ];
+ };
+ rust = ((pkgs.rustChannelOf { date = "2021-11-11"; channel = "nightly"; }).default.override {
+ extensions = [ "rust-src" ];
+ });
+ naersk-lib = naersk.lib."${system}".override {
+ rustc = rust;
+ cargo = rust;
+ };
+ in
+ rec {
+ checks = {
+ pre-commit-check = pre-commit-hooks.lib.${system}.run {
+ src = ./.;
+ hooks = {
+ nixpkgs-fmt.enable = true;
+ };
+ };
+ };
+ defaultPackage = naersk-lib.buildPackage {
+ pname = "dotman";
+ root = ./.;
+ buildInputs = with pkgs; [
+ pkgs.sqlite
+ ];
};
- in {
- defaultPackage = jrsonnet;
- devShell = pkgs.mkShell {};
- });
+ devShell = pkgs.mkShell {
+ inherit (checks.pre-commit-check) shellHook;
+ nativeBuildInputs = with pkgs;[
+ pkgs.binutils
+ pkgs.pkgconfig
+ pkgs.clang
+ pkgs.x11
+ pkgs.alsaLib
+ pkgs.libudev
+ pkgs.sqlite
+ rust
+ cargo-edit
+ go-jsonnet
+ ];
+ };
+ }
+ );
}