summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-07-23 17:00:56 +0100
committerubq323 <ubq323@ubq323.website>2024-07-23 17:00:56 +0100
commitaa0485fe33204169724d020f9c5e3b91e558ab1e (patch)
tree909ea369aa38854fe98396c61ecab6c600533f7a
parent726f9e814b29b4496d07c92323dc55dcf93c2a87 (diff)
add pend builtin function
-rw-r--r--doc.txt4
-rw-r--r--g.peg6
-rw-r--r--ideas35
-rw-r--r--lib.c17
-rw-r--r--tests/pend.bth25
-rw-r--r--tests/pend.out19
6 files changed, 102 insertions, 4 deletions
diff --git a/doc.txt b/doc.txt
index fce7e9d..d65c981 100644
--- a/doc.txt
+++ b/doc.txt
@@ -43,6 +43,10 @@
(arr): create new empty array
(append a x): appends to array a, returns a
(len a): get length of array a
+ (, ...): pend. concatenates arrays, promotes non-arrays to arrays
+ (, [1 2 3] 4) -> [1 2 3 4]
+ (, [1 2 3] [4 5]) -> [1 2 3 4 5]
+ (, 10 20) -> [10 20] etc
# cmdline args
bth [-Dl] [-Dt] filenames...
diff --git a/g.peg b/g.peg
index 08ded48..84d907e 100644
--- a/g.peg
+++ b/g.peg
@@ -32,12 +32,12 @@ expr <-
/ a:array { $$ = a; }
list <- { $$ = astnode_new_list(); }
- '('
+ '(' _
( e:expr { astnode_append(&$$, e); }
)*
')' _
array <- { $$ = astnode_new_arr(); }
- '['
+ '[' _
( e:expr { astnode_append(&$$, e); }
)*
']' _
@@ -46,7 +46,7 @@ number <- < [0-9]+ > (! ident_char) _ { $$ = astnode_new_num(atoi($1)); }
ident <- < ident_char+ > _ { $$ = astnode_new_ident($1); }
string <- '"' < [^"]* > '"' _ { $$ = astnode_new_string($1); }
-ident_char <- [-_a-zA-Z'+*/\\%=0-9<>!]
+ident_char <- [-_a-zA-Z'+*/\\%=0-9<>!,]
_ <- [ \t\n]*
diff --git a/ideas b/ideas
new file mode 100644
index 0000000..9717cb6
--- /dev/null
+++ b/ideas
@@ -0,0 +1,35 @@
+(, a b)
+pend.
+concatenates arrays, but enlists anything that isnt already an array
+thus
+ (, x xs) (, xs x) is like append or prepend
+ (, x y) is pair
+ (, x) is enlist
+ (, xs ys) is extend
+if you really want an array to be inside another array
+ you can do (, xs (, ys)) or equivalently (, xs [ys])
+ this is probably the rarer case so that's good
+this always returns (allocates) a new object. that's probably fine
+most of the time
+if you want it to modify inplace have a (,! ...) form
+but need to specify which one to modify ...
+ (,! x xs) (,! xs x) are unambiguous
+ but should (,! xs ys) copy ys to xs or vice versa?
+ maybe something like (,!< xs ys) (,!> xs ys) respectively
+ or maybe more generally (,! xs (! ys)) but that's uglier
+ (,! xs !ys) ???
+this also does string concatenation.
+have a variant (,, ...) maybe that puts spaces in between
+have a variant that uniions hashes
+ does (, {'x 10} {'y 20}) do {'x 10 'y 20} or [{'x 10} {'y 20}] ?
+ probably see which is commoner
+
+
+
+separate strings from symbols
+symbols are atomic and interned
+strings are just arrays of characters (codepoints)
+
+
+
+
diff --git a/lib.c b/lib.c
index e070bc0..a1ca311 100644
--- a/lib.c
+++ b/lib.c
@@ -40,7 +40,21 @@ static Val fn_len(State *S, int nargs, Val *args) {
ObjArr *a = AS_ARR(args[0]);
return VAL_NUM(a->len);
}
-
+static Val fn_pend(State *S, int nargs, Val *args) {
+ CHECK(nargs > 0, "need at least 1 arg to ,");
+ ObjArr *a = objarr_new(S);
+ for (int i = 0; i < nargs; i++) {
+ Val v = args[i];
+ if (!IS_ARR(v))
+ objarr_append(S, a, v);
+ else {
+ ObjArr *b = AS_ARR(v);
+ for (int j = 0; j < b->len; j++)
+ objarr_append(S, a, b->d[j]);
+ }
+ }
+ return VAL_OBJ(a);
+}
typedef struct {
@@ -55,6 +69,7 @@ static BuiltinFunc builtin_funcs[] = {
{ "arr", fn_arr },
{ "append", fn_append },
{ "len", fn_len },
+ { ",", fn_pend },
{ 0 },
};
diff --git a/tests/pend.bth b/tests/pend.bth
new file mode 100644
index 0000000..9a37f00
--- /dev/null
+++ b/tests/pend.bth
@@ -0,0 +1,25 @@
+(def xs [
+ (, 10)
+ (, [100 200])
+
+ (, 22 33)
+ (, 11 [111 222])
+ (, [333 444] 99)
+ (, [555 666] [777 888])
+
+ (, 10 11 12)
+ (, 10 11 [20 30])
+ (, 10 [222 333] 99)
+ (, 10 [22 33] [44 55])
+ (, [100 200] 33 44)
+ (, [100 200] 33 [444 555])
+ (, [100 200] [33 44] 55)
+ (, [100 200] [333 444] [555 666])
+
+ (, [])
+ (, [1])
+ (, 10 [])
+ (, [] 20)
+ (, [] [])
+])
+(each (x xs) (say x))
diff --git a/tests/pend.out b/tests/pend.out
new file mode 100644
index 0000000..44239f7
--- /dev/null
+++ b/tests/pend.out
@@ -0,0 +1,19 @@
+[ 10 ]
+[ 100 200 ]
+[ 22 33 ]
+[ 11 111 222 ]
+[ 333 444 99 ]
+[ 555 666 777 888 ]
+[ 10 11 12 ]
+[ 10 11 20 30 ]
+[ 10 222 333 99 ]
+[ 10 22 33 44 55 ]
+[ 100 200 33 44 ]
+[ 100 200 33 444 555 ]
+[ 100 200 33 44 55 ]
+[ 100 200 333 444 555 666 ]
+[ ]
+[ 1 ]
+[ 10 ]
+[ 20 ]
+[ ]