Skip to content

Commit

Permalink
wdte: Update documentation. (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
DeedleFake committed Feb 20, 2020
1 parent d5eac1a commit 1d75089
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 38 deletions.
53 changes: 30 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ I had a number of design goals in mind when I started working on this project:
* Extremely simple. Entire grammar is less than 20-30 lines of specification.
* Grammar is LL(1) parseable.
* Functional-ish, but not particularly strict about it.
* Designed primarily for embedding. No command-line interpreter by default.
* Designed primarily for embedding.
* Extremely easy to use from the binding side. In this case, that's primarily Go.

If you want to try the language yourself, feel free to take a look at [the playground][playground]. It shows not only some of the features of the language in terms of actually writing code in it, but also how embeddable it is. The playground runs entirely in the browser *on the client's end* thanks to WebAssembly.
Expand All @@ -34,48 +34,54 @@ import (
"strings"

"github.com/DeedleFake/wdte"
"github.com/DeedleFake/wdte/wdteutil"
)

const src = `
let i => import 'some/import/path/or/another';
i.print 3;
+ 5 2 -> i.print;
7 -> + 5 -> i.print;
`

func im(from string) (*wdte.Scope, error) {
var print wdte.GoFunc
print = wdte.GoFunc(func(frame wdte.Frame, args ...wdte.Func) wdte.Func {
if len(args) < 1 {
return print
}

a := args[0].Call(frame)
fmt.Println(a)
return a
})

return wdte.S().Map(map[wdte.ID]wdte.Func{
"print": print,
"print": wdteutil.Func("print", func(v interface{}) interface{} {
fmt.Println(v)
return v
}),
}), nil
}

func Sum(frame wdte.Frame, args ...wdte.Func) wdte.Func {
frame = frame.Sub("+")

if len(args) < 2 {
return wdteutil.SaveArgs(wdte.GoFunc(Sum), args...)
}

var sum wdte.Number
for _, arg := range args {
sum += arg.(wdte.Number)
}
return sum
}

func main() {
m, err := wdte.Parse(strings.NewReader(src), wdte.ImportFunc(im))
m, err := wdte.Parse(strings.NewReader(src), wdte.ImportFunc(im), nil)
if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing module: %v\n", err)
fmt.Fprintf(os.Stderr, "Error parsing script: %v\n", err)
os.Exit(1)
}

scope := wdte.S().Sub("+", wdte.GoFunc(func(frame wdte.Frame, args ...wdte.Func) wdte.Func {
var sum wdte.Number
for _, arg := range args {
sum += arg.Call(frame).(wdte.Number)
}
return sum
}))
scope := wdte.S().Add("+", wdte.GoFunc(Sum))

m.Call(wdte.F().WithScope(scope))
r := m.Call(wdte.F().WithScope(scope))
if err, ok := r.(error); ok {
fmt.Fprintf(os.Stderr, "Error running script: %v\n", err)
os.Exit(1)
}
}
```

Expand All @@ -84,6 +90,7 @@ func main() {
```
3
7
12
```

Documentation
Expand Down
31 changes: 16 additions & 15 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@
// nature so with some practice.
//
// A chain is a series of expressions separated by either the chain
// operator, "->", or the ignored chain operator, "--". Each piece of
// the chain is executed in turn, and the output of the previous
// section is passed as an argument to the output of the current
// section. In other words, in the previous example, the chain's
// execution matches the following pseudocode
// operator, "->", the ignored chain operator, "--", or the error
// chain operator, "-|". Each piece of the chain is executed in turn,
// and the output of the previous section is passed as an argument to
// the output of the current section. In other words, in the previous
// example, the chain's execution matches the following pseudocode
// r1 = a.stream(array)
// r2 = s.flatMap(<lambda>)
// r1 = r2(r1)
Expand All @@ -85,6 +85,17 @@
// is ignored, meaning that it doesn't affect the remainder of the
// chain.
//
// The "-|" chain operator is used for error handling. During the
// evaluation of a chain, if no errors have occurred, chain segements
// using "-|" are ignored completely. Unlike with "--", they are
// completely not executed. If, however, an error occurs, all chain
// segments that don't use "-|" are ignored instead. If a "-|" segment
// exists in the chain after the location that the error occurred,
// then that segment is executed next, following which normal
// execution continues, unless that segment itself returned an error.
// If no "-|" segment exists, the error is returned from the entire
// chain.
//
// Chains can also have "slots" assigned to each piece. This is an
// identifier immediately following the expression of a piece of
// chain. This identifier is inserted into the scope for the remainder
Expand Down Expand Up @@ -202,14 +213,4 @@
// required, possibly at the cost of some runtime performance,
// functions for automatically wrapping Go functions are provided in
// the wdteutil package.
//
// One final note: WDTE is lazily-evaluated. Very, very
// lazily-evaluated. Until Go code manually calls a Func
// implementation, most WDTE code is never evaluated at all past the
// initial parsing. In some cases some code may get called more times
// than expected as well. Because of this, it is highly recommended
// that any Go code that is expected to be directly called by WDTE
// provide a purely functional interface, deterministically returning
// the same thing for the same arguments. If code does not follow this
// guideline, expect occasional odd behavior for seemingly no reason.
package wdte
57 changes: 57 additions & 0 deletions readme_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package wdte_test

import (
"fmt"
"os"
"strings"

"github.com/DeedleFake/wdte"
"github.com/DeedleFake/wdte/wdteutil"
)

const src = `
let i => import 'some/import/path/or/another';
i.print 3;
+ 5 2 -> i.print;
7 -> + 5 -> i.print;
`

func im(from string) (*wdte.Scope, error) {
return wdte.S().Map(map[wdte.ID]wdte.Func{
"print": wdteutil.Func("print", func(v interface{}) interface{} {
fmt.Println(v)
return v
}),
}), nil
}

func Sum(frame wdte.Frame, args ...wdte.Func) wdte.Func {
frame = frame.Sub("+")

if len(args) < 2 {
return wdteutil.SaveArgs(wdte.GoFunc(Sum), args...)
}

var sum wdte.Number
for _, arg := range args {
sum += arg.(wdte.Number)
}
return sum
}

func ExampleREADME() {
m, err := wdte.Parse(strings.NewReader(src), wdte.ImportFunc(im), nil)
if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing script: %v\n", err)
os.Exit(1)
}

scope := wdte.S().Add("+", wdte.GoFunc(Sum))

r := m.Call(wdte.F().WithScope(scope))
if err, ok := r.(error); ok {
fmt.Fprintf(os.Stderr, "Error running script: %v\n", err)
os.Exit(1)
}
}

0 comments on commit 1d75089

Please sign in to comment.