Skip to content

Commit 6bb3dc5

Browse files
authored
Merge pull request #4 from goboscript/v2
v2.0.0
2 parents 4bd51f9 + 1562244 commit 6bb3dc5

File tree

13 files changed

+680
-162
lines changed

13 files changed

+680
-162
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.sb3

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 goboscript
3+
Copyright (c) 2025 aspizu
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
# std
1+
# `std` is the goboscript standard library
22

3-
std is the goboscript's standard library.
3+
## Installation
4+
5+
Add the following to your `goboscript.toml` file:
6+
7+
```toml
8+
std = "2.0.0"
9+
```

cmd.gs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
list cmd_args;
2+
3+
func cmd_next(start, cmd) {
4+
delete cmd_args;
5+
local key = "";
6+
local single_quote = false;
7+
local double_quote = false;
8+
local i = $start;
9+
until i > length($cmd) {
10+
if single_quote {
11+
if $cmd[i] == "'" and $cmd[i-1] != "\\" {
12+
single_quote = false;
13+
add key to cmd_args;
14+
key = "";
15+
}
16+
else {
17+
key &= $cmd[i];
18+
}
19+
}
20+
elif double_quote {
21+
if $cmd[i] == "\"" {
22+
double_quote = false;
23+
add key to cmd_args;
24+
key = "";
25+
}
26+
elif $cmd[i] == "\\" {
27+
i++;
28+
key &= $cmd[i];
29+
}
30+
else {
31+
key &= $cmd[i];
32+
}
33+
}
34+
elif $cmd[i] == "\"" {
35+
double_quote = true;
36+
}
37+
elif $cmd[i] == "'" {
38+
single_quote = true;
39+
}
40+
elif $cmd[i] == " " {
41+
if key != "" {
42+
add key to cmd_args;
43+
key = "";
44+
}
45+
}
46+
elif $cmd[i] == ";" {
47+
if key != "" {
48+
add key to cmd_args;
49+
}
50+
return i+1;
51+
}
52+
elif $cmd[i] == "\\" {
53+
i++;
54+
key &= $cmd[i];
55+
}
56+
else {
57+
key &= $cmd[i];
58+
}
59+
i++;
60+
}
61+
if key != "" {
62+
add key to cmd_args;
63+
}
64+
return 0;
65+
}

cskv.gs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
list cskv;
2+
list cskv_keys;
3+
list cskv_key_map;
4+
5+
%define CSKV_GET_INDEX(key) cskv_key_map[(key) in cskv_keys]
6+
%define CSKV_GET(key) cskv[cskv_key_map[(key) in cskv_keys]]
7+
8+
proc cskv_unpack text {
9+
delete cskv;
10+
local token = "";
11+
local i = 0;
12+
until i > length($text) {
13+
if $text[i] == "\\" {
14+
if $text[i+1] in ",:\\" {
15+
token &= $text[i+1];
16+
i++;
17+
} else {
18+
token &= "\\";
19+
}
20+
} elif $text[i] == "," {
21+
add token to cskv;
22+
token = "";
23+
} elif $text[i] == ":" {
24+
add token to cskv_keys;
25+
add 1+length(cskv) to cskv_key_map;
26+
token = "";
27+
} else {
28+
token &= $text[i];
29+
}
30+
i++;
31+
}
32+
add token to cskv;
33+
}
34+
35+
func cskv_pack() {
36+
local result = "";
37+
local i = 1;
38+
until i > length(cskv_keys) {
39+
result &= cskv_keys[i] & ":";
40+
if (cskv_key_map[i+1] - cskv_key_map[i]) > 2 {
41+
result &= cskv[cskv_key_map[i]] & ",";
42+
local j = 1;
43+
until j > cskv[cskv_key_map[i]] {
44+
local element = cskv[cskv_key_map[i] + j];
45+
local k = 1;
46+
until k > length(element) {
47+
if element[k] in "\\,:" {
48+
result &= "\\";
49+
}
50+
result &= element[k];
51+
k++;
52+
}
53+
j++;
54+
if i < length(cskv_keys) or j < cskv[cskv_key_map[i]] {
55+
result &= ",";
56+
}
57+
}
58+
} else {
59+
local j = 1;
60+
until j > length(cskv[cskv_key_map[i]]) {
61+
if cskv[cskv_key_map[i]][j] in "\\,:" {
62+
result &= "\\";
63+
}
64+
result &= cskv[cskv_key_map[i]][j];
65+
j++;
66+
}
67+
if i < length(cskv_keys) {
68+
result &= ",";
69+
}
70+
}
71+
i++;
72+
}
73+
return result;
74+
}

emoji.gs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Return the emoji for the shortcode `NAME`.
2-
%define EMOJI(NAME) emojis[(NAME) in emoji_names]
2+
%define EMOJI(NAME) emoji_values[(NAME) in emoji_names]
33

