Skip to content

Commit

Permalink
Improve stdlib
Browse files Browse the repository at this point in the history
  • Loading branch information
cerus committed Dec 5, 2022
1 parent 037d7b5 commit a62392e
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 2 deletions.
32 changes: 32 additions & 0 deletions stdlib/arrays.edina
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import "stdlib/stack" as stack

rt trim_array
# [NLen, Len, c, b, a]
over over # [NLen, Len, NLen, Len, c, b, a]
swap - # [Len-NLen, NLen, Len, c, b, a]
0 swap lte # [LTE, Len-NLen, 0, NLen, Len, c, b, a]
1 3 rroll # [0, LTE, Len-NLen, NLen, Len, c, b, a]
pop # [LTE, Len-NLen, NLen, Len, c, b, a]

0 swap lte 1 3 rroll pop
if
# Invalid
2 :stack.mpop # [Len, c, b, a]
else
# [Len-NLen, NLen, Len, c, b, a]
pop # [NLen, Len, c, b, a]
over - # [Len-NLen, Len, c, b, a]

# Trim to specified length
while
# [NLen, Len, c, b, a]
1 3 rroll # [c, NLen, Len, b, a]
pop swap # [Len, NLen, b, a]
1 swap - # [Len-1, NLen, b, a]
swap # [NLen, Len-1, b, a]
1 swap - # [NLen-1, Len-1, b, a]
end
# [NLen, Len, c, b, a]
pop # [Len, c, b, a]
end
end
7 changes: 7 additions & 0 deletions stdlib/io/files.edina
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import "stdlib/strings" as strings

rt read_file
# [Path, Flags] -> [Len, a, b, c]
native_open # [Fd]

end
20 changes: 20 additions & 0 deletions stdlib/io/utils.edina
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import "stdlib/stack" as stack

rt full_write
# [Fd, Len, c, b, a]
over 2 + # [Len+2, Fd, Len, c, b, a]
1 swap lroll # [Len, c, b, a, Fd]
:stack.copy # [Len, c, b, a, Len, c, b, a, Fd]
dup 2 * 3 + # [Len*2+3, Len, c, b, a, Len, c, b, a, Fd]
1 swap rroll # [Fd, Len, c, b, a, Len, c, b, a]
end

rt full_read
# [Fd]
0 swap # [Fd, Len]
1 # [Iter, Fd, Len]
while
# [Iter, Fd, Len]

end
end
197 changes: 196 additions & 1 deletion stdlib/math/ints.edina
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ rt int_to_str
1 3 lroll # [N, Q, X--100, R, X, S, ...]
swap pop 0 swap # Reset Q to zero
1 3 rroll # [X--100, N, Q, R, X, S, ...]
1 swap - # [X--100-1, N, Q, R, X, S, ...]

0 swap gte 1 3 rroll pop
if pop 0 end
Expand Down Expand Up @@ -235,6 +236,185 @@ rt int_str_size
end
end

rt parse_int
# [R, Len, A, B, C]
# R = Radix

# Check if length is > 0
over if
over 0 0 .int64_max .negate 1 4 rroll # [Len, Lim, i, Neg, R, Len, A, B, C]

# I messed up here. Strings are naturally reversed ("abc" -> [3(length), c, b, a]) and this code assumes
# that the first char of the string immediately follows after the length. I don't want to restructure all
# of the code, so I decided to just pull the real first char to the front.

dup 6 + 1 swap rroll # [C, Len, Lim, i, Neg, R, Len, A, B]
1 7 lroll # [Len, Lim, i, Neg, R, Len, C, A, B]
# The following comments will assume that the string remains in A, C, B order.
1 7 rroll # [A, Len, Lim, i, Neg, R, Len, B, C]

# Check first char
dup .char_zero swap .lt if
# First char < '0'; Possible leading + or -
dup .char_minus .eq if
# First char is -
# Set Neg to true
1 5 rroll pop 1 # [Neg(true), A, Len, Lim, i, R, Len, B, C]
1 5 lroll # [A, Len, Lim, i, Neg(true), R, Len, B, C]
# Set Lim to Int64 Min
1 3 rroll pop .int64_min # [Lim, A, Len, i, Neg(true), R, Len, B, C]
1 3 lroll # [A, Len, Lim, i, Neg(true), R, Len, B, C]
else
dup .char_plus .neq if
# First char is not +
# TODO: Throw error
end
end

# [A, Len, Lim, i, Neg, R, Len, B, C]
over 1 .eq if
# String only consists of + or -
# TODO: Throw error
end

