Skip to content

EverSharp Language Reference for AI Agents

Version: Current
Date: November 27, 2025
Purpose: Comprehensive reference for AI agents to understand, diagnose, and work with EverSharp code


Table of Contents

  1. Language Overview
  2. Lexical Structure
  3. Grammar Specification
  4. Type System
  5. Operators
  6. Statements
  7. Expressions
  8. Native Functions Reference
  9. Error Patterns
  10. Integration Patterns

1. Language Overview

1.1 What is EverSharp?

EverSharp is a dynamically-typed, interpreted meta-programming language designed for business rules and calculations in insurance quoting systems. It is implemented in C# and runs on .NET 9.0.

Key Characteristics:

  • Dynamic typing: Variables have no declared types; types are determined at runtime
  • Expression-oriented: Almost everything returns a value
  • C-family syntax: Similar to JavaScript/C# in appearance
  • Functional features: First-class functions, lambda expressions, array methods
  • Object-oriented: Object literals and property access
  • Imperative control flow: if/else, while loops
  • No classes or inheritance: Uses object literals and functions only
  • Lexically scoped: Block-level and function-level scoping

1.2 Architecture

Execution Pipeline:

Source Code → Tokenizer → Parser → AST → Interpreter → Result

Components:

  • RuleTokenizer: Lexical analysis using regex patterns
  • Parser: Recursive descent parser producing Abstract Syntax Tree (AST)
  • Interpreter: Tree-walking interpreter with visitor pattern
  • Environment: Lexically-scoped variable storage
  • Instance/InstanceArray: Runtime representations of objects and arrays

1.3 Design Principles

  1. No implicit type coercion: Operations between incompatible types throw errors
  2. Explicit over implicit: No automatic conversions
  3. Fail fast: Invalid operations throw runtime exceptions immediately
  4. Lexical scoping: Variables resolved at parse time
  5. Immutability preference: Many operations return new values rather than mutating

2. Lexical Structure

2.1 Tokens

EverSharp has 55 token types defined in TokenType.cs:

Operators:

  • Logical: || (OR), && (AND), ! (NEGATION)
  • Comparison: == (EQUAL), != (NOT_EQUAL), < (LESS), > (GREATER), <= (LESS_OR_EQUAL), >= (GREATER_OR_EQUAL)
  • Arithmetic: + (ADD), - (SUBTRACT), * (MULTIPLY), / (DIVIDE), % (MODULO)
  • Assignment: = (ASSIGN), += (ADD_ASSIGN), -= (SUBTRACT_ASSIGN), *= (MULTIPLY_ASSIGN), /= (DIVIDE_ASSIGN), %= (MODULO_ASSIGN)
  • Postfix: ++ (PLUS_PLUS), -- (MINUS_MINUS)

Delimiters:

  • Parentheses: ( (LEFT_PARENTHESIS), ) (RIGHT_PARENTHESIS)
  • Brackets: [ (LEFT_BRACKET), ] (RIGHT_BRACKET)
  • Braces: { (LEFT_CURLY_BRACKET), } (RIGHT_CURLY_BRACKET)
  • Others: ; (SEMICOLON), , (COMMA), . (DOT), : (COLON), ? (QUESTION_MARK)

Keywords:

  • Control flow: if, else, while, return, exit, throw
  • Declaration: function
  • Literals: true, false, null

Literals and Identifiers:

  • NUMBER: Decimal or integer literal
  • STRING: Double-quoted string with escape sequences
  • CHAR: Single-quoted character (rarely used)
  • IDENTIFIER: Variable, function, or property name

Special:

  • LAMBDA: => arrow for lambda expressions
  • WHITESPACE: Space, tab, newline (ignored)
  • COMMENT: // single-line or /* */ multi-line
  • EOF: End of file marker

2.2 Token Patterns (Regex)

Numbers:

^([0-9]*[.])?[0-9]+

Matches: 123, 3.14, .5, 0.001

Strings:

