Skip to content

kyleterry/glerp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

64 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

glerp

A small Scheme interpreter for embedding in Go programs. It serves as a scripting and configuration layer for larger applications. You can evaluate Scheme expressions, extend the language with Go procedures, or build custom DSLs by registering special forms.

go get go.e64ec.com/glerp

Language

glerp implements a practical subset of Scheme with extensions for embedding.

Literals

42          ; integer
3.14        ; float
"hello"     ; string
#t #f       ; booleans
'()         ; empty list
'(1 2 3)    ; quoted list
#(1 2 3)    ; vector
{ "k" "v" } ; hash table

Square brackets can be used anywhere in place of parentheses. They are common in binding lists:

(let [(x 3) (y 4)] (+ x y))

Core Forms

(define x 10)                           ; variable
(define (square n) (* n n))             ; function shorthand
(define (f x . rest) rest)              ; variadic function
(lambda (x y) (+ x y))                  ; anonymous function
(set! x 99)                             ; mutation
(if (> x 0) "pos" "neg")                ; conditional
(cond [(= x 1) "one"] [else "?"])       ; multi-branch
(case x [(1 2) "low"] [else "hi"])      ; dispatch on eqv?
(let [(a 1) (b 2)] (+ a b))             ; parallel binding
(let* [(a 1) (b (* a 2))] b)            ; sequential binding
(begin expr ...)                        ; sequence
(and expr ...) (or expr ...)            ; short-circuit logic
(quote x) 'x                            ; prevent evaluation
(define-values (lo hi) (values 3 7))    ; multiple values

Macros

glerp supports hygienic macros via define-syntax with syntax-rules or syntax-case.

(define-syntax when
  (syntax-rules ()
    [(when test body ...)
     (if test (begin body ...))]))

String Interpolation

The $"..." syntax embeds Scheme expressions in strings. Expressions inside {...} are evaluated and converted to strings.

(define name "Alice")
$"Hello {name}!"          ; "Hello Alice!"
$"squared: {(* 7 7)}"     ; "squared: 49"

Iteration

(do [(i 0 (+ i 1)) (s 0 (+ s i))]
    [(= i 5) s]
  (display i))

Built-in Procedures

+ - * /                arithmetic
< > <= >= =            numeric comparison
not                    boolean negation
car cdr cons           list primitives
list empty?            list utilities
vector vector-ref      vector primitives
hash-table-ref         hash table access
values                 multiple return values
display display-ln     output

Libraries

Import libraries with (import :prefix/name). Core libraries include :scheme/list, :scheme/math, and :scheme/time.

(import :scheme/list)
(import (only :scheme/list map filter))

Embedding

Evaluate Expressions

env := glerp.NewEnvironment(glerp.DefaultConfig())
results, err := glerp.Eval(`(+ 1 2)`, env)
fmt.Println(results[len(results)-1]) // 3

Register Go Procedures

Add custom builtins to the config before creating the environment.

cfg := glerp.DefaultConfig()
cfg.Builtins["http-get"] = func(args []glerp.Expr) (glerp.Expr, error) {
    // args are pre-evaluated
    return glerp.Void(), nil
}
env := glerp.NewEnvironment(cfg)

Configuration DSLs

Use Load to evaluate a file and extract typed values.

cfg, _ := glerp.Load("config.scm")
host, _ := cfg.String("host")
port, _ := cfg.Int("port")

Custom Special Forms

Special forms receive unevaluated arguments, allowing you to define custom evaluation logic or keyword-based DSLs.

cfg.Forms["routes"] = func(args []glerp.Expr, env *glerp.Environment) (glerp.Expr, error) {
    for _, arg := range args {
        // manually evaluate or inspect args
    }
    return glerp.Void(), nil
}

CLI

go install go.e64ec.com/glerp/cmd/glerp@latest

# REPL
glerp

# file runner
glerp script.scm

# eval expressions from stdin
echo '(display-ln "hi")' | glerp -

Development

task check  # run linter, vetter and tests

About

Scuffed Scheme interpreter written in Go. Can and should be used as an embeddable module in all your Go projects.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages