UDDIN-LANG Go Library
UDDIN-LANG (Unified Dynamic Decision Interpreter Notation) is available as a Go library that you can easily integrate into your Go applications.
Installation
go get github.com/bonkzero404/uddin-lang
Quick Start
Basic Usage
package main
import (
"fmt"
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
// Create a new engine
engine := uddin.New()
// Execute UDDIN-LANG code
stats, err := engine.ExecuteString(`
x = 10
y = 20
result = x + y
print("Result: " + str(result))
`)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Executed %d operations\n", stats.Total())
}
Evaluating Expressions
package main
import (
"fmt"
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
engine := uddin.New()
// Evaluate a mathematical expression
result, stats, err := engine.EvaluateString("(5 + 3) * 2")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Result: %v (executed %d operations)\n", result, stats.Total())
// Output: Result: 16 (executed 5 operations)
}
Setting Variables
package main
import (
"fmt"
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
engine := uddin.New()
// Set individual variables
engine.SetVariable("name", "John")
engine.SetVariable("age", 30)
// Or set multiple variables at once
engine.SetVariables(map[string]any{
"city": "New York",
"active": true,
})
// Use the variables in UDDIN-LANG code
_, err := engine.ExecuteString(`
print("Name: " + name)
print("Age: " + str(age))
print("City: " + city)
print("Active: " + str(active))
`)
if err != nil {
log.Fatal(err)
}
}
Custom I/O
package main
import (
"bytes"
"fmt"
"log"
"strings"
"github.com/bonkzero404/uddin-lang"
)
func main() {
engine := uddin.New()
// Capture output
var output bytes.Buffer
engine.SetStdout(&output)
// Provide input
input := strings.NewReader("Hello from input\n")
engine.SetStdin(input)
_, err := engine.ExecuteString(`
print("Enter your name: ")
name = read()
print("Hello, " + name)
`)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Captured output:\n%s", output.String())
}
Working with Functions
package main
import (
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
engine := uddin.New()
// Define and call functions
_, err := engine.ExecuteString(`
fun factorial(n):
if (n <= 1) then:
return 1
end
return n * factorial(n - 1)
end
result = factorial(5)
print("5! = " + str(result))
`)
if err != nil {
log.Fatal(err)
}
}
Error Handling
package main
import (
"fmt"
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
engine := uddin.New()
// This will cause a syntax error
_, err := engine.ExecuteString("x = ")
if err != nil {
fmt.Printf("Syntax error: %v\n", err)
}
// This will cause a runtime error
_, err = engine.ExecuteString("print(undefined_variable)")
if err != nil {
fmt.Printf("Runtime error: %v\n", err)
}
}
Parsing and Execution Separation
package main
import (
"fmt"
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
engine := uddin.New()
// Parse the program first
program, err := engine.ParseProgram([]byte(`
fun greet(name):
return "Hello, " + name + "!"
end
message = greet("World")
print(message)
`))
if err != nil {
log.Fatal("Parse error:", err)
}
// Execute the parsed program
stats, err := engine.ExecuteProgram(program)
if err != nil {
log.Fatal("Execution error:", err)
}
fmt.Printf("Program executed successfully with %d operations\n", stats.Total())
}
Memory Optimization
package main
import (
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
engine := uddin.New()
// Enable memory optimizations for better performance
engine.EnableMemoryOptimization()
// Execute memory-intensive operations
_, err := engine.ExecuteString(`
// Process large arrays
data = range(10000)
sum = 0
for (item in data):
sum = sum + item
end
print("Sum: " + str(sum))
`)
if err != nil {
log.Fatal(err)
}
}
Unit Testing Mode
package main
import (
"fmt"
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
engine := uddin.New()
// Enable unit test mode (prevents automatic main() execution)
engine.SetUnitTestMode(true)
// Define functions without executing main
_, err := engine.ExecuteString(`
fun add(a, b):
return a + b
end
fun main():
print("This won't be executed automatically")
end
`)
if err != nil {
log.Fatal(err)
}
// Manually test the add function
result, _, err := engine.EvaluateString("add(5, 3)")
if err != nil {
log.Fatal(err)
}
fmt.Printf("add(5, 3) = %v\n", result) // Output: add(5, 3) = 8
}
Convenience Functions
For simple use cases, you can use the convenience functions that don't require creating an engine instance:
package main
import (
"fmt"
"log"
"github.com/bonkzero404/uddin-lang"
)
func main() {
// Quick expression evaluation
result, _, err := uddin.EvaluateString("10 * 5 + 2")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Result: %v\n", result) // Output: Result: 52
// Quick program execution
_, err = uddin.ExecuteString(`print("Hello from UDDIN-LANG!")`)
if err != nil {
log.Fatal(err)
}
// Quick file execution
_, err = uddin.ExecuteFile("script.din")
if err != nil {
log.Fatal(err)
}
}
API Reference
Engine Methods
Creation and Configuration
New() *Engine
- Create a new engine with default configurationNewWithConfig(config *Config) *Engine
- Create a new engine with custom configurationSetStdout(w io.Writer)
- Set standard outputSetStdin(r io.Reader)
- Set standard inputSetArgs(args []string)
- Set command-line argumentsEnableMemoryOptimization()
- Enable memory optimizationsSetUnitTestMode(isUnitTest bool)
- Set unit test mode
Variable Management
SetVariable(name string, value any)
- Set a single variableSetVariables(vars map[string]any)
- Set multiple variables
Parsing
ParseExpression(source []byte) (Expression, error)
- Parse an expressionParseProgram(source []byte) (*Program, error)
- Parse a program
Execution
EvaluateExpression(expr Expression) (Value, *Stats, error)
- Evaluate a parsed expressionExecuteProgram(prog *Program) (*Stats, error)
- Execute a parsed programExecuteString(source string) (*Stats, error)
- Parse and execute source codeExecuteFile(filename string) (*Stats, error)
- Parse and execute a fileEvaluateString(source string) (Value, *Stats, error)
- Parse and evaluate an expression
AST Conversion
ConvertToJSON(source []byte) ([]byte, error)
- Convert UDDIN-LANG source to JSON ASTConvertFromJSON(jsonData []byte) (string, error)
- Convert JSON AST back to UDDIN-LANG sourceConvertStringToJSON(source string) ([]byte, error)
- Convert UDDIN-LANG string to JSON ASTConvertJSONToString(jsonData []byte) (string, error)
- Convert JSON AST back to UDDIN-LANG string
Convenience Functions
ParseExpression(source []byte) (Expression, error)
- Parse an expression with default settingsParseProgram(source []byte) (*Program, error)
- Parse a program with default settingsExecuteString(source string) (*Stats, error)
- Execute source code with default settingsExecuteFile(filename string) (*Stats, error)
- Execute a file with default settingsEvaluateString(source string) (Value, *Stats, error)
- Evaluate an expression with default settingsConvertToJSON(source []byte) ([]byte, error)
- Convert UDDIN-LANG source to JSON ASTConvertFromJSON(jsonData []byte) (string, error)
- Convert JSON AST back to UDDIN-LANG sourceConvertStringToJSON(source string) ([]byte, error)
- Convert UDDIN-LANG string to JSON ASTConvertJSONToString(jsonData []byte) (string, error)
- Convert JSON AST back to UDDIN-LANG string
Configuration Functions
DefaultConfig() *Config
- Get default configurationTestConfig() *Config
- Get configuration suitable for testingPrintStats(stats Stats, output io.Writer)
- Print execution statistics
AST Conversion Examples
// Convert source code to JSON AST
source := "x = 42\nprint(x)"
jsonData, err := uddin.ConvertStringToJSON(source)
if err != nil {
log.Fatal(err)
}
// Convert JSON AST back to source code
convertedSource, err := uddin.ConvertJSONToString(jsonData)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Original: %s\n", source)
fmt.Printf("Converted: %s\n", convertedSource)
// Round-trip conversion with byte arrays
originalBytes := []byte("fun factorial(n): if (n <= 1) then: return 1 else: return n * factorial(n - 1) end end")
jsonBytes, err := uddin.ConvertToJSON(originalBytes)
if err != nil {
log.Fatal(err)
}
restoredSource, err := uddin.ConvertFromJSON(jsonBytes)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Restored: %s\n", restoredSource)
Integration Examples
Web Server Integration
package main
import (
"encoding/json"
"net/http"
"log"
"github.com/bonkzero404/uddin-lang"
)
type EvalRequest struct {
Expression string `json:"expression"`
Variables map[string]any `json:"variables,omitempty"`
}
type EvalResponse struct {
Result any `json:"result"`
Error string `json:"error,omitempty"`
Stats *uddin.Stats `json:"stats"`
}
func evalHandler(w http.ResponseWriter, r *http.Request) {
var req EvalRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
engine := uddin.New()
engine.SetUnitTestMode(true)
if req.Variables != nil {
engine.SetVariables(req.Variables)
}
result, stats, err := engine.EvaluateString(req.Expression)
resp := EvalResponse{
Result: result,
Stats: stats,
}
if err != nil {
resp.Error = err.Error()
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
}
func main() {
http.HandleFunc("/eval", evalHandler)
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
CLI Tool Integration
package main
import (
"flag"
"fmt"
"log"
"os"
"github.com/bonkzero404/uddin-lang"
)
func main() {
var (
file = flag.String("file", "", "UDDIN-LANG file to execute")
expr = flag.String("expr", "", "UDDIN-LANG expression to evaluate")
profile = flag.Bool("profile", false, "Show execution statistics")
)
flag.Parse()
engine := uddin.New()
if *file != "" {
stats, err := engine.ExecuteFile(*file)
if err != nil {
log.Fatal(err)
}
if *profile {
uddin.PrintStats(*stats, os.Stderr)
}
} else if *expr != "" {
result, stats, err := engine.EvaluateString(*expr)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Result: %v\n", result)
if *profile {
uddin.PrintStats(*stats, os.Stderr)
}
} else {
fmt.Println("Please specify either -file or -expr")
flag.Usage()
os.Exit(1)
}
}
Performance Tips
- Reuse Engine Instances: Create an engine once and reuse it for multiple executions
- Enable Memory Optimization: Use
EnableMemoryOptimization()
for memory-intensive operations - Parse Once, Execute Many: Parse programs once and execute them multiple times
- Use Unit Test Mode: Enable unit test mode when you don't need automatic main() execution
- Capture Output: Use custom stdout/stderr to avoid console I/O overhead in production
Error Handling
The library provides detailed error information including:
- Syntax errors with line and column numbers
- Runtime errors with context
- Type errors with expected vs actual types
- Name errors for undefined variables/functions
All errors implement the standard Go error
interface and can be handled using normal Go error handling patterns.
Variable Management
Setting Variables
The library provides SetVariable
and SetVariables
methods to pass data from your Go application to UDDIN-LANG scripts:
engine := uddin.New()
// Set individual variables
engine.SetVariable("username", "alice")
engine.SetVariable("score", 95)
engine.SetVariable("active", true)
// Set multiple variables at once
engine.SetVariables(map[string]any{
"config": map[string]any{
"timeout": 30,
"retries": 3,
},
"items": []string{"apple", "banana", "cherry"},
})
Variable Access Pattern
UDDIN-LANG follows a one-way data flow pattern:
- Go → UDDIN: Use
SetVariable
/SetVariables
to pass data to scripts - UDDIN → Go: Use return values, output capture, or result objects to get data back
// Pass data to script
engine.SetVariable("input", 42)
// Get result back via return value
result, _, err := engine.EvaluateString("input * 2")
fmt.Printf("Result: %v\n", result) // Result: 84
// Or capture output
var output bytes.Buffer
engine.SetStdout(&output)
engine.ExecuteString(`print("Processed: " + str(input * 2))`)
fmt.Printf("Output: %s", output.String())
This design promotes clean separation between your Go application logic and UDDIN-LANG scripts, making the integration more predictable and maintainable.