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

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:
- flags: -tags "static_build"
ldflags: -w -X main.Version={{.Version}} -X main.Commit={{.Commit}}
- id: monkey
binary: monkey
main: ./cmd/monkey
flags: -tags "static_build"
ldflags: >-
-w
-X go.unflavoredmeson.com/monkey/v2.MonkeyVersion={{.Version}}
env:
- CGO_ENABLED=0
sign:
artifacts: checksum
archive:
replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
goos:
- darwin
- freebsd
- linux
goarch:
- amd64
- arm64
goarm:
- 6
- 7
- id: monkey-server
binary: monkey-server
main: ./cmd/monkey-server
flags: -tags "static_build"
ldflags: >-
-w
-X go.unflavoredmeson.com/monkey/v2.MonkeyVersion={{.Version}}
env:
- 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
COMMIT=$(shell git rev-parse --short HEAD)
all: dev
VERSION ?= $(shell git describe 2>/dev/null || echo "")
dev: build
@./monkey-lang -d
DESTDIR ?= $(GOBIN)
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 \
-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
@go install
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/...
image:
@docker build -t prologic/monkey-lang .
install: cli server ## Install monkey to $DESTDIR
@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
profile:
profile: ## Run tests with profiling enabled
@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=. ./...
test:
@go test -v -cover -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... -race ./...
test: ## Run unit tests
@go test -v \
-cover \
-coverprofile coverage.out \
-covermode atomic \
-coverpkg ./... \
-race \
./...
clean:
@git clean -f -d -X
clean: ## Cleanup untrakced files
@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)
// TODO: Make this more generic
xs := make([]int, len(a.Elements))
xs := []int{} //make([]int, len(a.Elements))
for n, e := range a.Elements {
if i, ok := e.(*object.Integer); ok {
xs = append(xs, int(i.Value))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

5
go.mod
View File

@@ -2,7 +2,10 @@ module monkey
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 (
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/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/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/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/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/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
VERSION="$(git describe --abbrev=0 --tags)"
VERSION=${VERSION:-'0.0.0'}
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
# Get number parts
MAJOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
MINOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
PATCH="${VERSION%%.*}"; VERSION="${VERSION#*.}"
syntax case match
# Increase version
PATCH=$((PATCH+1))
syntax keyword xType true false null int str bool array hash
TAG="${1}"
syntax keyword xKeyword fn if else return while
if [ "${TAG}" = "" ]; then
TAG="${MAJOR}.${MINOR}.${PATCH}"
fi
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
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}"
git push --tags
goreleaser release --rm-dist
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"