^"[^"\\]*(?:\\.[^"\\]*)*"

Matches: "hello", "line\nbreak", "quote\"inside"

Identifiers:

^[a-zA-Z_$][a-zA-Z0-9_$]*

Matches: variableName, $NativeFunction, _private, camelCase123

Comments:

^(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|(//.*)

Matches: // single line, /* multi line */

2.3 Whitespace and Comments

Whitespace: Spaces, tabs, and newlines are ignored except as token separators

Single-line comments:

// This is a comment
premium = 1000; // Calculate base premium

Multi-line comments:

/*
 * Calculate premium with adjustments
 * for age and coverage amount
 */
premium = basePremium * ageFactor;

2.4 Keywords

Reserved keywords that cannot be used as identifiers:

  • if, else, while, function, return
  • true, false, null

Note: Unlike JavaScript, EverSharp does NOT reserve: var, let, const, for, switch, case, class, new, etc.

2.5 Identifiers

Rules:

  • Must start with letter (a-z, A-Z), underscore (_), or dollar sign ($)
  • Can contain letters, digits, underscores, dollar signs
  • Case-sensitive: myVar ≠ MyVar
  • Dollar sign prefix ($) by convention indicates native function

Valid identifiers:

userName;
_privateVar;
$Max;
camelCase;
PascalCase;
snake_case;
variableName123;

Invalid identifiers:

123variable  // Cannot start with digit
my-variable  // Hyphen not allowed
my variable  // Space not allowed
if           // Reserved keyword

3. Grammar Specification

3.1 Complete BNF Grammar

program                 →   declaration* EOF ;
declaration             →   function_declaration | statement ;
function_declaration    →   "function" function ;
function                →   identifier "(" parameters* ")" block ;
parameters              →   identifier ( "," identifier )* ;
statement               →   expression_statement | if_statement | return_statement
                            | exit_statement | throw_statement | while_statement | block ;
expression_statement    →   expression ';' ;
if_statement            →   "if" "(" expression ")" statement ( "else" statement )? ;
return_statement        →   "return" expression? ";" ;
exit_statement          →   "exit" ";" ;
throw_statement         →   "throw" expression? ";" ;
while_statement         →   "while" "(" expression ")" statement ;
block                   →   "{" declaration* "}" ;
expression              →   assignment ;
assignment              →   (call ".") identifier ( "=" | "+=" | "-=" | "*=" | "/=" | "%=" )
                            argument | logical_or ;
logical_or              →   logical_and ( "||" logical_and )* ;
logical_and             →   equality ( "&&" equality )* ;
equality                →   comparison ( ( "!=" | "==" ) comparison )* ;
comparison              →   term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
term                    →   factor ( ( "-" | "+" ) factor )* ;
factor                  →   unary ( ( "/" | "*" | "%" ) unary )* ;
unary                   →   ( "!" | "-" ) unary | postfix ;
postfix                 →   primary ( "++" | "--" )? ;
call                    →   "{" properties? "}"
                            | "[" expression ( "," expression )* "]"
                            | primary ( "(" arguments? ")" | "." identifier | "[" expression "]" )* ;
properties              →   property_initialization ( "," property_initialization )* ;
property_initialization →   string ":" expression ;
arguments               →   argument ( "," argument )* ;
argument                →   lambda | expression ;
lambda                  →   ( identifier | "(" parameters* ")" ) "=>" lambda_body ;
lambda_body             →   expression | block ;
primary                 →   identifier | number | string | "true" | "false" | "null"
                            | "(" expression ")" ;

3.2 Grammar Notes

Precedence (highest to lowest):

  1. Primary expressions (literals, identifiers, grouping)
  2. Postfix (++, --)
  3. Unary (!, -)
  4. Factor (*, /, %)
  5. Term (+, -)
  6. Comparison (<, >, <=, >=)
  7. Equality (==, !=)
  8. Logical AND (&&)
  9. Logical OR (||)
  10. Assignment (=, +=, etc.)

Associativity:

  • Most binary operators: Left-to-right
  • Assignment operators: Right-to-left
  • Unary operators: Right-to-left

Statement vs Expression:

  • Statements do not return values (if, while, function declarations)
  • Expressions always return values (can be used in assignments, arguments, etc.)
  • Exception: return statement can include an expression

4. Type System

4.1 Overview

EverSharp is dynamically typed: variables do not have declared types, and types are checked at runtime.

Core Types:

  1. decimal - All numeric values
  2. string - Text values
  3. boolean - true or false
  4. null - Absence of value
  5. DateTime - Date and time values
  6. DateOnly - Date-only values (no time component)
  7. Instance - Object/dictionary with properties
  8. InstanceArray - Array of values

4.2 Decimal (Numbers)

Internal representation: C# decimal type (128-bit)

Literals:

123; // Integer
3.14; // Decimal
0.5; // Leading zero optional
0.5; // Leading zero omitted
0 - // Zero
  42; // Negative (unary minus)
1000000.99; // Large numbers

No support for:

  • Scientific notation (1e6)
  • Hexadecimal (0xFF)
  • Binary (0b1010)
  • Underscores (1_000_000)

Operations:

a + b; // Addition
a - b; // Subtraction
a * b; // Multiplication
a / b; // Division
(a % b) - // Modulo (remainder)
  a; // Negation
a++; // Post-increment (returns old value, increments variable)
a--; // Post-decrement (returns old value, decrements variable)

Type checking:

// All numbers are decimal - no integer vs float distinction
value = 10; // 10.0 internally
value = 10 / 3; // 3.3333... (decimal precision)

4.3 String

Literals: Double-quoted only

"hello";
"Hello, World!";
""; // Empty string

Escape sequences:

"\n"; // Newline
"\t"; // Tab
"\\"; // Backslash
"\""; // Double quote

No string interpolation: Must use concatenation or $Log formatting

name = "John";
message = "Hello, " + name; // Concatenation
$Log("Hello, {0}", name); // Format in $Log

Operations:

a + b; // Concatenation (if at least one is string)
a == b; // Equality comparison
a != b; // Inequality comparison

Instance methods (called with dot notation):

str.ToUpper();
str.ToLower();
str.Trim();
str.Split(separator);
str.StartsWith(prefix);
str.EndsWith(suffix);
str.Contains(substring);
str.ToString();
str.ToNumber(); // Convert to decimal

4.4 Boolean

Literals: true, false (lowercase only)

Operations:

a && b; // Logical AND (short-circuit)
a || b; // Logical OR (short-circuit)
!a; // Logical NOT
a == b; // Equality
a != b; // Inequality

Truthiness: EverSharp has strict boolean semantics

  • Only true and false are boolean values
  • No implicit conversion from other types
  • Comparison operators return boolean
  • Logical operators require boolean operands

Common patterns:

if (age > 18) {
} // Comparison returns boolean
if (isActive && hasLicense) {
} // Both must be boolean
if (!isExpired) {
} // Negation of boolean

4.5 Null

Literal: null (lowercase only)

Purpose: Represents absence of value or uninitialized variable

Default value: Variables auto-initialize to null if not assigned

// These are equivalent:
value; // Auto-initialized to null
value = null; // Explicitly set to null

Null operations:

value == null; // Check if null
value != null; // Check if not null

Null behavior:

  • Cannot call methods on null (throws RuntimeException)
  • Cannot access properties on null (throws RuntimeException)
  • Can be compared with == and !=
  • Can be passed as argument
  • Can be returned from functions

4.6 DateTime

Creation: Via native functions or string parsing

now = $Now(); // Current UTC time
today = $Today(); // Today at midnight
parsed = $ToDate("2023/12/25"); // Parse from string
utc = $ToDateUTC("2023/12/25 10:30"); // Parse as UTC

Operations: Via native functions

$Year(date);
$Month(date);
$Day(date);
$AddDays(date, days);
$AddMonths(date, months);
$AddYears(date, years);
$AddHours(date, hours);
$AddMinutes(date, minutes);
$AddSeconds(date, seconds);
$DifferenceInDays(date1, date2);
$DifferenceInYears(date1, date2);
// ... more functions in section 8

String representation: ISO 8601 format when converted to string

4.7 DateOnly

Creation: Via native function

dateOnly = $ToDateOnly("2023/12/25");

Purpose: Represents date without time component

Operations: Limited compared to DateTime (no time arithmetic)

4.8 Instance (Objects)

Creation: Object literal syntax

person = {
  name: "John",
  age: 30,
  active: true,
};

Property access:

person.name; // Get property
person.age = 31; // Set property
person.newProp = 5; // Add new property

Nested objects:

policy = {
  number: "POL-123",
  customer: {
    name: "Jane",
    address: {
      city: "Boston",
    },
  },
};

city = policy.customer.address.city; // Chained access

Instance methods:

obj.AddProperty(name, value); // Add property dynamically
obj.ToString(); // JSON representation

Native functions:

$GetValue(obj, "propertyName");
$SetValue(obj, "propertyName", value);

4.9 InstanceArray (Arrays)

Creation: Array literal or $Array function

numbers = [1, 2, 3, 4, 5];
mixed = ["hello", 42, true, null];
empty = [];
nested = [
  [1, 2],
  [3, 4],
];

// Or using $Array function
numbers = $Array(1, 2, 3, 4, 5);

Indexing: Zero-based

first = numbers[0]; // Get first element
numbers[2] = 99; // Set third element
last = numbers[numbers.Length - 1]; // Get last element

Property access:

len = array.Length; // Read-only length property

Instance methods (extensive - see section 8.4 for details):

array.Filter(predicate);
array.Map(transform);
array.ReduceToNum(fn, initial);
array.OrderBy(selector);
array.Reverse();
array.Find(predicate);
array.Any(predicate);
array.Push(item);
array.Slice(start, end);
// ... many more

Arrays of objects:

people = [
  { name: "John", age: 30 },
  { name: "Jane", age: 25 },
];

adults = people.Filter((p) => p.age >= 18);
names = people.Map((p) => p.name);

4.10 Type Coercion Rules

No implicit coercion: EverSharp does NOT automatically convert types

String concatenation: Special case for + operator

"Age: " + 30; // "Age: 30" (number converts to string)
30 + " years"; // "30 years" (number converts to string)

All other operations: Require matching types

5 + "10"; // "510" (string concat, not addition)
5 * "10"; // ERROR: Cannot multiply number and string
"5" == 5; // false (different types)
true + 1; // ERROR: Cannot add boolean and number

Explicit conversion: Use conversion functions

"123".ToNumber(); // 123 (string to decimal)
$ToNumber("123"); // 123 (string to decimal)
$ToString(123); // "123" (any value to string)

5. Operators

5.1 Operator Precedence Table

| Precedence | Operator | Description | Associativity | | ----------- | ---------------------------- | ------------------------------------- | ------------- | ---------- | ------------- | | 1 (highest) | () [] . | Grouping, array access, member access | Left-to-right | | 2 | ++ -- | Postfix increment/decrement | N/A | | 3 | ! - | Logical NOT, unary minus | Right-to-left | | 4 | * / % | Multiplication, division, modulo | Left-to-right | | 5 | + - | Addition, subtraction | Left-to-right | | 6 | < > <= >= | Comparison | Left-to-right | | 7 | == != | Equality | Left-to-right | | 8 | && | Logical AND | Left-to-right | | 9 | | | | Logical OR | Left-to-right | | 10 | ?: | Ternary conditional | Right-to-left | | 11 (lowest) | = += -= *= /= %= | Assignment | Right-to-left |

5.2 Arithmetic Operators

Binary arithmetic:

a + b; // Addition (also string concatenation)
a - b; // Subtraction
a * b; // Multiplication
a / b; // Division
a % b; // Modulo (remainder)

Unary arithmetic:

-a + // Negation (unary minus)
  a; // Unary plus (no-op in EverSharp)

Type requirements: Both operands must be decimal (except + with strings)

Examples:

premium = 1000 + 250; // 1250
discount = premium * 0.15; // 187.5
netPremium = premium - discount; // 1062.5
taxAmount = netPremium * 0.08; // 85
remainder = 17 % 5; // 2

5.3 Comparison Operators

Operators:

a < b; // Less than
a > b; // Greater than
a <= b; // Less than or equal
a >= b; // Greater than or equal
a == b; // Equal
a != b; // Not equal

Return type: Always boolean

Type requirements: Operands must be same type (decimal, string, boolean, DateTime, null)

Examples:

age > 18; // true if age is 19
premium <= 1000; // true if premium is 1000 or less
name == "John"; // true if name exactly matches
status != null; // true if status is not null
startDate < endDate; // Compare dates
"apple" < "banana"; // String comparison (lexicographic)

5.4 Logical Operators

Binary logical:

a && b; // Logical AND (short-circuit)
a || b; // Logical OR (short-circuit)

Unary logical:

!a; // Logical NOT

Type requirements: Operands must be boolean

Short-circuit evaluation:

  • &&: If left side is false, right side is NOT evaluated
  • ||: If left side is true, right side is NOT evaluated

Examples:

isAdult = age >= 18 && age <= 65;
isEligible = hasLicense || hasPermit;
isInvalid = !isValid;

// Short-circuit prevents error
if (policy != null && policy.active) {
  // policy.active only accessed if policy is not null
}

5.5 Assignment Operators

Simple assignment:

x = 10; // Assign value

Compound assignment:

x += 5; // Equivalent to: x = x + 5
x -= 3; // Equivalent to: x = x - 3
x *= 2; // Equivalent to: x = x * 2
x /= 4; // Equivalent to: x = x / 4
x %= 3; // Equivalent to: x = x % 3

Return value: Assignment expressions return the assigned value

a = b = c = 10; // Right-to-left: c=10, b=10, a=10

Property assignment:

obj.property = value;
obj.nested.property += 10;
array[index] = value;

5.6 Postfix Operators

Operators:

x++; // Post-increment: returns x, then increments
x--; // Post-decrement: returns x, then decrements

Implementation: These are syntactic sugar for compound assignment

x++; // Equivalent to: temp = x; x += 1; return temp;
x--; // Equivalent to: temp = x; x -= 1; return temp;

Type requirement: Variable must be decimal

Examples:

counter = 5;
oldValue = counter++; // oldValue = 5, counter = 6
newValue = counter--; // newValue = 6, counter = 5

Note: No prefix versions (++x or --x)

5.7 Ternary Operator

Syntax: condition ? trueExpression : falseExpression

Evaluation:

  1. Evaluate condition (must be boolean)
  2. If true, evaluate and return trueExpression
  3. If false, evaluate and return falseExpression

Examples:

premium = age > 65 ? basePremium * 1.5 : basePremium;

status = isActive ? "Active" : "Inactive";

max = a > b ? a : b; // Simple max function

// Nested ternary (discouraged for readability)
rate = age < 25 ? 0.15 : age < 65 ? 0.1 : 0.2;

5.8 Member Access Operator

Dot notation: object.property

Usage:

// Property access
person.name;
policy.customer.address.city;

// Property assignment
person.age = 31;

// Method calls
array.Filter(predicate);
string.ToUpper();

5.9 Array Access Operator

Bracket notation: array[index]

Zero-based indexing:

numbers = [10, 20, 30];
first = numbers[0]; // 10
second = numbers[1]; // 20
numbers[2] = 99; // Set third element

Accessing arrays of objects:

people = [{ name: "John" }, { name: "Jane" }];
firstName = people[0].name; // "John"

6. Statements

6.1 Expression Statements

Syntax: expression ;

Any expression followed by semicolon becomes a statement:

premium = 1000;
$Log("Hello");
person.age++;
numbers.Push(42);

6.2 If Statement

Syntax:

if (condition) statement
if (condition) statement else statement

Condition: Must evaluate to boolean

Examples:

// Simple if
if (age >= 18) {
  premium = basePremium;
}

// If-else
if (age < 25) {
  premium = basePremium * 1.5;
} else {
  premium = basePremium;
}

// If-else-if chain
if (age < 25) {
  premium = basePremium * 1.5;
} else if (age < 65) {
  premium = basePremium;
} else {
  premium = basePremium * 1.25;
}

// Single-line (no braces)
if (isActive) status = "Active";

Block statements: Use {} for multiple statements

if (premium > 5000) {
  discount = premium * 0.1;
  premium = premium - discount;
  $Log("Discount applied");
}

6.3 While Statement

Syntax: while (condition) statement

Condition: Must evaluate to boolean

Examples:

// Simple loop
counter = 0;
while (counter < 10) {
  $Log(counter);
  counter++;
}

// Loop through array (manual indexing)
index = 0;
while (index < items.Length) {
  $Log(items[index]);
  index++;
}

// Infinite loop (must have break mechanism)
while (true) {
  if (condition) {
    // Need external mechanism to exit
  }
}

Note: No break or continue statements in EverSharp

Alternative: Use array methods instead of loops

// Instead of while loop:
items.ForEach((item) => $Log(item));

6.4 Function Declaration

Syntax:

function name(param1, param2, ...) {
    // function body
}

Examples:

// Simple function
function calculatePremium(baseAmount, rate) {
  return baseAmount * rate;
}

// Function with multiple statements
function processPolicy(policy) {
  premium = policy.baseAmount;
  discount = calculateDiscount(policy);
  premium = premium - discount;
  return premium;
}

// Function with no parameters
function getCurrentTimestamp() {
  return $Now();
}

// Function with no return
function logMessage(message) {
  $Log(message);
}

Function calls:

result = calculatePremium(1000, 0.15);
processPolicy(myPolicy);
getCurrentTimestamp();

Scope: Functions create new scope; can access outer variables

6.5 Return Statement

Syntax:

return; // Return null
return expression; // Return value

Examples:

function getMax(a, b) {
  if (a > b) {
    return a;
  }
  return b;
}

function checkEligibility(age) {
  if (age < 18) {
    return false;
  }
  if (age > 80) {
    return false;
  }
  return true;
}

function earlyExit(condition) {
  if (condition) {
    return; // Return null
  }
  // Continue processing
  return result;
}

Note: Return immediately exits the function

6.6 Exit Statement

Syntax:

exit;

Purpose: Immediately terminates entire script execution

Examples:

// Terminate on critical error
if (premium > maxAllowed) {
  $Log("Premium exceeds limit");
  exit;
}

// Early termination
counter = 0;
while (counter < 100) {
  if (shouldStop) {
    exit; // Stops entire script
  }
  counter++;
}

Note: Exit terminates normally without error

6.7 Throw Statement

Syntax:

throw;                  // Throws "Runtime error"
throw expression;       // Throws evaluated message

Purpose: Immediately terminates script execution with an error

Examples:

// Basic throw with message
if (age < 0) {
  throw "Age cannot be negative";
}

// Throw with dynamic message
if (premium > maxPremium) {
  throw "Premium exceeds maximum: " + premium;
}

// Throw with expression
value = -10;
throw value < 0 ? "Negative value" : "Invalid value";

// Throw without message
if (criticalError) {
  throw; // Throws "Runtime error"
}

Error Detection in C#:

var runner = new EverSharpRunner();
runner.Run(@"
    age = -5;
    throw ""Invalid age: "" + age;
");

if (runner.HasErrors) {
    foreach (var error in runner.Errors) {
        Console.WriteLine($"Error: {error}");
        // Output: Error: Invalid age: -5
    }
}

Comparison:

Statement Scope Error Value
return Exits current function No Can return
exit Exits entire script No None
throw Exits entire script Yes Error message

When to use:

  • return: Normal function exit with optional value
  • exit: Graceful script termination
  • throw: Error conditions that need to be reported

6.8 Block Statement

Syntax: { declaration* }

Purpose: Group multiple statements into single statement

Creates new scope:

{
  localVar = 10; // Visible inside block
  $Log(localVar);
}
// localVar NOT visible here

Common usage:

// With if
if (condition) {
  statement1;
  statement2;
}

// With while
while (condition) {
  statement1;
  statement2;
}

// With function
function name() {
  statement1;
  statement2;
}

// Standalone (rarely used)
{
  tempValue = compute();
  process(tempValue);
}

7. Expressions

7.1 Literal Expressions

Number literals:

42;
3.14159;
0.5;
1000000;

String literals:

"Hello";
"Hello, World!";
""; // Empty string
"Line 1\nLine 2"; // With escape

Boolean literals:

true;
false;

Null literal:

null;

7.2 Variable Expressions

Declaration and initialization: No keyword required

variableName = value;

Auto-initialization: Undefined variables are null

result; // null by default

Usage:

x = 10;
y = x + 5;
result = calculateTotal(x, y);

7.3 Object Initialization

Syntax: { "key": value, "key2": value2, ... }

Examples:

// Simple object
person = {
  name: "John",
  age: 30,
};

// Nested objects
policy = {
  number: "POL-123",
  customer: {
    name: "Jane",
    email: "jane@example.com",
  },
  premium: 1500.0,
};

// Empty object
empty = {};

// Objects with expressions
calculation = {
  base: 1000,
  rate: 0.15,
  total: 1000 * 0.15,
};

Key requirements:

  • Keys must be strings (quoted)
  • Values can be any expression
  • Trailing comma not allowed

7.4 Array Initialization

Array literal syntax: [ expression, expression, ... ]

Examples:

// Numbers
numbers = [1, 2, 3, 4, 5];

// Strings
names = ["Alice", "Bob", "Charlie"];

// Mixed types
mixed = [42, "hello", true, null];

// Empty array
empty = [];

// Nested arrays
matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
];

// Array of objects
people = [
  { name: "John", age: 30 },
  { name: "Jane", age: 25 },
];

// With expressions
computed = [1 + 1, 2 * 3, $Max(5, 10)];

Function syntax: $Array(item1, item2, ...)

numbers = $Array(1, 2, 3, 4, 5);
mixed = $Array("hello", 42, true);

7.5 Function Call Expressions

User-defined functions:

result = myFunction(arg1, arg2);
processData(input);
value = computeValue();

Native functions (prefixed with $):

max = $Max(10, 20);
now = $Now();
sorted = $Sort(numbers);

Method calls (on objects/arrays/strings):

filtered = array.Filter((x) => x > 10);
upper = text.ToUpper();
obj.AddProperty("key", "value");

7.6 Lambda Expressions

Syntax:

// Single parameter (no parentheses)
x => expression

// Multiple parameters
(x, y) => expression

// No parameters
() => expression

// Block body
x => {
    statement1;
    statement2;
    return value;
}

// Multi-parameter block
(x, y) => {
    result = x + y;
    return result;
}

Examples:

// Simple transform
doubled = numbers.Map((x) => x * 2);

// Filter
adults = people.Filter((p) => p.age >= 18);

// Multi-parameter
summed = numbers.ReduceToNum((acc, x) => acc + x, 0);

// With index
indexed = items.Map((item, index) => {
  return {
    index: index,
    value: item,
  };
});

// Assigned to variable
addTen = (x) => x + 10;
result = addTen(5); // 15

// Passed as argument
applyFunction = (fn, value) => fn(value);
result = applyFunction((x) => x * 2, 10); // 20

Closure: Lambdas capture variables from outer scope

multiplier = 10;
multiply = (x) => x * multiplier;
result = multiply(5); // 50

7.7 Property Access Expressions

Dot notation: object.property

Examples:

// Simple access
name = person.name;
age = person.age;

// Nested access
city = policy.customer.address.city;

// Assignment
person.age = 31;
policy.premium = 2000;

// Chained access
finalValue = obj.nested.deep.property;

7.8 Array Access Expressions

Bracket notation: array[index]

Examples:

// Read
first = numbers[0];
last = numbers[numbers.Length - 1];

// Write
numbers[2] = 99;

// With variables
index = 3;
value = items[index];

// Array of objects
person = people[0];
name = people[0].name;

// Nested arrays
value = matrix[1][2];

7.9 Grouping Expressions

Syntax: ( expression )

Purpose: Override default precedence

Examples:

result = (a + b) * c; // Add first, then multiply
result = a + b * c; // Multiply first, then add

average = (a + b + c) / 3;
check = x > 5 && y < 10;

8. Native Functions Reference

8.1 Mathematics Functions

$Max

Signature: $Max(a, b) → decimal
Description: Returns the larger of two numbers
Example:

max = $Max(10, 20); // 20
max = $Max(age, minAge);

$Min

Signature: $Min(a, b) → decimal
Description: Returns the smaller of two numbers
Example:

min = $Min(10, 20); // 10
premium = $Min(calculated, maxPremium);

$Abs

Signature: $Abs(n) → decimal
Description: Returns absolute value
Example:

abs = $Abs(-5); // 5
difference = $Abs(value1 - value2);

$Round

Signature: $Round(n, decimals?) → decimal
Description: Rounds number to specified decimal places (default 0)
Example:

rounded = $Round(3.14159); // 3
rounded = $Round(3.14159, 2); // 3.14
premium = $Round(1234.567, 2); // 1234.57

$Sum

Signature: $Sum(array) → decimal or $Sum(arrayOfObjects, property) → decimal
Description: Sums array elements or property values
Example:

total = $Sum($Array(1, 2, 3, 4)); // 10
totalPremium = $Sum(policies, "premium");

8.2 Date/Time Functions

$Now

Signature: $Now() → DateTime
Description: Returns current UTC date and time
Example:

timestamp = $Now();

$Today

Signature: $Today() → DateTime
Description: Returns today's date at midnight (00:00:00)
Example:

today = $Today();

$Year

Signature: $Year(date) → decimal
Description: Extracts year from date
Example:

year = $Year("2023/12/25"); // 2023
currentYear = $Year($Now());

$Month

Signature: $Month(date) → decimal
Description: Extracts month from date (1-12)
Example:

month = $Month("2023/12/25"); // 12

$Day

Signature: $Day(date) → decimal
Description: Extracts day from date (1-31)
Example:

day = $Day("2023/12/25"); // 25

$AddYears

Signature: $AddYears(date, years) → DateTime
Description: Adds years to date
Example:

future = $AddYears("2023/01/15", 2); // 2025/01/15
expiry = $AddYears(startDate, termYears);

$AddMonths

Signature: $AddMonths(date, months) → DateTime
Description: Adds months to date
Example:

future = $AddMonths("2023/01/15", 6); // 2023/07/15

$AddDays

Signature: $AddDays(date, days) → DateTime
Description: Adds days to date
Example:

future = $AddDays("2023/01/15", 30);
deadline = $AddDays($Today(), 7);

$AddHours

Signature: $AddHours(date, hours) → DateTime
Description: Adds hours to datetime
Example:

future = $AddHours("2023/01/15 10:00", 3); // 13:00

$AddMinutes

Signature: $AddMinutes(date, minutes) → DateTime
Description: Adds minutes to datetime
Example:

future = $AddMinutes("2023/01/15 10:00", 30); // 10:30

$AddSeconds

Signature: $AddSeconds(date, seconds) → DateTime
Description: Adds seconds to datetime
Example:

future = $AddSeconds("2023/01/15 10:00:00", 45);

$DifferenceInYears

Signature: $DifferenceInYears(date1, date2) → decimal
Description: Calculates year difference (date2 - date1)
Example:

age = $DifferenceInYears(birthDate, $Today());
diff = $DifferenceInYears("2020/01/01", "2023/01/01"); // -3

$DifferenceInDays

Signature: $DifferenceInDays(date1, date2) → decimal
Description: Calculates day difference (date2 - date1)
Example:

days = $DifferenceInDays(startDate, endDate);

$DifferenceInHours

Signature: $DifferenceInHours(date1, date2) → decimal
Description: Calculates hour difference (date2 - date1)
Example:

hours = $DifferenceInHours(start, end);

$DifferenceInMinutes

Signature: $DifferenceInMinutes(date1, date2) → decimal
Description: Calculates minute difference (date2 - date1)
Example:

minutes = $DifferenceInMinutes(start, end);

$DifferenceInSeconds

Signature: $DifferenceInSeconds(date1, date2) → decimal
Description: Calculates second difference (date2 - date1)
Example:

seconds = $DifferenceInSeconds(start, end);

$StartOfDay

Signature: $StartOfDay(date) → DateTime
Description: Returns date at 00:00:00
Example:

start = $StartOfDay("2023/12/25 15:30"); // 2023/12/25 00:00:00

$EndOfDay

Signature: $EndOfDay(date) → DateTime
Description: Returns date at 23:59:59
Example:

end = $EndOfDay("2023/12/25 15:30"); // 2023/12/25 23:59:59

$ToDate

Signature: $ToDate(string) → DateTime
Description: Parses string to DateTime
Example:

date = $ToDate("2023/12/25");
date = $ToDate("2023/12/25 10:30");

$ToDateOnly

Signature: $ToDateOnly(string) → DateOnly
Description: Parses string to DateOnly
Example:

dateOnly = $ToDateOnly("2023/12/25");

$ToDateUTC

Signature: $ToDateUTC(string) → DateTime
Description: Parses string as UTC DateTime
Example:

utc = $ToDateUTC("2023/12/25 10:30");

$ToShortDateString

Signature: $ToShortDateString(date) → string
Description: Formats date to short string
Example:

formatted = $ToShortDateString($Today());

$ConvertTimeFromUtc

Signature: $ConvertTimeFromUtc(date, timezoneId) → DateTime
Description: Converts UTC time to specified timezone
Example:

local = $ConvertTimeFromUtc($Now(), "Eastern Standard Time");

$GetTimeZoneAbbreviation

Signature: $GetTimeZoneAbbreviation(timezoneId, date) → string
Description: Gets timezone abbreviation for date
Example:

abbr = $GetTimeZoneAbbreviation("Eastern Standard Time", $Now());

8.3 String Functions

$Length (for strings)

Signature: $Length(string) → decimal
Description: Returns string length
Example:

len = $Length("hello"); // 5

$ToString

Signature: $ToString(value) → string
Description: Converts value to string
Example:

str = $ToString(123); // "123"
str = $ToString(true); // "true"

$ToStringSafe

Signature: $ToStringSafe(value) → string
Description: Safely converts value to string (handles nulls)
Example:

str = $ToStringSafe(null); // ""

$Stringify

Signature: $Stringify(value) → string
Description: Converts value to JSON representation
Example:

json = $Stringify({ name: "John", age: 30 });

$Split (Instance Method)

Signature: string.Split(separator) → InstanceArray
Description: Splits string into array
Example:

parts = "a,b,c".Split(","); // ["a", "b", "c"]
words = sentence.Split(" ");

$Replace (Instance Method)

Signature: string.Replace(oldValue, newValue) → string
Description: Replaces substring
Example:

result = "hello world".Replace("world", "EverSharp");

$Contains (Instance Method)

Signature: string.Contains(substring) → boolean
Description: Checks if string contains substring
Example:

hasWorld = "hello world".Contains("world"); // true

$StartsWith (Instance Method)

Signature: string.StartsWith(prefix) → boolean
Description: Checks if string starts with prefix
Example:

check = "hello".StartsWith("he"); // true

$EndsWith (Instance Method)

Signature: string.EndsWith(suffix) → boolean
Description: Checks if string ends with suffix
Example:

check = "hello".EndsWith("lo"); // true

$RemoveNonAlpha (Instance Method)

Signature: string.RemoveNonAlpha() → string
Description: Removes non-alphabetic characters
Example:

clean = "abc123def".RemoveNonAlpha(); // "abcdef"

.ToUpper() (Instance Method)

Signature: string.ToUpper() → string
Description: Converts to uppercase
Example:

upper = "hello".ToUpper(); // "HELLO"

.ToLower() (Instance Method)

Signature: string.ToLower() → string
Description: Converts to lowercase
Example:

lower = "HELLO".ToLower(); // "hello"

.Trim() (Instance Method)

Signature: string.Trim() → string
Description: Removes leading/trailing whitespace
Example:

trimmed = "  hello  ".Trim(); // "hello"

.ToNumber() (Instance Method)

Signature: string.ToNumber() → decimal
Description: Parses string to number
Example:

num = "123.45".ToNumber(); // 123.45

.ToString() (Instance Method)

Signature: string.ToString() → string
Description: Returns string (identity)
Example:

str = "hello".ToString(); // "hello"

8.4 Array Functions

$Array

Signature: $Array(item1, item2, ...) → InstanceArray
Description: Creates array from arguments
Example:

arr = $Array(1, 2, 3, 4, 5);
mixed = $Array("hello", 42, true);

$Length (for arrays)

Signature: $Length(array) → decimal
Description: Returns array length
Example:

len = $Length($Array(1, 2, 3)); // 3

$Sort

Signature: $Sort(array) → InstanceArray or $Sort(arrayOfObjects, property) → InstanceArray
Description: Sorts array or array of objects by property
Example:

sorted = $Sort($Array(3, 1, 2)); // [1, 2, 3]
sortedPeople = $Sort(people, "age");

$Reverse

Signature: $Reverse(array) → InstanceArray
Description: Reverses array
Example:

reversed = $Reverse($Array(1, 2, 3)); // [3, 2, 1]

$Map

Signature: $Map(arrayOfObjects, property) → InstanceArray
Description: Extracts property from array of objects
Example:

names = $Map(people, "name"); // ["John", "Jane", ...]

$AddToArray

Signature: $AddToArray(array, item) → InstanceArray
Description: Returns new array with item added
Example:

newArr = $AddToArray(numbers, 99);

$FindEquals

Signature: $FindEquals(array, value) → InstanceArray or $FindEquals(arrayOfObjects, property, value) → InstanceArray
Description: Finds elements equal to value
Example:

matches = $FindEquals($Array(1, 2, 3, 2), 2); // [2, 2]
people = $FindEquals(users, "status", "active");

$FindNotEquals

Signature: $FindNotEquals(array, value) → InstanceArray or $FindNotEquals(arrayOfObjects, property, value) → InstanceArray
Description: Finds elements not equal to value
Example:

matches = $FindNotEquals($Array(1, 2, 3), 2); // [1, 3]

$FindGreaterThan

Signature: $FindGreaterThan(array, value) → InstanceArray or $FindGreaterThan(arrayOfObjects, property, value) → InstanceArray
Description: Finds elements greater than value
Example:

matches = $FindGreaterThan($Array(1, 5, 10), 4); // [5, 10]

$FindGreaterThanOrEqual

Signature: $FindGreaterThanOrEqual(array, value) → InstanceArray or $FindGreaterThanOrEqual(arrayOfObjects, property, value) → InstanceArray
Description: Finds elements >= value
Example:

matches = $FindGreaterThanOrEqual($Array(1, 5, 10), 5); // [5, 10]

$FindLessThan

Signature: $FindLessThan(array, value) → InstanceArray or $FindLessThan(arrayOfObjects, property, value) → InstanceArray
Description: Finds elements less than value
Example:

matches = $FindLessThan($Array(1, 5, 10), 6); // [1, 5]

$FindLessThanOrEqual

Signature: $FindLessThanOrEqual(array, value) → InstanceArray or $FindLessThanOrEqual(arrayOfObjects, property, value) → InstanceArray
Description: Finds elements <= value
Example:

matches = $FindLessThanOrEqual($Array(1, 5, 10), 5); // [1, 5]

$ToArray

Signature: $ToArray(value) → InstanceArray
Description: Converts value to array
Example:

arr = $ToArray(singleValue);

.Filter() or .Where() (Instance Method)

Signature: array.Filter(predicate) → InstanceArray
Description: Filters array by predicate function
Example:

evens = numbers.Filter((x) => x % 2 == 0);
adults = people.Filter((p) => p.age >= 18);

.Map() or .Select() (Instance Method)

Signature: array.Map(transform) → InstanceArray
Description: Transforms array elements; lambda receives (item, index)
Example:

doubled = numbers.Map(x => x * 2);
names = people.Map(p => p.name);
indexed = items.Map((item, i) => { "index": i, "value": item });

.ReduceToNum() (Instance Method)

Signature: array.ReduceToNum(fn, initial) → decimal
Description: Reduces array to number; lambda receives (accumulator, item, index)
Example:

sum = numbers.ReduceToNum((acc, x) => acc + x, 0);
product = numbers.ReduceToNum((acc, x) => acc * x, 1);

.ReduceToStr() (Instance Method)

Signature: array.ReduceToStr(fn, initial) → string
Description: Reduces array to string; lambda receives (accumulator, item, index)
Example:

joined = words.ReduceToStr((acc, w) => acc + w, "");

.ReduceToObj() (Instance Method)

Signature: array.ReduceToObj(fn, initial) → Instance
Description: Reduces array to object; lambda receives (accumulator, item, index)
Example:

grouped = items.ReduceToObj((acc, item) => {
  acc.AddProperty(item.key, item.value);
  return acc;
}, {});

.Reverse() (Instance Method)

Signature: array.Reverse() → InstanceArray
Description: Reverses array in place and returns it
Example:

reversed = numbers.Reverse();

.ForEach() (Instance Method)

Signature: array.ForEach(callback) → null
Description: Executes callback for each element
Example:

numbers.ForEach((n) => $Log(n));

.IndexOf() (Instance Method)

Signature: array.IndexOf(item) → decimal
Description: Returns index of item (-1 if not found)
Example:

index = numbers.IndexOf(42);

.Slice() (Instance Method)

Signature: array.Slice(start, end) → InstanceArray
Description: Returns subarray from start to end
Example:

sub = numbers.Slice(1, 3); // Elements at index 1 and 2

.Find() (Instance Method)

Signature: array.Find(predicate) → object?
Description: Returns first element matching predicate
Example:

first = numbers.Find((x) => x > 10);
person = people.Find((p) => p.id == targetId);

.Add() or .Push() (Instance Method)

Signature: array.Add(item) → null
Description: Adds item to end of array (mutates)
Example:

numbers.Add(42);
numbers.Push(99);

.AddRange() (Instance Method)

Signature: array.AddRange(otherArray) → null
Description: Adds all items from other array (mutates)
Example:

numbers.AddRange(moreNumbers);

.Clear() (Instance Method)

Signature: array.Clear() → null
Description: Removes all elements (mutates)
Example:

numbers.Clear();

.Remove() (Instance Method)

Signature: array.Remove(item) → null
Description: Removes first occurrence of item (mutates)
Example:

numbers.Remove(42);

.RemoveAt() (Instance Method)

Signature: array.RemoveAt(index) → null
Description: Removes element at index (mutates)
Example:

numbers.RemoveAt(2);

.Insert() (Instance Method)

Signature: array.Insert(index, item) → null
Description: Inserts item at index (mutates)
Example:

numbers.Insert(0, 99); // Insert at beginning

.OrderBy() (Instance Method)

Signature: array.OrderBy(selector) → InstanceArray
Description: Sorts array of objects by selector function
Example:

sortedByAge = people.OrderBy((p) => p.age);

.OrderByDescending() (Instance Method)

Signature: array.OrderByDescending(selector) → InstanceArray
Description: Sorts array descending by selector function
Example:

sortedByAge = people.OrderByDescending((p) => p.age);

.Take() (Instance Method)

Signature: array.Take(count) → InstanceArray
Description: Returns first N elements
Example:

topThree = numbers.Take(3);

.Join() (Instance Method)

Signature: array.Join(separator) → string
Description: Joins array elements into string
Example:

csv = items.Join(",");
sentence = words.Join(" ");

.Any() (Instance Method)

Signature: array.Any(predicate) → boolean
Description: Returns true if any element matches predicate
Example:

hasAdults = people.Any((p) => p.age >= 18);

.Distinct() (Instance Method)

Signature: array.Distinct() → InstanceArray
Description: Returns array with unique elements
Example:

unique = numbers.Distinct();

.ToString() (Instance Method)

Signature: array.ToString() → string
Description: Returns JSON representation
Example:

json = array.ToString();

8.5 Conversion Functions

$ToNumber

Signature: $ToNumber(string) → decimal
Description: Parses string to decimal
Example:

num = $ToNumber("123.45"); // 123.45

$ToDictionary

Signature: $ToDictionary(object) → EverDictionary
Description: Converts Instance to EverDictionary (C# interop)
Example:

dict = $ToDictionary(obj);

8.6 Utility Functions

$GetValue

Signature: $GetValue(object, propertyName) → object?
Description: Gets property value from object
Example:

name = $GetValue(person, "name");
value = $GetValue(obj, "nested.property");

$SetValue

Signature: $SetValue(object, propertyName, value) → null
Description: Sets property value on object
Example:

$SetValue(person, "age", 31);

.AddProperty() (Instance Method)

Signature: object.AddProperty(name, value) → null
Description: Adds property to object
Example:

person.AddProperty("email", "john@example.com");

$Log

Signature: $Log(message, ...args) → null
Description: Logs to standard output with optional formatting
Example:

$Log("Hello World");
$Log("Value is {0}", myValue);
$Log("Values: {0}, {1}", val1, val2);

$Fetch

Signature: $Fetch(url) → string
Description: Fetches content from URL
Example:

data = $Fetch("https://api.example.com/data");

$IsInRange

Signature: $IsInRange(value, min, max) → boolean
Description: Checks if value is between min and max (inclusive)
Example:

valid = $IsInRange(age, 18, 65); // true if 18 <= age <= 65

$Binary

Signature: $Binary(condition, trueValue, falseValue) → object?
Description: Function-based ternary operator
Example:

result = $Binary(age > 18, "Adult", "Minor");

8.7 Testing Functions

$AssertAreEqual

Signature: $AssertAreEqual(expected, actual) → null
Description: Asserts two values are equal (for unit testing)
Example:

$AssertAreEqual(10, result);

$AssertTrue

Signature: $AssertTrue(condition) → null
Description: Asserts condition is true
Example:

$AssertTrue(isValid);

$AssertFalse

Signature: $AssertFalse(condition) → null
Description: Asserts condition is false
Example:

$AssertFalse(hasErrors);

8.8 Domain-Specific Functions

$GetCountryNameFromISOCode

Signature: $GetCountryNameFromISOCode(isoCode) → string
Description: Converts ISO country code to name
Example:

country = $GetCountryNameFromISOCode("US"); // "United States"

$GetOptionInfoText

Signature: $GetOptionInfoText(...) → string
Description: Domain-specific function for option info text

$GetOptionName

Signature: $GetOptionName(...) → string
Description: Domain-specific function for option names

$GetOptionValue

Signature: $GetOptionValue(...) → object?
Description: Domain-specific function for option values

$GetRowFromLookupTable

Signature: $GetRowFromLookupTable(...) → object?
Description: Domain-specific function for table lookups


9. Error Patterns

9.1 Common Syntax Errors

Missing semicolon:

// ERROR
x = 10;
y = 20;

// CORRECT
x = 10;
y = 20;

Unquoted object keys:

// ERROR
obj = { name: "John" };

// CORRECT
obj = { name: "John" };

Single-quoted strings:

// ERROR
name = "John";

// CORRECT
name = "John";

Variable declaration with var/let/const:

// ERROR
var x = 10;
let y = 20;
const z = 30;

// CORRECT
x = 10;
y = 20;
z = 30;

Using keywords for, switch, class:

// ERROR - these don't exist
for (i = 0; i < 10; i++) {}
switch (value) {
}

// CORRECT - use while
i = 0;
while (i < 10) {
  i++;
}

9.2 Common Runtime Errors

Type mismatch in operations:

// ERROR: Cannot multiply string and number
result = "5" * 10;

// CORRECT: Convert first
result = "5".ToNumber() * 10;

Null reference:

// ERROR: Cannot access property of null
person = null;
name = person.name;

// CORRECT: Check null first
if (person != null) {
  name = person.name;
}

Array index out of bounds:

// ERROR: Index 10 doesn't exist
numbers = [1, 2, 3];
value = numbers[10];

// CORRECT: Check length
if (index < numbers.Length) {
  value = numbers[index];
}

Wrong number of arguments:

// ERROR: $Max requires 2 arguments
max = $Max(10);

// CORRECT
max = $Max(10, 20);

Invalid lambda parameter count:

// ERROR: Filter expects 1 parameter lambda
filtered = numbers.Filter((x, y) => x > 10);

// CORRECT
filtered = numbers.Filter((x) => x > 10);

9.3 Truthiness Errors

EverSharp requires explicit booleans in conditionals:

// ERROR: Numbers/strings are not boolean
if (count) {
}
if (name) {
}

// CORRECT: Use comparisons
if (count > 0) {
}
if (name != null) {
}
if (name != "") {
}

9.4 Scope Errors

Accessing variable before definition:

// ERROR: result not yet defined
$Log(result);
result = 10;

// CORRECT: Define first
result = 10;
$Log(result);

Accessing local variable from outer scope:

// ERROR: x not visible outside function
function test() {
  x = 10;
}
test();
$Log(x); // x is undefined here

// CORRECT: Use return or outer variable
result = 0;
function test() {
  result = 10;
}
test();
$Log(result);

9.5 Common Diagnostic Patterns

Identifying type errors:

  • Look for operations between incompatible types
  • Check for missing .ToNumber(), $ToString() conversions
  • Verify comparison operands are same type

Identifying null errors:

  • Check for property access without null checks
  • Look for method calls on potentially null values
  • Verify object initialization before access

Identifying arity errors:

  • Count arguments vs function parameter count
  • Check native function signatures
  • Verify lambda parameter counts match method expectations

Identifying scope errors:

  • Trace variable definition location
  • Check if variable is in outer/inner scope
  • Verify function vs block scope

10. Integration Patterns

10.1 EverSharpRunner C# API

Basic usage:

using Elements.Libs.EverSharp;

var runner = new EverSharpRunner();
runner.Run("premium = 1000;");

if (!runner.HasErrors)
{
    var premium = runner.GlobalVariables["premium"];  // 1000m
}
else
{
    foreach (var error in runner.Errors)
    {
        Console.WriteLine(error);
    }
}

Running expressions:

var runner = new EverSharpRunner();
var result = runner.RunExpression("10 + 20");  // Returns 30m

Validation only:

var runner = new EverSharpRunner();
var errors = runner.Validate("x = 10; y = 20;");

if (!errors.Any())
{
    Console.WriteLine("Valid syntax");
}

10.2 Passing Data In/Out

Setting constants (read-only):

var constants = new EverDictionary
{
    { "TAX_RATE", 0.08m },
    { "MIN_PREMIUM", 500m }
};

var variables = new EverDictionary();

var runner = new EverSharpRunner();
runner.InitializeEnvironment(constants, variables);

runner.Run("premium = MIN_PREMIUM * (1 + TAX_RATE);");

Setting variables (mutable):

var variables = new EverDictionary
{
    { "age", 35m },
    { "coverage", 100000m }
};

runner.InitializeEnvironment(new EverDictionary(), variables);
runner.Run("premium = coverage * 0.01 * (age / 30);");

var premium = runner.GlobalVariables.GetNumber("premium");

Setting variables at runtime:

runner.SetExternalVariable("discount", 0.15m);
runner.Run("finalPremium = basePremium * (1 - discount);");

Getting results:

// Access by key
var value = runner.GlobalVariables["variableName"];

// Typed access (extension methods)
var num = runner.GlobalVariables.GetNumber("premium");
var str = runner.GlobalVariables.GetStr("name");
var bool = runner.GlobalVariables.GetBool("isActive");
var dict = runner.GlobalVariables.GetDictionary("policy");
var arr = runner.GlobalVariables.GetArray("items");

10.3 Type Conversions

C# to EverSharp:

// Primitives
variables["age"] = 35m;              // decimal
variables["name"] = "John";          // string
variables["active"] = true;          // bool
variables["date"] = DateTime.Now;    // DateTime

// Objects (use EverDictionary)
variables["person"] = new EverDictionary
{
    { "name", "John" },
    { "age", 35m }
};

// Arrays
variables["numbers"] = new object[] { 1m, 2m, 3m };

EverSharp to C#:

// Primitives
var num = (decimal)runner.GlobalVariables["value"];
var str = (string)runner.GlobalVariables["name"];
var flag = (bool)runner.GlobalVariables["active"];

// Objects (returns EverDictionary)
var dict = runner.GlobalVariables.GetDictionary("person");
var name = dict.GetStr("name");

// Arrays (returns object[])
var arr = runner.GlobalVariables.GetArray("numbers");
var first = (decimal)arr[0];

10.4 Custom Extension Functions

Implementing Callable interface:

using Elements.Libs.EverSharp;
using Elements.Libs.EverSharp.Visitors;

public class CustomFunction : Callable
{
    public object? Call(Interpreter interpreter, List<object?> arguments)
    {
        // Validate argument count
        if (arguments.Count != 2)
            throw new RuntimeException("CustomFunction requires 2 arguments");

        // Extract and validate arguments
        var a = (decimal)arguments[0];
        var b = (decimal)arguments[1];

        // Perform calculation
        return a * b + 100;
    }

    public int? Arity() => 2;  // Fixed arity
    // Return null for variable arity
}

Registering extensions:

var extensions = new Dictionary<string, Callable>
{
    { "$CustomFunction", new CustomFunction() },
    { "$AnotherFunction", new AnotherFunction() }
};

var runner = new EverSharpRunner(extensions: extensions);

runner.Run("result = $CustomFunction(10, 20);");  // 300

Variable arity example:

public class VariableArityFunction : Callable
{
    public object? Call(Interpreter interpreter, List<object?> arguments)
    {
        // Sum all arguments
        decimal sum = 0;
        foreach (var arg in arguments)
        {
            sum += (decimal)arg;
        }
        return sum;
    }

    public int? Arity() => null;  // Accepts any number of arguments
}

10.5 Preloading Libraries

Using library scripts:

var libraries = new List<string>
{
    @"
        function calculatePremium(base, rate) {
            return base * rate;
        }

        function applyDiscount(amount, discountRate) {
            return amount * (1 - discountRate);
        }
    "
};

var runner = new EverSharpRunner(libraries: libraries);

// Now these functions are available
runner.Run("premium = calculatePremium(1000, 0.15);");

10.6 Error Handling

Checking for errors:

runner.Run(script);

if (runner.HasErrors)
{
    foreach (var error in runner.Errors)
    {
        Console.WriteLine($"Error: {error}");
        // Log or handle error
    }
}

Exception types:

  • ParserException: Syntax errors during parsing
  • RuntimeException: Runtime errors during execution
  • Generic Exception: Unexpected errors

10.7 Standard Output

Capturing $Log output:

runner.Run(@"
    $Log(""Starting calculation"");
    result = 10 + 20;
    $Log(""Result: {0}"", result);
");

var output = runner.StandardOutput;
// "Starting calculation\nResult: 30\n"

10.8 Best Practices

1. Always check for errors:

runner.Run(script);
if (runner.HasErrors) {
    // Handle errors before accessing results
}

2. Use type-safe access methods:

// Preferred
var num = runner.GlobalVariables.GetNumber("premium");

// Instead of
var num = (decimal)runner.GlobalVariables["premium"];

3. Initialize environment before running:

runner.InitializeEnvironment(constants, variables);
runner.Run(script);

4. Validate syntax first for user-provided scripts:

var errors = runner.Validate(userScript);
if (!errors.Any()) {
    runner.Run(userScript);
}

5. Use EverDictionary for complex objects:

var policy = new EverDictionary
{
    { "number", "POL-123" },
    { "premium", 1500m },
    { "customer", new EverDictionary
        {
            { "name", "John" },
            { "age", 35m }
        }
    }
};

End of AI Reference Document

This comprehensive reference provides all necessary information for AI agents to understand, diagnose, and work with EverSharp code. For human-readable documentation, refer to the main documentation files organized by topic.