From 1082f62696255f6ba59fcc87f37bea20f568d4b4 Mon Sep 17 00:00:00 2001 From: i do not exist Date: Sun, 30 Aug 2026 22:30:30 +0300 Subject: [PATCH] fix config and compilation; add arg! macro --- src/config.rs | 130 +++++++++++++++++++++----------------------------- src/tek.edn | 25 ++++++---- 2 files changed, 70 insertions(+), 85 deletions(-) diff --git a/src/config.rs b/src/config.rs index 8875649d..e3652fac 100644 --- a/src/config.rs +++ b/src/config.rs @@ -23,7 +23,7 @@ pub fn config_init > (config: C) -> Usually { pub fn config_load , L: Language> (config: C, src: L) -> Usually { config.as_ref().clear(); config.as_ref().stamp.store(quanta::Clock::new().raw(), Relaxed); - src.each(config, |c, s|config_load_item(c, s)) + src.each(config, |c, s|config_load_item(c, s.trim())) } pub fn config_load_item , L: Language> (config: C, src: L) -> Usually { @@ -263,9 +263,9 @@ impl View { UsuallyDrawn + Send + Sync>>> { let source = source.as_ref(); - let layer = if let Some(expr) = source.expr()? { + let layer = if let Ok(Some(expr)) = source.expr() { Self::compile_expr(expr.into())? - } else if let Some(word) = source.word()? { + } else if let Ok(Some(word)) = source.word() { Self::compile_word(word.into())? } else { return Err(format!("not word/expr:\n{source:?}").into()) @@ -276,15 +276,24 @@ impl View { fn compile_expr (expr: Arc) -> UsuallyDrawn + Send + Sync>>> { + + macro_rules! arg { + ($src:expr, $head:expr, $index:expr, $name:expr) => { + $src.nth($index)? + .ok_or_else(||Box::::from(format!( + "{}: no arg #{} ({}) in {}", $head, $index, $name, $src + )))? + }; + } + Ok(Arc::new(if let Some(head) = expr.head()? && let Some(ns) = head.split('/').next() { match ns { "when" => { - let cond = Arc::from(expr.nth(1)?.ok_or_else(||Box::::from("when: no arg0: condition"))?); + let cond = Arc::from(arg!(expr, head, 1, "condition")); let cond = move|state: &App|state.namespace(&cond)?.ok_or_else(||Box::::from("when: no condition value")); - let thunk = expr.nth(2)?.ok_or_else(||Box::::from("when: no arg1: content"))?; - let thunk = Self::compile(thunk)?; + let thunk = Self::compile(arg!(expr, head, 2, "content"))?; Self::boxed(move|state, screen|{ when( cond(state)?, @@ -294,12 +303,10 @@ impl View { }, "either" => { - let cond = Arc::from(expr.nth(1)?.ok_or_else(||Box::::from("either: no arg0: condition"))?); + let cond = Arc::from(arg!(expr, head, 1, "condition")); let cond = move|state: &App|state.namespace(&cond)?.ok_or_else(||Box::::from("either: no condition value")); - let a = expr.nth(2)?.ok_or_else(||Box::::from("either: no arg1: content"))?; - let a = Self::compile(a)?; - let b = expr.nth(3)?.ok_or_else(||Box::::from("either: no arg2: content"))?; - let b = Self::compile(b)?; + let a = Self::compile(arg!(expr, head, 2, "content A"))?; + let b = Self::compile(arg!(expr, head, 3, "content B"))?; Self::boxed(move|state, screen|{ either( cond(state)?, @@ -309,7 +316,7 @@ impl View { }) }, - "bsp" | "split" => { + "bsp" | "split" | "stack" => { let split = head.split('/').skip(1).next(); let split = match split { Some("n") => Split::North, @@ -320,8 +327,8 @@ impl View { Some("b") => Split::Below, _ => return Err(format!("invalid split: {split:?}").into()) }; - let a = Self::compile(expr.nth(1)?.ok_or_else(||Box::::from("either: no arg0: content"))?)?; - let b = Self::compile(expr.nth(2)?.ok_or_else(||Box::::from("either: no arg1: content"))?)?; + let a = Self::compile(arg!(expr, head, 1, "content A"))?; + let b = Self::compile(arg!(expr, head, 2, "content B"))?; Self::boxed(move|state, screen|{ split.stack( draw(|screen|a(state, screen)), @@ -346,8 +353,7 @@ impl View { Some("y") => Azimuth::Y, _ => return Err(format!("invalid azimuth: {azimuth:?}").into()) }; - let thunk = Self::compile(expr.nth(2)? - .ok_or_else(||Box::::from("either: no arg1: content"))?)?; + let thunk = Self::compile(arg!(expr, head, 1, "content"))?; Self::boxed(move|state, screen|{ Align( Some(azimuth), @@ -356,9 +362,8 @@ impl View { }) }, - "full" => { - let thunk = Self::compile(expr.nth(2)? - .ok_or_else(||Box::::from("either: no arg1: content"))?)?; + "full" | "fill" => { + let thunk = Self::compile(arg!(expr, head, 1, "content"))?; match head.split('/').skip(1).next() { Some("w") | Some("x") => Self::boxed(move|state, screen|{ Full::W(draw(|screen|thunk(state, screen))).draw(screen) @@ -366,83 +371,56 @@ impl View { Some("h") | Some("y") => Self::boxed(move|state, screen|{ Full::H(draw(|screen|thunk(state, screen))).draw(screen) }), - Some("wh") | Some("xy") => Self::boxed(move|state, screen|{ + Some("wh") | Some("xy") | None => Self::boxed(move|state, screen|{ Full::WH(draw(|screen|thunk(state, screen))).draw(screen) }), _ => unreachable!() } }, - "exact" | "min" | "max" | "push" | "pull" => { + "exact" | "min" | "max" | "push" | "pull" | "pad" => { match head.split('/').skip(1).next() { Some("w") | Some("x") => { - let value = Arc::from(expr.nth(1)?.ok_or_else(||Box::::from("{}: no arg1: value"))?); + let value = Arc::from(arg!(expr, head, 1, "value")); let value = move|state: &App|state.namespace(&value); - let thunk = Self::compile(expr.nth(2)?.ok_or_else(||Box::::from("either: no arg2: content"))?)?; + let thunk = Self::compile(arg!(expr, head, 2, "content"))?; match ns { - "exact" => Self::boxed(move|state, screen|Exact::W( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), - "push" => Self::boxed(move|state, screen|Push::X( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), - "pull" => Self::boxed(move|state, screen|Pull::X( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), - "min" => Self::boxed(move|state, screen|Min::W( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), - "max" => Self::boxed(move|state, screen|Max::W( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), + "exact" => Self::boxed(move|state, screen|Exact::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "push" => Self::boxed(move|state, screen|Push::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "pull" => Self::boxed(move|state, screen|Pull::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "pad" => Self::boxed(move|state, screen|Pad::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "min" => Self::boxed(move|state, screen|Min::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "max" => Self::boxed(move|state, screen|Max::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), _ => unreachable!() } }, Some("h") | Some("y") => { - let value = Arc::from(expr.nth(1)?.ok_or_else(||Box::::from("{}: no arg1: value"))?); + let value = Arc::from(arg!(expr, head, 1, "value")); let value = move|state: &App|state.namespace(&value); - let thunk = Self::compile(expr.nth(2)?.ok_or_else(||Box::::from("either: no arg2: content"))?)?; + let thunk = Self::compile(arg!(expr, head, 2, "content"))?; match ns { - "exact" => Self::boxed(move|state, screen|Exact::H( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), - "push" => Self::boxed(move|state, screen|Push::Y( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), - "pull" => Self::boxed(move|state, screen|Pull::Y( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), - "min" => Self::boxed(move|state, screen|Min::H( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), - "max" => Self::boxed(move|state, screen|Max::H( - draw(|screen|thunk(state, screen)), value(state)? - ).draw(screen)), + "exact" => Self::boxed(move|state, screen|Exact::H(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "push" => Self::boxed(move|state, screen|Push::Y(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "pull" => Self::boxed(move|state, screen|Pull::Y(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "pad" => Self::boxed(move|state, screen|Pad::Y(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "min" => Self::boxed(move|state, screen|Min::H(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), + "max" => Self::boxed(move|state, screen|Max::H(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)), _ => unreachable!() } }, - Some("wh") | Some("xy") => { - let value1 = Arc::from(expr.nth(1)?.ok_or_else(||Box::::from("{}: no arg1: value"))?); + Some("wh") | Some("xy") | None => { + let value1 = Arc::from(arg!(expr, head, 1, "value")); let value1 = move|state: &App|state.namespace(&value1); - let value2 = Arc::from(expr.nth(2)?.ok_or_else(||Box::::from("{}: no arg2: value"))?); + let value2 = Arc::from(arg!(expr, head, 2, "value")); let value2 = move|state: &App|state.namespace(&value2); - let thunk = Self::compile(expr.nth(3)?.ok_or_else(||Box::::from("either: no arg3: content"))?)?; + let thunk = Self::compile(arg!(expr, head, 3, "content"))?; match ns { - "exact" => Self::boxed(move|state, screen|Exact::WH( - draw(|screen|thunk(state, screen)), value1(state)?, value2(state)? - ).draw(screen)), - "push" => Self::boxed(move|state, screen|Push::XY( - draw(|screen|thunk(state, screen)), value1(state)?, value2(state)? - ).draw(screen)), - "pull" => Self::boxed(move|state, screen|Pull::XY( - draw(|screen|thunk(state, screen)), value1(state)?, value2(state)? - ).draw(screen)), - "min" => Self::boxed(move|state, screen|Min::WH( - draw(|screen|thunk(state, screen)), value1(state)?, value2(state)? - ).draw(screen)), - "max" => Self::boxed(move|state, screen|Max::WH( - draw(|screen|thunk(state, screen)), value1(state)?, value2(state)? - ).draw(screen)), + "exact" => Self::boxed(move|state, screen|Exact::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)), + "push" => Self::boxed(move|state, screen|Push::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)), + "pull" => Self::boxed(move|state, screen|Pull::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)), + "pad" => Self::boxed(move|state, screen|Pad::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)), + "min" => Self::boxed(move|state, screen|Min::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)), + "max" => Self::boxed(move|state, screen|Max::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)), _ => unreachable!() } }, @@ -451,9 +429,9 @@ impl View { }, "fg" | "bg" => { - let color = Arc::from(expr.nth(1)?.ok_or_else(||Box::::from("{}: no arg1: color"))?); + let color = Arc::from(arg!(expr, head, 1, "color")); let color = move|state: &App|state.namespace(&color); - let thunk = Self::compile(expr.nth(2)?.ok_or_else(||Box::::from("either: no arg2: thunk"))?)?; + let thunk = Self::compile(arg!(expr, head, 2, "content"))?; match ns { "fg" => Self::boxed(move|state, screen|fg( color(state)?.unwrap_or_default(), draw(|screen|thunk(state, screen)) diff --git a/src/tek.edn b/src/tek.edn index b102b865..bf204e91 100644 --- a/src/tek.edn +++ b/src/tek.edn @@ -1,8 +1,8 @@ (view :logo (text tek)) (view :browse (bsp/s - (pad 3 1 :browse-title) - (fg (g 96) browser)) + (pad/xy 3 1 :browse-title) + (fg (g 96) browser))) (mode :transport (name Transport) @@ -82,22 +82,29 @@ (mode browse (keys :browse)) (mode rename (keys :pool/rename)) (mode length (keys :pool/length)) - (bsp/s (exact/h 1 :transport) - (bsp/n (exact/h 1 :status) - (fill (bsp/a (fill/xy (align/e :pool)) :editor))))) + (view + (bsp/s (exact/h 1 :transport) + (bsp/n (exact/h 1 :status) + (fill/xy (bsp/a (fill/xy (align/e :pool)) + :editor)))))) (mode :sampler (name Sampler) (info Sample player.) (keys :sampler/directions :sampler/record :sampler/play) - (bsp/s (exact/h 1 :transport) - (bsp/n (exact/h 1 :status) - (fill :samples/grid)))) + (view + (bsp/s (exact/h 1 :transport) + (bsp/n (exact/h 1 :status) + (fill/xy :samples/grid))))) (mode :groovebox (name Groovebox) (info Sequencer with sampler.) (keys :clock :editor :sampler :global) (mode browse (keys :browse)) (mode rename (keys :pool-rename)) (mode length (keys :pool-length)) - (bsp/w :meters/output (bsp/e :meters/input (bsp/w :groove/meta :groove/editor)))) + (view + (bsp/w :meters/output + (bsp/e :meters/input + (bsp/w :groove/meta + :groove/editor))))) (view :groove/meta (fill/y (align/n (stack/s :midi-ins/status :midi-outs/status :audio-ins/status :audio-outs/status :pool))))