build changes
Some checks failed
Publish Image / publish (push) Waiting to run
Test / build (push) Waiting to run
Build / build (push) Has been cancelled

This commit is contained in:
Chuck Smith
2024-03-28 15:11:47 -04:00
parent fd8311b280
commit 138df71cc8
22 changed files with 392 additions and 99 deletions

22
.chglog/CHANGELOG.tpl.md Normal file
View File

@@ -0,0 +1,22 @@
{{ range .Versions }}
<a name="{{ .Tag.Name }}"></a>
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }})
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
* {{ .Subject }}
{{ end }}
{{ end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}

37
.chglog/config.yml Normal file
View File

@@ -0,0 +1,37 @@
---
style: Github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://go.unflavoredmeson.com/monkey
options:
commits:
filters:
Type:
- Add
- Fix
- Update
- Document
commit_groups:
title_maps:
Add: Features
Update: Updates
Fix: Bug Fixes
Document: Documentation
header:
pattern: "^((\\w+)\\s.*)$"
pattern_maps:
- Subject
- Type
refs:
actions:
- Closes
- Fixes
reverts:
pattern: "^Revert \"([\\s\\S]*)\"$"
pattern_maps:
- Header
notes:
keywords:
- NOTE
- BREAKING CHANGE

View File

@@ -0,0 +1,17 @@
#!/bin/sh
set -e
if [ "$(id -u)" -eq 0 ]; then
[ -n "${PUID}" ] && usermod -u "${PUID}" monkey
[ -n "${PGID}" ] && groupmod -g "${PGID}" monkey
fi
printf "Configuring application...\n"
if [ "$(id -u)" -eq 0 ]; then
printf "Switching UID=%s and GID=%s\n" "$(id -u monkey)" "$(id -g monkey)"
exec su-exec monkey:monkey "$@"
else
exec "$@"
fi

View File

@@ -1,22 +0,0 @@
kind: pipeline
name: default
steps:
- name: build
image: golang:latest
commands:
- go test -v -short -cover -coverprofile=coverage.txt ./...
- name: coverage
image: plugins/codecov
settings:
token:
from_secret: codecov-token
- name: notify
image: plugins/webhook
urls:
when:
status:
- success
- failure

View File

@@ -1,4 +1,3 @@
--- ---
name: Build name: Build

View File

@@ -0,0 +1,33 @@
---
name: Publish Image
on:
push:
branches: [master]
env:
REGISTRY: r.unflavoredmeson.com
IMAGE: prologic/monkey
TAG: latest
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: actions/setup-buildx@v2
- name: Login to Registry
uses: actions/docker-login@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASS }}
- name: Build and Push Image
uses: actions/docker-build-push@v4
with:
context: .
push: true
tags: ${{ env.REGISTRY}}/${{ env.IMAGE }}:${{ env.TAG }}

View File

@@ -1,24 +1,48 @@
---
builds: builds:
- flags: -tags "static_build" - id: monkey
ldflags: -w -X main.Version={{.Version}} -X main.Commit={{.Commit}} binary: monkey
main: ./cmd/monkey
flags: -tags "static_build"
ldflags: >-
-w
-X go.unflavoredmeson.com/monkey/v2.MonkeyVersion={{.Version}}
env: env:
- CGO_ENABLED=0 - CGO_ENABLED=0
sign: goos:
artifacts: checksum - darwin
archive: - freebsd
replacements: - linux
darwin: Darwin goarch:
linux: Linux - amd64
windows: Windows - arm64
386: i386 goarm:
amd64: x86_64 - 6
checksum: - 7
name_template: 'checksums.txt' - id: monkey-server
snapshot: binary: monkey-server
name_template: "{{ .Tag }}-next" main: ./cmd/monkey-server
changelog: flags: -tags "static_build"
sort: asc ldflags: >-
filters: -w
exclude: -X go.unflavoredmeson.com/monkey/v2.MonkeyVersion={{.Version}}
- '^docs:' env:
- '^test:' - CGO_ENABLED=0
goos:
- darwin
- freebsd
- linux
goarch:
- amd64
- arm64
goarm:
- 6
- 7
signs:
- artifacts: checksum
release:
gitea:
owner: unflavoredmeson
name: monkey
gitea_urls:
api: https://gitea.unflavoredmeson.com/api/v1/

77
Dockerfile Normal file
View File

