Switching to wsl
Some checks failed
Build / build (push) Successful in 10m47s
Publish Image / publish (push) Failing after 30s
Test / build (push) Successful in 11m0s

This commit is contained in:
Charles Smith
2024-03-31 19:35:04 -04:00
parent 7a32cce8a1
commit a85dc73954
15 changed files with 91 additions and 85 deletions

View File

@@ -42,7 +42,7 @@ signs:
- artifacts: checksum
release:
gitea:
owner: unflavoredmeson
owner: UnflavoredMeson
name: monkey
gitea_urls:
api: https://gitea.unflavoredmeson.com/api/v1/

7
Benchmark.md Normal file
View 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 |

View File

@@ -7,14 +7,14 @@ VERSION ?= $(shell git describe 2>/dev/null || echo "")
DESTDIR ?= $(GOBIN)
ifeq ($(LOCAL), 1)
IMAGE := r.mills.io/prologic/monkey
IMAGE := r.unflavoredmeson.com/UnflavoredMeson/monkey
TAG := dev
else
ifeq ($(BRANCH), master)
IMAGE := prologic/monkey
IMAGE := UnflavoredMeson/monkey
TAG := latest
else
IMAGE := prologic/monkey
IMAGE := UnflavoredMeson/monkey
TAG := dev
endif
endif
@@ -33,14 +33,14 @@ build: clean cli server ## Build monkey
cli: ## Build monkey CLI
@go build \
-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: ## Build Monkey server
@go build \
-tags "netgo static_build" -installsuffix netgo \
-ldflags "-w -X go.mills.io/monkey/v2.MonkeyVersion=$(VERSION)" \
./cmd/monkey-server/...
-ldflags "-w -X go.unflavoredmeson.com/monkey/v2.MonkeyVersion=$(VERSION)" \
./cmd/monkey/...
install: cli server ## Install monkey to $DESTDIR
@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 ./...
compare: ## Run benchmarks comparing Monkey with other languages
@hyperfine -w 5 -p 'make build; gcc -o examples/fib examples/fib.c' \
-n c -n go -n tengo -n python -n tauc -n taugo -n monkey \
@hyperfine -w 3 -p 'make build; gcc -o examples/fib examples/fib.c' \
-n c -n go -n tengo -n python -n monkey \
--sort mean-time --export-markdown Benchmark.md \
'./examples/fib' \
'go run examples/fib.go' \
'tengo examples/fib.tengo' \
'python3 examples/fib.py' \
'tauc examples/fib.tau' \
'taugo examples/fib.tau' \
'./monkey examples/fib.m'
'./monkey examples/fib.monkey'
bench: # Run test benchmarks
@go test -v -benchmem -bench=. ./...

1
go.sum
View File

@@ -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.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
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=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=

View File

@@ -17,13 +17,13 @@ func Accept(args ...object.Object) object.Object {
}
var (
nfd syscall.Handle
nfd int
err error
)
fd := int(args[0].(*object.Integer).Value)
nfd, _, err = syscall.Accept(syscall.Handle(fd))
nfd, _, err = syscall.Accept(fd)
if err != nil {
return newError("SocketError: %s", err)
}

View File

@@ -24,7 +24,7 @@ func Bind(args ...object.Object) object.Object {
fd := int(args[0].(*object.Integer).Value)
address := args[1].(*object.String).Value
sockaddr, err = syscall.Getsockname(syscall.Handle(fd))
sockaddr, err = syscall.Getsockname(fd)
if err != nil {
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)
}
err = syscall.Bind(syscall.Handle(fd), sockaddr)
err = syscall.Bind(fd, sockaddr)
if err != nil {
return newError("SocketError: %s", err)
}

View File

