Transpiler Usage Guide
The JSSON transpiler is the engine that converts your clean JSSON syntax into valid JSON. Let’s explore how it works and how to use it! ⚙️
How It Works
Section titled “How It Works”The transpiler follows a three-stage pipeline:
JSSON Source → Lexer → Parser → Transpiler → JSON Output1. Lexer (Tokenization)
Section titled “1. Lexer (Tokenization)”Breaks your JSSON into tokens:
name = JoãoBecomes:
IDENT("name") ASSIGN IDENT("João")2. Parser (AST Generation)
Section titled “2. Parser (AST Generation)”Creates an Abstract Syntax Tree:
Program└── AssignmentStatement ├── name: "name" └── value: StringLiteral("João")3. Transpiler (JSON Generation)
Section titled “3. Transpiler (JSON Generation)”Converts the AST to JSON:
{ "name": "João"}Using the Transpiler
Section titled “Using the Transpiler”Command Line
Section titled “Command Line”The easiest way:
jsson -i input.jsson -o output.jsonProgrammatic Usage (Go)
Section titled “Programmatic Usage (Go)”Use JSSON as a library in your Go code:
package main
import ( "fmt" "jsson/internal/lexer" "jsson/internal/parser" "jsson/internal/transpiler")
func main() { // Your JSSON source source := ` app { name = "My App" version = "1.0.0" } `
// Step 1: Lex l := lexer.New(source)
// Step 2: Parse p := parser.New(l) program := p.ParseProgram()
// Check for parse errors if len(p.Errors()) > 0 { for _, err := range p.Errors() { fmt.Println(err) } return }
// Step 3: Transpile t := transpiler.New() json, err := t.Transpile(program) if err != nil { fmt.Println("Transpile error:", err) return }
fmt.Println(json)}Reading from Files
Section titled “Reading from Files”package main
import ( "fmt" "os" "jsson/internal/lexer" "jsson/internal/parser" "jsson/internal/transpiler")
func transpileFile(inputPath, outputPath string) error { // Read input file content, err := os.ReadFile(inputPath) if err != nil { return err }
// Lex and parse l := lexer.New(string(content)) l.SetSourceFile(inputPath) // For better error messages
p := parser.New(l) program := p.ParseProgram()
if len(p.Errors()) > 0 { for _, err := range p.Errors() { fmt.Println(err) } return fmt.Errorf("parse errors") }
// Transpile t := transpiler.New() json, err := t.Transpile(program) if err != nil { return err }
// Write output return os.WriteFile(outputPath, []byte(json), 0644)}
func main() { err := transpileFile("config.jsson", "config.json") if err != nil { fmt.Println("Error:", err) os.Exit(1) }}Output Formats
Section titled “Output Formats”Currently, JSSON transpiles to JSON. Future versions may support:
- YAML — For Kubernetes configs
- TOML — For Rust/Go configs
- XML — For legacy systems
- Custom formats — Via plugins
Performance Considerations
Section titled “Performance Considerations”File Size
Section titled “File Size”JSSON handles files efficiently:
- Small files (< 1KB): Instant
- Medium files (1-100KB): < 100ms
- Large files (> 100KB): < 1s
Memory Usage
Section titled “Memory Usage”The transpiler loads the entire file into memory. For very large files (> 10MB), consider:
- Splitting with includes
- Processing in chunks
- Streaming (future feature)
Optimization Tips
Section titled “Optimization Tips”1. Use includes for large configs:
// Instead of one 1000-line fileinclude "users.jsson" // 200 linesinclude "products.jsson" // 300 linesinclude "settings.jsson" // 500 lines2. Avoid deeply nested structures:
// This is fineuser { profile { settings { theme = dark } }}
// This might be slow (10+ levels deep)a { b { c { d { e { f { g { h { i { j { value = deep}}}}}}}}}}3. Use template arrays efficiently:
// Good - 1000 usersusers [ template { name, email } // ... 1000 rows]
// Better - split into multiple filesinclude "users-1-500.jsson"include "users-501-1000.jsson"Error Handling
Section titled “Error Handling”The transpiler provides detailed error messages:
Lex Errors
Section titled “Lex Errors”Lex goblin: config.jsson:15:8 — Illegal character: '@'Parse Errors
Section titled “Parse Errors”Parse wizard: config.jsson:20:5 — Unexpected token: expected '=', got '{'Transpile Errors
Section titled “Transpile Errors”Transpiler gremlin: config.jsson:25:10 — Undefined reference: 'config.port'See the Errors & Debugging guide for details!
Extending the Transpiler
Section titled “Extending the Transpiler”Custom Output Format (Future)
Section titled “Custom Output Format (Future)”// Future API (not yet implemented)type OutputFormatter interface { Format(program *ast.Program) (string, error)}
type YAMLFormatter struct{}
func (y *YAMLFormatter) Format(program *ast.Program) (string, error) { // Convert AST to YAML return yaml, nil}
// Usaget := transpiler.New()t.SetFormatter(&YAMLFormatter{})output, _ := t.Transpile(program)Custom Transformations
Section titled “Custom Transformations”You can modify the AST before transpiling:
// Example: Add a timestamp to all objectsfunc addTimestamp(program *ast.Program) { for _, stmt := range program.Statements { if assign, ok := stmt.(*ast.AssignmentStatement); ok { if obj, ok := assign.Value.(*ast.ObjectLiteral); ok { // Add timestamp field obj.Pairs["_timestamp"] = &ast.StringLiteral{ Value: time.Now().Format(time.RFC3339), } } } }}
// Use itprogram := p.ParseProgram()addTimestamp(program)json, _ := t.Transpile(program)Integration Examples
Section titled “Integration Examples”Web Server
Section titled “Web Server”package main
import ( "net/http" "jsson/internal/lexer" "jsson/internal/parser" "jsson/internal/transpiler")
func transpileHandler(w http.ResponseWriter, r *http.Request) { // Read JSSON from request body body, _ := io.ReadAll(r.Body)
// Transpile l := lexer.New(string(body)) p := parser.New(l) program := p.ParseProgram()
if len(p.Errors()) > 0 { http.Error(w, p.Errors()[0], http.StatusBadRequest) return }
t := transpiler.New() json, err := t.Transpile(program) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return }
w.Header().Set("Content-Type", "application/json") w.Write([]byte(json))}
func main() { http.HandleFunc("/transpile", transpileHandler) http.ListenAndServe(":8080", nil)}Build Tool Plugin
Section titled “Build Tool Plugin”// Webpack/Vite plugin conceptfunc JssonPlugin() { return Plugin{ Name: "jsson", Transform: func(code, id string) (string, error) { if !strings.HasSuffix(id, ".jsson") { return code, nil }
// Transpile JSSON to JSON l := lexer.New(code) p := parser.New(l) program := p.ParseProgram()
t := transpiler.New() json, err := t.Transpile(program) if err != nil { return "", err }
// Return as JS module return fmt.Sprintf("export default %s", json), nil }, }}What’s Next?
Section titled “What’s Next?”- AST Reference — Understand the Abstract Syntax Tree
- Errors & Debugging — Handle errors gracefully
- CLI Guide — Master the command-line tool
The transpiler is the heart of JSSON — now you know how it works! ⚙️