JASON is a JSON-based scripting language that combines the readability of JSON with the power of programming constructs. It's designed to be simple to understand yet capable of handling complex programming tasks.
- Features
- Basic Syntax
- Standard Library
- Control Structures
- Java Interoperability
- Examples
- Error Handling
- Best Practices
- Limitations & Future Improvements
- JSON-based syntax for easy parsing and writing
- First-class function support
- Built-in standard library
- Type system with support for integers, floats, strings
- Control flow structures (if-else, while loops)
- Java interoperability through reflection and annotations
- Mathematical functions and operations
- Unit testing framework
{
"myFunction": {
"type": "function",
"name": "myFunction",
"return_type": "int",
"parameters": ["x", "y"],
"parameter_types": ["int", "int"],
"body": [
// Function statements
]
}
}{
"type": "variable",
"name": "result",
"value": {
"type": "operation",
"operator": "+",
"left": {
"type": "variable",
"name": "x"
},
"right": {
"type": "value",
"value": 1
}
}
}print(value): Prints a valueprintln(value): Prints a value with a newlinedownload(url): Downloads content from a URLinvoke(className, methodName, ...args): Invokes Java methods
abs(number): Absolute valuesqrt(number): Square rootsin(number): Sinecos(number): Cosinetan(number): Tangent
{
"type": "if",
"condition": {
"type": "operation",
"operator": "==",
"left": {
"type": "variable",
"name": "x"
},
"right": {
"type": "value",
"value": 0
}
},
"then": [
// Then statements
],
"else": [
// Else statements
]
}{
"type": "while_loop",
"condition": {
"type": "operation",
"operator": "<",
"left": {
"type": "variable",
"name": "i"
},
"right": {
"type": "value",
"value": 10
}
},
"body": [
// Loop body
]
}JASON provides annotations for Java integration:
@Interpreter.ScriptType: Marks a class as available to JASON@Interpreter.ScriptConstructor: Exposes constructors@Interpreter.ScriptFunction: Exposes methods
@Interpreter.ScriptType(name = "Person")
public class Person {
private String name;
private int age;
@Interpreter.ScriptConstructor(name="withParams")
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Interpreter.ScriptConstructor(name="default")
public Person() {
this.name="joe";
this.age=80;
}
@Interpreter.ScriptFunction(name = "getName")
public String getName() {
return name;
}
@Interpreter.ScriptFunction(name = "greet")
public void greet(){
System.out.println("Greetings, im " + name + " and i am " + age);
}
}{
"createPerson": {
"type": "function",
"name": "createPerson",
"return_type": "void",
"parameters": [],
"parameter_types": [],
"body": [
{
"type": "variable",
"name": "person",
"value": {
"type": "call",
"name": "Person.withParams",
"arguments": [
{
"type": "value",
"value": "Alice"
},
{
"type": "value",
"value": 25
}
]
}
},
{
"type": "call",
"name": "person.greet",
"arguments": []
}
]
}
}{
"fibonacci": {
"type": "function",
"name": "fibonacci",
"return_type": "int",
"parameters": ["n"],
"parameter_types": ["int"],
"body": [
{
"type": "if",
"condition": {
"type": "operation",
"operator": "<=",
"left": {
"type": "variable",
"name": "n"
},
"right": {
"type": "value",
"value": 1
}
},
"then": [
{
"type": "return",
"value": {
"type": "variable",
"name": "n"
}
}
]
},
{
"type": "return",
"value": {
"type": "operation",
"operator": "+",
"left": {
"type": "call",
"name": "fibonacci",
"arguments": [
{
"type": "operation",
"operator": "-",
"left": {
"type": "variable",
"name": "n"
},
"right": {
"type": "value",
"value": 1
}
}
]
},
"right": {
"type": "call",
"name": "fibonacci",
"arguments": [
{
"type": "operation",
"operator": "-",
"left": {
"type": "variable",
"name": "n"
},
"right": {
"type": "value",
"value": 2
}
}
]
}
}
}
]
}
}{
"assertEquals": {
"type": "function",
"name": "assertEquals",
"return_type": "void",
"parameters": ["expected", "actual", "message"],
"parameter_types": ["any", "any", "string"],
"body": [
{
"type": "if",
"condition": {
"type": "operation",
"operator": "!=",
"left": {
"type": "variable",
"name": "expected"
},
"right": {
"type": "variable",
"name": "actual"
}
},
"then": [
{
"type": "call",
"name": "println",
"arguments": [
{
"type": "operation",
"operator": "+",
"left": {
"type": "value",
"value": "❌ Test failed: "
},
"right": {
"type": "variable",
"name": "message"
}
}
]
}
],
"else": [
{
"type": "call",
"name": "println",
"arguments": [
{
"type": "operation",
"operator": "+",
"left": {
"type": "value",
"value": "✓ Test passed: "
},
"right": {
"type": "variable",
"name": "message"
}
}
]
}
]
}
]
}
}The interpreter throws InterpreterException with detailed error messages and position information for:
- Type mismatches
- Unknown functions
- Invalid operations
- Runtime errors
-
Code Organization
- Use descriptive function and variable names
- Structure code using functions for reusability
- Include proper type annotations
-
Java Integration
- Use meaningful names for exposed constructors and methods
- Keep method signatures simple
- Provide proper error handling
- Document parameter types and return values
-
Testing
- Use the built-in testing framework
- Write comprehensive test cases
- Test edge cases and error conditions
-
Performance
- Avoid deep recursion when possible
- Use appropriate data types
- Consider caching results for expensive operations
- Basic data types only (int, float, string)
- No direct array support
- Limited to synchronous operations
- Standard library functions implemented in Kotlin/Java
- Array and collection support
- More data structures
- Enhanced standard library
- Asynchronous operations
- Native implementation of standard library functions
- Additional mathematical and utility functions
We welcome contributions! Please feel free to submit pull requests or open issues for:
- Bug fixes
- New features
- Documentation improvements
- Test cases
- Examples