TEMP_JS was born out of a desire to help developers focus purely on logic in programming and worry less about
superficial rules. It is a statically-typed, transpiled language that embraces simplicity using intelligent type
inference to give you the safety of a compiled language with the lightweight feel of a scripting language, combining
aspects of famous languages like Python, Rust, JavaScript, and more.
The core philosophy behind TEMP_JS is safety through minimalism. We ditched semicolons and made variables
immutable by default to prevent accidental state changes, requiring an explicit mut keyword to allow
reassignment. Whether you are iterating through arrays or evaluating complex logical expressions, the language
gets out of your way and catches your logical errors at compile-time.
TEMP_JS serves as a complete showcase of modern compiler
architecture. Through semantic analysis and constant-folding optimization down to its final JavaScript code
generation, everything is designed to make the programmer feel at ease with their work.
Language Features
Core Type System
num: Support for both integers and floating-point numbers.
str: Standard string literals defined by double quotes ("...").
bool: Boolean logic using true and false.
array: Typed array literals (e.g., [1, 2, 3]).
Enums: User-defined types for categorical data.
Variables & State
let x = 5: Creates an immutable binding; the value cannot be changed.
mut x = 5: Creates a mutable binding. The variable is type-locked upon
initialization but allows reassignment.
x = 5: Reassigns a value to an existing mut variable.
a[0] = 99: Performs index assignment (supported for mut arrays only).
Expressions & Operators
Arithmetic:+, -, *, /, %,
and ** (exponentiation).
Comparison:==, !=, <, <=, >
, >=.
Logical:&& (AND), || (OR), ! (NOT).
F-strings: Powerful template literals using f"hello {name}" syntax.
Accessors: Array indexing via a[i] and enum member access via Color.Red.
Control Flow
Branching:if / else blocks for conditional logic.
Iteration:while loops for condition-based entry and for...in loops
for array traversal.
Pattern Matching: The match statement provides robust branching with mandatory
exhaustiveness checking.
Jump Statements:break to exit loops and return (with or without a value)
for functions.
Safety & Optimization
Static Analysis: Enforces scope isolation, detects undeclared variables, and ensures type consistency.
Match Exhaustiveness: Ensures all possible cases are covered (booleans, enums, or wildcards for nums/strs).
Optimizer: Includes constant folding, dead code elimination, and strength reduction (e.g., simplifying x *
1 to x).
Static Semantics & Language Constraints
TEMP_JS features a custom static analyzer that enforces type safety, immutability, and safe control flow before your code
ever runs. Below are the rules and constraints enforced by the compiler.
Variables and Mutability
Declaration Required: All variables must be declared using let or mut
before they are accessed or modified.
Immutability by Default: Variables declared with let are strictly immutable. They
cannot be reassigned, modified via compound assignments (+=, -=), incremented/decremented
(++, --), or have their array indices modified.
Loop Variables: The iteration variable introduced in a for ... in loop is implicitly
treated as an immutable let binding within the loop body.
Type System
Strong Type Inference: Variable types are inferred from their initial assignment. Any subsequent
assignments (for mut variables) must perfectly match the initially inferred type.
Math Operations: The -, *, /, // (floor division),
%, and ** operators strictly require numeric (num) operands. The + operator
requires either both num or both string (str) operands. Unary - requires a
num operand.
Compound Assignments:-= requires num operands. += requires both
operands to match and must be either num or str.
Comparisons: Relational operators (<, <=, >,
>=) require numeric operands. Equality operators (==, !=) require both operands
to be of the exact same type.
Booleans:if statements, while loops, unary !, and binary
logical operators (&&, ||) strictly require boolean (bool) expressions.
Functions
Valid Invocation: Function calls must reference a previously declared function or a built-in
(range, floor_div).
Strict Arity: The number of arguments passed to a function must exactly match the function's
declared parameter count.
Return Consistency: A function's return type is inferred from the first evaluated
return statement. All subsequent return statements in that same function must yield
values of the identical inferred type.
Scope Limits: The return keyword is strictly prohibited outside of a function body.
Arrays and Iteration
Strict Indexing: Bracket notation (array[index]) can only be used on variables
of type array. Furthermore, the index expression must evaluate to a num.
Iterable Loops: The iterable expression in a for ... in loop must evaluate to
an array.
Control Flow: The break statement is only permitted inside the boundaries of a
loop body.
Enums and Pattern Matching
Enum Resolution: Enums must be declared before use. Any member access (e.g., MyEnum.
Variant) must reference a valid variant defined inside that specific enum block.
Exhaustive Matching: All match expressions must be exhaustive to guarantee safe
execution. Booleans must match true and false. Numbers and strings strictly require
a wildcard arm. Enums must explicitly cover every declared variant or provide a wildcard.
Pattern Safety: A match arm's pattern type must explicitly match the type of the
expression being evaluated. Duplicate patterns are not allowed.
Wildcard Rules: If a wildcard pattern (_) is used, it must appear as the very last
arm in the match block.
Reserved Keywords
You cannot use the following reserved language keywords as variable or function identifiers:
fn, let, mut, if, else, while,
for, in, return, break, print, true,
false, match, enum
Example Programs
Here are five complete programs covering every syntactic form in TEMP_JS. Try running them or modifying the code!
1. Enums and Pattern Matching
This example demonstrates how to define Enums and use the Match statement to handle
data variants. It showcases how TEMP_JS ensures exhaustiveness—meaning you must account for every possible enum
variant or boolean state.
2. Functions and String Interpolation
Here you can see Function declarations in action, along with f-strings
(formatted strings). This example also highlights how scoping works within if/else branches and how the
compiler handles mathematical expressions within print statements.
3. Conditionals and While Loops
This program utilizes a while loop and mutable variables to iterate through a
sequence. It combines these with a match statement to transform raw numbers into descriptive strings,
demonstrating how the language handles logic flow and state changes.
4. Ranges and For-In Loops
This example showcases the built-in range() function. It demonstrates the three ways to call range
(single argument, start/stop, and start/stop/step) and how to use the for-in loop to iterate through
these sequences efficiently.
5. Arrays and Mutability
The "Kitchen Sink" example focuses on Array manipulation. It shows how to pass arrays to functions,
iterate over them, and perform index assignment on mut arrays. It serves as a practical
look at how TEMP_JS handles collections and data mutability.
6. Structs and Field Access
This example introduces structs, TEMP_JS's named record type. It shows how to declare a structs
, create both immutable and mutable instances, read fields with dot notation, mutate fields on mut
variables, pass structs into functions, and store them in arrays.
7. Interfaces and Method Calls
This example demonstrates interfaces and impl blocks. An interface declares the method
signatures a type must provide; the impl block attaches those methods to a struct, with self
referring to the instance.
The Creators
Quinn Austin
Focused on the semantic analyzer and type inference engine, along with the
JavaScript backend. Quinn built out the core logic that makes TEMP_JS safe and reliable.
Colin Bajo-Smith
Worked on Ohm grammar design, custom AST generation pipeline, and the webpage/embedded
compiler. Colin ensured the syntax remained clean and minimalist.
Max Lehmann
Created constant folding and JavaScript code generation. Max designed and implemented everything
relating to the test suites and code flow.