Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,14 @@ jobs:

- name: Run integration tests
run: cargo test -p pine-integration-tests -- --nocapture

examples:
name: Build Examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: extractions/setup-just@v2
- name: Compile all examples
run: just compile-examples
3 changes: 1 addition & 2 deletions benches/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ fn bench_compile_only(c: &mut Criterion) {
for (name, source) in TEST_SCRIPTS {
group.bench_with_input(BenchmarkId::from_parameter(name), source, |b, source| {
b.iter(|| {
let _ = Script::compile::<pine_builtins::DefaultLogger>(black_box(source), None)
.unwrap();
let _ = Script::compile(black_box(source)).unwrap();
});
});
}
Expand Down
2 changes: 1 addition & 1 deletion benches/src/test_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl HistoricalDataProvider for BenchHistoricalData {
/// This helper compiles a script, sets up the historical data provider,
/// and executes it with the last bar in the dataset.
pub fn execute_with_history(source: &str, bars: &[Bar]) -> Result<(), pine::Error> {
let mut script = Script::compile::<pine_builtins::DefaultLogger>(source, None)?;
let mut script = Script::compile(source)?;
let historical_data = BenchHistoricalData::new(bars.to_vec());
historical_data.set_current_bar(bars.len() - 1);
script.set_historical_provider(Box::new(historical_data));
Expand Down
38 changes: 19 additions & 19 deletions crates/pine-builtins/src/box/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use pine_builtin_macro::BuiltinFunction;
use pine_interpreter::{Color, Interpreter, PineBox, RuntimeError, Value};
use pine_interpreter::{BoxOutput, Color, Interpreter, PineBox, RuntimeError, Value};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
Expand Down Expand Up @@ -44,10 +44,10 @@ impl BoxNew {
fn execute(&self, ctx: &mut Interpreter) -> Result<Value, RuntimeError> {
// Create a box struct
let box_obj = PineBox {
left: self.left.clone(),
top: self.top.clone(),
right: self.right.clone(),
bottom: self.bottom.clone(),
left: self.left.as_number()?,
top: self.top.as_number()?,
right: self.right.as_number()?,
bottom: self.bottom.as_number()?,
border_color: self.border_color.clone(),
border_width: self.border_width,
border_style: self.border_style.clone(),
Expand Down Expand Up @@ -86,7 +86,7 @@ impl BoxSetLeft {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
box_obj.left = self.left.clone();
box_obj.left = self.left.as_number()?;
Ok(Value::Na)
}
}
Expand All @@ -106,7 +106,7 @@ impl BoxSetTop {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
box_obj.top = self.top.clone();
box_obj.top = self.top.as_number()?;
Ok(Value::Na)
}
}
Expand All @@ -126,7 +126,7 @@ impl BoxSetRight {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
box_obj.right = self.right.clone();
box_obj.right = self.right.as_number()?;
Ok(Value::Na)
}
}
Expand All @@ -146,7 +146,7 @@ impl BoxSetBottom {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
box_obj.bottom = self.bottom.clone();
box_obj.bottom = self.bottom.as_number()?;
Ok(Value::Na)
}
}
Expand All @@ -167,8 +167,8 @@ impl BoxSetLefttop {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
box_obj.left = self.left.clone();
box_obj.top = self.top.clone();
box_obj.left = self.left.as_number()?;
box_obj.top = self.top.as_number()?;
Ok(Value::Na)
}
}
Expand All @@ -189,8 +189,8 @@ impl BoxSetRightbottom {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
box_obj.right = self.right.clone();
box_obj.bottom = self.bottom.clone();
box_obj.right = self.right.as_number()?;
box_obj.bottom = self.bottom.as_number()?;
Ok(Value::Na)
}
}
Expand Down Expand Up @@ -452,8 +452,8 @@ impl BoxSetXloc {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
box_obj.left = self.left.clone();
box_obj.right = self.right.clone();
box_obj.left = self.left.as_number()?;
box_obj.right = self.right.as_number()?;
box_obj.xloc = self.xloc.clone();
Ok(Value::Na)
}
Expand All @@ -473,7 +473,7 @@ impl BoxGetLeft {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
Ok(box_obj.left.clone())
Ok(Value::Number(box_obj.left))
}
}

Expand All @@ -491,7 +491,7 @@ impl BoxGetTop {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
Ok(box_obj.top.clone())
Ok(Value::Number(box_obj.top))
}
}

Expand All @@ -509,7 +509,7 @@ impl BoxGetRight {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
Ok(box_obj.right.clone())
Ok(Value::Number(box_obj.right))
}
}

Expand All @@ -527,7 +527,7 @@ impl BoxGetBottom {
.output
.get_box_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Box with id {} not found", id)))?;
Ok(box_obj.bottom.clone())
Ok(Value::Number(box_obj.bottom))
}
}

Expand Down
20 changes: 10 additions & 10 deletions crates/pine-builtins/src/label/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use pine_builtin_macro::BuiltinFunction;
use pine_interpreter::{Color, Interpreter, Label, RuntimeError, Value};
use pine_interpreter::{Color, Interpreter, Label, LabelOutput, RuntimeError, Value};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
Expand Down Expand Up @@ -36,8 +36,8 @@ impl LabelNew {
fn execute(&self, ctx: &mut Interpreter) -> Result<Value, RuntimeError> {
// Create a label struct
let label = Label {
x: self.x.clone(),
y: self.y.clone(),
x: self.x.as_number()?,
y: self.y.as_number()?,
text: self.text.clone(),
xloc: self.xloc.clone(),
yloc: self.yloc.clone(),
Expand Down Expand Up @@ -73,7 +73,7 @@ impl LabelSetX {
.output
.get_label_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Label with id {} not found", id)))?;
label.x = self.x.clone();
label.x = self.x.as_number()?;
Ok(Value::Na)
}
}
Expand All @@ -93,7 +93,7 @@ impl LabelSetY {
.output
.get_label_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Label with id {} not found", id)))?;
label.y = self.y.clone();
label.y = self.y.as_number()?;
Ok(Value::Na)
}
}
Expand All @@ -114,8 +114,8 @@ impl LabelSetXy {
.output
.get_label_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Label with id {} not found", id)))?;
label.x = self.x.clone();
label.y = self.y.clone();
label.x = self.x.as_number()?;
label.y = self.y.as_number()?;
Ok(Value::Na)
}
}
Expand All @@ -136,7 +136,7 @@ impl LabelSetXloc {
.output
.get_label_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Label with id {} not found", id)))?;
label.x = self.x.clone();
label.x = self.x.as_number()?;
label.xloc = self.xloc.clone();
Ok(Value::Na)
}
Expand Down Expand Up @@ -336,7 +336,7 @@ impl LabelGetX {
.output
.get_label_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Label with id {} not found", id)))?;
Ok(label.x.clone())
Ok(Value::Number(label.x))
}
}

Expand All @@ -354,7 +354,7 @@ impl LabelGetY {
.output
.get_label_mut(id)
.ok_or_else(|| RuntimeError::TypeError(format!("Label with id {} not found", id)))?;
Ok(label.y.clone())
Ok(Value::Number(label.y))
}
}

Expand Down
23 changes: 13 additions & 10 deletions crates/pine-builtins/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ use std::rc::Rc;
// Re-export for convenience
pub use pine_interpreter::Bar;
pub use pine_interpreter::BuiltinFn;
pub use pine_interpreter::DefaultPineOutput;
pub use pine_interpreter::EvaluatedArg;

// Re-export log types for custom logger support
pub use log::{DefaultLogger, Log, LogLevel, Logger};
pub use pine_interpreter::LogLevel;

// Namespace modules
mod array;
Expand Down Expand Up @@ -151,7 +150,10 @@ impl Fixnan {
/// Returns namespace objects to be loaded as variables (e.g., "array", "str", "ta")
/// and global builtin functions (e.g., "na")
/// Each member stores the builtin function pointer as Value::BuiltinFunction
pub fn register_namespace_objects() -> HashMap<String, Value> {
///
/// This uses DefaultPineOutput for now. Full generic support will be added when the
/// BuiltinFunction macro is updated to support generic output types.
pub fn register_namespace_objects() -> HashMap<String, Value<DefaultPineOutput>> {
let mut namespaces = HashMap::new();

// Register namespace objects
Expand All @@ -160,6 +162,7 @@ pub fn register_namespace_objects() -> HashMap<String, Value> {
namespaces.insert("color".to_string(), color::register());
namespaces.insert("currency".to_string(), currency::register());
namespaces.insert("label".to_string(), label::register());
namespaces.insert("log".to_string(), log::register::<DefaultPineOutput>());
namespaces.insert("math".to_string(), math::register());
namespaces.insert("matrix".to_string(), matrix::register());
namespaces.insert("str".to_string(), str::register());
Expand All @@ -168,27 +171,27 @@ pub fn register_namespace_objects() -> HashMap<String, Value> {
// Register global builtin functions
namespaces.insert(
"na".to_string(),
Value::BuiltinFunction(Rc::new(Na::builtin_fn) as BuiltinFn),
Value::BuiltinFunction(Rc::new(Na::builtin_fn) as BuiltinFn<DefaultPineOutput>),
);
namespaces.insert(
"bool".to_string(),
Value::BuiltinFunction(Rc::new(Bool::builtin_fn) as BuiltinFn),
Value::BuiltinFunction(Rc::new(Bool::builtin_fn) as BuiltinFn<DefaultPineOutput>),
);
namespaces.insert(
"int".to_string(),
Value::BuiltinFunction(Rc::new(Int::builtin_fn) as BuiltinFn),
Value::BuiltinFunction(Rc::new(Int::builtin_fn) as BuiltinFn<DefaultPineOutput>),
);
namespaces.insert(
"float".to_string(),
Value::BuiltinFunction(Rc::new(Float::builtin_fn) as BuiltinFn),
Value::BuiltinFunction(Rc::new(Float::builtin_fn) as BuiltinFn<DefaultPineOutput>),
);
namespaces.insert(
"nz".to_string(),
Value::BuiltinFunction(Rc::new(Nz::builtin_fn) as BuiltinFn),
Value::BuiltinFunction(Rc::new(Nz::builtin_fn) as BuiltinFn<DefaultPineOutput>),
);
namespaces.insert(
"fixnan".to_string(),
Value::BuiltinFunction(Rc::new(Fixnan::builtin_fn) as BuiltinFn),
Value::BuiltinFunction(Rc::new(Fixnan::builtin_fn) as BuiltinFn<DefaultPineOutput>),
);

// Register time/date functions
Expand Down
Loading
Loading