Got basic demo working, ran go fmt

This commit is contained in:
Brian Picciano 2021-12-30 15:29:38 -07:00
parent 6257495fe4
commit ebf57591a8
11 changed files with 131 additions and 66 deletions

View File

@ -1,37 +1,7 @@
# Ginger # Ginger
Fibonacci function in ginger: A programming language utilizing a graph datastructure for syntax. Currently in
super-early-alpha-don't-actually-use-this-for-anything development.
```
fib = {
decr = { out = add < (in; -1;); };
out = {
n = tupEl < (in; 0;);
a = tupEl < (in; 1;);
b = tupEl < (in; 2;);
out = if < (
zero? < n;
a;
recur < (
decr < n;
b;
add < (a;b;);
);
);
} < (in; 0; 1;);
};
```
Usage of the function to generate the 6th fibonnaci number:
```
fib < 5;
```
## Development ## Development
@ -48,3 +18,16 @@ from the repo root and you will be dropped into a shell with all dependencies
(including the correct go version) in your PATH, ready to use. This could (including the correct go version) in your PATH, ready to use. This could
probably be expanded to other OSs/architectures easily, if you care to do so probably be expanded to other OSs/architectures easily, if you care to do so
please check out the `default.nix` file and submit a PR! please check out the `default.nix` file and submit a PR!
## Demo
An example program which computes the Nth fibonacci number can be found at
`examples/fib.gg`. You can try it out by doing:
```
go run ./cmd/eval/main.go "$(cat examples/fib.gg)" 5
```
Where you can replace `5` with any number. The vm has only been given enough
capability to run this program as a demo, and is extremely poorly optimized (as
will be evident if you input any large number). Further work is obviously TODO.

41
cmd/eval/main.go Normal file
View File

@ -0,0 +1,41 @@
package main
import (
"bytes"
"fmt"
"os"
"github.com/mediocregopher/ginger/gg"
"github.com/mediocregopher/ginger/vm"
)
func main() {
if len(os.Args) < 3 {
fmt.Printf(`Usage: %s <operation source> "in = <value>"\n`, os.Args[0])
return
}
opSrc := os.Args[1]
inSrc := os.Args[2]
inVal, err := gg.DecodeSingleValueFromLexer(
gg.NewLexer(bytes.NewBufferString(inSrc + ";")),
)
if err != nil {
panic(fmt.Sprintf("decoding input: %v", err))
}
res, err := vm.EvaluateSource(
bytes.NewBufferString(opSrc),
inVal,
vm.GlobalScope,
)
if err != nil {
panic(fmt.Sprintf("evaluating: %v", err))
}
fmt.Println(res)
}

19
examples/fib.gg Normal file
View File

@ -0,0 +1,19 @@
out = {
decr = { out = add < (in; -1;); };
n = tupEl < (in; 0;);
a = tupEl < (in; 1;);
b = tupEl < (in; 2;);
out = if < (
isZero < n;
a;
recur < (
decr < n;
b;
add < (a;b;);
);
);
} < (in; 0; 1;);

View File

@ -291,7 +291,7 @@ func (d *decoder) parseValIn(into *Graph, toks []LexerToken) (*Graph, []LexerTok
return into.AddValueIn(dstVal, oe), toks, nil return into.AddValueIn(dstVal, oe), toks, nil
} }
func (d *decoder) decode(lexer Lexer) (*Graph, error) { func (d *decoder) readAllTokens(lexer Lexer) ([]LexerToken, error) {
var toks []LexerToken var toks []LexerToken
@ -309,6 +309,17 @@ func (d *decoder) decode(lexer Lexer) (*Graph, error) {
toks = append(toks, tok) toks = append(toks, tok)
} }
return toks, nil
}
func (d *decoder) decode(lexer Lexer) (*Graph, error) {
toks, err := d.readAllTokens(lexer)
if err != nil {
return nil, err
}
val, _, _, err := d.parseGraphValue(toks, false) val, _, _, err := d.parseGraphValue(toks, false)
if err != nil { if err != nil {
@ -326,3 +337,17 @@ func DecodeLexer(lexer Lexer) (*Graph, error) {
decoder := &decoder{} decoder := &decoder{}
return decoder.decode(lexer) return decoder.decode(lexer)
} }
func DecodeSingleValueFromLexer(lexer Lexer) (Value, error) {
decoder := &decoder{}
toks, err := decoder.readAllTokens(lexer)
if err != nil {
return ZeroValue, err
}
val, _, _, err := decoder.parseSingleValue(toks)
return val, err
}

View File

@ -284,7 +284,6 @@ outer:
return true return true
} }
func mapReduce[Ea, Va Value, Vb any]( func mapReduce[Ea, Va Value, Vb any](
root *OpenEdge[Ea, Va], root *OpenEdge[Ea, Va],
mapVal func(Va) (Vb, error), mapVal func(Va) (Vb, error),

View File

@ -1,8 +1,8 @@
package graph package graph
import ( import (
"fmt"
"errors" "errors"
"fmt"
"strconv" "strconv"
"testing" "testing"

View File

@ -44,7 +44,6 @@ func evalThunks(args []Thunk) Thunk {
} }
} }
// Operation is an entity which can accept one or more arguments (each not // Operation is an entity which can accept one or more arguments (each not
// having been evaluated yet) and return a Thunk which will perform some // having been evaluated yet) and return a Thunk which will perform some
// internal processing on those arguments and return a resultant Value. // internal processing on those arguments and return a resultant Value.

View File

@ -74,5 +74,4 @@ var GlobalScope = ScopeMap{
"recur": Value{Operation: OperationFunc(func(args []Thunk, op Operation) (Thunk, error) { "recur": Value{Operation: OperationFunc(func(args []Thunk, op Operation) (Thunk, error) {
return op.Perform(args, op) return op.Perform(args, op)
})}, })},
} }

View File

@ -2,8 +2,8 @@
package vm package vm
import ( import (
"io"
"fmt" "fmt"
"io"
"strings" "strings"
"github.com/mediocregopher/ginger/gg" "github.com/mediocregopher/ginger/gg"