@@ -0,0 +1,77 @@
# Build
FROM golang:alpine AS build
RUN apk add --no-cache -U make
RUN mkdir -p /src
WORKDIR /src
# Copy Makefile
COPY Makefile ./
# Copy go.mod and go.sum and install and cache dependencies
COPY go.mod .
COPY go.sum .
# Copy static assets
COPY ./internal/server/static/ace/* ./internal/server/static/ace/
COPY ./internal/server/static/* ./internal/server/static/
# Copy sources
COPY *.go ./
COPY ./internal/ast/*.go ./internal/ast/
COPY ./internal/builtins/*.go ./internal/builtins/
COPY ./internal/code/*.go ./internal/code/
COPY ./internal/compiler/*.go ./internal/compiler/
COPY ./internal/context/*.go ./internal/context/
COPY ./internal/eval/*.go ./internal/eval/
COPY ./internal/lexer/*.go ./internal/lexer/
COPY ./internal/object/*.go ./internal/object/
COPY ./internal/parser/*.go ./internal/parser/
COPY ./internal/server/*.go ./internal/server/
COPY ./internal/token/*.go ./internal/token/
COPY ./internal/typing/*.go ./internal/typing/
COPY ./internal/utils/*.go ./internal/utils/
COPY ./internal/vm/*.go ./internal/vm/
COPY ./cmd/monkey/*.go ./cmd/monkey/
COPY ./cmd/monkey-server/*.go ./cmd/monkey-server/
# Version (there there is no .git in Docker build context)
# NOTE: This is fairly low down in the Dockerfile instructions so
# we don't break the Docker build cache just by changing
# unrelated files that actually haven't changed but caused the
# VERSION value to change.
ARG VERSION="0.0.0"
# Build cli and server binaries
RUN make build VERSION=$VERSION
# Runtime
FROM alpine:latest
RUN apk --no-cache -U add su-exec shadow ca-certificates tzdata
ENV PUID=1000
ENV PGID=1000
RUN addgroup -g "${PGID}" monkey && \
adduser -D -H -G monkey -h /var/empty -u "${PUID}" monkey && \
mkdir -p /data && chown -R monkey:monkey /data
VOLUME /data
WORKDIR /
# force cgo resolver
ENV GODEBUG=netdns=cgo
COPY --from=build /src/monkey /usr/local/bin/monkey
COPY --from=build /src/monkey-server /usr/local/bin/monkey-server
COPY .dockerfiles/entrypoint.sh /init
ENTRYPOINT ["/init"]
CMD ["monkey"]

View File

@@ -1,36 +1,93 @@
.PHONY: dev build install image release profile bench test clean .PHONY: dev build cli server install image release profile compare bench test clean
CGO_ENABLED=0 CGO_ENABLED=0
COMMIT=$(shell git rev-parse --short HEAD)
all: dev VERSION ?= $(shell git describe 2>/dev/null || echo "")
dev: build DESTDIR ?= $(GOBIN)
@./monkey-lang -d
build: clean ifeq ($(LOCAL), 1)
IMAGE := r.mills.io/prologic/monkey
TAG := dev
else
ifeq ($(BRANCH), master)
IMAGE := prologic/monkey
TAG := latest
else
IMAGE := prologic/monkey
TAG := dev
endif
endif
all: help
help: ## Show this help message
@echo "monkey - Monkey Lang"
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
dev: cli ## Build monkey and run the REPL
@./monkey
build: clean cli server ## Build monkey
cli: ## Build monkey CLI
@go build \ @go build \
-tags "netgo static_build" -installsuffix netgo \ -tags "netgo static_build" -installsuffix netgo \
-ldflags "-w -X $(shell go list)/version/.GitCommit=$(COMMIT)" \ -ldflags "-w -X go.mills.io/monkey/v2.MonkeyVersion=$(VERSION)" \
. ./cmd/monkey/...
install: build server: ## Build Monkey server
@go install @go build \
-tags "netgo static_build" -installsuffix netgo \
-ldflags "-w -X go.mills.io/monkey/v2.MonkeyVersion=$(VERSION)" \
./cmd/monkey-server/...
image: install: cli server ## Install monkey to $DESTDIR
@docker build -t prologic/monkey-lang . @install -D -m 755 monkey $(DESTDIR)/monkey
@install -D -m 755 monkey-server $(DESTDIR)monkey-server
release: ifeq ($(PUBLISH), 1)
image: ## Build and Publish the Docker image
@docker buildx build \
--build-arg VERSION="$(VERSION)" \
--build-arg COMMIT="$(COMMIT)" \
--build-arg BUILD="$(BUILD)" \
--platform linux/amd64,linux/arm64 --push -t $(IMAGE):$(TAG) .
else
image: ## Build the Docker image
@docker build \
--build-arg VERSION="$(VERSION)" -t $(IMAGE):$(TAG) .
endif
release: ## Release monkey
@./tools/release.sh @./tools/release.sh
profile: 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 ./...
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 \
--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'
bench: # Run test benchmarks
@go test -v -benchmem -bench=. ./... @go test -v -benchmem -bench=. ./...
test: test: ## Run unit tests
@go test -v -cover -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... -race ./... @go test -v \
-cover \
-coverprofile coverage.out \
-covermode atomic \
-coverpkg ./... \
-race \
./...
clean: clean: ## Cleanup untrakced files
@git clean -f -d -X @git clean -f -d -X 2> /dev/null || true

7
README.md Normal file
View File

@@ -0,0 +1,7 @@
# monkey-lang
Monkey programming language interpreter designed in [_Writing An Interpreter In Go_](https://interpreterbook.com/).
A step-by-step walk-through where each commit is a fully working part.
Read the book and follow along with the commit history.
## Table of Contents

View File

@@ -18,7 +18,7 @@ func Max(args ...object.Object) object.Object {
a := args[0].(*object.Array) a := args[0].(*object.Array)
// TODO: Make this more generic // TODO: Make this more generic
xs := make([]int, len(a.Elements)) xs := []int{} //make([]int, len(a.Elements))
for n, e := range a.Elements { for n, e := range a.Elements {
if i, ok := e.(*object.Integer); ok { if i, ok := e.(*object.Integer); ok {
xs = append(xs, int(i.Value)) xs = append(xs, int(i.Value))

View File

@@ -18,7 +18,7 @@ func Min(args ...object.Object) object.Object {
a := args[0].(*object.Array) a := args[0].(*object.Array)
// TODO: Make this more generic // TODO: Make this more generic
xs := make([]int, len(a.Elements)) xs := []int{} //make([]int, len(a.Elements))
for n, e := range a.Elements { for n, e := range a.Elements {
if i, ok := e.(*object.Integer); ok { if i, ok := e.(*object.Integer); ok {
xs = append(xs, int(i.Value)) xs = append(xs, int(i.Value))

View File

@@ -1,4 +1,4 @@
#!./monkey-lang #!/usr/bin/env monkey-lang
fill := fn(x, i) { fill := fn(x, i) {
xs := [] xs := []

View File

@@ -1,4 +1,4 @@
#!./monkey-lang #!/usr/bin/env monkey-lang
fd := socket("tcp4") fd := socket("tcp4")
bind(fd, "127.0.0.1:32535") bind(fd, "127.0.0.1:32535")

View File

@@ -1,11 +1,12 @@
#!./monkey-lang #!/usr/bin/env monkey-lang
fd := socket("tcp4") fd := socket("tcp4")
bind(fd, "0.0.0.0:8000") bind(fd, "0.0.0.0:8000")
listen(fd, 1) listen(fd, 1)
while (true) {
nfd := accept(fd) nfd := accept(fd)
msg := read(nfd) msg := read(nfd)
write(nfd, msg) write(nfd, msg)
close(nfd) close(nfd)
close(fd) }

View File

@@ -1,9 +1,6 @@
fib := fn(x) { fib := fn(x) {
if (x == 0) { if (x < 2) {
return 0 return x
}
if (x == 1) {
return 1
} }
return fib(x-1) + fib(x-2) return fib(x-1) + fib(x-2)
} }

View File

@@ -1,4 +1,4 @@
#!./monkey-lang #!/usr/bin/env monkey-lang
test := fn(n) { test := fn(n) {
if (n % 15 == 0) { if (n % 15 == 0) {

View File

@@ -1,4 +1,4 @@
#!./monkey-lang #!/usr/bin/env monkey-lang
prime := fn(n) { prime := fn(n) {
# Corner cases # Corner cases

5
go.mod
View File

@@ -2,7 +2,10 @@ module monkey
go 1.21 go 1.21
require github.com/stretchr/testify v1.8.4 require (
github.com/stretchr/testify v1.8.4
github.com/pkg/profile v1.7.0
)
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect

14
go.sum
View File

@@ -1,9 +1,23 @@
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,25 +1,52 @@
#!/bin/sh " Vim Syntax File
" Language: monkey
" Creator: James Mills, prologic at shortcircuit dot net dot au
" Last Change: 31st January 2019
# Get the highest tag number if version < 600
VERSION="$(git describe --abbrev=0 --tags)" syntax clear
VERSION=${VERSION:-'0.0.0'} elseif exists("b:current_syntax")
finish
endif
# Get number parts syntax case match
MAJOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
MINOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
PATCH="${VERSION%%.*}"; VERSION="${VERSION#*.}"
# Increase version syntax keyword xType true false null int str bool array hash
PATCH=$((PATCH+1))
TAG="${1}" syntax keyword xKeyword fn if else return while
if [ "${TAG}" = "" ]; then syntax keyword xFunction len input print first last rest push pop exit assert
TAG="${MAJOR}.${MINOR}.${PATCH}" syntax keyword xFunction bool int str typeof args lower upper join split find
fi syntax keyword xFunction read write
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 match xOperator "\v\|\|"
git tag -a -s -m "Release ${TAG}" "${TAG}" syntax region xString start=/"/ skip=/\\./ end=/"/
git push --tags
goreleaser release --rm-dist 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"