Skip to content

A JavaScript-inspired interpreted programming language with C++-like structure, built in Node.js.

Notifications You must be signed in to change notification settings

inertz/inertz-script

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Inertz Script

A JavaScript-inspired interpreted programming language with C++-like structure, built in Node.js.

Features

Data Types

  • Numbers: int and float (automatic detection)
  • Strings: "hello world"
  • Booleans: true, false
  • Null: null
  • Arrays: [1, 2, 3, "hello"]
  • Objects: {name: "Alice", age: 30}
  • Regular Expressions: /pattern/flags (via RegExp() constructor)
  • Sets: new Set([1, 2, 3])
  • Maps: new Map([["key", "value"]])

Language Constructs

  • Variables: var name = value;
  • Functions: function name(params) { ... }
  • Async Functions: async function name(params) { ... }
  • Arrow Functions: x => x * 2, (a, b) => a + b
  • Async Arrow Functions: async x => await someAsyncOp(x)
  • Classes: class MyClass { constructor() { ... } method() { ... } async asyncMethod() { ... } }
  • Inheritance: class ChildClass extends ParentClass { ... }
  • Object Instantiation: var obj = new MyClass();
  • this keyword: Refers to the current object instance within methods.
  • super keyword: Used to call methods on the superclass.
  • await keyword: Pause execution until a Promise resolves (only inside async functions).
  • Control Flow: if/else, while loops, for loops
  • For-In Loops: for (var key in object) and for (var index in array)
  • Loop Control: break and continue statements
  • Exception Handling: try/catch/finally, throw
  • Modules: import, export, from, as, default for organizing code.
  • Operators: Arithmetic (+, -, *, /, %), Comparison (==, !=, >, <, >=, <=), Logical (&&, ||, !)
  • Ternary: condition ? true_value : false_value
  • Array Access: array[index]
  • Object/Instance Access: object.property or object["property"]

Built-in Functions

Basic Functions

  • print(...) - Output to console
  • len(value) - Get length of string, array, object, Set, or Map
  • typeof(value) - Get type of value
  • delay(milliseconds) - Returns a Promise that resolves after a given time (for async examples)

Array Manipulation

  • push(array, value) - Add element to array
  • pop(array) - Remove and return last element from array

Array Methods (Functional Programming)

  • map(array, function) - Transform each element using a function
  • filter(array, function) - Keep elements that match a condition
  • reduce(array, function, initialValue) - Combine all elements into single value
  • find(array, function) - Get first element that matches condition
  • some(array, function) - Check if any element matches condition
  • every(array, function) - Check if all elements match condition
  • forEach(array, function) - Execute function for each element
  • indexOf(array, element) - Find index of element (-1 if not found)
  • includes(array, element) - Check if array contains element
  • slice(array, start, end) - Extract portion of array
  • splice(array, start, deleteCount, ...items) - Modify array by removing/adding elements

Object Functions

  • keys(object) - Get array of object keys
  • values(object) - Get array of object values
  • hasOwnProperty(object, property) - Check if object has property
  • assign(target, ...sources) - Copy properties from source objects to target

Math Functions

  • abs(number) - Absolute value
  • floor(number) - Floor function
  • ceil(number) - Ceiling function
  • round(number) - Round to nearest integer
  • sqrt(number) - Square root
  • pow(base, exp) - Power function

Regular Expression Functions

  • RegExp(pattern, flags) - Constructor to create a regular expression object.
    • pattern: A string containing the regular expression pattern.
    • flags: An optional string containing flags (e.g., "g" for global, "i" for case-insensitive).
    • Returns a RegExp object with methods:
      • regex.test(string): Returns true if the regex matches the string, false otherwise.
      • regex.exec(string): Returns an array of match results or null.
      • regex.source: Returns the source pattern string.
      • regex.flags: Returns the flags string.

Set Functions (New!)

  • Set(iterable) - Constructor to create a Set object.
    • iterable: An optional array or other iterable to initialize the set.
    • Returns a Set object with methods:
      • set.add(value): Adds a value to the set.
      • set.delete(value): Deletes a value from the set.
      • set.has(value): Returns true if a value is in the set.
      • set.clear(): Removes all elements from the set.
      • set.size: Returns the number of elements in the set.

