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
|
# 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
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
|
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
|
||||||
|
}
|
||||||
|
@ -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),
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package graph
|
package graph
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"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
|
// 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.
|
||||||
|
@ -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)
|
||||||
})},
|
})},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user