Browse Source

Improved build and added version support. Added support for executing files and some cli options

pull/2/head
James Mills 3 years ago
parent
commit
c1f96ed02e
Signed by: prologic GPG Key ID: AC4C014F1440EBD6
  1. 5
      .gitignore
  2. 33
      Makefile
  3. 1
      examples/hello.monkey
  4. 53
      main.go
  5. 33
      repl/repl.go
  6. 18
      version.go

5
.gitignore

@ -1,4 +1,5 @@
*~*
*~
*.bak
*.txt
monkey
/monkey-lang

33
Makefile

@ -1,16 +1,33 @@
.PHONY: build test deps clean
.PHONY: dev build install image profile bench test clean
all: build
@./monkey
CGO_ENABLED=0
COMMIT=$(shell git rev-parse --short HEAD)
deps:
@go get ./...
all: dev
build:
@go build -o monkey .
dev: build
@./monkey-lang -d
build: clean
@go build \
-tags "netgo static_build" -installsuffix netgo \
-ldflags "-w -X $(shell go list)/version/.GitCommit=$(COMMIT)" \
.
install: build
@go install
image:
@docker build -t prologic/monkey-lang .
profile:
@go test -cpuprofile cpu.prof -memprofile mem.prof -v -bench ./...
bench:
@go test -v -bench ./...
test:
@go test -v -cover -coverprofile=coverage.txt -covermode=atomic ./...
@go test -v -cover -coverprofile=coverage.txt -covermode=atomic -coverpkg=./... -race ./...
clean:
@git clean -f -d -X

1
examples/hello.monkey

@ -0,0 +1 @@
puts("Hello World!")

53
main.go

@ -1,23 +1,64 @@
package main
// Package main implements the main process which invokes the interpreter's
// Package main implements the main process which executes a program if
// a filename is supplied as an argument or invokes the interpreter's
// REPL and waits for user input before lexing, parsing nad evaulating.
import (
"flag"
"fmt"
"log"
"os"
"os/user"
"path"
"github.com/prologic/monkey-lang/repl"
)
var (
interactive bool
version bool
debug bool
)
func init() {
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] [<filename>]", path.Base(os.Args[0]))
flag.PrintDefaults()
os.Exit(0)
}
flag.BoolVar(&version, "v", false, "display version information")
flag.BoolVar(&debug, "d", false, "enable debug mode")
flag.BoolVar(&interactive, "i", false, "enable interactive mode")
}
func main() {
flag.Parse()
if version {
fmt.Printf("%s %s", path.Base(os.Args[0]), FullVersion())
os.Exit(0)
}
user, err := user.Current()
if err != nil {
panic(err)
log.Fatalf("could not determine current user: %s", err)
}
if flag.NArg() == 1 {
f, err := os.Open(flag.Arg(0))
if err != nil {
log.Fatalf("could not open source file %s: %s", flag.Arg(0), err)
}
env := repl.Exec(f)
if interactive {
repl.Start(os.Stdin, os.Stdout, env)
}
} else {
fmt.Printf("Hello %s! This is the Monkey programming language!\n", user.Username)
fmt.Printf("Feel free to type in commands\n")
repl.Start(os.Stdin, os.Stdout, nil)
}
fmt.Printf("Hello %s! This is the Monkey programming language!\n",
user.Username)
fmt.Printf("Feel free to type in commands\n")
repl.Start(os.Stdin, os.Stdout)
}

33
repl/repl.go

@ -7,6 +7,8 @@ import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"github.com/prologic/monkey-lang/eval"
"github.com/prologic/monkey-lang/lexer"
@ -32,10 +34,37 @@ const MonkeyFace = ` __,__
'-----'
`
// Exec parses and executes the program given by f and returns the resulting
// environment, any errors are printed to stderr
func Exec(f io.Reader) (env *object.Environment) {
env = object.NewEnvironment()
b, err := ioutil.ReadAll(f)
if err != nil {
fmt.Fprintf(os.Stderr, "error reading source file: %s", err)
return
}
l := lexer.New(string(b))
p := parser.New(l)
program := p.ParseProgram()
if len(p.Errors()) != 0 {
printParserErrors(os.Stderr, p.Errors())
return
}
eval.Eval(program, env)
return
}
// Start starts the REPL in a continious loop
func Start(in io.Reader, out io.Writer) {
func Start(in io.Reader, out io.Writer, env *object.Environment) {
scanner := bufio.NewScanner(in)
env := object.NewEnvironment()
if env == nil {
env = object.NewEnvironment()
}
for {
fmt.Printf(PROMPT)

18
version.go

@ -0,0 +1,18 @@
package main
import (
"fmt"
)
var (
// Version release version
Version = "0.0.1"
// GitCommit will be overwritten automatically by the build system
GitCommit = "HEAD"
)
// FullVersion returns the full version and commit hash
func FullVersion() string {
return fmt.Sprintf("%s@%s", Version, GitCommit)
}
Loading…
Cancel
Save