Map Functions (New!)

  • Map(iterable) - Constructor to create a Map object.
    • iterable: An optional array of [key, value] pairs or other iterable to initialize the map.
    • Returns a Map object with methods:
      • map.set(key, value): Sets a value for a key in the map.
      • map.get(key): Returns the value associated with the key.
      • map.delete(key): Deletes a key-value pair from the map.
      • map.has(key): Returns true if a key exists in the map.
      • map.clear(): Removes all key-value pairs from the map.
      • map.size: Returns the number of key-value pairs in the map.
      • map.keys(): Returns an array of keys in insertion order.
      • map.values(): Returns an array of values in insertion order.
      • map.entries(): Returns an array of [key, value] pairs in insertion order.

JSON Functions (New!)

  • JSON.stringify(value, replacer, space): Converts a JavaScript value to a JSON string.
    • value: The value to convert to a JSON string.
    • replacer: (Optional) A function or an array that transforms the results.
    • space: (Optional) A string or number of spaces to use for indentation.
  • JSON.parse(jsonString): Parses a JSON string, constructing the JavaScript value or object described by the string.
    • jsonString: The JSON string to parse.

Installation & Usage

Running Files

# Install dependencies
npm install

# Run a Inertz Script file
npm start examples/demo.is
npm run example

# Run arrays and objects example
node src/main.js examples/arrays-objects.is

# Run for loops example
node src/main.js examples/for-loops.is

# Run break and continue example
node src/main.js examples/break-continue.is

# Run array methods example
node src/main.js examples/array-methods.is

# Run advanced features example
node src/main.js examples/advanced-features.is

# Run specific file
node src/main.js path/to/your/file.is

Interactive REPL

# Start the REPL
npm run repl

# In REPL, type Inertz Script code:
inertz> var numbers = [1, 2, 3, 4, 5];
inertz> var doubled = map(numbers, x => x * 2);
inertz> print(doubled);
[2, 4, 6, 8, 10]
inertz> async function test() { await delay(100); print("Delayed!"); }
inertz> test();
inertz> var myRegex = RegExp("hello", "i");
inertz> print(myRegex.test("Hello World")); // true
inertz> print(myRegex.exec("Hello World")); // ["Hello"]
inertz> var mySet = new Set([1, 2, 3]);
inertz> print(mySet.has(2)); // true
inertz> var myMap = new Map([["key", "value"]]);
inertz> print(myMap.get("key")); // "value"
inertz> var obj = {a: 1, b: "hello"};
inertz> print(JSON.stringify(obj)); // {"a":1,"b":"hello"}
inertz> exit

Running Tests

npm test

Exception Handling

Try/Catch/Finally

try {
    // Risky code
    throw "Something went wrong!";
} catch (error) {
    print("Caught error:", error);
} finally {
    print("This always executes");
}

Throwing Exceptions

function safeDivide(a, b) {
    if (b == 0) {
        throw "Division by zero";
    }
    return a / b;
}

try {
    var result = safeDivide(10, 0);
} catch (error) {
    print("Error:", error);
}

Arrow Functions

Basic Syntax

// Single parameter
var double = x => x * 2;

// Multiple parameters
var add = (a, b) => a + b;

// With array methods
var numbers = [1, 2, 3, 4, 5];
var doubled = map(numbers, x => x * 2);
var evens = filter(numbers, x => x % 2 == 0);
var sum = reduce(numbers, (acc, x) => acc + x, 0);

Complex Examples

var people = [
    {name: "Alice", age: 25, salary: 50000},
    {name: "Bob", age: 30, salary: 60000}
];

// Chain operations with arrow functions
var highEarnerNames = map(
    filter(people, person => person.salary >= 60000),
    person => person.name
);

Classes and Inheritance

Basic Class Definition

class Greeter {
    constructor(name) {
        this.name = name;
    }

    greet() {
        print("Hello, " + this.name + "!");
    }
}

var g = new Greeter("World");
g.greet(); // Output: Hello, World!

Inheritance

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        print(this.name + " makes a sound.");
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }

    speak() {
        super.speak(); // Call parent method
        print(this.name + " barks!");
    }

    fetch() {
        print(this.name + " fetches the ball.");
    }
}

var myDog = new Dog("Buddy", "Golden Retriever");
myDog.speak();
myDog.fetch();
// Output:
// Buddy makes a sound.
// Buddy barks!
// Buddy fetches the ball.

Modules (New!)

Exporting

// math.is
export var PI = 3.14159;
export function add(a, b) { return a + b; }
export default class Calculator {
    add(a, b) { return a + b; }
}

Importing

// main.is
import { PI, add as sum } from "./math.is";
import MyCalc from "./math.is";
import * as MathUtils from "./math.is";

print(PI); // 3.14159
print(sum(1, 2)); // 3

var calc = new MyCalc();
print(calc.add(5, 6)); // 11

print(MathUtils.PI); // 3.14159

Async/Await (New!)

Async Functions

async function delayedPrint(message, ms) {
    print("Starting delay for:", message);
    await delay(ms);
    print("Finished delay for:", message);
    return "Done: " + message;
}

async function main() {
    print("Main started.");
    var result1 = await delayedPrint("First task", 50);
    print(result1);
    var result2 = await delayedPrint("Second task", 20);
    print(result2);
    print("Main finished.");
}

main();
// Expected (approximate) output order:
// Main started.
// Starting delay for: First task
// Finished delay for: First task
// Done: First task
// Starting delay for: Second task
// Finished delay for: Second task
// Done: Second task
// Main finished.

Async Arrow Functions

var asyncMultiply = async (a, b) => {
    await delay(10);
    return a * b;
};

async function calculate() {
    var product = await asyncMultiply(3, 4);
    print("Product:", product);
}

calculate(); // Output: Product: 12 (after a short delay)

Async Class Methods

class DataFetcher {
    constructor(source) {
        this.source = source;
    }

    async fetch() {
        print("Fetching from " + this.source + "...");
        await delay(100); // Simulate network request
        return "Data from " + this.source;
    }
}

async function app() {
    var fetcher = new DataFetcher("API");
    var data = await fetcher.fetch();
    print(data);
}

app();
// Output:
// Fetching from API...
// Data from API

Project Structure

inertz-script/
├── src/
│   ├── main.js         # Main CLI interface
│   ├── repl.js         # Interactive REPL
│   ├── lexer.js        # Tokenizer/Lexer
│   ├── parser.js       # Parser (generates AST)
│   ├── ast.js          # AST node definitions
│   ├── interpreter.js  # Interpreter/Evaluator
│   ├── environment.js  # Variable scoping
│   ├── builtins.js     # Built-in functions
│   ├── token.js        # Token definitions
│   └── test.js         # Test suite
├── examples/
│   ├── demo.is         # Language showcase
│   ├── fibonacci.is    # Fibonacci sequence
│   ├── calculator.is   # Simple calculator
│   ├── arrays-objects.is # Arrays and objects demo
│   ├── for-loops.is    # For loops demonstration
│   ├── break-continue.is # Break and continue examples
│   ├── array-methods.is # Array methods demonstration
│   ├── advanced-features.is # Exception handling, arrow functions, etc.
│   ├── classes.is      # Classes and inheritance examples
│   ├── modules/        # New: Directory for module examples
│   │   ├── main.is
│   │   └── math.is
│   └── async-await.is  # New: Async/await examples
└── README.md

Language Design

Inertz Script follows these design principles:

  1. Familiar Syntax: JavaScript-inspired syntax for ease of learning
  2. Strong Foundation: Proper lexer, parser, and AST-based interpreter
  3. Modular Architecture: Clean separation of concerns
  4. Extensible: Easy to add new features and built-ins
  5. Error Handling: Comprehensive error reporting with try/catch/finally
  6. Rich Data Types: Support for arrays and objects with intuitive syntax
  7. Flexible Iteration: Multiple loop types for different use cases
  8. Structured Control Flow: Break and continue for precise loop control
  9. Functional Programming: Array methods and arrow functions for elegant data transformation
  10. Exception Safety: Proper exception handling with custom error types
  11. Object-Oriented: Support for classes, inheritance, this, and super for structured code.
  12. Asynchronous Programming: First-class support for async/await for handling non-blocking operations.
  13. Regular Expressions: Built-in RegExp constructor and methods for powerful string pattern matching.
  14. Standard Library: Expanded with JSON object and Set/Map data structures.

Technical Implementation

  • Lexical Analysis: Converts source code into tokens (including async, await, module keywords)
  • Parsing: Builds Abstract Syntax Tree (AST) using recursive descent parser (now includes async functions, await expressions, import, export nodes)
  • Interpretation: Tree-walking interpreter with proper scoping, now fully asynchronous to handle Promises and await expressions.
  • Environment: Lexical scoping with environment chains
  • Built-ins: Native function support with proper arity checking, including new delay for async examples, RegExp constructor, Set constructor, Map constructor, and JSON object.
  • Data Structures: Native JavaScript arrays and objects with Inertz Script syntax, now including InertzRegExp, InertzSet, and InertzMap wrappers.
  • Loop Constructs: Traditional for loops and for-in iteration
  • Exception Handling: Try/catch/finally with custom exception types
  • Arrow Functions: Concise function syntax with lexical scoping, now supporting async variants.
  • Enhanced Array Methods: Comprehensive functional programming support
  • Object Methods: Better support for object-oriented patterns
  • Classes and Inheritance: Custom InertzClass and InertzInstance runtime objects for full OOP support, including async methods.
  • Module System: Implemented import and export statements with a module caching mechanism for code organization and reusability.
  • Regular Expressions: Introduced InertzRegExp class to wrap native RegExp objects, exposing test, exec, source, and flags methods.

Advanced Features

Exception Handling

  • Try/Catch/Finally: Full exception handling support
  • Custom Exceptions: Throw custom error messages
  • Nested Exception Handling: Try/catch blocks can be nested
  • Finally Blocks: Code that always executes regardless of exceptions

Arrow Functions

  • Concise Syntax: x => x * 2 for single parameters, (a, b) => a + b for multiple
  • Lexical Scoping: Arrow functions capture variables from enclosing scope
  • Functional Programming: Perfect for use with array methods
  • Expression Bodies: Arrow functions return the expression result automatically
  • Async Arrow Functions: async (a, b) => await somePromise()

Enhanced Array Methods

  • forEach: Execute function for each element without returning new array
  • indexOf: Find the index of an element in the array
  • includes: Check if array contains a specific element
  • slice: Extract a portion of array without modifying original
  • splice: Modify array by removing/adding elements at specific positions

Object Methods

  • hasOwnProperty: Check if object has a specific property
  • assign: Copy properties from source objects to target object
  • Enhanced Object Manipulation: Better support for object-oriented patterns

Classes and Inheritance

  • Class Declarations: Define custom types with class MyClass { ... }
  • Constructors: Special constructor method for initializing new instances.
  • Methods: Functions defined within a class, automatically bound to this.
  • this Keyword: Access instance properties and methods.
  • Inheritance: Extend existing classes using extends.
  • super Keyword: Call methods of the parent class.
  • Object Instantiation: Create new objects using the new keyword.
  • Async Methods: async methods within classes that can use await.

Modules

  • import statements: Support for named imports ({ name }), aliased named imports ({ name as alias }), namespace imports (* as namespace), default imports (defaultName), and side-effect imports ("module").
  • export statements: Support for named exports (export var/function/class, export { name }), and default exports (export default ...).
  • Module Resolution: Basic relative path resolution for module imports.
  • Module Caching: Modules are loaded and interpreted only once.

Async/Await

  • async keyword: Marks a function (or method, or arrow function) as asynchronous, allowing it to use the await keyword and implicitly returning a Promise.
  • await keyword: Can only be used inside an async function. It pauses the execution of the async function until the Promise it's waiting on settles (resolves or rejects), and then resumes execution with the resolved value.
  • Promise Integration: The interpreter now natively handles JavaScript Promises, allowing them to be returned from async functions and awaited.

Regular Expressions

  • RegExp(pattern, flags) constructor: Create regular expression objects.
  • regex.test(string): Check for a match.
  • regex.exec(string): Get match details.
  • regex.source: Access the pattern string.
  • regex.flags: Access the flags string.
