picol

package module
v0.0.0-...-0b09e5f Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2017 License: MIT Imports: 6 Imported by: 0

README

picol.go

Motivation

Wanted a minimal Tcl implementation, which could be used as an experimental extention mechanism for golang projects.

TODO
  • Support interface{} as the command argument and return type instead of string
  • Reduce memory allocations, review the parser implementation to reduce operations, which would create string copies.
  • More test-cases
Won't do
  • Comprehensiveness & compatibility with the standard Tcl implementation
  • Tcl standard library
Old Readme

Original http://oldblog.antirez.com/post/picol.html

Sample use:

func CommandPuts(i *picol.Interp, argv []string, pd interface{}) (string, error) {
	if len(argv) != 2 {
		return "", fmt.Errorf("Wrong number of args for %s %s", argv[0], argv)
	}
	fmt.Println(argv[1])
	return "", nil
}
...
	interp := picol.InitInterp()
	// add core functions
	interp.RegisterCoreCommands()
	// add user function
	interp.RegisterCommand("puts", CommandPuts, nil)
	// eval
	result, err := interp.Eval(string(buf))
	if err != nil {
		fmt.Println("ERROR", err, result)
	} else {
		fmt.Println(result)
	}

Documentation

Index

Constants

View Source
const (
	PT_ESC = iota
	PT_STR
	PT_CMD
	PT_VAR
	PT_SEP
	PT_EOL
	PT_EOF
)

Variables

View Source
var (
	PICOL_RETURN   = errors.New("RETURN")
	PICOL_BREAK    = errors.New("BREAK")
	PICOL_CONTINUE = errors.New("CONTINUE")
	UNDEFINED_VAR  = errors.New("Undefined variable")
	CMD_EXISTS     = errors.New("Command with the given name is already registered")
)

Functions

func ArityErr

func ArityErr(i *Interp, name string, argv []interface{}) error

func CommandCallProc

func CommandCallProc(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandError

func CommandError(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandIf

func CommandIf(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandMath

func CommandMath(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandProc

func CommandProc(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandRetCodes

func CommandRetCodes(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandReturn

func CommandReturn(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandSet

func CommandSet(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandUnset

func CommandUnset(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

func CommandWhile

func CommandWhile(i *Interp, argv []interface{}, pd interface{}) (interface{}, error)

Types

type CallFrame

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

type Cmd

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

type CmdFunc

type CmdFunc func(i *Interp, argv []interface{}, privdata interface{}) (interface{}, error)

by default, all args are assumed to be strings, I am changing them to interface{}, so we could pass custom data type objects to the commands, the return type should also be interface{} instead of the default string

type Interp

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

func InitInterp

func InitInterp() *Interp

func (*Interp) Command

func (i *Interp) Command(name string) *Cmd

func (*Interp) Eval

func (i *Interp) Eval(t string) (interface{}, error)
EVAL!

Ideally Eval should take interface{}, which would help us either evaluate a string or an already parsed lexical tokens. For now we are starting with string and we could optimize on this at a later stage when we rewrite our parser module.

func (*Interp) RegisterCommand

func (i *Interp) RegisterCommand(name string, fn CmdFunc, privdata interface{}) error

func (*Interp) RegisterCoreCommands

func (i *Interp) RegisterCoreCommands()

func (*Interp) SetVar

func (i *Interp) SetVar(name string, val interface{})

func (*Interp) UnsetVar

func (i *Interp) UnsetVar(name string)

func (*Interp) Var

func (i *Interp) Var(name string) (interface{}, error)

Looks up for variables by iterating through the call frames, starting with the current to the root call frame, till a variable name match is found.

type Parser

type Parser struct {
	Type int
	// contains filtered or unexported fields
}

func InitParser

func InitParser(text string) *Parser

func (*Parser) GetToken

func (p *Parser) GetToken() string

type Var

type Var interface{}

Not sure if this explicit type for interface it required, I would just go with inteface{} in all places, but lets this be there for now.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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