@@ -18,7 +18,7 @@ func Close(args ...object.Object) object.Object {
fd := int(args[0].(*object.Integer).Value)
err := syscall.Close(syscall.Handle(fd))
err := syscall.Close(fd)
if err != nil {
return newError("IOError: %s", err)
}

View File

@@ -21,7 +21,7 @@ func Connect(args ...object.Object) object.Object {
fd := int(args[0].(*object.Integer).Value)
address := args[1].(*object.String).Value
sockaddr, err := syscall.Getsockname(syscall.Handle(fd))
sockaddr, err := syscall.Getsockname(fd)
if err != nil {
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)
}
if err = syscall.Connect(syscall.Handle(fd), sa); err != nil {
if err = syscall.Connect(fd, sa); err != nil {
return newError("SocketError: %s", err)
}

View File

@@ -19,7 +19,7 @@ func Listen(args ...object.Object) object.Object {
fd := int(args[0].(*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)
}

View File

@@ -31,7 +31,7 @@ func Read(args ...object.Object) object.Object {
}
buf := make([]byte, n)
n, err := syscall.Read(syscall.Handle(fd), buf)
n, err := syscall.Read(fd, buf)
if err != nil {
return newError("IOError: %s", err)
}

View File

@@ -28,7 +28,7 @@ func Seek(args ...object.Object) object.Object {
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 {
return newError("IOError: %s", err)
}

View File

@@ -19,7 +19,7 @@ func Write(args ...object.Object) object.Object {
fd := int(args[0].(*object.Integer).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 {
return newError("IOError: %s", err)
}

View File

@@ -11,7 +11,7 @@ type BinaryOpError struct {
}
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

View File

@@ -3,14 +3,21 @@
package main
import (
"monkey/internal/compiler"
"monkey/internal/parser"
"monkey/internal/vm"
"flag"
"fmt"
"log"
"os"
"runtime"
"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) {
if (n < 2) {
return n
@@ -18,44 +25,64 @@ fib := fn(n) {
return fib(n-1) + fib(n-2)
}
print(fib(35))`
print(fib(%d))`
func check(err error) {
func checkErr(err error) {
if err != nil {
panic(err)
}
}
func code(path string) string {
func readFile(path string) string {
b, err := os.ReadFile(path)
check(err)
checkErr(err)
return string(b)
}
func fileOrDefault() string {
if len(os.Args) > 1 {
return code(os.Args[1])
if flag.NArg() > 0 {
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() {
n := flag.Int("n", 35, "Set n for fib(n) [Default: 35]")
flag.Parse()
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()
if strings.Count(code, "%d") > 0 {
code = fmt.Sprintf(code, *n)
}
log.Printf("Code:\n%s\n", code)
tree, errs := parser.Parse("<profiler>", code)
if len(errs) > 0 {
for _, err := range errs {
log.Println(err)
}
panic("parser errors")
}
c := compiler.New()
c.SetFileInfo("<profiler>", code)
check(c.Compile(tree))
check(pprof.StartCPUProfile(cpuf))
checkErr(c.Compile(tree))
checkErr(pprof.StartCPUProfile(cpuf))
defer pprof.StopCPUProfile()
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")
}

View File

@@ -1,52 +1,25 @@
" Vim Syntax File
" Language: monkey
" Creator: James Mills, prologic at shortcircuit dot net dot au
" Last Change: 31st January 2019
#!/bin/sh
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
# Get the highest tag number
VERSION="$(git describe --abbrev=0 --tags)"
VERSION=${VERSION:-'0.0.0'}
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
syntax keyword xFunction bool int str typeof args lower upper join split find
syntax keyword xFunction read write
if [ "${TAG}" = "" ]; then
TAG="${MAJOR}.${MINOR}.${PATCH}"
fi
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 match xOperator "\v\|\|"
echo "Releasing ${TAG} ..."
syntax region xString start=/"/ skip=/\\./ end=/"/
syntax region xComment start='#' end='$' keepend
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"
git tag -a -s -m "Release ${TAG}" "${TAG}"
git push --tags
goreleaser release --rm-dist