Skip to content

Commit

Permalink
fix a bug in pre-evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
kaikalii committed Nov 27, 2024
1 parent d610a3b commit fd116b6
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ impl Compiler {
let input: EcoString = fs::read_to_string(path)
.map_err(|e| UiuaErrorKind::Load(path.into(), e.into()))?
.into();
// _ = crate::lsp::Spans::from_input(&input);
_ = crate::lsp::Spans::from_input(&input);
self.asm.inputs.files.insert(path.into(), input.clone());
self.load_impl(&input, InputSrc::File(path.into()))
}
Expand Down Expand Up @@ -661,12 +661,12 @@ code:
}
// Try to evaluate at comptime
// This can be done when:
// - the pre-eval mode is not `Line`
// - the pre-eval mode is greater that `Line`
// - there are at least as many push nodes preceding the current line as there are arguments to the line
// - the words create no bindings
if precomp
&& error_count_after == error_count_before
&& self.pre_eval_mode != PreEvalMode::Line
&& self.pre_eval_mode > PreEvalMode::Line
&& !line_node.is_empty()
&& binding_count_before == binding_count_after
&& root_len_before == self.asm.root.len()
Expand Down
23 changes: 14 additions & 9 deletions src/compile/modifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1177,7 +1177,7 @@ impl Compiler {
})
.collect();

let mut code = String::new();
let mut code: Option<String> = None;
(|| -> UiuaResult {
if let Some(index) = self.node_unbound_index(&mac.root.node) {
let name = self.scope.names.iter().find_map(|(name, local)| {
Expand Down Expand Up @@ -1225,8 +1225,9 @@ impl Compiler {
Ok(strings) => strings,
Err(_) => val.representation().lines().map(Into::into).collect(),
};
let code = code.get_or_insert_with(String::new);
for s in strings {
if s.chars().last().is_some_and(|c| !c.is_whitespace()) {
if code.chars().last().is_some_and(|c| !c.is_whitespace()) {
code.push(' ');
}
code.push_str(&s);
Expand All @@ -1247,14 +1248,18 @@ impl Compiler {
.map_err(|e| e.trace_macro(mac_name.clone(), modifier_span.clone()))?;

// Quote
self.code_meta
.macro_expansions
.insert(full_span, (mac_name.clone(), code.clone()));
self.suppress_diagnostics(|comp| {
comp.temp_scope(mac.names, None, |comp| {
comp.quote(&code, mac_name, &modifier_span)
if let Some(code) = code {
self.code_meta
.macro_expansions
.insert(full_span, (mac_name.clone(), code.clone()));
self.suppress_diagnostics(|comp| {
comp.temp_scope(mac.names, None, |comp| {
comp.quote(&code, mac_name, &modifier_span)
})
})
})
} else {
Ok(Node::empty())
}
}
fn node_unbound_index(&self, node: &Node) -> Option<usize> {
match node {
Expand Down
8 changes: 4 additions & 4 deletions src/compile/pre_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ use super::*;
pub enum PreEvalMode {
/// Does not evalute pure constants and expressions at comptime, but still evaluates `comptime`
Lazy,
/// Evaluate as much as possible at compile time, even impure expressions
///
/// Recursive functions and certain system functions are not evaluated
Lsp,
/// Pre-evaluate each line, but not multiple lines together
Line,
/// The normal mode. Tries to evaluate pure, time-bounded constants and expressions at comptime
#[default]
Normal,
/// Evaluate as much as possible at compile time, even impure expressions
///
/// Recursive functions and certain system functions are not evaluated
Lsp,
}

const MAX_PRE_EVAL_ELEMS: usize = 1000;
Expand Down
6 changes: 6 additions & 0 deletions tests/macros.ua
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ M! ←^ ⋅"∘"
@a @b
⍤⤙≍ "b" [⋅M!∘]

Join! ←^ ↯:@⊂↥0-1⋕
{Join!0 "a" "bc" "def"}
{Join!1 "a" "bc" "def"}
{Join!2 "a" "bc" "def"}
◌◌◌

# Experimental!

# Inline macros
Expand Down

0 comments on commit fd116b6

Please sign in to comment.