From 9e337a2309c9dcadd91fb3878c2194c477b92bf7 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sun, 10 Dec 2023 02:50:39 +0100 Subject: Add another Andy post --- src/blog/andy-val/angle-bracket.an.gsp | 11 +++ src/blog/andy-val/cartesian.an.gsp | 4 + src/blog/andy-val/dynamic-func.an.gsp | 4 + src/blog/andy-val/index.gsp | 160 ++++++++++++++++++++++++++++++++ "src/blog/andy-val/na\303\257ve.an.gsp" | 6 ++ src/blog/andy-val/posix-fail.sh.gsp | 3 + src/blog/andy-val/smart.an.gsp | 7 ++ src/blog/andy-val/trap.sh.gsp | 1 + src/blog/index.gsp | 1 + src/style.css | 5 +- 10 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 src/blog/andy-val/angle-bracket.an.gsp create mode 100644 src/blog/andy-val/cartesian.an.gsp create mode 100644 src/blog/andy-val/dynamic-func.an.gsp create mode 100644 src/blog/andy-val/index.gsp create mode 100644 "src/blog/andy-val/na\303\257ve.an.gsp" create mode 100644 src/blog/andy-val/posix-fail.sh.gsp create mode 100644 src/blog/andy-val/smart.an.gsp create mode 100644 src/blog/andy-val/trap.sh.gsp diff --git a/src/blog/andy-val/angle-bracket.an.gsp b/src/blog/andy-val/angle-bracket.an.gsp new file mode 100644 index 0000000..1599dce --- /dev/null +++ b/src/blog/andy-val/angle-bracket.an.gsp @@ -0,0 +1,11 @@ +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .cmt {-# `(D…){P…\} is syntax for splitting a process P’s} +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .cmt {-# output on the delimiters D.} +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .fn {-printf} %s\\n @span .str {-'> '}@span .op {-`}(\\n)@span .op {-{}@span .fn {-grep} MHz /proc/cpuinfo@span .op {-\}} +>cpu MHz : 1127.333 +>cpu MHz : 1199.957 +>cpu MHz : 1139.098 +>cpu MHz : 1200.000 +>cpu MHz : 1172.249 +>cpu MHz : 1199.957 +>cpu MHz : 1151.501 +>cpu MHz : 1199.996 diff --git a/src/blog/andy-val/cartesian.an.gsp b/src/blog/andy-val/cartesian.an.gsp new file mode 100644 index 0000000..fb09f2c --- /dev/null +++ b/src/blog/andy-val/cartesian.an.gsp @@ -0,0 +1,4 @@ +@span .cmt {-# foo.c foo.h bar.c bar.h baz.c baz.h} +@span .fn {-echo} (foo bar baz)(.c .h) +@span .cmt {-# Or alternatively:} +@span .fn {-echo} (foo bar baz).(c h) diff --git a/src/blog/andy-val/dynamic-func.an.gsp b/src/blog/andy-val/dynamic-func.an.gsp new file mode 100644 index 0000000..abacc80 --- /dev/null +++ b/src/blog/andy-val/dynamic-func.an.gsp @@ -0,0 +1,4 @@ +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .fn {-set} foo bar +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .kw {-func} @span .var {-$foo} {\} +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .fn {-type} bar +function diff --git a/src/blog/andy-val/index.gsp b/src/blog/andy-val/index.gsp new file mode 100644 index 0000000..63f0699 --- /dev/null +++ b/src/blog/andy-val/index.gsp @@ -0,0 +1,160 @@ +html lang="en" { + head { m4_include(head.gsp) } + body { + header { + div { + h1 {-So Much Value} + m4_include(nav.gsp) + } + + figure .quote { + blockquote { + p {= + Complexity is a backdoor and can be misinterpreted as + sophistication. + } + } + figcaption {-asvln.com} + } + } + + main { + h2 #value {-Values} + p {- + As covered in @a href="/blog/new-sh" {-my last post}, I’m working on + Andy, my personal shell. One of the pretty interesting features of Andy + I think is the way that @em{-values} are handled. In the conventional + shell, you can think of a value as a string. In @code{-echo foo}, both + ‘echo’ and ‘foo’ can be thought of as values. Values aren’t just + string-literals though, a Bash process-redirection (@code{-<(cmd)}) is + also a value; typically one that looks like ‘/dev/fd/N’. + } + + p {- + In Andy this mostly holds, with one very important difference: values + are not strings — they’re lists of strings. While the string-literal + @code{-"foo"} might be a string list of length 1, the + process-redirection of @code{-<>{cmd\}} is a list of 2 strings — a path + to a file you can read from, and a path to a file you can write to. + } + + p {- + This is an important distinction to make because of the fact that + value-concatenation goes from a simple string-concatenation to a + cartesian product of the left- and right values: + } + + figure { + pre {= m4_fmt_code(cartesian.an.gsp) } + } + + p {- + This is not just constrainted to literals of course, process + substitutions are also values, so appending each line of a processes + output with a closing-angle-bracket becomes trivial: + } + + figure { + pre {= m4_fmt_code(angle-bracket.an.gsp) } + } + + p {- + Of course you can also append the closing-angle-bracket using + @code{-printf} itself, but it’s just an example after all. + } + + h2 #dynamic {-Dynamic Code} + p {- + What makes Andy different is not just the behavior of values, but where + you can use them. In most shells, various syntactic elements are not + expanded in the same way that regular values are. The following example + results in an error because the function name @code{-$foo} doesn’t get + expanded into @code{-bar}: + } + + figure { + pre {= m4_fmt_code(posix-fail.sh.gsp) } + } + + p {- + Andy doesn’t give a fuck though, it lets you do this if you really want + to: + } + + figure { + pre {= m4_fmt_code(dynamic-func.an.gsp) } + } + + p {- + Now you might think that this is really retarded — especially if you’re + a Rust developer — and you know what? I did too! But you know what the + beauty of recreational programming is? It doesn’t @code{-have} to be + good — and once you learn to ignore the low-value morons that will + see you experimenting with new ideas and call it garbage — you can start + to actually develop some pretty neat solutions to problems. + } + + p {- + For example, Andy like all shells implements support for signal + handling. In the POSIX shell this is done via the ‘trap’ builtin + function: + } + + figure { + pre {= m4_fmt_code(trap.sh.gsp) } + } + + p {- + Now personally, I really don’t like @code{-trap}. Having to write your + signal handling code in string is just not very ergonomic. You + @em{-can} put your code in a function that you then call in your signal + handler, but I think Andy can do better. The way you handle a signal in + Andy is to simply define a function of the name ‘sigX’ where ‘X’ is the + name of the signal. If you want to write a handler for SIGINT, you + simply define the ‘sigint’ function! + } + + p {- + What if we want to handle multiple signals though? In the above + example, we deleted some temporary files on SIGQUIT and also on the + special SIGEXIT (a fake signal that signifies that the process is + exiting). Well the naïve solution is to simply define a handler + function that you call from your handlers: + } + + figure { + pre .sh {= m4_fmt_code(naïve.an.gsp) } + } + + p {- + But wait… remember how we can dynamically define functions? What if we + just… dynamically define our signal handlers: + } + + figure { + pre .sh {= m4_fmt_code(smart.an.gsp) } + } + + p {- + Personally, I think that’s pretty neat, and I like it! Of course some + Haskell developer that’s never @em{-actually} written any working + software will probably be sending me an angry email right about now + about how this is unsafe code and blah blah, but I don’t care. + } + + p {- + I suppose while this post is primarily about just showing off some of + Andy’s behavior, I also want to make the point that it’s always a good + idea to just try new ideas, no matter how contrary they are to ‘best + practices’ and Rust developers. Don’t waste your time worrying about + what other people think about what you make; I used to do that, and it’s + not great. Just make shit, even if it’s weird. You might just + accidentally add a cool new feature you actually kind of like. + } + } + + hr{} + + footer { m4_footer } + } +} diff --git "a/src/blog/andy-val/na\303\257ve.an.gsp" "b/src/blog/andy-val/na\303\257ve.an.gsp" new file mode 100644 index 0000000..661af89 --- /dev/null +++ "b/src/blog/andy-val/na\303\257ve.an.gsp" @@ -0,0 +1,6 @@ +@span .kw {-func} handler { + @span .fn {-rm} -f (foo bar).tmp +\} + +@span .kw {-func} sigquit { @span .fn {-handler} \} +@span .kw {-func} sigexit { @span .fn {-handler} \} diff --git a/src/blog/andy-val/posix-fail.sh.gsp b/src/blog/andy-val/posix-fail.sh.gsp new file mode 100644 index 0000000..b66ce22 --- /dev/null +++ b/src/blog/andy-val/posix-fail.sh.gsp @@ -0,0 +1,3 @@ +@span .p {-thomas} @span .pp {-~} @span .p {-〉}foo@span .op {-=}bar +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .var {-$foo}() { @span .fn {-:}@span .op {-;} \} +bash: `$bar': not a valid identifier diff --git a/src/blog/andy-val/smart.an.gsp b/src/blog/andy-val/smart.an.gsp new file mode 100644 index 0000000..668f189 --- /dev/null +++ b/src/blog/andy-val/smart.an.gsp @@ -0,0 +1,7 @@ +@span .cmt {-# $_ represents the current iteration variable. You can give an explicit name} +@span .cmt {-# with a for-in loop though.} +@span .kw {-for} quit exit { + @span .kw {-func} sig$_ { + @span .fn {-rm} -f (foo bar).tmp + \} +\} diff --git a/src/blog/andy-val/trap.sh.gsp b/src/blog/andy-val/trap.sh.gsp new file mode 100644 index 0000000..30a60ad --- /dev/null +++ b/src/blog/andy-val/trap.sh.gsp @@ -0,0 +1 @@ +@span .fn {-trap} @span .str {-"rm -f foo.tmp bar.tmp"} QUIT EXIT diff --git a/src/blog/index.gsp b/src/blog/index.gsp index 7ad0296..aac12e0 100644 --- a/src/blog/index.gsp +++ b/src/blog/index.gsp @@ -28,6 +28,7 @@ html lang="en" { p {-Posts:} ul { + m4_article(andy-val, {-Values in Andy}) m4_article(new-sh, {-Making a New Shell}) m4_article(extend, {-Extensible Scripting}) m4_article(nvim-ts, {-Hacking with Tree-Sitter on Neovim}) diff --git a/src/style.css b/src/style.css index 6581e9d..42b55e1 100644 --- a/src/style.css +++ b/src/style.css @@ -170,11 +170,12 @@ dl { /* New classes */ .cmt { color: var(--lesser); font-style: italic; } +.cnst { color: var(--blue); } .fn { color: var(--accent); } .kw { color: var(--green); } -.str { color: var(--aqua); } -.cnst { color: var(--blue); } .op { color: var(--lesser); } +.str { color: var(--aqua); } +.var { color: var(--blue); font-style: italic; } /* Terminal prompt */ .p { color: #24DFC4; font-weight: bold; } -- cgit v1.2.3