Skip to content

Commit 85cd7e6

Browse files
committed
Replace old RCall API
1 parent a28e334 commit 85cd7e6

File tree

4 files changed

+69
-103
lines changed

4 files changed

+69
-103
lines changed

crates/ark/src/variables/variable.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use amalthea::comm::variables_comm::ClipboardFormatFormat;
99
use amalthea::comm::variables_comm::Variable;
1010
use amalthea::comm::variables_comm::VariableKind;
11-
use harp::call::RCall;
1211
use harp::environment::Binding;
1312
use harp::environment::BindingValue;
1413
use harp::environment::Environment;
@@ -497,8 +496,7 @@ impl PositronVariable {
497496
Ok(RSymbol::new_unchecked(code).to_string())
498497
},
499498
LANGSXP => {
500-
let code = RCall::new(code)?;
501-
let fun = RSymbol::new(CAR(*code))?;
499+
let fun = RSymbol::new(CAR(code))?;
502500
if fun == "lazyLoadDBfetch" {
503501
return Ok(String::from("(unevaluated)"))
504502
}

crates/harp/src/call.rs

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,86 @@
55
//
66
//
77

8-
use std::ops::Deref;
8+
use libr::*;
99

10-
use libr::LANGSXP;
11-
use libr::SEXP;
12-
13-
use crate::error::Result;
1410
use crate::object::RObject;
15-
use crate::utils::r_assert_type;
11+
use crate::protect::RProtect;
12+
use crate::r_symbol;
13+
use crate::utils::r_typeof;
1614

1715
pub struct RCall {
18-
pub object: RObject,
16+
function: RObject,
17+
arguments: Vec<RArgument>,
1918
}
2019

2120
impl RCall {
22-
pub fn new_unchecked(object: impl Into<RObject>) -> Self {
21+
pub fn new(function: impl Into<RObject>) -> Self {
2322
Self {
24-
object: object.into(),
23+
function: function.into(),
24+
arguments: Vec::new(),
2525
}
2626
}
2727

28-
pub fn new(object: impl Into<RObject>) -> Result<Self> {
29-
let object = object.into();
30-
r_assert_type(*object, &[LANGSXP])?;
31-
Ok(Self::new_unchecked(object))
28+
pub fn param(&mut self, name: &str, value: impl Into<RObject>) -> &mut Self {
29+
self.arguments.push(RArgument {
30+
name: name.to_string(),
31+
value: value.into(),
32+
});
33+
self
3234
}
33-
}
3435

35-
impl Deref for RCall {
36-
type Target = SEXP;
37-
fn deref(&self) -> &Self::Target {
38-
&self.object
36+
pub fn add(&mut self, value: impl Into<RObject>) -> &mut Self {
37+
self.param("", value)
38+
}
39+
40+
pub fn build(&self) -> RObject {
41+
unsafe {
42+
let mut protect = RProtect::new();
43+
44+
// Now, build the actual call to be evaluated
45+
let size = (1 + self.arguments.len()) as R_xlen_t;
46+
let call = protect.add(Rf_allocVector(LANGSXP, size));
47+
SET_TAG(call, R_NilValue);
48+
SETCAR(call, self.function.sexp);
49+
50+
// Append arguments to the call
51+
let mut slot = CDR(call);
52+
for argument in self.arguments.iter() {
53+
// Quote language objects by default
54+
// FIXME: Shouldn't this be done by the caller?
55+
let mut sexp = argument.value.sexp;
56+
if matches!(r_typeof(sexp), LANGSXP | SYMSXP | EXPRSXP) {
57+
let quote = protect.add(Rf_lang3(
58+
r_symbol!("::"),
59+
r_symbol!("base"),
60+
r_symbol!("quote"),
61+
));
62+
sexp = protect.add(Rf_lang2(quote, sexp));
63+
}
64+
65+
SETCAR(slot, sexp);
66+
if !argument.name.is_empty() {
67+
SET_TAG(slot, r_symbol!(argument.name));
68+
}
69+
70+
slot = CDR(slot);
71+
}
72+
73+
RObject::new(call)
74+
}
3975
}
4076
}
4177

42-
impl From<RCall> for RObject {
43-
fn from(value: RCall) -> Self {
44-
value.object
78+
pub struct RArgument {
79+
pub name: String,
80+
pub value: RObject,
81+
}
82+
83+
impl RArgument {
84+
pub fn new(name: &str, value: RObject) -> Self {
85+
Self {
86+
name: name.to_string(),
87+
value,
88+
}
4589
}
4690
}

crates/harp/src/exec.rs

Lines changed: 2 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::os::raw::c_void;
1212

1313
use libr::*;
1414

15+
use crate::call::RCall;
1516
use crate::environment::R_ENVS;
1617
use crate::error::Error;
1718
use crate::error::Result;
@@ -25,87 +26,9 @@ use crate::r_string;
2526
use crate::r_symbol;
2627
use crate::utils::r_inherits;
2728
use crate::utils::r_stringify;
28-
use crate::utils::r_typeof;
2929
use crate::vector::CharacterVector;
3030
use crate::vector::Vector;
3131

32-
pub struct RCall {
33-
function: RObject,
34-
arguments: Vec<RArgument>,
35-
}
36-
37-
impl RCall {
38-
pub fn new(function: impl Into<RObject>) -> Self {
39-
Self {
40-
function: function.into(),
41-
arguments: Vec::new(),
42-
}
43-
}
44-
45-
pub fn param(&mut self, name: &str, value: impl Into<RObject>) -> &mut Self {
46-
self.arguments.push(RArgument {
47-
name: name.to_string(),
48-
value: value.into(),
49-
});
50-
self
51-
}
52-
53-
pub fn add(&mut self, value: impl Into<RObject>) -> &mut Self {
54-
self.param("", value)
55-
}
56-
57-
pub fn build(&self) -> RObject {
58-
unsafe {
59-
let mut protect = RProtect::new();
60-
61-
// Now, build the actual call to be evaluated
62-
let size = (1 + self.arguments.len()) as R_xlen_t;
63-
let call = protect.add(Rf_allocVector(LANGSXP, size));
64-
SET_TAG(call, R_NilValue);
65-
SETCAR(call, self.function.sexp);
66-
67-
// Append arguments to the call
68-
let mut slot = CDR(call);
69-
for argument in self.arguments.iter() {
70-
// Quote language objects by default
71-
// FIXME: Shouldn't this be done by the caller?
72-
let mut sexp = argument.value.sexp;
73-
if matches!(r_typeof(sexp), LANGSXP | SYMSXP | EXPRSXP) {
74-
let quote = protect.add(Rf_lang3(
75-
r_symbol!("::"),
76-
r_symbol!("base"),
77-
r_symbol!("quote"),
78-
));
79-
sexp = protect.add(Rf_lang2(quote, sexp));
80-
}
81-
82-
SETCAR(slot, sexp);
83-
if !argument.name.is_empty() {
84-
SET_TAG(slot, r_symbol!(argument.name));
85-
}
86-
87-
slot = CDR(slot);
88-
}
89-
90-
RObject::new(call)
91-
}
92-
}
93-
}
94-
95-
pub struct RArgument {
96-
pub name: String,
97-
pub value: RObject,
98-
}
99-
100-
impl RArgument {
101-
pub fn new(name: &str, value: RObject) -> Self {
102-
Self {
103-
name: name.to_string(),
104-
value,
105-
}
106-
}
107-
}
108-
10932
pub struct RFunction {
11033
pub call: RCall,
11134
is_namespaced: bool,
@@ -735,6 +658,7 @@ mod tests {
735658
use crate::r_test;
736659
use crate::utils::r_envir_remove;
737660
use crate::utils::r_is_null;
661+
use crate::utils::r_typeof;
738662

739663
#[test]
740664
fn test_basic_function() {

crates/harp/src/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ use libr::*;
1414
use once_cell::sync::Lazy;
1515
use regex::Regex;
1616

17+
use crate::call::RArgument;
1718
use crate::environment::Environment;
1819
use crate::environment::R_ENVS;
1920
use crate::error::Error;
2021
use crate::error::Result;
2122
use crate::eval::r_parse_eval0;
2223
use crate::exec::geterrmessage;
23-
use crate::exec::RArgument;
2424
use crate::exec::RFunction;
2525
use crate::exec::RFunctionExt;
2626
use crate::object::RObject;

0 commit comments

Comments
 (0)