feat(engine): establish calcpad-engine workspace with Epic 1 modules
Cherry-picked and integrated the best code from 105 parallel epic branches into a clean workspace structure: - calcpad-engine/: Core Rust crate with lexer, parser, AST, interpreter, types, FFI (C ABI), pipeline, error handling, span tracking, eval context (from epic/1-5 base) - calcpad-engine/src/number.rs: Arbitrary precision arithmetic via dashu crate, WASM-compatible, exact decimals (from epic/1-4) - calcpad-engine/src/sheet_context.rs: SheetContext with dependency graph, dirty tracking, circular detection, cheap clone (from epic/1-8) - calcpad-wasm/: Thin WASM wrapper crate via wasm-bindgen, delegates to calcpad-engine (from epic/1-6) - Updated .gitignore for target/, node_modules/, build artifacts - Fixed run-pipeline.sh for macOS compat and CalcPad phases 79 tests passing across workspace.
This commit is contained in:
40
calcpad-engine/src/pipeline.rs
Normal file
40
calcpad-engine/src/pipeline.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
use crate::context::EvalContext;
|
||||
use crate::interpreter::evaluate;
|
||||
use crate::lexer::tokenize;
|
||||
use crate::parser::parse;
|
||||
use crate::span::Span;
|
||||
use crate::types::CalcResult;
|
||||
|
||||
/// Evaluate a single line of input and return the result.
|
||||
pub fn eval_line(input: &str, ctx: &mut EvalContext) -> CalcResult {
|
||||
let trimmed = input.trim();
|
||||
if trimmed.is_empty() {
|
||||
return CalcResult::error("empty input", Span::new(0, 0));
|
||||
}
|
||||
|
||||
let tokens = tokenize(trimmed);
|
||||
|
||||
// Check for text-only or comment-only lines
|
||||
let has_expr = tokens.iter().any(|t| {
|
||||
!matches!(
|
||||
t.kind,
|
||||
crate::token::TokenKind::Text(_)
|
||||
| crate::token::TokenKind::Comment(_)
|
||||
| crate::token::TokenKind::Eof
|
||||
)
|
||||
});
|
||||
if !has_expr {
|
||||
return CalcResult::error("no expression found", Span::new(0, trimmed.len()));
|
||||
}
|
||||
|
||||
match parse(tokens) {
|
||||
Ok(expr) => evaluate(&expr, ctx),
|
||||
Err(e) => CalcResult::error(&e.message, e.span),
|
||||
}
|
||||
}
|
||||
|
||||
/// Evaluate multiple lines of input, sharing context across lines.
|
||||
/// Variable assignments on earlier lines are visible to later lines.
|
||||
pub fn eval_sheet(lines: &[&str], ctx: &mut EvalContext) -> Vec<CalcResult> {
|
||||
lines.iter().map(|line| eval_line(line, ctx)).collect()
|
||||
}
|
||||
Reference in New Issue
Block a user