Skip to content

Complete Syntax Reference ​

All NullScript Syntax in One Place

This comprehensive reference covers every aspect of NullScript syntax, from basic keywords to advanced language features.

Basic Syntax ​

File Extension ​

NullScript files use the .ns extension:

bash
# File naming
app.ns          # Main application file
utils.ns        # Utility functions
components.ns   # React components

Comments ​

javascript
// Single-line comment
/* Multi-line comment
   spanning multiple lines */

// NullScript also supports JavaScript-style comments

Semicolons ​

Semicolons are optional but recommended:

javascript
run greet() {
  speak.say("Hello")  // No semicolon needed
  return "Hello"       // But recommended for clarity
}

Keywords and Operators ​

Variable Declarations ​

JavaScriptNullScriptDescription
constfixedDeclare a constant (cannot be reassigned)
letletDeclare a mutable variable
varvarFunction-scoped variable (avoid in modern code)
javascript
// Variable declarations
fixed MAX_RETRIES = 3;           // Constant
let currentAttempt = 0;          // Mutable
var legacyVariable = "old";      // Function-scoped (avoid)

// Object destructuring
fixed { name, age } = person;
fixed [first, second] = array;

Function Declarations ​

JavaScriptNullScriptDescription
functionrunDeclare a function
=>=>Arrow function syntax (unchanged)
javascript
// Function declarations
run greet(name) {
  return `Hello, ${name}!`;
}

// Arrow functions (unchanged)
const greetArrow = (name) => `Hello, ${name}!`;
const processData = (data) => {
  return data.map(item => item.name);
};

Console Methods ​

JavaScriptNullScriptDescription
console.log()speak.say()Print information to console
console.error()speak.scream()Print error to console
console.warn()speak.whisper()Print warning to console
console.info()speak.tell()Print info to console
console.debug()speak.murmur()Print debug info to console
javascript
// Console methods
speak.say("This is information");
speak.scream("This is an error!");
speak.whisper("This is a warning");
speak.tell("This is info");
speak.murmur("This is debug info");

Boolean Values ​

JavaScriptNullScriptDescription
trueyesBoolean true value
falsenoBoolean false value
javascript
// Boolean values
fixed isActive = yes;
fixed isHidden = no;
fixed hasPermission = yes;

Control Flow Keywords ​

JavaScriptNullScriptDescription
ifwhateverConditional statement
elseotherwiseElse clause
else ifotherwise whateverElse if clause
switchchooseSwitch statement
caseoptionCase in switch
defaultfallbackDefault case
forwhenFor loop
whileduringWhile loop
dodoDo-while loop (unchanged)
breakbreakBreak statement (unchanged)
continuecontinueContinue statement (unchanged)

Class Keywords ​

JavaScriptNullScriptDescription
classmodelDefine a class
newfreshCreate new instance
thisselfReference to current instance
constructor__init__Class constructor
extendsextendsClass inheritance (unchanged)
supersuperCall parent constructor (unchanged)
staticstaticStatic methods (unchanged)

Module Keywords ​

JavaScriptNullScriptDescription
importuseImport modules
exportshareExport modules
fromfromImport source (unchanged)
defaultdefaultDefault export (unchanged)

Error Handling ​

JavaScriptNullScriptDescription
trytestTry block
catchgrabCatch block
finallyfinallyFinally block (unchanged)
throwthrowThrow error (unchanged)

Async/Await ​

JavaScriptNullScriptDescription
asynclaterAsync function
awaitholdAwait promise

Control Flow ​

Conditional Statements ​

javascript
// Basic if-else
whatever (user.isLoggedIn) {
  speak.say("Welcome back!");
} otherwise {
  speak.say("Please log in");
}

// If-else if-else
whatever (user.role === 'admin') {
  speak.say("Admin access granted");
} otherwise whatever (user.role === 'moderator') {
  speak.say("Moderator access granted");
} otherwise {
  speak.say("User access granted");
}

// Ternary operator (unchanged)
const message = user.isLoggedIn ? "Welcome!" : "Please log in";

Switch Statements ​

