GotalkInterpreter

command module
v0.0.0-...-239939c Latest Latest
Warning

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

Go to latest
Published: Nov 24, 2023 License: MIT Imports: 7 Imported by: 0

README

GotalkInterpreter

It's a simplistic Smalltalk code interpreter written in Golang by Alex and Michael.

Who can use it

The entire purpose of this library is to use Smalltalk for dynamic code (string) evaluation in Golang applications. It is optimized to reevaluate same code lines with different scope (variables). Typical use case: our app reads xml file with a markup and a Smalltalk code, evaluates this code and uses the result. We use it to build and animate an OpenGL UI for our embedded software.

Why Smalltalk

Smalltalk is beautiful dynamic language with a concise and readable syntax. Also we are smalltalkers so that's why.

Contents

Scanner and Parser are essentially standard Smalltalk Scanner and Parser rewritten in Go. We used VisualWorks and Pharo realizations as reference implementations. Evaluator is the API entry point. You can expand functionality by modifying smalltalkObjects.go file.

Bugs, Tests etc

There are a lot of tests for everything here so we are pretty sure that this library is actually useable. You can use its tests (specifically smalltalkEvaluator_test.go) to better understand what you can do with this library. We can rewrite some parts later just to make our Go code better and somehow expand overall functionality.

Installation

GotalkInterpreter does not use any third party libraries. To get it run on your machine, you just:

go get github.com/SealNTibbers/GotalkInterpreter

API and Examples

Result of our Smalltalk code evaluation can be number (float64 or int. Internally it's always float64), bool or string.

In our little Smalltalk we have supported limited amount of messages that is enough for our internal project but it's easily expandable.

Numbers can receive following messages:

`value`           
`=`               
`~=`            
`>`             
`>=`             
`<`              
`<=`             
`+`             
`-`               
`*`             
`/`             
`\\`             
`//`             
`rem:`           
`max:`            
`min:`            
`abs`           
`sqrt`            
`sqr`             
`sin`             
`cos`             
`tan`             
`arcSin`          
`arcCos`         
`arcTan`          
`rounded`         
`truncated`       
`fractionPart`     
`floor`           
`ceiling`          
`negated`       
`degreesToRadians`

Booleans can receive following messages:

`value`
`=`
`~=`
`ifTrue:`
`ifFalse:`
`ifTrue:ifFalse:`
`ifFalse:ifTrue:`
`and:`
`&`
`or:`
`|`
`xor:`
`not`

Blocks can receive following messages:

`value`
`value:`

Arrays can receive following messages:

`at:`
`+`
`-`
`*`
`/`
`\\`
`//`
Low-lewel API example
//so we have smalltalk code string and want to evaluate it `angle\\10/10-0.9*10`

globalScope := new(treeNodes.Scope).Initialize()
globalScope.SetVar("angle", treeNodes.NewSmalltalkNumber(25))

evaluator = evaluator.NewEvaluatorWithGlobalScope(globalScope)
resultObject = evaluator.RunProgram(`angle\\10/10-0.9*10`)

result = resultObject.(*treeNodes.SmalltalkNumber).GetValue()
//so now we have result which is float64 and equals to -4
Higher level API example. See TestAPI func in smalltalkEvaluator_test.go
vm := NewSmalltalkVM()
vm.SetNumberVar("swordsAmount", 9001)
vm.SetBoolVar("lie",false)
chant := "I am the bone of my sword.."
vm.SetStringVar("chant",chant)

smalltalkProgram1 := `(swordsAmount > 9000) ifTrue:[chant] ifFalse:['ouch it hurts']`
smalltalkProgram2 := `(swordsAmount > 1.2e4) ifTrue:[-1] ifFalse:[42]`
smalltalkProgram3 := `lie ifTrue:[0.001] ifFalse:[-0.56]`
smalltalkProgram4 := `swordsAmount > 1.2e4`

var result1 string
var result2 int64
var result3 float64
var result4 bool

result1 = vm.EvaluateToString(smalltalkProgram1)
testutils.ASSERT_STREQ(t, result1, chant)

result2 = vm.EvaluateToInt64(smalltalkProgram2)
testutils.ASSERT_EQ(t, int(result2), 42)

result3 = vm.EvaluateToFloat64(smalltalkProgram3)
testutils.ASSERT_FLOAT64_EQ(t, result3, -0.56)

result4 = vm.EvaluateToBool(smalltalkProgram4)
testutils.ASSERT_FALSE(t, result4)
Nested variable scopes
var inputString1, inputString2 string
var result1, result2 int64

vm := NewSmalltalkVM()
vm.SetNumberVar("x", 11)

inputString1 = `|x| x := 25. x+75`
result1 = vm.EvaluateToInt64(inputString1)
testutils.ASSERT_EQ(t, int(result1), 100)

inputString2 = `x+75`
result2 = vm.EvaluateToInt64(inputString2)
testutils.ASSERT_EQ(t, int(result2), 86)

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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