Skip to content
Closed
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
45 changes: 45 additions & 0 deletions compare.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail

if [ $# -lt 3 ]; then
echo "Usage: $0 <branch1> <branch2> <script.ndc>" >&2
exit 1
fi

BRANCH1="$1"
BRANCH2="$2"
SCRIPT="$(realpath "$3")"
REPO_ROOT="$(git -C "$(dirname "$0")" rev-parse --show-toplevel)"
WORKDIR="$(mktemp -d)"

cleanup() {
git -C "$REPO_ROOT" worktree remove --force "$WORKDIR/b1" 2>/dev/null || true
git -C "$REPO_ROOT" worktree remove --force "$WORKDIR/b2" 2>/dev/null || true
rm -rf "$WORKDIR"
}
trap cleanup EXIT

build_branch() {
local branch="$1"
local worktree="$2"
local out="$3"

echo "==> Building $branch..."
git -C "$REPO_ROOT" worktree add --quiet --detach "$worktree" "$branch"
cargo build --release --quiet --manifest-path "$worktree/Cargo.toml" -p ndc_bin 2>&1
cp "$worktree/target/release/ndc" "$out"
echo " Built $branch -> $out"
}

BIN1="$WORKDIR/ndc-$(echo "$BRANCH1" | tr '/' '-')"
BIN2="$WORKDIR/ndc-$(echo "$BRANCH2" | tr '/' '-')"

build_branch "$BRANCH1" "$WORKDIR/b1" "$BIN1"
build_branch "$BRANCH2" "$WORKDIR/b2" "$BIN2"

echo ""
hyperfine \
--warmup 3 \
--shell none \
-n "$BRANCH1" "$BIN1 $SCRIPT" \
-n "$BRANCH2" "$BIN2 $SCRIPT"
2 changes: 1 addition & 1 deletion ndc_lib/src/interpreter/environment.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::interpreter::function::{Function, StaticType};

use ndc_parser::ResolvedVar;
use crate::interpreter::value::Value;
use ndc_parser::ResolvedVar;
use std::cell::RefCell;
use std::fmt;
use std::fmt::Formatter;
Expand Down
77 changes: 77 additions & 0 deletions ndc_lib/src/interpreter/evaluate/flat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use crate::interpreter::InterpreterError;
use crate::interpreter::environment::Environment;
use crate::interpreter::evaluate::{EvaluationError, LiftEvaluationResult, PoolWalker};
use crate::interpreter::function::FunctionCarrier;
use crate::interpreter::int::Int;
use crate::interpreter::num::Number;
use crate::interpreter::value::Value;
use ndc_parser::{Expression, ExpressionPool};
use std::cell::RefCell;
use std::rc::Rc;

fn evaluate_flat(
pool: ExpressionPool,
environment: &Rc<RefCell<Environment>>,
) -> Result<Value, FunctionCarrier> {
let pool = Rc::new(pool);

let mut value = Value::unit();
let mut state: Vec<Value> = Vec::with_capacity(pool.len());
for (idx, expr) in pool.iter().enumerate() {
match &expr.expression {
Expression::BoolLiteral(v) => state[idx] = Value::Bool(*v),
Expression::StringLiteral(s) => state[idx] = Value::string(s),
Expression::Int64Literal(i) => state[idx] = Value::from(*i),
Expression::Float64Literal(f) => state[idx] = Value::from(*f),
Expression::BigIntLiteral(i) => {
state[idx] = Value::Number(Number::Int(Int::BigInt(i.clone())))
} // TODO: mem take?
Expression::ComplexLiteral(c) => state[idx] = Value::Number(Number::Complex(c.clone())),
Expression::Identifier { .. } => {}
Expression::Statement(_) => {}
Expression::Logical { .. } => {}
Expression::Grouping(_) => {}
Expression::VariableDeclaration { .. } => {}
Expression::Assignment { .. } => {}
Expression::OpAssignment { .. } => {}
Expression::FunctionDeclaration { .. } => {}
Expression::Block { .. } => {}
Expression::If { .. } => {}
Expression::While { .. } => {}
Expression::For { .. } => {}
Expression::Call {
function,
arguments,
} => {
let mut arguments: Vec<_> = arguments
.into_iter()
.map(|arg| state.remove(arg.as_usize()))
.collect();

let function = &state[function.as_usize()];

if let Value::Function(function) = function {
state[idx] = function
.call(&mut arguments, environment)
.add_span(expr.span)?
} else {
return Err(FunctionCarrier::EvaluationError(EvaluationError::new(
format!("Unable to invoke {} as a function.", function.static_type()),
expr.span,
)));
}
}
Expression::Index { .. } => {}
Expression::Tuple { .. } => {}
Expression::List { .. } => {}
Expression::Map { .. } => {}
Expression::Return { .. } => {}
Expression::Break => {}
Expression::Continue => {}
Expression::RangeInclusive { .. } => {}
Expression::RangeExclusive { .. } => {}
}
}

Ok(Value::unit())
}
37 changes: 21 additions & 16 deletions ndc_lib/src/interpreter/evaluate/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@
//! | Backward index | -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
//! +----------------+-----+----+----+----+----+----+----+----+----+----+

use ndc_parser::{Expression, ExpressionLocation};
use super::{EvaluationError, EvaluationResult, IntoEvaluationResult, evaluate_expression};
use super::{EvaluationError, EvaluationResult, IntoEvaluationResult, PoolWalker, evaluate_expression};
use crate::interpreter::environment::Environment;
use crate::{
interpreter::{function::FunctionCarrier, sequence::Sequence, value::Value},
};
use crate::interpreter::{function::FunctionCarrier, sequence::Sequence, value::Value};
use itertools::Itertools;
use ndc_lexer::Span;
use ndc_parser::Expression;
use std::cell::RefCell;
use std::cmp::min;
use std::ops::IndexMut;
Expand Down Expand Up @@ -63,40 +61,43 @@ impl EvaluatedIndex {
}

pub(crate) fn evaluate_as_index(
expression_location: &ExpressionLocation,
walker: PoolWalker,
environment: &Rc<RefCell<Environment>>,
) -> Result<EvaluatedIndex, FunctionCarrier> {
let (range_start, range_end, inclusive) = match expression_location.expression {
let expression_location = walker.current();
let span = expression_location.span;

let (range_start, range_end, inclusive) = match &expression_location.expression {
Expression::RangeExclusive {
start: ref range_start,
end: ref range_end,
start: range_start,
end: range_end,
} => (range_start, range_end, false),
Expression::RangeInclusive {
start: ref range_start,
end: ref range_end,
start: range_start,
end: range_end,
} => (range_start, range_end, true),
_ => {
let result = evaluate_expression(expression_location, environment)?;
let result = evaluate_expression(walker, environment)?;
return Ok(EvaluatedIndex::Index(result));
}
};

if inclusive && range_end.is_none() {
return Err(EvaluationError::new(
"inclusive ranges must have an end".to_string(),
expression_location.span,
span,
)
.into());
}

let start = if let Some(range_start) = range_start {
Some(evaluate_expression(range_start, environment)?)
Some(evaluate_expression(walker.resolve(*range_start), environment)?)
} else {
None
};

let end = if let Some(range_end) = range_end {
Some(evaluate_expression(range_end, environment)?)
Some(evaluate_expression(walker.resolve(*range_end), environment)?)
} else {
None
};
Expand Down Expand Up @@ -300,7 +301,11 @@ pub fn set_at_index(
Offset::Range(from_usize, to_usize) => {
let tail = list.drain(from_usize..).collect::<Vec<_>>();

list.extend(rhs.try_into_vec().expect("this must succeed, but not sure why").into_iter());
list.extend(
rhs.try_into_vec()
.expect("this must succeed, but not sure why")
.into_iter(),
);

list.extend_from_slice(&tail[(to_usize - from_usize)..]);
}
Expand Down
Loading