javascript
// Switch statement
choose (user.role) {
  option 'admin':
    speak.say("Full access granted");
    break;
  option 'moderator':
    speak.say("Moderate access granted");
    break;
  option 'user':
    speak.say("Basic access granted");
    break;
  fallback:
    speak.say("Guest access granted");
}

Loops ​

javascript
// For loop
when (let i = 0; i < 5; i++) {
  speak.say(`Count: ${i}`);
}

// For...of loop (unchanged)
for (const item of items) {
  speak.say(item.name);
}

// For...in loop (unchanged)
for (const key in object) {
  speak.say(`${key}: ${object[key]}`);
}

// While loop
during (condition) {
  // Loop body
  break; // Exit loop
}

// Do-while loop
do {
  // Loop body
} during (condition);

Functions ​

Function Declarations ​

javascript
// Basic function
run greet(name) {
  return `Hello, ${name}!`;
}

// Function with default parameters
run createUser(name, email, role = 'user') {
  return {
    name,
    email,
    role,
    createdAt: new Date()
  };
}

// Rest parameters
run sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

// Arrow functions (unchanged)
const multiply = (a, b) => a * b;
const processItems = (items) => items.map(item => item.name);

Function Types ​

javascript
// Regular function
run regularFunction() {
  return "Hello";
}

// Arrow function (unchanged)
const arrowFunction = () => "Hello";

// Generator function (unchanged)
function* generatorFunction() {
  yield 1;
  yield 2;
}

// Async function
later asyncFunction() {
  const result = hold fetch('/api/data');
  return hold result.json();
}

Classes and Objects ​

Class Definition ​

javascript
// Basic class
model User {
  __init__(name, email) {
    self.name = name;
    self.email = email;
    self.createdAt = new Date();
  }

  run getInfo() {
    return `${self.name} (${self.email})`;
  }

  run updateEmail(newEmail) {
    self.email = newEmail;
    self.updatedAt = new Date();
  }
}

// Class inheritance
model Admin extends User {
  __init__(name, email, permissions) {
    super(name, email);
    self.permissions = permissions;
  }

  run hasPermission(permission) {
    return self.permissions.includes(permission);
  }
}

// Using classes
fixed user = fresh User("Alice", "alice@example.com");
fixed admin = fresh Admin("Bob", "bob@example.com", ["read", "write", "delete"]);

Object Literals ​

javascript
// Object creation
fixed person = {
  name: "Alice",
  age: 30,
  isActive: yes,

  // Method shorthand
  greet() {
    return `Hello, I'm ${self.name}`;
  }
};

// Object destructuring
fixed { name, age } = person;
fixed { name: userName, age: userAge } = person;

// Object spread
fixed updatedPerson = { ...person, age: 31 };

Modules ​

Import Statements ​

javascript
// Named imports
use { useState, useEffect } from 'react';
use { format, parseISO } from 'date-fns';

// Default imports
use React from 'react';
use express from 'express';

// Mixed imports
use React, { useState, useEffect } from 'react';

// Renamed imports
use { useState as useLocalState } from 'react';

// Namespace imports
use * as utils from './utils.ns';

Export Statements ​

javascript
// Named exports
run formatDate(date) {
  return date.toLocaleDateString();
}

run validateEmail(email) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

share { formatDate, validateEmail };

// Default export
run App() {
  return <div>Hello World</div>;
}

share default App;

// Re-exporting
share { formatDate } from './dateUtils.ns';
share default from './MainComponent.ns';

Advanced Features ​

Template Literals ​

javascript
// Basic template literals (unchanged)
fixed name = "Alice";
fixed greeting = `Hello, ${name}!`;

// Multi-line strings
fixed multiLine = `
  This is a multi-line
  string in NullScript
  with ${name} as a variable
`;

// Tagged templates (unchanged)
run highlight(strings, ...values) {
  return strings.reduce((result, str, i) => {
    return result + str + (values[i] ? `<mark>${values[i]}</mark>` : '');
  }, '');
}

Destructuring ​

javascript
// Array destructuring
fixed [first, second, ...rest] = [1, 2, 3, 4, 5];