# i++
1 4 rroll 1 + # [i+1, A, Len, Lim, Neg, R, Len, B, C]
1 4 lroll # [A, Len, Lim, i+1, Neg, R, Len, B, C]
end

# [A, Len, Lim, i, Neg, R, Len, B, C]
over 1 swap - 1 swap 7 + # [Len-1+7, 1, A, Len, Lim, i, Neg, R, Len, B, C]
lroll # [Len, Lim, i, Neg, R, Len, B, C, A]

# [Len, Lim, i, Neg, R, Len, B, C, A]
# 1 7 lroll
1 3 rroll swap # [Len, i, Lim, Neg, R, Len, B, C, A]
- # [Len-i, Lim, Neg, R, Len, B, C, A]
1 4 rroll dup 1 5 lroll # [R, Len-i, Lim, Neg, R, Len, B, C, A]
1 3 rroll dup 1 4 lroll # [Lim, R, Len-i, Lim, Neg, R, Len, B, C, A]
/ 0 1 3 rroll # [Len-i, Res, Lim/R -> Mm, Lim, Neg, R, Len, B, C, A]

# [Leni, Res, Mm, Lim, Neg, R, Len, B, C, A]
#1 + # [Leni+1, Res, Mm, Lim, Neg, R, Len, B, C, A]
while
#1 swap - # [Leni, Res, Mm, Lim, Neg, R, Len, B, C, A]

# TODO: Implement the following Java code
# // Accumulating negatively avoids surprises near MAX_VALUE
# int digit = Character.digit(s.charAt(i++),radix);
# if (digit < 0 || result < multmin) {
# throw NumberFormatException.forInputString(s, radix);
# }
# result *= radix;
# if (result < limit + digit) {
# throw NumberFormatException.forInputString(s, radix);
# }
# result -= digit;

# Would be +8, but we have to dup so we add 8 instead
dup 8 + 1 over # [Leni+8, 1, Leni+8, Leni, Res, Mm, Lim, Neg, R, Len, B, C, A]
rroll # [C, Leni+8, Leni, Res, Mm, Lim, Neg, R, Len, B, A]
dup .latin1_digit # [Dig, C, Leni+8, Leni, Res, Mm, Lim, Neg, R, Len, B, A]

# Dig < 0 || Dig < Mm
0 over .lt # [Dig<0, Dig, C, Leni+8, Leni, Res, Mm, Lim, Neg, R, Len, B, A]
1 7 rroll # [Mm, Dig<0, Dig, C, Leni+8, Leni, Res, Lim, Neg, R, Len, B, A]
1 7 rroll # [Res, Mm, Dig<0, Dig, C, Leni+8, Leni, Lim, Neg, R, Len, B, A]
over over .lt # [Res<Mm, Res, Mm, Dig<0, Dig, C, Leni+8, Leni, Lim, Neg, R, Len, B, A]
swap 1 8 lroll # [Res<Mm, Mm, Dig<0, Dig, C, Leni+8, Leni, Res, Lim, Neg, R, Len, B, A]
swap 1 8 lroll # [Res<Mm, Dig<0, Dig, C, Leni+8, Leni, Res, Mm, Lim, Neg, R, Len, B, A]
| if
# TODO: Throw error
end

1 5 rroll # [Res, Dig, C, Leni+8, Leni, Mm, Lim, Neg, R, Len, B, A]
1 9 rroll # [R, Res, Dig, C, Leni+8, Leni, Mm, Lim, Neg, Len, B, A]
swap over * swap # [R, R*Res, Dig, C, Leni+8, Leni, Mm, Lim, Neg, Len, B, A]
1 9 lroll # [R*Res, Dig, C, Leni+8, Leni, Mm, Lim, Neg, R, Len, B, A]

# TODO: if (result < limit + digit)

- # [R*Res-Dig, C, Leni+8, Leni, Mm, Lim, Neg, R, Len, B, A]

# What we need: [Leni, Res, Mm, Lim, Neg, R, Len, B, C, A]
swap 1 3 rroll # [Leni+8, C, R*Res-Dig, Leni, Mm, Lim, Neg, R, Len, B, A]
1 swap - # [Leni+7, C, R*Res-Dig, Leni, Mm, Lim, Neg, R, Len, B, A]
1 swap lroll swap # [Leni, R*Res-Dig, Mm, Lim, Neg, R, Len, B, C, A]
1 swap - # [Leni-1, R*Res-Dig, Mm, Lim, Neg, R, Len, B, C, A]
end