44
# List of all emoji shortcodes.
55
list emoji_names = [
@@ -5727,7 +5727,7 @@ list emoji_names = [
57275727
];
57285728

57295729
# List of all emojis.
5730-
list emojis = [
5730+
list emoji_values = [
57315731
"💯",
57325732
"🔢",
57335733
"⚽",

algo.gs renamed to list.gs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
%define INSERTION_SORT(LIST) \
33
local i = 2; \
44
until i > length(LIST) { \
5-
local x = LIST[i]; \
5+
local isx = LIST[i]; \
66
local j = i; \
7-
until j <= 1 or LIST[j - 1] <= x { \
7+
until j <= 1 or LIST[j - 1] <= isx { \
88
LIST[j] = LIST[j - 1]; \
99
j--; \
1010
} \
11-
LIST[j] = x; \
11+
LIST[j] = isx; \
1212
i++; \
1313
}
1414

@@ -17,13 +17,13 @@
1717
%define INSERTION_SORT_BY_FIELD(TYPE,LIST,FIELD) \
1818
local i = 2; \
1919
until i > length(LIST) { \
20-
local TYPE x = LIST[i]; \
20+
local TYPE isfx = LIST[i]; \
2121
local j = i; \
22-
until j <= 1 or LIST[j - 1].FIELD <= x.FIELD { \
22+
until j <= 1 or LIST[j - 1]FIELD <= isfx FIELD { \
2323
LIST[j] = LIST[j - 1]; \
2424
j--; \
2525
} \
26-
LIST[j] = x; \
26+
LIST[j] = isfx; \
2727
i++; \
2828
}
2929

@@ -54,7 +54,7 @@
5454
# Find the largest element in `LIST` that satisfies `CMP`, and store the result in
5555
# `STORE`. local `i` is the index of the current element.
5656
%define FINDMAX(LIST,CMP,STORE) \
57-
local STORE = LIST[1]; \
57+
local STORE = "-Infinity"; \
5858
local i = 1; \
5959
repeat length(LIST) { \
6060
if CMP { \
@@ -68,7 +68,7 @@
6868
# Find the smallest element in `LIST` that satisfies `CMP`, and store the result in
6969
# `STORE`. local `i` is the index of the current element.
7070
%define FINDMIN(LIST,CMP,STORE) \
71-
local STORE = LIST[1]; \
71+
local STORE = "Infinity"; \
7272
local i = 1; \
7373
repeat length(LIST) { \
7474
if CMP { \
@@ -100,6 +100,14 @@
100100
i++; \
101101
}
102102

103+
# Extend `DEST` with the elements of `SRC`.
104+
%define EXTEND(SRC,DEST) \
105+
local i = 1; \
106+
repeat length(SRC) { \
107+
add SRC[i] to DEST; \
108+
i++; \
109+
}
110+
103111
# Remove duplicate elements from `LIST`.
104112
%define UNIQUE(LIST) \
105113
local i = 1; \
@@ -115,40 +123,43 @@
115123
i++; \
116124
}
117125

118-
# Sum the field `FIELD` in `LIST` of type `TYPE` that satisfy `CMP`, and store the
119-
# result in `STORE`.
120-
%define SUM_BY_FIELD(TYPE,LIST,FIELD,CMP,STORE) \
126+
# Sum the field `FIELD` in `LIST` that satisfy `CMP`, and store the result in `STORE`.
127+
%define SUM_BY_FIELD(LIST,FIELD,CMP,STORE) \
121128
local STORE = 0; \
122129
local i = 1; \
123130
repeat length(LIST) { \
124131
if CMP { \
125-
STORE += LIST[i].FIELD; \
132+
STORE += LIST[i]FIELD; \
126133
} \
127134
i++; \
128135
}
129136

137+
# TODO [BLOCKED BY]: https://github.com/aspizu/goboscript/issues/71
130138
# Find the largest `FIELD` value in `LIST` of type `TYPE` that satisfies `CMP` and store
131139
# the result in `STORE`.
132140
%define FINDMAX_BY_FIELD(TYPE,LIST,FIELD,CMP,STORE) \
133-
local TYPE STORE = LIST[1]; \
141+
local TYPE STORE; \
142+
STORE FIELD = "-Infinity"; \
134143
local i = 1; \
135144
repeat length(LIST) { \
136145
if CMP { \
137-
if LIST[i].FIELD > STORE.FIELD { \
146+
if LIST[i]FIELD > STORE FIELD { \
138147
STORE = LIST[i]; \
139148
} \
140149
} \
141150
i++; \
142151
}
143152

153+
# TODO [BLOCKED BY]: https://github.com/aspizu/goboscript/issues/71
144154
# Find the smallest `FIELD` value in `LIST` of type `TYPE` that satisfies `CMP` and
145155
# store the result in `STORE`.
146156
%define FINDMIN_BY_FIELD(TYPE,LIST,FIELD,CMP,STORE) \
147-
local TYPE STORE = LIST[1]; \
157+
local TYPE STORE; \
158+
STORE FIELD = "Infinity"; \
148159
local i = 1; \
149160
repeat length(LIST) { \
150161
if CMP { \
151-
if LIST[i].FIELD < STORE.FIELD { \
162+
if LIST[i]FIELD < STORE FIELD { \
152163
STORE = LIST[i]; \
153164
} \
154165
} \
@@ -161,7 +172,7 @@
161172
until i > length(LIST) { \
162173
local j = i + 1; \
163174
until j > length(LIST) { \
164-
if LIST[i].FIELD == LIST[j].FIELD { \
175+
if LIST[i] FIELD == LIST[j] FIELD { \
165176
delete LIST[j]; \
166177
} else { \
167178
j++; \

math.gs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
%define PI 3.141592653589793
2+
%define E 2.718281828459045
3+
%define SQRT2 1.4142135623730951
4+
15
# Return the minimum of `A` and `B`.
26
%define MIN(A,B) ((A) - ((A) - (B)) * ((A) > (B)))
37

@@ -16,10 +20,26 @@
1620
# Parse a binary value.
1721
%define BIN(VALUE) (("0b"&(VALUE))+0)
1822

23+
# Parse a octal value.
24+
%define OCT(VALUE) (("0o"&(VALUE))+0)
25+
26+
%define ACOSH(X) ln((X)+sqrt((X)*(X)-1))
27+
%define ASINH(X) ln((X)+sqrt((X)*(X)+1))
28+
%define ATANH(X) ln((1+(X))/(1-(X)))/2
29+
%define COSH(X) ((antiln(X)+antiln(-(X)))/2)
30+
%define SINH(X) ((antiln(X)-antiln(-(X)))/2)
31+
%define TANH(X) ((antiln(X)-antiln(-(X)))/(antiln(X)+antiln(-(X))))
32+
33+
# Return the distance between the points `(X1,Y1)` and `(X2,Y2)`.
34+
%define DIST(X1,Y1,X2,Y2) sqrt(((X2)-(X1))*((X2)-(X1))+((Y2)-(Y1))*((Y2)-(Y1)))
35+
36+
# Return the magnitude of the vector `(X,Y)`.
37+
%define MAG(X,Y) sqrt((X)*(X)+(Y)*(Y))
38+
1939
# Return `BASE` raised to the power of `EXP`.
2040
%define POW(BASE,EXP) antiln(ln(BASE)*(EXP))
2141

22-
# Return the gamma function of `VALUE`.
42+
# Gamma correct `VALUE` with power 2.2
2343
%define GAMMA(VALUE) antiln(ln(VALUE)/2.2)
2444

2545
# Clamp `VALUE` above zero. (Returns 0 for `VALUE` < 0)
@@ -33,16 +53,19 @@
3353
%define CLAMP(VALUE,MIN,MAX) (((VALUE)>(MIN))*((MAX)+((VALUE)-(MAX))*((VALUE)<(MAX))))
3454
3555
# Return the `N`th bit of `V`'s binary representation.
36-
%define BIT(N, V) (((V) // antiln((N) * ln 2) % 2)
56+
%define BIT(N,V) (((V) // antiln((N) * ln 2) % 2))
3757
38-
# Return the distance between the points `(X1,Y1)` and `(X2,Y2)`.
39-
%define DIST(X1,Y1,X2,Y2) sqrt(((X2)-(X1))*((X2)-(X1))+((Y2)-(Y1))*((Y2)-(Y1)))
58+
# Linearly interpolate between `A` and `B` by `T`.
59+
%define LERP(A,B,T) ((A)+((B)-(A))*(T))
4060
41-
%define ACOSH(X) ln((X)+sqrt((X)*(X)-1))
42-
%define ASINH(X) ln((X)+sqrt((X)*(X)+1))
43-
%define ATANH(X) ln((1+(X))/(1-(X)))/2
44-
%define COSH(X) ((antiln(X)+antiln(-(X)))/2)
45-
%define SINH(X) ((antiln(X)-antiln(-(X)))/2)
46-
%define TANH(X) ((antiln(X)-antiln(-(X)))/(antiln(X)+antiln(-(X))))
47-
%define PI 3.141592653589793
48-
%define E 2.718281828459045
61+
# Work out the ratio of `VAL` from `A` to `B`.
62+
%define INVLERP(VAL,A,B) ((VAL) - (A)) / ((B) - (A))
63+
64+
# Re-maps a `V` from the range `A` to `B` to the range `C` to `D`.
65+
%define MAP(A,B,C,D,V) (((V)-(B))*((D)-(C))/((A)-(B))+(C))
66+
67+
# Convert degrees to radians.
68+
%define RAD(DEG) ((DEG) * 0.017453292519943295)
69+
70+
# Convert radians to degrees.
71+
%define DEG(RAD) ((RAD) * 57.29577951308232)

0 commit comments

Comments
 (0)