// Example: Using RegExp
var emailRegex = RegExp("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
print(emailRegex.test("test@example.com")); // true
print(emailRegex.test("invalid-email")); // false

var globalMatch = RegExp("a", "g");
var text = "banana";
var match1 = globalMatch.exec(text); // ["a"]
var match2 = globalMatch.exec(text); // ["a"]
var match3 = globalMatch.exec(text); // ["a"]
var match4 = globalMatch.exec(text); // null
print(match1);
print(match2);
print(match3);
print(match4);
print(globalMatch.source); // "a"
print(globalMatch.flags);   // "g"

Set Data Structure

  • new Set(iterable) constructor: Create Set objects.
  • set.add(value): Add elements.
  • set.delete(value): Remove elements.
  • set.has(value): Check for element existence.
  • set.clear(): Clear all elements.
  • set.size: Get the number of elements.
// Example: Using Set
var mySet = new Set();
print(typeof(mySet)); // "set"
mySet.add(10);
mySet.add("hello");
mySet.add(10); // Duplicate, won't be added again
print(mySet.has(10));    // true
print(mySet.has("world")); // false
print(mySet.size);       // 2

mySet.delete("hello");
print(mySet.has("hello")); // false
print(mySet.size);       // 1

var initialSet = new Set([1, 2, 2, 3, "apple"]);
print(initialSet.size); // 4 (duplicates removed)
print(initialSet);      // Set { 1, 2, 3, apple }

initialSet.clear();
print(initialSet.size); // 0

Map Data Structure

  • new Map(iterable) constructor: Create Map objects.
  • map.set(key, value): Set key-value pairs.
  • map.get(key): Retrieve values by key.
  • map.delete(key): Remove key-value pairs.
  • map.has(key): Check for key existence.
  • map.clear(): Clear all entries.
  • map.size: Get the number of entries.
  • map.keys(): Get an array of keys.
  • map.values(): Get an array of values.
  • map.entries(): Get an array of [key, value] pairs.
// Example: Using Map
var myMap = new Map();
print(typeof(myMap)); // "map"
myMap.set("name", "Alice");
myMap.set("age", 30);
myMap.set(1, "one");

print(myMap.get("name")); // "Alice"
print(myMap.get(1));      // "one"
print(myMap.has("age"));  // true
print(myMap.size);        // 3

myMap.delete("age");
print(myMap.has("age"));  // false
print(myMap.size);        // 2

var initialMap = new Map([["fruit", "apple"], ["color", "red"]]);
print(initialMap.get("fruit")); // "apple"
print(initialMap.keys());       // ["fruit", "color"]
print(initialMap.values());     // ["apple", "red"]
print(initialMap.entries());    // [["fruit", "apple"], ["color", "red"]]
print(initialMap);              // Map { fruit => apple, color => red }

initialMap.clear();
print(initialMap.size); // 0

JSON Object

  • JSON.stringify(value, replacer, space): Convert Inertz Script values to JSON strings.
  • JSON.parse(jsonString): Parse JSON strings into Inertz Script values.
// Example: Using JSON
var data = {
    name: "Inertz",
    version: 1.0,
    isInterpreter: true,
    features: ["async", "modules", "classes"],
    config: null
};

// Stringify with no formatting
var jsonString = JSON.stringify(data);
print(jsonString);
// Output: {"name":"Inertz","version":1,"isInterpreter":true,"features":["async","modules","classes"],"config":null}

// Stringify with 2-space indentation
var prettyJson = JSON.stringify(data, null, 2);
print(prettyJson);
// Output:
// {
//   "name": "Inertz",
//   "version": 1,
//   "isInterpreter": true,
//   "features": [
//     "async",
//     "modules",
//     "classes"
//   ],
//   "config": null
// }

// Parse a JSON string
var parsedData = JSON.parse('{"user": "Alice", "id": 123, "active": true}');
print(parsedData.user);   // "Alice"
print(parsedData.id);     // 123
print(parsedData.active); // true

var jsonArray = JSON.parse('[10, "hello", false, null]');
print(jsonArray[0]); // 10
print(jsonArray[1]); // "hello"
print(jsonArray[2]); // false
print(jsonArray[3]); // null

Future Enhancements

  • Bytecode compilation
  • Debugging support

About

A JavaScript-inspired interpreted programming language with C++-like structure, built in Node.js.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published