diff --git a/examples/curlywas/cube_wireframe.cwa b/examples/curlywas/cube_wireframe.cwa
new file mode 100644
index 0000000..a7b9de8
--- /dev/null
+++ b/examples/curlywas/cube_wireframe.cwa
@@ -0,0 +1,254 @@
+/*
+ This program renders a rotating 3D wireframe cube on a 2D screen using the MicroW8 platform.
+
+ code : zbyti
+ date : 2025.04.15
+ platform : MicroW8 0.4.1
+
+ https://exoticorn.github.io/microw8/
+ https://exoticorn.github.io/microw8/docs/
+
+ https://github.com/exoticorn/microw8
+ https://github.com/exoticorn/curlywas
+
+ https://developer.mozilla.org/en-US/docs/WebAssembly
+
+ https://en.wikipedia.org/wiki/Rotation_matrix
+*/
+
+//-----------------------------------------------------------------------------
+// MicroW8 API
+//-----------------------------------------------------------------------------
+
+//include "../include/microw8-api.cwa"
+
+// Import memory allocation: 4 pages (64KB) of memory (256KB total)
+import "env.memory" memory(4);
+
+// Import MicroW8 API functions for graphics and math operations
+import "env.cls" fn cls(i32); // Clears the screen
+import "env.time" fn time() -> f32; // Returns the current time as a float for animation
+import "env.sin" fn sin(f32) -> f32; // Computes the sine of an angle (in radians)
+import "env.cos" fn cos(f32) -> f32; // Computes the cosine of an angle (in radians)
+import "env.line" fn line(f32, f32, f32, f32, i32); // Draws a line between two 2D points with a color
+
+// Define the starting address for user memory
+const USER_MEM = 0x14000;
+
+//-----------------------------------------------------------------------------
+// CONSTANTS
+//-----------------------------------------------------------------------------
+
+// Screen and rendering constants
+const CENTER_X = 320.0 / 2.0; // X-coordinate of the screen center (320px width)
+const CENTER_Y = 240.0 / 2.0; // Y-coordinate of the screen center (240px height)
+const ROTATE_SPEED = 0.5; // Speed at which the cube rotates
+const PI = 3.14159265; // Mathematical constant Pi for angle conversions
+const RADIAN = PI / 180.0; // Conversion factor from degrees to radians
+const SCALE = 65.0; // Scaling factor to adjust the size of the cube on screen
+const PERSPECTIVE = SCALE * 0.5; // Perspective factor
+const LINE_COLOR = 0xBF; // Color value for drawing the cube's edges (hexadecimal)
+
+// Memory layout for vertex data
+const V_BASE = USER_MEM; // Base vertices stored as 8-bit integers (i8)
+const V_ROT = V_BASE + (3 * 8); // Rotated vertices stored as 32-bit floats (f32), offset after V_BASE
+
+// Offsets for accessing X, Y, Z coordinates in memory (in bytes)
+const X = 0; // Offset for X coordinate
+const Y = 4; // Offset for Y coordinate
+const Z = 8; // Offset for Z coordinate
+
+// Memory offsets for each rotated vertex (8 vertices, 3 floats each, 12 bytes per vertex)
+const VA = V_ROT + (0 * 3 * 4); // Vertex A (front-top-left)
+const VB = V_ROT + (1 * 3 * 4); // Vertex B (front-top-right)
+const VC = V_ROT + (2 * 3 * 4); // Vertex C (front-bottom-right)
+const VD = V_ROT + (3 * 3 * 4); // Vertex D (front-bottom-left)
+const VE = V_ROT + (4 * 3 * 4); // Vertex E (back-top-left)
+const VF = V_ROT + (5 * 3 * 4); // Vertex F (back-top-right)
+const VG = V_ROT + (6 * 3 * 4); // Vertex G (back-bottom-right)
+const VH = V_ROT + (7 * 3 * 4); // Vertex H (back-bottom-left)
+
+//-----------------------------------------------------------------------------
+// Function to rotate the cube around X, Y, and Z axes based on time
+//-----------------------------------------------------------------------------
+
+fn rotate() {
+ // Calculate the rotation angle using the current time for continuous animation
+ let angle = time() * ROTATE_SPEED;
+
+ // Precompute sine and cosine values once for efficiency
+ let sn = sin(angle);
+ let cs = cos(angle);
+
+ let calc = 0;
+ loop calc { // Iterate over all 8 vertices
+ // Calculate memory offset for current vertex (12 bytes per vertex: 4 bytes each for X, Y, Z)
+ let v = calc * 12;
+ let inline vX = v + X;
+ let inline vY = v + Y;
+ let inline vZ = v + Z;
+
+ // Load original vertex coordinates from V_BASE (stored as i8, converted to f32)
+ let x = i32.load8_s(V_BASE+(calc * 3 + 0)) as f32; // X coordinate
+ let y = i32.load8_s(V_BASE+(calc * 3 + 1)) as f32; // Y coordinate
+ let z = i32.load8_s(V_BASE+(calc * 3 + 2)) as f32; // Z coordinate
+
+ // Rotate around Z-axis: updates X and Y, Z stays the same
+ (vX)$V_ROT = x * cs - y * sn;
+ (vY)$V_ROT = x * sn + y * cs;
+ (vZ)$V_ROT = z;
+
+ // Rotate around Y-axis: updates X and Z, Y stays the same
+ x = (vX)$V_ROT;
+ z = (vZ)$V_ROT;
+ (vX)$V_ROT = x * cs + z * sn;
+ (vZ)$V_ROT = z * cs - x * sn;
+
+ // Rotate around X-axis: updates Y and Z, X stays the same
+ y = (vY)$V_ROT;
+ z = (vZ)$V_ROT;
+ (vY)$V_ROT = y * cs - z * sn;
+ (vZ)$V_ROT = y * sn + z * cs;
+
+ // Move to the next vertex until all 8 are processed
+ branch_if (calc +:= 1) < 8: calc;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Function to project 3D vertices to 2D screen space and draw the cube's edges
+//-----------------------------------------------------------------------------
+
+fn drawLines() {
+ let scale = 0;
+ loop scale { // Scale and center each vertex for 2D projection
+ // Calculate memory offset for current vertex (12 bytes per vertex: 4 bytes each for X, Y, Z)
+ let v = scale * 12;
+ let inline vX = v + X;
+ let inline vY = v + Y;
+
+ // Load Z coordinate of current vertex (from rotated vertex data)
+ let inline z = (v + Z)$V_ROT;
+
+ // Calculate perspective factor:
+ // - When z=0 (midpoint), factor=1.0 (no scaling)
+ // - Positive z (farther away) → factor<1.0 (objects appear smaller)
+ // - Negative z (closer) → factor>1.0 (objects appear larger)
+ let lazy factor = PERSPECTIVE / (PERSPECTIVE + z) * SCALE;
+
+ // Apply perspective projection, scaling and shift to center for X and Y coordinats:
+ // 1. Multiply by perspective factor
+ // 2. Apply global scaling (SCALE constant)
+ // 3. Center on screen (CENTER_X, CENTER_Y)
+ (vX)$V_ROT = (vX)$V_ROT * factor + CENTER_X; // X
+ (vY)$V_ROT = (vY)$V_ROT * factor + CENTER_Y; // Y
+
+ // Continue until all 8 vertices are scaled
+ branch_if (scale +:= 1) < 8: scale;
+ }
+
+ // Draw the front face of the cube (vertices A-B-C-D)
+ line(VA$X, VA$Y, VB$X, VB$Y, LINE_COLOR);
+ line(VB$X, VB$Y, VC$X, VC$Y, LINE_COLOR);
+ line(VC$X, VC$Y, VD$X, VD$Y, LINE_COLOR);
+ line(VD$X, VD$Y, VA$X, VA$Y, LINE_COLOR);
+
+ // Draw the back face of the cube (vertices E-F-G-H)
+ line(VE$X, VE$Y, VF$X, VF$Y, LINE_COLOR);
+ line(VF$X, VF$Y, VG$X, VG$Y, LINE_COLOR);
+ line(VG$X, VG$Y, VH$X, VH$Y, LINE_COLOR);
+ line(VH$X, VH$Y, VE$X, VE$Y, LINE_COLOR);
+
+ // Draw edges connecting front and back faces
+ line(VA$X, VA$Y, VE$X, VE$Y, LINE_COLOR);
+ line(VB$X, VB$Y, VF$X, VF$Y, LINE_COLOR);
+ line(VC$X, VC$Y, VG$X, VG$Y, LINE_COLOR);
+ line(VD$X, VD$Y, VH$X, VH$Y, LINE_COLOR);
+}
+
+//-----------------------------------------------------------------------------
+// Entry point for INIT type function, starts first
+//-----------------------------------------------------------------------------
+
+/*
+export fn start() {
+ let init = 0;
+ loop init {
+ // Calculate memory offset for current vertex (12 bytes per vertex: 4 bytes each for X, Y, Z)
+ let v = init * 12;
+
+ (v + X)$V_ROT = i32.load8_s(V_BASE+(init * 3) + 0) as f32;
+ (v + Y)$V_ROT = i32.load8_s(V_BASE+(init * 3) + 1) as f32;
+ (v + Z)$V_ROT = i32.load8_s(V_BASE+(init * 3) + 2) as f32;
+ branch_if (init +:= 1) < 8: init;
+ }
+}
+*/
+
+//-----------------------------------------------------------------------------
+// Main update function called every frame to refresh the screen
+//-----------------------------------------------------------------------------
+
+export fn upd() {
+ cls(0); // Clear the screen with color 0 (black)
+ rotate(); // Perform cube rotation calculations
+ drawLines(); // Draw the rotated cube on the screen
+}
+
+//-----------------------------------------------------------------------------
+// DATA
+//-----------------------------------------------------------------------------
+
+/*
+ Initial vertex data for the cube (8 vertices, each with X, Y, Z as 8-bit signed integers)
+ Each vertex represents a corner of a unit cube centered at the origin
+
+ F - front, B - back, L - left, R - right, U - up, D - down
+*/
+data V_BASE { // 3 * 8 -> 3 bytes per vertex * 8 vertices = 24 bytes
+ i8(
+ // X Y Z
+ -1, -1, 1, // FLU Vertex A
+ 1, -1, 1, // FRU Vertex B
+ 1, 1, 1, // FRD Vertex C
+ -1, 1, 1, // FLD Vertex D
+ -1, -1, -1, // BLU Vertex E
+ 1, -1, -1, // BRU Vertex F
+ 1, 1, -1, // BRD Vertex G
+ -1, 1, -1 // BLD Vertex H
+ )
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+ Storage for rotated vertex data (8 vertices, each with X, Y, Z as 32-bit signed floats)
+ Initialized to zero and updated during rotation
+*/
+data V_ROT { // 4 * 3 * 8 -> 12 bytes per vertex * 8 vertices = 96 bytes
+ f32(
+ // X Y Z
+ 0.0, 0.0, 0.0, // VA -> Vertex A
+ 0.0, 0.0, 0.0, // VB -> Vertex B
+ 0.0, 0.0, 0.0, // VC -> Vertex C
+ 0.0, 0.0, 0.0, // VD -> Vertex D
+ 0.0, 0.0, 0.0, // VE -> Vertex E
+ 0.0, 0.0, 0.0, // VF -> Vertex F
+ 0.0, 0.0, 0.0, // VG -> Vertex G
+ 0.0, 0.0, 0.0 // VH -> Vertex H
+ )
+}
+
+//-----------------------------------------------------------------------------
+// SNIPPETS
+//-----------------------------------------------------------------------------
+
+/*
+ let tmp: f32;
+ tmp = -123.0;
+ f32.store(tmp, V_ROT);
+ tmp = f32.load(V_ROT);
+ printInt(tmp as i32);
+*/
+
+//-----------------------------------------------------------------------------
diff --git a/examples/curlywas/plasma.cwa b/examples/curlywas/plasma.cwa
new file mode 100644
index 0000000..4db0350
--- /dev/null
+++ b/examples/curlywas/plasma.cwa
@@ -0,0 +1,51 @@
+/*
+ Plasma effect (sizecoding)
+
+ Combines sine waves to create a 2D pixel pattern with intensity-based colors.
+
+ code : zbyti & Grok 3
+ date : 2025.04.17
+ platform : MicroW8 0.4.1
+*/
+
+include "../include/microw8-api.cwa"
+
+// Constants for color, math, and screen dimensions
+const BASE_COLOR = 0xF0; // Base color value for pixel coloring
+const PI = 3.14159265; // Mathematical constant π
+const RAD = PI / 180.0; // Conversion factor from degrees to radians
+const SCR_X = 320; // Screen width in pixels
+const SCR_Y = 240; // Screen height in pixels
+const SCR_SIZE = SCR_X * SCR_Y; // Screen size in bytes
+
+// Global variables to track animation phases
+global mut phaseX = 0; // Phase offset for X-axis wave animation
+global mut phaseY = 0; // Phase offset for Y-axis wave animation
+
+// Update function called each frame to render the plasma effect
+export fn upd() {
+ let i = 0;
+ loop i {
+ // Calculate pixel coordinates from linear index
+ let lazy x = i % SCR_X; // X-coordinate (column)
+ let lazy y = i / SCR_X; // Y-coordinate (row)
+
+ // Compute three sine waves with different frequencies and phases
+ let inline val1 = sin(RAD * 2.25 * (x + phaseX) as f32); // Wave along X-axis
+ let inline val2 = sin(RAD * 3.25 * (y + phaseY) as f32); // Wave along Y-axis
+ let inline val3 = sin(RAD * 1.25 * (x + y + phaseX) as f32); // Diagonal wave
+
+ // Combine waves, scale to color range, and convert to integer
+ let inline c = BASE_COLOR + ((val1 + val2 + val3) * 4.75) as i32;
+
+ // Set pixel color based on computed intensity
+ setPixel(x, y, c);
+
+ // Continue loop until all pixels are processed
+ branch_if (i +:= 1) < (SCR_SIZE): i;
+ }
+
+ // Update phase offsets for animation (different speeds for dynamic effect)
+ phaseX += 1; // Increment X-phase for horizontal wave movement
+ phaseY += 2; // Increment Y-phase for vertical wave movement
+}
\ No newline at end of file
diff --git a/examples/curlywas/plasma_chars.cwa b/examples/curlywas/plasma_chars.cwa
new file mode 100644
index 0000000..f2f1e5e
--- /dev/null
+++ b/examples/curlywas/plasma_chars.cwa
@@ -0,0 +1,168 @@
+/*
+ Plasma effect (chars)
+
+ Combines sine waves to create a 2D pattern, maps to custom characters,
+ and renders to the 40x30 character grid with intensity-based colors.
+
+ code : zbyti (conversion & optimizations)
+ original : https://github.com/tebe6502/Mad-Pascal/blob/origin/samples/a8/demoeffects/plasma_2.pas
+ date : 2025.04.16
+ platform : MicroW8 0.4.1
+*/
+
+include "../include/microw8-api.cwa"
+
+//-----------------------------------------------------------------------------
+// Constants defining memory layout, screen dimensions, and effect parameters
+//-----------------------------------------------------------------------------
+
+const MEM_END = 0x40000;
+
+const CUSTOM_FONT = FONT + 0x100;
+const CHARS = 0x20;
+const BASE_COLOR = 0xF0;
+
+const PI = 3.14159265;
+const RAD = PI / 180.0;
+
+const SCR_X = 320;
+const SCR_Y = 240;
+const SCR_W = SCR_X / 8; // 40
+const SCR_H = SCR_Y / 8; // 30
+const SCR_SIZE = SCR_X * SCR_Y;
+
+const SIN_TABLE_SIZE = 128; // Number of entries in the sine lookup table
+const SIN_TABLE_MASK = SIN_TABLE_SIZE - 1;
+
+const SIN_TABLE = MEM_END - SIN_TABLE_SIZE; // Memory address for sine table
+const ROW_BUFFER = SIN_TABLE - SCR_W; // Memory address for precomputed row buffer
+
+//-----------------------------------------------------------------------------
+// Global variables to track animation state
+//-----------------------------------------------------------------------------
+
+global mut phaseA = 1; // Phase offset for the first sine wave, controls animation
+global mut phaseB = 5; // Phase offset for the second sine wave, controls animation
+
+//-----------------------------------------------------------------------------
+
+/*
+ Logs a value to the console (STDOUT) with a prefix for debugging purposes
+
+ Args:
+ prefix : 4-character identifier (i32) to label the output
+ log : Integer value to log (i32)
+
+ Prints to console and returns to screen output
+*/
+fn console(prefix: i32, log: i32) {
+ printChar('\6'); // Switch output to console
+ printChar(prefix); // Print the prefix
+ printInt(log); // Print the integer value
+ printChar('\n\4'); // Print newline and switch back to screen output
+}
+
+//-------------------------------------
+
+/*
+ Fills a sine table with precomputed values for fast lookups
+
+ Args:
+ adr : Memory address where the sine table is stored
+ size : Number of entries in the table
+
+ Computes: sin(i * 180/size * radians) * 255 for i = 0 to size-1, scaled to 0-255
+*/
+fn fillSin(adr: i32, size: i32) {
+ let i = 0;
+ let inline f = 180.00 / size as f32 * RAD;
+ loop i {
+ (adr+i)?0 = (sin(f * i as f32) * 255.0) as i32;
+ branch_if (i +:= 1) < size: i;
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+ Initialization function called when the program starts
+*/
+export fn start() {
+ // Populate the sine table with values for fast wave calculations
+ fillSin(SIN_TABLE, SIN_TABLE_SIZE);
+}
+
+//-------------------------------------
+
+/*
+ Update function called each frame to render the plasma effect
+*/
+export fn upd() {
+ let pA = phaseA; // Local copy of phaseA to avoid modifying global during frame
+ let pB = phaseB; // Local copy of phaseB for the same reason
+
+ let i = 0;
+ loop i {
+ // Wrap phase values to stay within sine table bounds using bitwise AND
+ pA &= SIN_TABLE_MASK;
+ pB &= SIN_TABLE_MASK;
+
+ // Combine two sine waves and store in row buffer
+ i?ROW_BUFFER = pA?SIN_TABLE + pB?SIN_TABLE;
+
+ pA += 3; // Shift phase for first sine wave (controls wave speed)
+ pB += 7; // Shift phase for second sine wave (different speed for variety)
+
+ branch_if (i +:= 1) < SCR_W: i;
+ }
+
+ i = 0;
+ loop i {
+ let j = 0;
+ loop j {
+ // Combine wave values from row buffer for current position
+ // Use bitwise AND to clamp to 0-255, then scale to 0-15 for character index
+ let c = ((j?ROW_BUFFER + i?ROW_BUFFER) & 255) >> 4;
+
+ // Set text color based on intensity (base color + scaled value)
+ setTextColor(BASE_COLOR + c);
+ // Draw custom character corresponding to intensity
+ printChar(CHARS + c);
+
+ branch_if (j +:= 1) < SCR_W: j;
+ }
+ branch_if (i +:= 1) < SCR_H: i;
+ }
+
+ // Update global phase offsets for the next frame to animate the pattern
+ phaseA += 0; // Increment phaseA to shift the pattern (+/- speed move)
+ phaseB += 1; // Increment phaseB to shift the pattern (+/- right/left move)
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+ Custom font data defining 16 characters (8x8 pixels each)
+ Each character represents a different intensity level for the plasma effect
+ Pixels range from empty (0x00) to nearly full (0xFE or 0x7F) to simulate gradients
+*/
+data CUSTOM_FONT {
+ i8(
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
+ 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00,
+ 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00,
+ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00,
+ 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+ 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00,
+ 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ )
+}
diff --git a/syntax/SublimeText/CurlyWASM.sublime-completions b/syntax/SublimeText/CurlyWASM.sublime-completions
new file mode 100644
index 0000000..bd3901f
--- /dev/null
+++ b/syntax/SublimeText/CurlyWASM.sublime-completions
@@ -0,0 +1,789 @@
+{
+ "scope": "source.curlywasm",
+ "completions": [
+ // Keywords
+ {
+ "trigger": "if",
+ "contents": "if ${1:condition} {\n\t${2:// Your start code here}\n}",
+ "details": "if (condition) { block }",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "else",
+ "contents": "else {\n\t${1:// Your start code here}\n}",
+ "details": "else { block }",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "loop",
+ "contents": "loop ${1:label} {\n\t${2:// Your start code here}\n}",
+ "details": "loop label { block }",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "fn",
+ "contents": "fn ${1:name}(${2:params}) {\n\t${3:// Your start code here}\n}",
+ "details": "fn name(params) [-> return_type] { block }",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "let",
+ "contents": "let ${1:variable} = ${2:value};",
+ "details": "let variable[: type] = value;",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "const",
+ "contents": "const ${1:name} = ${2:value};",
+ "details": "const name[: type] = value;",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "branch_if",
+ "contents": "branch_if ${1:condition}: ${2:label};",
+ "details": "branch_if (condition): label;",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "global",
+ "contents": "global mut ${1:name} = ${2:value};",
+ "details": "global mut name[: type] = value;",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "import",
+ "contents": "import \"${1:module.name}\" ${2:|memory(min_pages)|global var_name: type|fn fun_name(param_types) [-> return_type]};",
+ "details": "import \"module.name\" memory(min_pages); import \"module.name\" global var_name: type; import \"module.name\" fn fun_name(param_types) [-> return_type];",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "include",
+ "contents": "include \"${1:path}\"",
+ "details": "include \"path\"",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "api",
+ "contents": "include \"../include/microw8-api.cwa\"",
+ "details": "include \"path\"",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "common",
+ "contents": "include \"../include/common.cwa\"",
+ "details": "include \"path\"",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "export",
+ "contents": "export fn ${1:name}(${2:params}) ${3:-> ${4:return_type}} { ${5:block} }",
+ "details": "export fn name(params) [-> return_type] { block }",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "block",
+ "contents": "block ${1:label} {\n\t${2://content}\n}",
+ "details": "block label { block }",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "branch",
+ "contents": "branch ${1:label};",
+ "details": "branch label;",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "data",
+ "contents": "data ${1:address} {\n\t${2:type}(\n\t\t${3:values}\n\t)\n}",
+ "details": "data address { content }",
+ "kind": "keyword"
+ },
+ {
+ "trigger": "mut",
+ "contents": "mut",
+ "details": "Mutable variable modifier",
+ "kind": "storage.modifier"
+ },
+ {
+ "trigger": "lazy",
+ "contents": "lazy",
+ "details": "Lazy variable modifier",
+ "kind": "storage.modifier"
+ },
+ {
+ "trigger": "inline",
+ "contents": "inline",
+ "details": "Inline variable modifier",
+ "kind": "storage.modifier"
+ },
+
+ // Operators
+ {
+ "trigger": "as",
+ "contents": "as",
+ "details": "Type cast",
+ "kind": "keyword.operator.type"
+ },
+ {
+ "trigger": "?",
+ "contents": "?",
+ "details": "Load byte",
+ "kind": "keyword.operator.memory"
+ },
+ {
+ "trigger": "!",
+ "contents": "!",
+ "details": "Load word",
+ "kind": "keyword.operator.memory"
+ },
+ {
+ "trigger": "$",
+ "contents": "$",
+ "details": "Load float",
+ "kind": "keyword.operator.memory"
+ },
+ {
+ "trigger": "<|",
+ "contents": "<|",
+ "details": "Take first (sequencing operator)",
+ "kind": "keyword.operator.misc"
+ },
+
+ // Memory access intrinsic functions (i32 and f32 only)
+ {
+ "trigger": "i32.load",
+ "contents": "i32.load(${1:base}, ${2:offset}${3:, ${4:align}})",
+ "details": "i32.load(base: i32, offset: i32 = 0, align: i32 = 2) -> i32: Load 32-bit word",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.load8_u",
+ "contents": "i32.load8_u(${1:base}, ${2:offset}${3:, ${4:align}})",
+ "details": "i32.load8_u(base: i32, offset: i32 = 0, align: i32 = 0) -> i32: Load 8-bit unsigned",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.load8_s",
+ "contents": "i32.load8_s(${1:base}, ${2:offset}${3:, ${4:align}})",
+ "details": "i32.load8_s(base: i32, offset: i32 = 0, align: i32 = 0) -> i32: Load 8-bit signed",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.load16_u",
+ "contents": "i32.load16_u(${1:base}, ${2:offset}${3:, ${4:align}})",
+ "details": "i32.load16_u(base: i32, offset: i32 = 0, align: i32 = 1) -> i32: Load 16-bit unsigned",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.load16_s",
+ "contents": "i32.load16_s(${1:base}, ${2:offset}${3:, ${4:align}})",
+ "details": "i32.load16_s(base: i32, offset: i32 = 0, align: i32 = 1) -> i32: Load 16-bit signed",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.store",
+ "contents": "i32.store(${1:value}, ${2:base}, ${3:offset}${4:, ${5:align}});",
+ "details": "i32.store(value: i32, base: i32, offset: i32 = 0, align: i32 = 2): Store 32-bit word",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.store8",
+ "contents": "i32.store8(${1:value}, ${2:base}, ${3:offset}${4:, ${5:align}});",
+ "details": "i32.store8(value: i32, base: i32, offset: i32 = 0, align: i32 = 0): Store 8-bit",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.store16",
+ "contents": "i32.store16(${1:value}, ${2:base}, ${3:offset}${4:, ${5:align}});",
+ "details": "i32.store16(value: i32, base: i32, offset: i32 = 0, align: i32 = 1): Store 16-bit",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "f32.load",
+ "contents": "f32.load(${1:base}, ${2:offset}${3:, ${4:align}})",
+ "details": "f32.load(base: i32, offset: i32 = 0, align: i32 = 2) -> f32: Load 32-bit float",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "f32.store",
+ "contents": "f32.store(${1:value}, ${2:base}, ${3:offset}${4:, ${5:align}});",
+ "details": "f32.store(value: f32, base: i32, offset: i32 = 0, align: i32 = 2): Store 32-bit float",
+ "kind": "support.function"
+ },
+
+ // API functions
+ {
+ "trigger": "sin",
+ "contents": "sin(${1:x})",
+ "details": "sin(x: f32) -> f32: Returns the sine of x (radians)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "cos",
+ "contents": "cos(${1:x})",
+ "details": "cos(x: f32) -> f32: Returns the cosine of x (radians)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "tan",
+ "contents": "tan(${1:x})",
+ "details": "tan(x: f32) -> f32: Returns the tangent of x (radians)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "asin",
+ "contents": "asin(${1:x})",
+ "details": "asin(x: f32) -> f32: Returns the arcsine of x (radians)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "acos",
+ "contents": "acos(${1:x})",
+ "details": "acos(x: f32) -> f32: Returns the arccosine of x (radians)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "atan",
+ "contents": "atan(${1:x})",
+ "details": "atan(x: f32) -> f32: Returns the arctangent of x (radians)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "atan2",
+ "contents": "atan2(${1:y}, ${2:x})",
+ "details": "atan2(y: f32, x: f32) -> f32: Returns the angle in radians of the point (x, y)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "pow",
+ "contents": "pow(${1:x}, ${2:y})",
+ "details": "pow(x: f32, y: f32) -> f32: Returns x raised to the power of y",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "log",
+ "contents": "log(${1:x})",
+ "details": "log(x: f32) -> f32: Returns the natural logarithm of x",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "fmod",
+ "contents": "fmod(${1:x}, ${2:y})",
+ "details": "fmod(x: f32, y: f32) -> f32: Returns the remainder of x/y",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "random",
+ "contents": "random()",
+ "details": "random() -> i32: Returns a random 32-bit integer",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "randomf",
+ "contents": "randomf()",
+ "details": "randomf() -> f32: Returns a random float [0, 1)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "randomSeed",
+ "contents": "randomSeed(${1:seed});",
+ "details": "randomSeed(seed: i32): Seeds the random number generator",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "cls",
+ "contents": "cls(${1:color});",
+ "details": "cls(color: i32): Clears the screen with the given color, resets cursor to 0,0, disables graphics mode",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "setPixel",
+ "contents": "setPixel(${1:x}, ${2:y}, ${3:color});",
+ "details": "setPixel(x: i32, y: i32, color: i32): Sets the pixel at (x, y) to color",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "getPixel",
+ "contents": "getPixel(${1:x}, ${2:y})",
+ "details": "getPixel(x: i32, y: i32) -> i32: Gets the color of the pixel at (x, y) (returns 0 if out of bounds)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "hline",
+ "contents": "hline(${1:left}, ${2:right}, ${3:y}, ${4:color});",
+ "details": "hline(left: i32, right: i32, y: i32, color: i32): Fills the horizontal line [left, right), y",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "rectangle",
+ "contents": "rectangle(${1:x}, ${2:y}, ${3:width}, ${4:height}, ${5:color});",
+ "details": "rectangle(x: f32, y: f32, w: f32, h: f32, color: i32): Fills the rectangle x,y - x+w,y+h",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "circle",
+ "contents": "circle(${1:cx}, ${2:cy}, ${3:radius}, ${4:color});",
+ "details": "circle(cx: f32, cy: f32, radius: f32, color: i32): Fills the circle at cx, cy with radius",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "line",
+ "contents": "line(${1:x1}, ${2:y1}, ${3:x2}, ${4:y2}, ${5:color});",
+ "details": "line(x1: f32, y1: f32, x2: f32, y2: f32, color: i32): Draws a line from x1,y1 to x2,y2",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "time",
+ "contents": "time()",
+ "details": "time() -> f32: Returns the current time in seconds",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "isButtonPressed",
+ "contents": "isButtonPressed(${1:button})",
+ "details": "isButtonPressed(button: i32) -> bool: Checks if a button is pressed this frame (returns i32)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "isButtonTriggered",
+ "contents": "isButtonTriggered(${1:button})",
+ "details": "isButtonTriggered(button: i32) -> bool: Checks if a button is newly pressed this frame (returns i32)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "printChar",
+ "contents": "printChar(${1:char});",
+ "details": "printChar(char: i32): Prints the character in the lower 8 bits",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "printString",
+ "contents": "printString(${1:ptr});",
+ "details": "printString(ptr: i32): Prints the zero-terminated string at memory address ptr",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "printInt",
+ "contents": "printInt(${1:value});",
+ "details": "printInt(value: i32): Prints an integer as a signed decimal number",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "setTextColor",
+ "contents": "setTextColor(${1:color});",
+ "details": "setTextColor(color: i32): Sets the text color",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "setBackgroundColor",
+ "contents": "setBackgroundColor(${1:color});",
+ "details": "setBackgroundColor(color: i32): Sets the background color",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "setCursorPosition",
+ "contents": "setCursorPosition(${1:x}, ${2:y});",
+ "details": "setCursorPosition(x: i32, y: i32): Sets the cursor position (character or pixel coords depending on mode)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "rectangleOutline",
+ "contents": "rectangleOutline(${1:x}, ${2:y}, ${3:width}, ${4:height}, ${5:color});",
+ "details": "rectangleOutline(x: f32, y: f32, w: f32, h: f32, color: i32): Draws a rectangle outline",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "circleOutline",
+ "contents": "circleOutline(${1:cx}, ${2:cy}, ${3:radius}, ${4:color});",
+ "details": "circleOutline(cx: f32, cy: f32, radius: f32, color: i32): Draws a circle outline",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "exp",
+ "contents": "exp(${1:x})",
+ "details": "exp(x: f32) -> f32: Returns e raised to the power of x",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "playNote",
+ "contents": "playNote(${1:channel}, ${2:note}${3:, ${4:duration}${5:, ${6:volume}}});",
+ "details": "playNote(channel: i32, note: i32): Triggers a note on the given channel (note 0 stops, 128-255 triggers attack+release)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "sndGes",
+ "contents": "sndGes(${1:sampleIndex})",
+ "details": "sndGes(sampleIndex: i32) -> f32: Sound generator function (uses 32 bytes at 0x50 by default)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "blitSprite",
+ "contents": "blitSprite(${1:spriteData}, ${2:size}, ${3:x}, ${4:y}, ${5:control});",
+ "details": "blitSprite(spriteData: i32, size: i32, x: i32, y: i32, control: i32): Copies sprite data to screen",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "grabSprite",
+ "contents": "grabSprite(${1:spriteData}, ${2:size}, ${3:x}, ${4:y}, ${5:control});",
+ "details": "grabSprite(spriteData: i32, size: i32, x: i32, y: i32, control: i32): Copies screen data to sprite",
+ "kind": "support.function"
+ },
+
+ // Built-in functions (or commonly used intrinsics)
+ {
+ "trigger": "start",
+ "contents": "export fn start() {\n\t${1:// Your start code here}\n}",
+ "details": "export fn start(): Called once after module is loaded",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "upd",
+ "contents": "export fn upd() {\n\t${1:// Your update code here}\n}",
+ "details": "export fn upd(): Called once per frame",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "memory.fill",
+ "contents": "memory.fill(${1:dest}, ${2:value}, ${3:size});",
+ "details": "memory.fill(dest: i32, value: i32, size: i32): Fills a memory area",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "memory.copy",
+ "contents": "memory.copy(${1:dest}, ${2:src}, ${3:size});",
+ "details": "memory.copy(dest: i32, src: i32, size: i32): Copies a memory block",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "sqrt",
+ "contents": "sqrt(${1:x})",
+ "details": "sqrt(x: f32) -> f32: Returns the square root of x",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "min",
+ "contents": "min(${1:x}, ${2:y})",
+ "details": "min(x: f32, y: f32) -> f32: Returns the minimum of x and y",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "max",
+ "contents": "max(${1:x}, ${2:y})",
+ "details": "max(x: f32, y: f32) -> f32: Returns the maximum of x and y",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "ceil",
+ "contents": "ceil(${1:x})",
+ "details": "ceil(x: f32) -> f32: Returns the smallest integer >= x",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "floor",
+ "contents": "floor(${1:x})",
+ "details": "floor(x: f32) -> f32: Returns the largest integer <= x",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "trunc",
+ "contents": "trunc(${1:x})",
+ "details": "trunc(x: f32) -> f32: Returns the nearest integer to x toward zero",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "nearest",
+ "contents": "nearest(${1:x})",
+ "details": "nearest(x: f32) -> f32: Returns the nearest integer to x (round to nearest, ties to even)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "abs",
+ "contents": "abs(${1:x})",
+ "details": "abs(x: f32) -> f32: Returns the absolute value of x",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "copysign",
+ "contents": "copysign(${1:x}, ${2:y})",
+ "details": "copysign(x: f32, y: f32) -> f32: Returns x with the sign of y",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "select",
+ "contents": "select(${1:a}, ${2:b}, ${3:c})",
+ "details": "select(a: f32, b: f32, c: f32) -> f32: Selects b if a is non-zero, otherwise selects c (equivalent to a != 0 ? b : c)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.clz",
+ "contents": "i32.clz(${1:value})",
+ "details": "i32.clz(value: i32) -> i32: Count Leading Zeros",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.ctz",
+ "contents": "i32.ctz(${1:value})",
+ "details": "i32.ctz(value: i32) -> i32: Count Trailing Zeros",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.popcnt",
+ "contents": "i32.popcnt(${1:value})",
+ "details": "i32.popcnt(value: i32) -> i32: Population Count (number of set bits)",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.bswap",
+ "contents": "i32.bswap(${1:value})",
+ "details": "i32.bswap(value: i32) -> i32: Byte Swap",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.trunc_sat_f32_u",
+ "contents": "i32.trunc_sat_f32_u(${1:value})",
+ "details": "i32.trunc_sat_f32_u(value: f32) -> i32: Truncate f32 to i32 unsigned, saturating",
+ "kind": "support.function"
+ },
+ {
+ "trigger": "i32.trunc_sat_f32_s",
+ "contents": "i32.trunc_sat_f32_s(${1:value})",
+ "details": "i32.trunc_sat_f32_s(value: f32) -> i32: Truncate f32 to i32 signed, saturating",
+ "kind": "support.function"
+ },
+ // Added Constants
+ {
+ "trigger": "TIME_MS",
+ "contents": "TIME_MS",
+ "details": "0x40 Time since module start in ms",
+ "kind": "constant"
+ },
+ {
+ "trigger": "GAMEPAD",
+ "contents": "GAMEPAD",
+ "details": "0x44 Gamepad state",
+ "kind": "constant"
+ },
+ {
+ "trigger": "FRAMEBUFFER",
+ "contents": "FRAMEBUFFER",
+ "details": "0x78 Frame buffer address",
+ "kind": "constant"
+ },
+ {
+ "trigger": "PALETTE",
+ "contents": "PALETTE",
+ "details": "0x13000 Palette address",
+ "kind": "constant"
+ },
+ {
+ "trigger": "FONT",
+ "contents": "FONT",
+ "details": "0x13400 Font address",
+ "kind": "constant"
+ },
+ {
+ "trigger": "USER_MEM",
+ "contents": "USER_MEM",
+ "details": "0x14000 Start of general user memory",
+ "kind": "constant"
+ },
+ {
+ "trigger": "BUTTON_UP",
+ "contents": "BUTTON_UP",
+ "details": "0x00 Gamepad button Up",
+ "kind": "constant"
+ },
+ {
+ "trigger": "BUTTON_DOWN",
+ "contents": "BUTTON_DOWN",
+ "details": "0x01 Gamepad button Down",
+ "kind": "constant"
+ },
+ {
+ "trigger": "BUTTON_LEFT",
+ "contents": "BUTTON_LEFT",
+ "details": "0x02 Gamepad button Left",
+ "kind": "constant"
+ },
+ {
+ "trigger": "BUTTON_RIGHT",
+ "contents": "BUTTON_RIGHT",
+ "details": "0x03 Gamepad button Right",
+ "kind": "constant"
+ },
+ {
+ "trigger": "BUTTON_A",
+ "contents": "BUTTON_A",
+ "details": "0x04 Gamepad button A (Z on keyboard)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "BUTTON_B",
+ "contents": "BUTTON_B",
+ "details": "0x05 Gamepad button B (X on keyboard)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "BUTTON_X",
+ "contents": "BUTTON_X",
+ "details": "0x06 Gamepad button X (A on keyboard)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "BUTTON_Y",
+ "contents": "BUTTON_Y",
+ "details": "0x07 Gamepad button Y (S on keyboard)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "PI",
+ "contents": "PI",
+ "details": "Mathematical constant π",
+ "kind": "constant"
+ },
+ {
+ "trigger": "RAD",
+ "contents": "RAD",
+ "details": "One radian value",
+ "kind": "constant"
+ },
+ {
+ "trigger": "SCR_X",
+ "contents": "SCR_X",
+ "details": "Screen width in pixels",
+ "kind": "constant"
+ },
+ {
+ "trigger": "SCR_Y",
+ "contents": "SCR_Y",
+ "details": "Screen height in pixels",
+ "kind": "constant"
+ },
+ {
+ "trigger": "SCR_W",
+ "contents": "SCR_W",
+ "details": "Screen width in chars (40)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "SCR_H",
+ "contents": "SCR_H",
+ "details": "Screen height in chars (30)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "CENTER_X",
+ "contents": "CENTER_X",
+ "details": "X-coordinate of the screen center (160)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "CENTER_Y",
+ "contents": "CENTER_Y",
+ "details": "Y-coordinate of the screen center (120)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "SCR_SIZE",
+ "contents": "SCR_SIZE",
+ "details": "Total screen size in pixels (76800)",
+ "kind": "constant"
+ },
+ {
+ "trigger": "MEM_END",
+ "contents": "MEM_END",
+ "details": "End of available memory",
+ "kind": "constant"
+ },
+ {
+ "trigger": "CUSTOM_FONT",
+ "contents": "CUSTOM_FONT",
+ "details": "Address for a custom font",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_BLACK",
+ "contents": "COLOR_BLACK",
+ "details": "0x00 Black",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_DARK_BLUE",
+ "contents": "COLOR_DARK_BLUE",
+ "details": "0x17 Dark Blue",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_DARK_PURPLE",
+ "contents": "COLOR_DARK_PURPLE",
+ "details": "0x27 Dark Purple",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_CYAN",
+ "contents": "COLOR_CYAN",
+ "details": "0x37 Cyan",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_BRIGHT_RED",
+ "contents": "COLOR_BRIGHT_RED",
+ "details": "0x47 Bright Red",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_MAGENTA",
+ "contents": "COLOR_MAGENTA",
+ "details": "0x57 Magenta",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_ORANGE",
+ "contents": "COLOR_ORANGE",
+ "details": "0x58 Orange",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_BRIGHT_YELLOW",
+ "contents": "COLOR_BRIGHT_YELLOW",
+ "details": "0x67 Bright Yellow",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_MEDIUM_GREY",
+ "contents": "COLOR_MEDIUM_GREY",
+ "details": "0x78 Medium Grey",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_LIGHT_GREY",
+ "contents": "COLOR_LIGHT_GREY",
+ "details": "0x7C Light Grey",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_WHITE",
+ "contents": "COLOR_WHITE",
+ "details": "0xF8 White",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_BRIGHT_GREEN",
+ "contents": "COLOR_BRIGHT_GREEN",
+ "details": "0x87 Bright Green",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_BROWN",
+ "contents": "COLOR_BROWN",
+ "details": "0xD4 Brown",
+ "kind": "constant"
+ },
+ {
+ "trigger": "COLOR_DARK_GREY",
+ "contents": "COLOR_DARK_GREY",
+ "details": "0xE1 Dark Grey",
+ "kind": "constant"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/syntax/SublimeText/CurlyWASM.sublime-syntax b/syntax/SublimeText/CurlyWASM.sublime-syntax
new file mode 100644
index 0000000..2a522bc
--- /dev/null
+++ b/syntax/SublimeText/CurlyWASM.sublime-syntax
@@ -0,0 +1,234 @@
+%YAML 1.2
+---
+# ==========================================================
+# http://www.sublimetext.com/docs/syntax.html
+# created by: zbyti & various AI
+# ==========================================================
+# For best results, use with Rust-themed color schemes like:
+# - "RustEnhanced"
+# - "Atomized"
+# - "Solarized Rust"
+# ==========================================================
+name: CurlyWASM
+file_extensions: [cwa]
+scope: source.curlywasm
+
+contexts:
+ main:
+ # Comments
+ - match: /\*
+ scope: comment.block.curlywasm
+ push: block_comment
+ - match: //
+ scope: comment.line.curlywasm
+ push: line_comment
+
+ # Module system
+ - match: \b(import|include|export)\b
+ scope: keyword.control.import.curlywasm
+
+ # Declarations and definitions
+ - match: \b(fn)\b
+ scope: keyword.declaration.function.curlywasm
+
+ - match: \b(const)\b
+ scope: storage.modifier.const.curlywasm
+
+ - match: \b(global|mut|let|lazy|inline)\b
+ scope: storage.modifier.curlywasm
+
+ # Control flow
+ - match: \b(if|else|block|loop|branch|branch_if)\b
+ scope: keyword.control.flow.curlywasm
+
+ # Type conversion
+ - match: \b(as)\b
+ scope: keyword.operator.type.curlywasm
+
+ # WASM memory access operators
+ - match: \b(load|store)\b
+ scope: keyword.operator.memory.curlywasm
+
+ # API functions
+ - match: \b(sin|cos|tan|asin|acos|atan|atan2|pow|log|fmod|random|randomf|randomSeed|cls|setPixel|getPixel|hline|rectangle|circle|line|time|isButtonPressed|isButtonTriggered|printChar|printString|printInt|setTextColor|setBackgroundColor|setCursorPosition|rectangleOutline|circleOutline|exp|playNote|sndGes|blitSprite|grabSprite)\b
+ scope: support.function.curlywasm
+
+ # Built-in functions
+ - match: \b(start|upd|sqrt|min|max|ceil|floor|trunc|nearest|abs|copysign|select)\b
+ scope: support.function.curlywasm
+
+ # Data blocks - Match 'data {' together and push context
+ - match: \b(data)\s*(\{)
+ captures:
+ 1: storage.type.data.curlywasm
+ 2: punctuation.section.block.begin.curlywasm
+ push: data_content
+
+ # Base types
+ - match: \b(i8|i16|i32|i64|f32|f64)\b
+ scope: storage.type.primitive.curlywasm
+
+ # Memory access operators
+ - match: (\?|\$|\!)
+ scope: keyword.operator.memory.curlywasm
+
+ # Operators
+ - match: (->)
+ scope: keyword.operator.arrow.curlywasm
+
+ # Assignment operators
+ - match: (=|:=|\+=|-=|\*=|/=|%=|&=|\|=|\^=|#/=)
+ scope: keyword.operator.assignment.curlywasm
+
+ # Arithmetic operators
+ - match: (\+|-|\*|/|%|#/|#%)
+ scope: keyword.operator.arithmetic.curlywasm
+
+ # Bitwise operators
+ - match: (\&|\||\^|<<|>>|#>>)
+ scope: keyword.operator.bitwise.curlywasm
+
+ # Comparison operators
+ - match: (<|>|<=|>=|#<|#<=|#>|#>=|==|!=)
+ scope: keyword.operator.comparison.curlywasm
+
+ # Other operators
+ - match: (<\|)
+ scope: keyword.operator.misc.curlywasm
+
+ # Numeric literals
+ - match: \b(0x[0-9a-fA-F]+)\b
+ scope: constant.numeric.hex.curlywasm
+
+ - match: '\b\d+(_f)\b'
+ scope: constant.numeric.float.curlywasm
+
+ - match: \b0x[0-9a-fA-F]+_f\b
+ scope: constant.numeric.float.curlywasm
+
+ - match: \b([0-9]+\.[0-9]+)\b
+ scope: constant.numeric.float.curlywasm
+
+ - match: \b([0-9]+)\b
+ scope: constant.numeric.integer.curlywasm
+
+ # String literals
+ - match: \"
+ scope: punctuation.definition.string.begin.curlywasm
+ push: double_quoted_string
+ - match: \'
+ scope: punctuation.definition.string.begin.curlywasm
+ push: single_quoted_string
+
+ # Function calls
+ - match: \b([a-zA-Z_][a-zA-Z0-9_]*)\s*\(
+ captures:
+ 1: entity.name.function.call.curlywasm
+
+ # Function declarations
+ - match: \bfn\s+([a-zA-Z_][a-zA-Z0-9_]*)\b
+ captures:
+ 1: entity.name.function.declaration.curlywasm
+
+ # Constants (Upper case convention)
+ - match: \b([A-Z_][A-Z0-9_]*)\b
+ scope: constant.other.curlywasm
+
+ # Variables (Lower case convention)
+ - match: \b([a-z_][a-zA-Z0-9_]*)\b
+ scope: variable.other.curlywasm
+
+ # Punctuation
+ - match: \{
+ scope: punctuation.section.block.begin.curlywasm
+ - match: \}
+ scope: punctuation.section.block.end.curlywasm
+ - match: \(
+ scope: punctuation.section.group.begin.curlywasm
+ - match: \)
+ scope: punctuation.section.group.end.curlywasm
+ - match: \[
+ scope: punctuation.section.brackets.begin.curlywasm
+ - match: \]
+ scope: punctuation.section.brackets.end.curlywasm
+ - match: ;
+ scope: punctuation.terminator.curlywasm
+ - match: \,
+ scope: punctuation.separator.curlywasm
+ - match: ':'
+ scope: punctuation.separator.type.curlywasm
+
+ # Context for /* ... */ block comments
+ block_comment:
+ - meta_scope: comment.block.curlywasm
+ - match: \*/
+ scope: punctuation.definition.comment.end.curlywasm
+ pop: true
+
+ # Context for // ... line comments
+ line_comment:
+ - meta_scope: comment.line.double-slash.curlywasm
+ - match: $ # Pop at the end of the line
+ pop: true
+
+ # Context for "..." strings
+ double_quoted_string:
+ - meta_scope: string.quoted.double.curlywasm
+ - match: \"
+ scope: punctuation.definition.string.end.curlywasm
+ pop: true
+ - match: \\. # Escape sequences
+ scope: constant.character.escape.curlywasm
+
+ # Context for '...' strings
+ single_quoted_string:
+ - meta_scope: string.quoted.single.curlywasm
+ - match: \'
+ scope: punctuation.definition.string.end.curlywasm
+ pop: true
+ - match: \\. # Escape sequences
+ scope: constant.character.escape.curlywasm
+
+ # Context for the content inside data { ... }
+ data_content:
+ - meta_scope: meta.data.content.curlywasm
+ # Match the closing brace to pop the context
+ - match: \}
+ scope: punctuation.section.block.end.curlywasm
+ pop: true
+ # Include rules for literals within the data block
+ - include: literals
+ # Specific types/keywords allowed inside data blocks
+ - match: \b(i8|i16|i32|i64|f32|f64)\b
+ scope: storage.type.primitive.curlywasm
+ - match: \b(file)\b
+ scope: keyword.control.curlywasm
+ # Punctuation inside data blocks
+ - match: \(
+ scope: punctuation.section.group.begin.curlywasm
+ - match: \)
+ scope: punctuation.section.group.end.curlywasm
+ - match: \,
+ scope: punctuation.separator.curlywasm
+ # Potentially allow comments inside data blocks
+ - include: block_comment
+ - include: line_comment
+
+ # Reusable patterns for literals (used via include)
+ literals:
+ # Numeric literals
+ - match: \b(0x[0-9a-fA-F]+)\b
+ scope: constant.numeric.hex.curlywasm
+ - match: '\b\d+(_f)\b'
+ scope: constant.numeric.float.curlywasm
+ - match: \b([0-9]+\.[0-9]+)\b
+ scope: constant.numeric.float.curlywasm
+ - match: \b([0-9]+)\b
+ scope: constant.numeric.integer.curlywasm
+ # String literals
+ - match: \"
+ scope: punctuation.definition.string.begin.curlywasm
+ push: double_quoted_string
+ - match: \'
+ scope: punctuation.definition.string.begin.curlywasm
+ push: single_quoted_string
diff --git a/syntax/SublimeText/data-block.sublime-snippet b/syntax/SublimeText/data-block.sublime-snippet
new file mode 100644
index 0000000..ef8a8ed
--- /dev/null
+++ b/syntax/SublimeText/data-block.sublime-snippet
@@ -0,0 +1,11 @@
+
+
+ datatype
+ Data block definition
+
diff --git a/syntax/SublimeText/fn-export.sublime-snippet b/syntax/SublimeText/fn-export.sublime-snippet
new file mode 100644
index 0000000..18b9c0d
--- /dev/null
+++ b/syntax/SublimeText/fn-export.sublime-snippet
@@ -0,0 +1,9 @@
+
+ ${3:return_type} {
+ ${4:// Function body}
+}
+]]>
+ fnexport
+ Exported function definition
+
diff --git a/syntax/SublimeText/if-else.sublime-snippet b/syntax/SublimeText/if-else.sublime-snippet
new file mode 100644
index 0000000..7688126
--- /dev/null
+++ b/syntax/SublimeText/if-else.sublime-snippet
@@ -0,0 +1,11 @@
+
+
+ ifelse
+ If-else statement
+
diff --git a/syntax/SublimeText/let-inline.sublime-snippet b/syntax/SublimeText/let-inline.sublime-snippet
new file mode 100644
index 0000000..cfdee88
--- /dev/null
+++ b/syntax/SublimeText/let-inline.sublime-snippet
@@ -0,0 +1,7 @@
+
+
+ letinline
+ Lazy variable declaration
+
diff --git a/syntax/SublimeText/let-lazy.sublime-snippet b/syntax/SublimeText/let-lazy.sublime-snippet
new file mode 100644
index 0000000..acaa041
--- /dev/null
+++ b/syntax/SublimeText/let-lazy.sublime-snippet
@@ -0,0 +1,7 @@
+
+
+ letlazy
+ Lazy variable declaration
+
diff --git a/syntax/SublimeText/loop-branch_if.sublime-snippet b/syntax/SublimeText/loop-branch_if.sublime-snippet
new file mode 100644
index 0000000..0c6bf25
--- /dev/null
+++ b/syntax/SublimeText/loop-branch_if.sublime-snippet
@@ -0,0 +1,11 @@
+
+
+ loopbr
+ Loop with branch_if
+