schego

package module
v0.0.0-...-be9e085 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2018 License: MIT Imports: 9 Imported by: 0

README

Schego - A Scheme implementation written in Go

shay-go: noun

definition: yet another Scheme implementation that probably didn't need to exist, but does anyway.

What?

The title is pretty descriptive. But it's missing some details. In addition to being a (soon-to-be) fully R7RS-compatible Scheme implementation, Schego will also include a stack-based, language-agnostic VM, suitable for implementing other languages instead of Scheme.

At some point in the future, Schego's VM will also include a JIT targeting the x86-64/amd64 platform (and perhaps some ARM devices), in addition to being able to be embedded into any Go application to provide Scheme scripting support, or just a generic VM to build on top of. Why would you want to do that when LLVM exists? I'm not entirely sure. But you could.

To summarize Schego's (planned) feature set in a quick bullet point list:

  • Complete R7RS Scheme implementation
  • R7RS SLib (https://github.com/petercrlane/r7rs-libs) compatibility
  • Hyrbrid JIT backend targeting x86-64/amd64 and maybe possibly some ARM devices down the road
  • libschego build target allowing embedding into almost any Go application
  • STM (Software Transactional Memory) multitasking model, possibly the first of its kind in Scheme

Why?

To familiarize myself with Go, primarily. There was, at least at the time I write this, very little practical need for a serious Scheme implementation in Go - many good, established Scheme implementations are already out there, with some of them even having basically the entire feature set I initially planned for Schego.

I do intend to implement Schego with a watchful eye towards readability, so hopefully the codebase will be able to serve as a reasonable frame of reference towards anyone trying to implement something similar. I'll also cover Schego's progress on my blog, which will hopefully be educational and at least slightly entertaining.

That, and I needed an excuse to do something with Scheme.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RunVM

func RunVM(opcodes []byte, console VMConsole) int64

Types

type AddExp

type AddExp struct {
	SExp
}

func NewAddExp

func NewAddExp(lhs AstNode, rhs AstNode) *AddExp

func (AddExp) DebugString

func (a AddExp) DebugString() string

func (AddExp) GetType

func (a AddExp) GetType() AstNodeType

type AstNode

type AstNode interface {
	GetSubNodes() []AstNode
	AddSubNode(AstNode)
	GetType() AstNodeType
	DebugString() string
}

base interface for functions needing to accept any kind of AST node

type AstNodeType

type AstNodeType int
const (
	ProgramNode AstNodeType = iota
	AddNode
	SubNode
	MulNode
	DivNode
	GtNode
	LtNode
	GteNode
	LteNode
	EqNode
	IfNode
	DefNode
	LambdaNode
	IdentNode
	IntNode
	FloatNode
	StringNode
	BoolNode
)

type BoolLiteral

type BoolLiteral struct {
	SExp
	Value bool
}

func NewBoolLiteral

func NewBoolLiteral(value bool) *BoolLiteral

func (BoolLiteral) DebugString

func (b BoolLiteral) DebugString() string

func (BoolLiteral) GetType

func (b BoolLiteral) GetType() AstNodeType

type DefExp

type DefExp struct {
	SExp
	Name string
}

func NewDefExp

func NewDefExp(name string, exp AstNode) *DefExp

func (DefExp) DebugString

func (d DefExp) DebugString() string

func (DefExp) GetType

func (d DefExp) GetType() AstNodeType

type DivExp

type DivExp struct {
	SExp
}

func NewDivExp

func NewDivExp(lhs AstNode, rhs AstNode) *DivExp

func (DivExp) DebugString

func (d DivExp) DebugString() string

func (DivExp) GetType

func (d DivExp) GetType() AstNodeType

type EqExp

type EqExp struct {
	SExp
}

func NewEqExp

func NewEqExp(lhs AstNode, rhs AstNode) *EqExp

func (EqExp) DebugString

func (e EqExp) DebugString() string

func (EqExp) GetType

func (e EqExp) GetType() AstNodeType

type FloatLiteral

type FloatLiteral struct {
	SExp
	Value float64
}

func NewFloatLiteral

func NewFloatLiteral(value float64) *FloatLiteral

func (FloatLiteral) DebugString

func (f FloatLiteral) DebugString() string

func (FloatLiteral) GetType

func (f FloatLiteral) GetType() AstNodeType

type GtExp

type GtExp struct {
	SExp
}

func NewGtExp

func NewGtExp(lhs AstNode, rhs AstNode) *GtExp

func (GtExp) DebugString

func (g GtExp) DebugString() string

func (GtExp) GetType

func (g GtExp) GetType() AstNodeType

type GteExp

type GteExp struct {
	SExp
}

func NewGteExp

func NewGteExp(lhs AstNode, rhs AstNode) *GteExp

func (GteExp) DebugString

func (g GteExp) DebugString() string

func (GteExp) GetType

func (g GteExp) GetType() AstNodeType

type IdentExp

type IdentExp struct {
	SExp
	Name string
}

func NewIdentExp

func NewIdentExp(name string) *IdentExp

func (IdentExp) DebugString

func (i IdentExp) DebugString() string

func (IdentExp) GetType

func (i IdentExp) GetType() AstNodeType

type IfExp

type IfExp struct {
	SExp
}

func NewIfExp

func NewIfExp(cond AstNode, onTrue AstNode, onFalse AstNode) *IfExp

func (IfExp) DebugString

func (i IfExp) DebugString() string

func (IfExp) GetType

func (i IfExp) GetType() AstNodeType

type IntLiteral

type IntLiteral struct {
	SExp
	Value int64
}

func NewIntLiteral

func NewIntLiteral(value int64) *IntLiteral

func (IntLiteral) DebugString

func (i IntLiteral) DebugString() string

func (IntLiteral) GetType

func (i IntLiteral) GetType() AstNodeType

type LambdaExp

type LambdaExp struct {
	SExp
	Args []string
}

func NewLambdaExp

func NewLambdaExp(args []string, exp AstNode) *LambdaExp

func (LambdaExp) DebugString

func (l LambdaExp) DebugString() string

func (LambdaExp) GetType

func (l LambdaExp) GetType() AstNodeType

type LtExp

type LtExp struct {
	SExp
}

func NewLtExp

func NewLtExp(lhs AstNode, rhs AstNode) *LtExp

func (LtExp) DebugString

func (l LtExp) DebugString() string

func (LtExp) GetType

func (l LtExp) GetType() AstNodeType

type LteExp

type LteExp struct {
	SExp
}

func NewLteExp

func NewLteExp(lhs AstNode, rhs AstNode) *LteExp

func (LteExp) DebugString

func (l LteExp) DebugString() string

func (LteExp) GetType

func (l LteExp) GetType() AstNodeType

type MulExp

type MulExp struct {
	SExp
}

func NewMulExp

func NewMulExp(lhs AstNode, rhs AstNode) *MulExp

func (MulExp) DebugString

func (m MulExp) DebugString() string

func (MulExp) GetType

func (m MulExp) GetType() AstNodeType

type Program

type Program struct {
	SExp
}

func NewProgram

func NewProgram(nodes ...AstNode) *Program

func ParseTokens

func ParseTokens(tokens []*Token) *Program

ParseTokens takes tokens and returns an AST (Abstract Syntax Tree) representation

func (Program) GetType

func (p Program) GetType() AstNodeType

type SExp

type SExp struct {
	// contains filtered or unexported fields
}

base struct that all AST node implementations build off of

func (*SExp) AddSubNode

func (s *SExp) AddSubNode(node AstNode)

func (*SExp) GetSubNodes

func (s *SExp) GetSubNodes() []AstNode

type StringLiteral

type StringLiteral struct {
	SExp
	Value string
}

func NewStringLiteral

func NewStringLiteral(value string) *StringLiteral

func (StringLiteral) DebugString

func (s StringLiteral) DebugString() string

func (StringLiteral) GetType

func (s StringLiteral) GetType() AstNodeType

type SubExp

type SubExp struct {
	SExp
}

func NewSubExp

func NewSubExp(lhs AstNode, rhs AstNode) *SubExp

func (SubExp) DebugString

func (s SubExp) DebugString() string

func (SubExp) GetType

func (s SubExp) GetType() AstNodeType

type Token

type Token struct {
	Type  TokenType
	Value bytes.Buffer
}

func LexExp

func LexExp(input string) []*Token

LexExp lexes an input string into Token objects. There are no possible user-facing errors from this process.

func NewTokenRaw

func NewTokenRaw(tokenType TokenType, tokenBuffer bytes.Buffer) *Token

NewTokenRaw creates a new token from a raw Buffer.

func NewTokenString

func NewTokenString(tokenType TokenType, tokenString string) *Token

NewTokenString is a convenience function that returns a token with a given string value.

type TokenType

type TokenType int
const (
	TokenNone TokenType = iota
	TokenRParen
	TokenLParen
	TokenIdent
	TokenIntLiteral
	TokenFloatLiteral
	TokenStringLiteral
	TokenBoolLiteral
	TokenDot
	TokenOp
	TokenChar
)

type VMConsole

type VMConsole interface {
	Write(string)
}

interface to write a null-terminated string to stdout

type VMHeap

type VMHeap struct {
	// contains filtered or unexported fields
}

func NewVMHeap

func NewVMHeap() *VMHeap

func (*VMHeap) Allocate

func (h *VMHeap) Allocate(numBytes uint64) uint64

func (*VMHeap) AllocateRootBlock

func (h *VMHeap) AllocateRootBlock(heapSize uint64)

func (*VMHeap) CreateBlock

func (h *VMHeap) CreateBlock(order uint8)

func (*VMHeap) Free

func (h *VMHeap) Free(address uint64)

func (*VMHeap) GetBuddyAddress

func (h *VMHeap) GetBuddyAddress(address uint64, order uint8) uint64

func (*VMHeap) GetFreeBlock

func (h *VMHeap) GetFreeBlock(order uint8) uint64

func (*VMHeap) GetUnusedBlockIndex

func (h *VMHeap) GetUnusedBlockIndex(address uint64, order uint8) int

func (*VMHeap) HasBuddy

func (h *VMHeap) HasBuddy(address uint64, order uint8) bool

func (*VMHeap) MergeWithBuddy

func (h *VMHeap) MergeWithBuddy(address uint64, order uint8)

func (*VMHeap) NoFreeBlocksFor

func (h *VMHeap) NoFreeBlocksFor(order uint8) bool

func (*VMHeap) OrderFor

func (h *VMHeap) OrderFor(requestedBytes uint64) uint8

func (*VMHeap) Read

func (h *VMHeap) Read(numBytes uint64, address uint64) *bytes.Buffer

func (*VMHeap) ReadString

func (h *VMHeap) ReadString(address uint64) []byte

func (*VMHeap) RemoveBlockFromUnused

func (h *VMHeap) RemoveBlockFromUnused(index int, order uint8)

func (*VMHeap) SplitBlock

func (h *VMHeap) SplitBlock(address uint64, order uint8)

func (*VMHeap) Write

func (h *VMHeap) Write(data *bytes.Buffer, address uint64)

type VMStack

type VMStack struct {
	// contains filtered or unexported fields
}

data structure to contain the stack for a single VM instance

func (*VMStack) Dup

func (s *VMStack) Dup()

func (VMStack) Length

func (s VMStack) Length() uint64

func (*VMStack) PopByte

func (s *VMStack) PopByte() byte

func (*VMStack) PopCell

func (s *VMStack) PopCell() []uint64

func (*VMStack) PopDouble

func (s *VMStack) PopDouble() float64

func (*VMStack) PopInt

func (s *VMStack) PopInt() int64

func (*VMStack) PopString

func (s *VMStack) PopString() []byte

func (*VMStack) PushByte

func (s *VMStack) PushByte(newValue byte)

func (*VMStack) PushCell

func (s *VMStack) PushCell(cell []byte)

func (*VMStack) PushDouble

func (s *VMStack) PushDouble(doubleBytes []byte)

func (*VMStack) PushEmptyCell

func (s *VMStack) PushEmptyCell()

func (*VMStack) PushInt

func (s *VMStack) PushInt(intBytes []byte)

func (*VMStack) PushString

func (s *VMStack) PushString(runeBytes []byte)

type VMState

type VMState struct {
	Stack   VMStack
	Heap    VMHeap
	Console VMConsole
	// contains filtered or unexported fields
}

func NewVM

func NewVM(opcodes []byte, console VMConsole) *VMState

func (*VMState) CanStep

func (v *VMState) CanStep() bool

func (*VMState) ExitCode

func (v *VMState) ExitCode() int64

func (*VMState) NextOpcode

func (v *VMState) NextOpcode() byte

func (*VMState) ReadBytes

func (v *VMState) ReadBytes(length int) []byte

func (*VMState) Step

func (v *VMState) Step()

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL