Skip to content

Commit

Permalink
Implement split_each
Browse files Browse the repository at this point in the history
  • Loading branch information
brendantang committed Aug 16, 2021
1 parent 2d66497 commit 15684ba
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 24 deletions.
10 changes: 4 additions & 6 deletions eval/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func CoreDict() *data.Dictionary {
">": data.NewProc(greaterThan),
"<=": data.NewProc(lessThanOrEq),
">=": data.NewProc(greaterThanOrEq),
"length": data.NewProc(length), // push length of the quotation or string on top of the stack
"length": data.NewProc(length), // pop a quotation or string and push its length

// BOOLEANS
"true": data.NewBoolean(true), // TRUE literal
Expand Down Expand Up @@ -286,10 +286,9 @@ func then(d *data.Dictionary, s *data.Stack) error {

// Quotation manipulation.

// length returns the length of the quotation on top of the stack without
// popping it.
// length pops a quotation or string and pushes its length.
func length(d *data.Dictionary, s *data.Stack) error {
val, err := s.Peek()
val, err := s.Pop()
if err != nil {
return err
}
Expand Down Expand Up @@ -458,11 +457,10 @@ func find(d *data.Dictionary, s *data.Stack) error {
if err != nil {
return err
}
str, err := s.PeekType(data.String)
str, err := s.PopType(data.String)
if err != nil {
return err
}
s.Push(substr)
s.Push(data.NewNumber(float64(strings.Index(str.Str, substr.Str))))
return nil
}
4 changes: 2 additions & 2 deletions interpret/basics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ var basicTestCases = []interpretTestCase{
[]string{`
{ -- Not tail recursive, could have bad performance?
"f" let
length "l" let
dup length "l" let
{
lop
f apply
{f each} length 0 = not then apply
{f each} dup length 0 = not then apply
} l 0 = not then apply
} "each" define
{1 2 3} {say} each
Expand Down
57 changes: 46 additions & 11 deletions interpret/prelude.naiveconcat
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
-- Not tail recursive, could have bad performance
{
"f" let
length "l" let
dup length "l" let
{
lop
f apply
{f each} length 0 = not then apply
{f each} dup length 0 = not then apply
} l 0 = not then apply
} "each" define

Expand All @@ -33,10 +33,10 @@
{
"f" let
"accumulator" let
length "l" let
dup length "l" let
{
lop "x" let
length "next_l" let
dup length "next_l" let
accumulator x f apply
{f reduce} {swap drop} next_l 0 = not if
} l 0 = not then apply
Expand All @@ -58,25 +58,60 @@
-- STRINGS


{ split swap drop } "trim_front" define
-- > "Foobar" 2 trim_front
-- ["obar"]

{ find 0 >= } "has_substring?" define
-- > "Brendan" "end" has_substring?
-- [ TRUE ]

{
find "index" let
"delimiter" let
"original" let
delimiter length "delimiter_length" let

{
original delimiter find "index" let
original index split -- split before the delimiter
delimiter length swap drop -- drop the delimiter
split swap drop
swap {} append append -- quote the two values
delimiter_length trim_front -- drop the delimiter
"second part" let
"first part" let
{} first_part append second_part append
}
{ original {} append }
index 0 >= if
{ {} original append }
original delimiter has_substring? if

} "split_on" define


{
"delimiter" let
"original" let
delimiter length "delimiter_length" let

{
original delimiter find "index" let
original index split -- split before the delimiter
delimiter_length trim_front -- drop the delimiter
"second part" let
"first part" let
{} first_part append
second_part
{ -- split_each the second part and concat the result
delimiter split_each concat
}
{ -- or just append the second part if no more splits necessary
append
}
second_part delimiter has_substring? if
}
{ {} original append }
original delimiter has_substring? if
} "split_each" define


-- CONCAT


{ swap {append} reduce } "concat" define
{ swap { append } reduce } "concat" define
10 changes: 5 additions & 5 deletions parse/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
)

const (
wordRunes = "abcdefghijjklmnopqrstuvwxyz+-*/=_><" // wordRunes are legal characters in a word name.
stringDelimiter rune = '"' // delimiter that opens or closes a string.
stringEscaper rune = '\\' // delimiter that escapes the following character in a string.
quotationOpener rune = '{' // delimiter that opens a quotation.
quotationCloser rune = '}' // delimiter that closes a quotation.
wordRunes = "abcdefghijjklmnopqrstuvwxyz+-*/=_><?" // wordRunes are legal characters in a word name.
stringDelimiter rune = '"' // delimiter that opens or closes a string.
stringEscaper rune = '\\' // delimiter that escapes the following character in a string.
quotationOpener rune = '{' // delimiter that opens a quotation.
quotationCloser rune = '}' // delimiter that closes a quotation.
)

// Lexer scans an input src and emits a stream of lexed tokens.
Expand Down

0 comments on commit 15684ba

Please sign in to comment.