// Object destructuring
fixed { name, age, ...otherProps } = person;

// Nested destructuring
fixed { address: { city, country } } = user;

// Default values
fixed { name = "Anonymous", age = 18 } = user;

Spread and Rest ​

javascript
// Array spread
fixed numbers = [1, 2, 3];
fixed moreNumbers = [...numbers, 4, 5];

// Object spread
fixed baseConfig = { timeout: 5000 };
fixed fullConfig = { ...baseConfig, retries: 3 };

// Rest parameters
run sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

// Rest destructuring
fixed [first, ...rest] = [1, 2, 3, 4, 5];
fixed { name, ...otherProps } = user;

Optional Chaining and Nullish Coalescing ​

javascript
// Optional chaining (unchanged)
const userName = user?.profile?.name;
const userAge = user?.profile?.age ?? 18;

// Nullish coalescing (unchanged)
const displayName = user.name ?? "Anonymous";
const retryCount = config.retries ?? 3;

JavaScript Compatibility ​

What Works Unchanged ​

javascript
// All JavaScript syntax works
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((n) => n * 2);
const sum = numbers.reduce((total, n) => total + n, 0);

// Modern JavaScript features
const { name, age } = person;
const [first, second] = array;
const newArray = [...oldArray, newItem];

// Async/await
async function fetchData() {
  try {
    const response = await fetch("/api/data");
    return await response.json();
  } catch (error) {
    console.error("Error:", error);
  }
}

Mixed Usage ​

javascript
// Mix JavaScript and NullScript
function legacyFunction() {  // JavaScript function
  return "legacy";
}

run modernFunction() {        // NullScript function
  return "modern";
}

// Use both in the same file
const legacy = legacyFunction();
const modern = modernFunction();
speak.say(`${legacy} + ${modern}`);

Testing Syntax ​

Jest Testing ​

javascript
// Test file: user.test.ns
use { User } from './user.ns';

describe('User Class', () => {
  test('should create user with name and email', () => {
    fixed user = fresh User("Alice", "alice@example.com");

    expect(user.name).toBe("Alice");
    expect(user.email).toBe("alice@example.com");
    expect(user.createdAt).toBeInstanceOf(Date);
  });

  test('should update email', () => {
    fixed user = fresh User("Alice", "alice@example.com");
    user.updateEmail("alice.new@example.com");

    expect(user.email).toBe("alice.new@example.com");
    expect(user.updatedAt).toBeInstanceOf(Date);
  });
});

Common Pitfalls ​

1. Keyword Conflicts ​

javascript
// ❌ Don't use reserved keywords as variable names
let run = "function"; // 'run' is a keyword
let whatever = "if"; // 'whatever' is a keyword

// ✅ Use descriptive names instead
let functionName = "function";
let conditionType = "if";

2. Module Import/Export Consistency ​

javascript
// ❌ Mixing import styles
use { useState } from 'react';
import { useEffect } from 'react';  // Inconsistent

// ✅ Use consistent NullScript syntax
use { useState, useEffect } from 'react';

3. Boolean Value Usage ​

javascript
// ❌ Mixing boolean values
let isActive = true; // JavaScript style
let isHidden = no; // NullScript style

// ✅ Use consistent NullScript style
let isActive = yes;
let isHidden = no;

Quick Reference Card ​

Essential Keywords ​

javascript
fixed; // const
let // let (unchanged)
  run; // function
speak.say(); // console.log()
yes; // true
no; // false
whatever; // if
otherwise; // else
when; // for
during; // while
model; // class
fresh; // new
self; // this
use; // import
share; // export
test; // try
grab; // catch
later; // async
hold; // await

Common Patterns ​

javascript
// Function declaration
run functionName(param) { ... }

// Conditional
whatever (condition) { ... } otherwise { ... }

// Loop
when (let i = 0; i < n; i++) { ... }

// Class
model ClassName { __init__() { ... } }

// Import/Export
use { name } from 'module';
share { name };

Need more details on specific features? 📖

View Keywords | Try Examples | Use Playground