Switching to wsl
This commit is contained in:
@@ -42,7 +42,7 @@ signs:
|
|||||||
- artifacts: checksum
|
- artifacts: checksum
|
||||||
release:
|
release:
|
||||||
gitea:
|
gitea:
|
||||||
owner: unflavoredmeson
|
owner: UnflavoredMeson
|
||||||
name: monkey
|
name: monkey
|
||||||
gitea_urls:
|
gitea_urls:
|
||||||
api: https://gitea.unflavoredmeson.com/api/v1/
|
api: https://gitea.unflavoredmeson.com/api/v1/
|
||||||
7
Benchmark.md
Normal file
7
Benchmark.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|
||||||
|
|:---|---:|---:|---:|---:|
|
||||||
|
| `c` | 36.7 ± 0.6 | 36.0 | 37.8 | 1.00 |
|
||||||
|
| `go` | 230.2 ± 14.0 | 206.2 | 252.9 | 6.28 ± 0.40 |
|
||||||
|
| `python` | 1366.9 ± 30.8 | 1330.9 | 1411.3 | 37.27 ± 1.06 |
|
||||||
|
| `tengo` | 1704.3 ± 16.0 | 1687.2 | 1739.3 | 46.47 ± 0.91 |
|
||||||
|
| `monkey` | 3347.6 ± 22.3 | 3314.0 | 3396.0 | 91.27 ± 1.69 |
|
||||||
20
Makefile
20
Makefile
@@ -7,14 +7,14 @@ VERSION ?= $(shell git describe 2>/dev/null || echo "")
|
|||||||
DESTDIR ?= $(GOBIN)
|
DESTDIR ?= $(GOBIN)
|
||||||
|
|
||||||
ifeq ($(LOCAL), 1)
|
ifeq ($(LOCAL), 1)
|
||||||
IMAGE := r.mills.io/prologic/monkey
|
IMAGE := r.unflavoredmeson.com/UnflavoredMeson/monkey
|
||||||
TAG := dev
|
TAG := dev
|
||||||
else
|
else
|
||||||
ifeq ($(BRANCH), master)
|
ifeq ($(BRANCH), master)
|
||||||
IMAGE := prologic/monkey
|
IMAGE := UnflavoredMeson/monkey
|
||||||
TAG := latest
|
TAG := latest
|
||||||
else
|
else
|
||||||
IMAGE := prologic/monkey
|
IMAGE := UnflavoredMeson/monkey
|
||||||
TAG := dev
|
TAG := dev
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@@ -33,14 +33,14 @@ build: clean cli server ## Build monkey
|
|||||||
cli: ## Build monkey CLI
|
cli: ## Build monkey CLI
|
||||||
@go build \
|
@go build \
|
||||||
-tags "netgo static_build" -installsuffix netgo \
|
-tags "netgo static_build" -installsuffix netgo \
|
||||||
-ldflags "-w -X go.mills.io/monkey/v2.MonkeyVersion=$(VERSION)" \
|
-ldflags "-w -X go.unflavoredmeson.com/monkey/v2.MonkeyVersion=$(VERSION)" \
|
||||||
./cmd/monkey/...
|
./cmd/monkey/...
|
||||||
|
|
||||||
server: ## Build Monkey server
|
server: ## Build Monkey server
|
||||||
@go build \
|
@go build \
|
||||||
-tags "netgo static_build" -installsuffix netgo \
|
-tags "netgo static_build" -installsuffix netgo \
|
||||||
-ldflags "-w -X go.mills.io/monkey/v2.MonkeyVersion=$(VERSION)" \
|
-ldflags "-w -X go.unflavoredmeson.com/monkey/v2.MonkeyVersion=$(VERSION)" \
|
||||||
./cmd/monkey-server/...
|
./cmd/monkey/...
|
||||||
|
|
||||||
install: cli server ## Install monkey to $DESTDIR
|
install: cli server ## Install monkey to $DESTDIR
|
||||||
@install -D -m 755 monkey $(DESTDIR)/monkey
|
@install -D -m 755 monkey $(DESTDIR)/monkey
|
||||||
@@ -66,16 +66,14 @@ profile: ## Run tests with profiling enabled
|
|||||||
@go test -cpuprofile cpu.prof -memprofile mem.prof -v -bench ./...
|
@go test -cpuprofile cpu.prof -memprofile mem.prof -v -bench ./...
|
||||||
|
|
||||||
compare: ## Run benchmarks comparing Monkey with other languages
|
compare: ## Run benchmarks comparing Monkey with other languages
|
||||||
@hyperfine -w 5 -p 'make build; gcc -o examples/fib examples/fib.c' \
|
@hyperfine -w 3 -p 'make build; gcc -o examples/fib examples/fib.c' \
|
||||||
-n c -n go -n tengo -n python -n tauc -n taugo -n monkey \
|
-n c -n go -n tengo -n python -n monkey \
|
||||||
--sort mean-time --export-markdown Benchmark.md \
|
--sort mean-time --export-markdown Benchmark.md \
|
||||||
'./examples/fib' \
|
'./examples/fib' \
|
||||||
'go run examples/fib.go' \
|
'go run examples/fib.go' \
|
||||||
'tengo examples/fib.tengo' \
|
'tengo examples/fib.tengo' \
|
||||||
'python3 examples/fib.py' \
|
'python3 examples/fib.py' \
|
||||||
'tauc examples/fib.tau' \
|
'./monkey examples/fib.monkey'
|
||||||
'taugo examples/fib.tau' \
|
|
||||||
'./monkey examples/fib.m'
|
|
||||||
|
|
||||||
bench: # Run test benchmarks
|
bench: # Run test benchmarks
|
||||||
@go test -v -benchmem -bench=. ./...
|
@go test -v -benchmem -bench=. ./...
|
||||||
|
|||||||
1
go.sum
1
go.sum
@@ -17,6 +17,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tebeka/atexit v0.3.0 h1:jleL99H7Ywt80oJKR+VWmJNnezcCOG0CuzcN3CIpsdI=
|
||||||
github.com/tebeka/atexit v0.3.0/go.mod h1:WJmSUSmMT7WoR7etUOaGBVXk+f5/ZJ+67qwuedq7Fbs=
|
github.com/tebeka/atexit v0.3.0/go.mod h1:WJmSUSmMT7WoR7etUOaGBVXk+f5/ZJ+67qwuedq7Fbs=
|
||||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ func Accept(args ...object.Object) object.Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
nfd syscall.Handle
|
nfd int
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
fd := int(args[0].(*object.Integer).Value)
|
fd := int(args[0].(*object.Integer).Value)
|
||||||
|
|
||||||
nfd, _, err = syscall.Accept(syscall.Handle(fd))
|
nfd, _, err = syscall.Accept(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("SocketError: %s", err)
|
return newError("SocketError: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func Bind(args ...object.Object) object.Object {
|
|||||||
fd := int(args[0].(*object.Integer).Value)
|
fd := int(args[0].(*object.Integer).Value)
|
||||||
address := args[1].(*object.String).Value
|
address := args[1].(*object.String).Value
|
||||||
|
|
||||||
sockaddr, err = syscall.Getsockname(syscall.Handle(fd))
|
sockaddr, err = syscall.Getsockname(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("ValueError: %s", err)
|
return newError("ValueError: %s", err)
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ func Bind(args ...object.Object) object.Object {
|
|||||||
return newError("ValueError: Invalid socket type %T for bind '%s'", sockaddr, address)
|
return newError("ValueError: Invalid socket type %T for bind '%s'", sockaddr, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = syscall.Bind(syscall.Handle(fd), sockaddr)
|
err = syscall.Bind(fd, sockaddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("SocketError: %s", err)
|
return newError("SocketError: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func Close(args ...object.Object) object.Object {
|
|||||||
|
|
||||||
fd := int(args[0].(*object.Integer).Value)
|
fd := int(args[0].(*object.Integer).Value)
|
||||||
|
|
||||||
err := syscall.Close(syscall.Handle(fd))
|
err := syscall.Close(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("IOError: %s", err)
|
return newError("IOError: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func Connect(args ...object.Object) object.Object {
|
|||||||
fd := int(args[0].(*object.Integer).Value)
|
fd := int(args[0].(*object.Integer).Value)
|
||||||
address := args[1].(*object.String).Value
|
address := args[1].(*object.String).Value
|
||||||
|
|
||||||
sockaddr, err := syscall.Getsockname(syscall.Handle(fd))
|
sockaddr, err := syscall.Getsockname(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("ValueError: %s", err)
|
return newError("ValueError: %s", err)
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ func Connect(args ...object.Object) object.Object {
|
|||||||
return newError("ValueError: Invalid socket type %T for bind '%s'", sockaddr, address)
|
return newError("ValueError: Invalid socket type %T for bind '%s'", sockaddr, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = syscall.Connect(syscall.Handle(fd), sa); err != nil {
|
if err = syscall.Connect(fd, sa); err != nil {
|
||||||
return newError("SocketError: %s", err)
|
return newError("SocketError: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func Listen(args ...object.Object) object.Object {
|
|||||||
fd := int(args[0].(*object.Integer).Value)
|
fd := int(args[0].(*object.Integer).Value)
|
||||||
backlog := int(args[1].(*object.Integer).Value)
|
backlog := int(args[1].(*object.Integer).Value)
|
||||||
|
|
||||||
if err := syscall.Listen(syscall.Handle(fd), backlog); err != nil {
|
if err := syscall.Listen(fd, backlog); err != nil {
|
||||||
return newError("SocketError: %s", err)
|
return newError("SocketError: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func Read(args ...object.Object) object.Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf := make([]byte, n)
|
buf := make([]byte, n)
|
||||||
n, err := syscall.Read(syscall.Handle(fd), buf)
|
n, err := syscall.Read(fd, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("IOError: %s", err)
|
return newError("IOError: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func Seek(args ...object.Object) object.Object {
|
|||||||
whence = int(args[2].(*object.Integer).Value)
|
whence = int(args[2].(*object.Integer).Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
offset, err := syscall.Seek(syscall.Handle(fd), offset, whence)
|
offset, err := syscall.Seek(fd, offset, whence)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("IOError: %s", err)
|
return newError("IOError: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func Write(args ...object.Object) object.Object {
|
|||||||
fd := int(args[0].(*object.Integer).Value)
|
fd := int(args[0].(*object.Integer).Value)
|
||||||
data := []byte(args[1].(*object.String).Value)
|
data := []byte(args[1].(*object.String).Value)
|
||||||
|
|
||||||
n, err := syscall.Write(syscall.Handle(fd), data)
|
n, err := syscall.Write(fd, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("IOError: %s", err)
|
return newError("IOError: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ type BinaryOpError struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e BinaryOpError) Error() string {
|
func (e BinaryOpError) Error() string {
|
||||||
return fmt.Sprintf("unsupported types for binary operation: %s %s %s", e.left.Type(), e.op, e.right.Type())
|
return fmt.Sprintf("unsupported types for binary operation: %s %s %s %s %s", e.left.Type(), e.left.Inspect(), e.op, e.right.Type(), e.right.Inspect())
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBinaryOpError returns a new BinaryOpError
|
// NewBinaryOpError returns a new BinaryOpError
|
||||||
|
|||||||
59
profile.go
59
profile.go
@@ -3,14 +3,21 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"monkey/internal/compiler"
|
"flag"
|
||||||
"monkey/internal/parser"
|
"fmt"
|
||||||
"monkey/internal/vm"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.mills.io/prologic/monkey-lang/internal/compiler"
|
||||||
|
"git.mills.io/prologic/monkey-lang/internal/object"
|
||||||
|
"git.mills.io/prologic/monkey-lang/internal/parser"
|
||||||
|
"git.mills.io/prologic/monkey-lang/internal/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
const fib = `
|
const defaultCode = `
|
||||||
fib := fn(n) {
|
fib := fn(n) {
|
||||||
if (n < 2) {
|
if (n < 2) {
|
||||||
return n
|
return n
|
||||||
@@ -18,44 +25,64 @@ fib := fn(n) {
|
|||||||
return fib(n-1) + fib(n-2)
|
return fib(n-1) + fib(n-2)
|
||||||
}
|
}
|
||||||
|
|
||||||
print(fib(35))`
|
print(fib(%d))`
|
||||||
|
|
||||||
func check(err error) {
|
func checkErr(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func code(path string) string {
|
func readFile(path string) string {
|
||||||
b, err := os.ReadFile(path)
|
b, err := os.ReadFile(path)
|
||||||
check(err)
|
checkErr(err)
|
||||||
|
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fileOrDefault() string {
|
func fileOrDefault() string {
|
||||||
if len(os.Args) > 1 {
|
if flag.NArg() > 0 {
|
||||||
return code(os.Args[1])
|
log.Printf("Using %s as program input...", flag.Arg(0))
|
||||||
|
object.Args = flag.Args()[1:]
|
||||||
|
return readFile(flag.Arg(0))
|
||||||
}
|
}
|
||||||
return fib
|
return defaultCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
n := flag.Int("n", 35, "Set n for fib(n) [Default: 35]")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
cpuf, err := os.Create("cpu.prof")
|
cpuf, err := os.Create("cpu.prof")
|
||||||
check(err)
|
checkErr(err)
|
||||||
|
|
||||||
|
heapf, err := os.Create("heap.prof")
|
||||||
|
checkErr(err)
|
||||||
|
|
||||||
|
log.Printf("Using %d as n", *n)
|
||||||
|
|
||||||
code := fileOrDefault()
|
code := fileOrDefault()
|
||||||
|
if strings.Count(code, "%d") > 0 {
|
||||||
|
code = fmt.Sprintf(code, *n)
|
||||||
|
}
|
||||||
|
log.Printf("Code:\n%s\n", code)
|
||||||
tree, errs := parser.Parse("<profiler>", code)
|
tree, errs := parser.Parse("<profiler>", code)
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
|
for _, err := range errs {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
panic("parser errors")
|
panic("parser errors")
|
||||||
}
|
}
|
||||||
|
|
||||||
c := compiler.New()
|
c := compiler.New()
|
||||||
c.SetFileInfo("<profiler>", code)
|
c.SetFileInfo("<profiler>", code)
|
||||||
check(c.Compile(tree))
|
checkErr(c.Compile(tree))
|
||||||
|
checkErr(pprof.StartCPUProfile(cpuf))
|
||||||
check(pprof.StartCPUProfile(cpuf))
|
|
||||||
defer pprof.StopCPUProfile()
|
defer pprof.StopCPUProfile()
|
||||||
mvm := vm.New("<profiler>", c.Bytecode())
|
mvm := vm.New("<profiler>", c.Bytecode())
|
||||||
mvm.Run()
|
checkErr(mvm.Run())
|
||||||
|
runtime.GC()
|
||||||
|
checkErr(pprof.WriteHeapProfile(heapf))
|
||||||
|
log.Println("CPU Profile written to cpu.prof")
|
||||||
|
log.Println("Heap Profile written to heap.prof")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,25 @@
|
|||||||
" Vim Syntax File
|
#!/bin/sh
|
||||||
" Language: monkey
|
|
||||||
" Creator: James Mills, prologic at shortcircuit dot net dot au
|
|
||||||
" Last Change: 31st January 2019
|
|
||||||
|
|
||||||
if version < 600
|
# Get the highest tag number
|
||||||
syntax clear
|
VERSION="$(git describe --abbrev=0 --tags)"
|
||||||
elseif exists("b:current_syntax")
|
VERSION=${VERSION:-'0.0.0'}
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
syntax case match
|
# Get number parts
|
||||||
|
MAJOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
|
||||||
|
MINOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
|
||||||
|
PATCH="${VERSION%%.*}"; VERSION="${VERSION#*.}"
|
||||||
|
|
||||||
syntax keyword xType true false null int str bool array hash
|
# Increase version
|
||||||
|
PATCH=$((PATCH+1))
|
||||||
|
|
||||||
syntax keyword xKeyword fn if else return while
|
TAG="${1}"
|
||||||
|
|
||||||
syntax keyword xFunction len input print first last rest push pop exit assert
|
if [ "${TAG}" = "" ]; then
|
||||||
syntax keyword xFunction bool int str typeof args lower upper join split find
|
TAG="${MAJOR}.${MINOR}.${PATCH}"
|
||||||
syntax keyword xFunction read write
|
fi
|
||||||
|
|
||||||
syntax match xOperator "\v\=\="
|
echo "Releasing ${TAG} ..."
|
||||||
syntax match xOperator "\v!\="
|
|
||||||
syntax match xOperator "\v<"
|
|
||||||
syntax match xOperator "\v>"
|
|
||||||
syntax match xOperator "\v!"
|
|
||||||
syntax match xOperator "\v\+"
|
|
||||||
syntax match xOperator "\v-"
|
|
||||||
syntax match xOperator "\v\*"
|
|
||||||
syntax match xOperator "\v/"
|
|
||||||
syntax match xOperator "\v:\="
|
|
||||||
syntax match xOperator "\v\="
|
|
||||||
syntax match xOperator "\v&"
|
|
||||||
syntax match xOperator "\v\|"
|
|
||||||
syntax match xOperator "\v^"
|
|
||||||
syntax match xOperator "\v\~"
|
|
||||||
syntax match xOperator "\v&&"
|
|
||||||
syntax match xOperator "\v\|\|"
|
|
||||||
|
|
||||||
syntax region xString start=/"/ skip=/\\./ end=/"/
|
git tag -a -s -m "Release ${TAG}" "${TAG}"
|
||||||
|
git push --tags
|
||||||
syntax region xComment start='#' end='$' keepend
|
goreleaser release --rm-dist
|
||||||
syntax region xComment start='//' end='$' keepend
|
|
||||||
|
|
||||||
highlight link xType Type
|
|
||||||
highlight link xKeyword Keyword
|
|
||||||
highlight link xFunction Function
|
|
||||||
highlight link xString String
|
|
||||||
highlight link xComment Comment
|
|
||||||
highlight link xOperator Operator
|
|
||||||
|
|
||||||
let b:current_syntax = "monkey"
|
|
||||||
Reference in New Issue
Block a user