# [Leni, R*Res-Dig, Mm, Lim, Neg, R, Len, B, C, A]
1 5 rroll # [Neg, Leni, Res, Mm, Lim, R, Len, B, C, A]
1 3 rroll # [Res, Neg, Leni, Mm, Lim, R, Len, B, C, A]
swap 0 .eq if
# Negate
.negate
end
# [Res, Leni, Mm, Lim, R, Len, B, C, A]
1 5 lroll pop pop pop pop # [Res, Len, B, C, A]
over 2 + 1 swap lroll # [Len, B, C, A, Res]

# [Len, B, C, A, Res]

while
dup 1 + 1 swap rroll # [A, Len, B, C, Res]
pop 1 swap - # [Len, B, C, Res]
end
pop # [Res]

# If
else
# TODO: Throw error
end
end

# Equivalent to Character.digit(char, radix)
# [Ch]
rt latin1_digit
0 # [V, Ch]

# int v = -1;
# if (i >= '0' && i <= '9') { v = i - '0'; }
# else if (i >= 'A' && i <= 'Z') { v = i - 'A' + 10; }
# else if (i >= 'a' && i <= 'z') { v = i - 'a' + 10; }
# if (i % 20 == 0) System.out.println();
# System.out.printf("%2d, ", v);

swap dup # [Ch, Ch, V]
.char_zero swap .gte # [Ch >= '0', Ch, V]
over .char_nine swap .lte # [Ch <= '9', Ch >= '0', Ch, V]
& if
# if (i >= '0' && i <= '9')
# [Ch, V]
dup .char_zero swap - # [Ch-'0', Ch, V]
1 3 rroll pop # [Ch-'0' -> V, Ch]
swap
else
dup # [Ch, V]
.char_A swap .gte # [Ch >= 'A', Ch, V]
over .char_Z swap .lte # [Ch <= 'Z', Ch >= 'A', Ch, V]
& if
# else if (i >= 'A' && i <= 'Z')
# [Ch, V]
dup .char_A swap - 10 + # [Ch-'A'+10, Ch, V]
1 3 rroll pop # [Ch-'A'+10 -> V, Ch]
swap
else
dup # [Ch, V]
.char_a swap .gte # [Ch >= 'a', Ch, V]
over .char_z swap .lte # [Ch <= 'z', Ch >= 'a', Ch, V]
& if
# else if (i >= 'a' && i <= 'z')
# [Ch, V]
dup .char_a swap - 10 + # [Ch-'A'+10, Ch, V]
1 3 rroll pop # [Ch-'A'+10 -> V, Ch]
swap
end
end
end
pop
end



# #####################
Expand All @@ -246,4 +426,19 @@ rt _digit_one
end
rt _digit_ten
10 swap / 48 +
end
end

rt char_zero "0" pop end
rt char_nine "9" pop end
rt char_A "A" pop end
rt char_Z "Z" pop end
rt char_a "a" pop end
rt char_z "z" pop end
rt char_plus "+" pop end
rt char_minus "-" pop end

rt eq eq 1 3 lroll pop pop end
rt neq neq 1 3 lroll pop pop end
rt lt lt 1 3 lroll pop pop end
rt lte lte 1 3 lroll pop pop end
rt gte gte 1 3 lroll pop pop end
37 changes: 36 additions & 1 deletion stdlib/stack.edina
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,39 @@ end
stack={ in="Amount of items to rotate $int" out="" }
desc="Alias for .rotate"
} ]
rt rot .rotate end
rt rot .rotate end

rt multi_pop
# [N, ...]
1 swap gte # [GTE, N, 1, ...]
3 1 rroll pop # [GTE, N, ...]
if
while
swap # [..., N]
pop # [N]
1 swap - # [N-1]
end
pop
end
end

rt mpop .multi_pop end

rt copy
# [Len, c, b, a]
dup # [Len->Iter, Len, c, b, a]
while
# [Iter, Len, ...]
dup 2 + # [Iter+2, Iter, Len, c, b, a]
1 swap rroll # [a, Iter, Len, c, b]
dup 1 3 rroll # [Iter, a, a, Len, c, b]
swap # [a, Iter, a, Len, c, b]
over 3 + # [Iter+3, a, Iter, a, Len, c, b]
1 swap lroll # [Iter, a, Len, c, b, a]
1 3 lroll # [a, Len, Iter, c, b, a]
over 3 + # [Len+3, a, Len, Iter, c, b, a]
1 swap lroll # [Len, Iter, c, b, a, a]
swap 1 swap - # [Iter-1, Len, c, b, a, a]
end
pop pop
end

0 comments on commit a62392e

Please sign in to comment.