Got basic demo working, ran go fmt
This commit is contained in:
parent
6257495fe4
commit
ebf57591a8
47
README.md
47
README.md
@ -1,37 +1,7 @@
|
||||
# Ginger
|
||||
|
||||
Fibonacci function in ginger:
|
||||
|
||||
```
|
||||
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;
|
||||
```
|
||||
A programming language utilizing a graph datastructure for syntax. Currently in
|
||||
super-early-alpha-don't-actually-use-this-for-anything 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
|
||||
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!
|
||||
|
||||
## 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
41
cmd/eval/main.go
Normal 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
19
examples/fib.gg
Normal 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;);
|
@ -291,7 +291,7 @@ func (d *decoder) parseValIn(into *Graph, toks []LexerToken) (*Graph, []LexerTok
|
||||
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
|
||||
|
||||
@ -309,6 +309,17 @@ func (d *decoder) decode(lexer Lexer) (*Graph, error) {
|
||||
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)
|
||||
|
||||
if err != nil {
|
||||
@ -326,3 +337,17 @@ func DecodeLexer(lexer Lexer) (*Graph, error) {
|
||||
decoder := &decoder{}
|
||||
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
|
||||
}
|
||||
|
@ -284,7 +284,6 @@ outer:
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func mapReduce[Ea, Va Value, Vb any](
|
||||
root *OpenEdge[Ea, Va],
|
||||
mapVal func(Va) (Vb, error),
|
||||
|
@ -1,8 +1,8 @@
|
||||
package graph
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
|
1
vm/op.go
1
vm/op.go
@ -44,7 +44,6 @@ func evalThunks(args []Thunk) Thunk {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
// internal processing on those arguments and return a resultant Value.
|
||||
|
@ -74,5 +74,4 @@ var GlobalScope = ScopeMap{
|
||||
"recur": Value{Operation: OperationFunc(func(args []Thunk, op Operation) (Thunk, error) {
|
||||
return op.Perform(args, op)
|
||||
})},
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user