diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 8e63b430..a1e25e5f 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -28,19 +28,20 @@ /** @internal Symbol to token type mapping */ static const SymbolEntry symbols[] = { - {"%", TOK_MODL}, {"(", TOK_LPAREN}, {")", TOK_RPAREN}, - {"{", TOK_LBRACE}, {"}", TOK_RBRACE}, {"[", TOK_LBRACKET}, - {"]", TOK_RBRACKET}, {"..", TOK_RANGE}, {";", TOK_SEMICOLON}, - {",", TOK_COMMA}, {".", TOK_DOT}, {"=>", TOK_RIGHT_ARROW}, - {"==", TOK_EQEQ}, {"!=", TOK_NEQ}, {"<=", TOK_LE}, - {">=", TOK_GE}, {"&&", TOK_AND}, {"||", TOK_OR}, - {"=", TOK_EQUAL}, {"+", TOK_PLUS}, {"-", TOK_MINUS}, - {"*", TOK_STAR}, {"/", TOK_SLASH}, {"<", TOK_LT}, - {">", TOK_GT}, {"&", TOK_AMP}, {"|", TOK_PIPE}, - {"^", TOK_CARET}, {"~", TOK_TILDE}, {"!", TOK_BANG}, - {"?", TOK_QUESTION}, {"::", TOK_RESOLVE}, {":", TOK_COLON}, - {"_", TOK_SYMBOL}, {"++", TOK_PLUSPLUS}, {"--", TOK_MINUSMINUS}, - {"<<", TOK_SHIFT_LEFT}, {">>", TOK_SHIFT_RIGHT}, {"@", TOK_AT}, + {"%", TOK_MODL}, {"(", TOK_LPAREN}, {")", TOK_RPAREN}, + {"{", TOK_LBRACE}, {"}", TOK_RBRACE}, {"[", TOK_LBRACKET}, + {"]", TOK_RBRACKET}, {"..", TOK_RANGE}, {";", TOK_SEMICOLON}, + {",", TOK_COMMA}, {".", TOK_DOT}, {"->", TOK_RIGHT_ARROW}, + {"<-", TOK_LEFT_ARROW}, {"==", TOK_EQEQ}, {"!=", TOK_NEQ}, + {"<=", TOK_LE}, {">=", TOK_GE}, {"&&", TOK_AND}, + {"||", TOK_OR}, {"=", TOK_EQUAL}, {"+", TOK_PLUS}, + {"-", TOK_MINUS}, {"*", TOK_STAR}, {"/", TOK_SLASH}, + {"<", TOK_LT}, {">", TOK_GT}, {"&", TOK_AMP}, + {"|", TOK_PIPE}, {"^", TOK_CARET}, {"~", TOK_TILDE}, + {"!", TOK_BANG}, {"?", TOK_QUESTION}, {"::", TOK_RESOLVE}, + {":", TOK_COLON}, {"_", TOK_SYMBOL}, {"++", TOK_PLUSPLUS}, + {"--", TOK_MINUSMINUS}, {"<<", TOK_SHIFT_LEFT}, {">>", TOK_SHIFT_RIGHT}, + {"@", TOK_AT}, }; /** @internal Keyword text to token type mapping */ diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index af8ce62e..eea4f578 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -114,7 +114,8 @@ typedef enum { TOK_SHIFT_LEFT, /**< << */ TOK_SHIFT_RIGHT, /**< >> */ TOK_RANGE, /**< .. */ - TOK_RIGHT_ARROW, /**< => */ + TOK_RIGHT_ARROW, /**< -> */ + TOK_LEFT_ARROW, /**< <- */ TOK_MODL, /**< % */ TOK_WHITESPACE, /**< whitespace */ TOK_COMMENT /**< comment */ diff --git a/src/parser/stmt.c b/src/parser/stmt.c index 7201f965..18603895 100644 --- a/src/parser/stmt.c +++ b/src/parser/stmt.c @@ -123,7 +123,7 @@ Stmt *const_stmt(Parser *parser, bool is_public, bool returns_ownership, is_public, line, col); } - p_consume(parser, TOK_EQUAL, "Expected '=' after const name"); + p_consume(parser, TOK_RIGHT_ARROW, "Expected '->' after const name"); // Handle complex constant types (functions, structs, enums) switch (p_current(parser).type_) { diff --git a/src/typechecker/expr.c b/src/typechecker/expr.c index 09a23c8b..884e3e27 100644 --- a/src/typechecker/expr.c +++ b/src/typechecker/expr.c @@ -825,7 +825,7 @@ AstNode *typecheck_input_expr(AstNode *expr, Scope *scope, } // Check that message is a string type - AstNode *expected_string = create_basic_type(arena, "string", 0, 0); + AstNode *expected_string = create_basic_type(arena, "str", 0, 0); TypeMatchResult match = types_match(expected_string, msg_type); if (match == TYPE_MATCH_NONE) { diff --git a/std/math.lx b/std/math.lx index e37a838a..6928e3c8 100644 --- a/std/math.lx +++ b/std/math.lx @@ -28,15 +28,15 @@ pub const SIN_TABLE: [double; 129] = [ 1.000000 ]; -pub const rand = fn (seed: *int) int { +pub const rand -> fn (seed: *int) int { *seed = (*seed * 1103515245 + 12345) % 2147483648; return *seed; } -pub const add = fn (x: int, y: int) int { return x + y; } -pub const subtract = fn (x: int, y: int) int { return x - y; } -pub const multiply = fn (x: int, y: int) int { return x * y; } -pub const divide = fn (x: int, y: int) int { +pub const add -> fn (x: int, y: int) int { return x + y; } +pub const subtract -> fn (x: int, y: int) int { return x - y; } +pub const multiply -> fn (x: int, y: int) int { return x * y; } +pub const divide -> fn (x: int, y: int) int { if (y == 0) { output("(Division by zero error) "); return 0; @@ -44,7 +44,7 @@ pub const divide = fn (x: int, y: int) int { return x / y; } -pub const mod = fn (x: int, y: int) int { +pub const mod -> fn (x: int, y: int) int { if (y == 0) { output("(Division by zero error) "); return 0; @@ -52,13 +52,13 @@ pub const mod = fn (x: int, y: int) int { return x % y; } -pub const fib = fn (n: int, a: int, b: int) int { +pub const fib -> fn (n: int, a: int, b: int) int { if (n == 0) { return a; } if (n == 1) { return b; } return fib(n - 1, b, a + b); } -pub const power = fn (base: double, exponent: int) double { +pub const power -> fn (base: double, exponent: int) double { if (exponent == 0) { return 1.0; } let result: double = 1.0; @@ -76,17 +76,17 @@ pub const power = fn (base: double, exponent: int) double { return result; } -pub const max_size = fn (a: int, b: int) int { +pub const max_size -> fn (a: int, b: int) int { if (a > b) { return a; } return b; } -pub const min_size = fn (a: int, b: int) int { +pub const min_size -> fn (a: int, b: int) int { if (a < b) { return a; } return b; } -pub const sin = fn (a: double) double { +pub const sin -> fn (a: double) double { // Normalize into [0, TWO_PI) let k: int = cast(a / TWO_PI); a = a - k * TWO_PI; @@ -122,15 +122,15 @@ pub const sin = fn (a: double) double { } } -pub const cos = fn (x: double) double { return sin(x + HALF_PI); } +pub const cos -> fn (x: double) double { return sin(x + HALF_PI); } -pub const tan = fn (x: double) double { return sin(x)/(cos(x)+0.000000001); } +pub const tan -> fn (x: double) double { return sin(x)/(cos(x)+0.000000001); } -pub const sec = fn (x: double) double { return 1/(cos(x)+0.000000001); } +pub const sec -> fn (x: double) double { return 1/(cos(x)+0.000000001); } -pub const csc = fn (x: double) double { return 1/(sin(x)+0.000000001); } +pub const csc -> fn (x: double) double { return 1/(sin(x)+0.000000001); } -pub const cot = fn (x: double) double { return cos(x)/(sin(x)+0.000000001); } +pub const cot -> fn (x: double) double { return cos(x)/(sin(x)+0.000000001); } // const f = fn (x: double) double { // return math::sin(x); diff --git a/std/memory.lx b/std/memory.lx index 39781303..7f5dea9a 100644 --- a/std/memory.lx +++ b/std/memory.lx @@ -1,6 +1,6 @@ @module "memory" -pub const memcpy = fn (dest: *void, src: *void, n: int) *void { +pub const memcpy -> fn (dest: *void, src: *void, n: int) *void { let d: *char = cast<*char>(dest); let s: *char = cast<*char>(src); @@ -11,7 +11,7 @@ pub const memcpy = fn (dest: *void, src: *void, n: int) *void { return dest; } -pub const memcmp = fn (a: *void, b: *void, n: int) int { +pub const memcmp -> fn (a: *void, b: *void, n: int) int { let x: *char = cast<*char>(a); let y: *char = cast<*char>(b); loop [i: int = 0](i < n) : (++i) { @@ -22,7 +22,7 @@ pub const memcmp = fn (a: *void, b: *void, n: int) int { return 0; } -pub const memset = fn (dest: *void, value: int, n: int) *void { +pub const memset -> fn (dest: *void, value: int, n: int) *void { let d: *char = cast<*char>(dest); let c: char = cast(value); let i: int = 0; @@ -40,7 +40,7 @@ pub const memset = fn (dest: *void, value: int, n: int) *void { } // Move memory regions (handles overlapping regions correctly) -pub const memmove = fn (dest: *void, src: *void, n: int) *void { +pub const memmove -> fn (dest: *void, src: *void, n: int) *void { let d: *char = cast<*char>(dest); let s: *char = cast<*char>(src); @@ -60,7 +60,7 @@ pub const memmove = fn (dest: *void, src: *void, n: int) *void { } // Find first occurrence of byte in memory -pub const memchr = fn (ptr: *void, value: int, n: int) *void { +pub const memchr -> fn (ptr: *void, value: int, n: int) *void { let p: *char = cast<*char>(ptr); let target: char = cast(value); @@ -74,11 +74,11 @@ pub const memchr = fn (ptr: *void, value: int, n: int) *void { } // Zero out memory (common operation) -pub const memzero = fn (dest: *void, n: int) *void { return memset(dest, 0, n); } +pub const memzero -> fn (dest: *void, n: int) *void { return memset(dest, 0, n); } // Allocate and zero memory (calloc equivalent) #returns_ownership -pub const calloc = fn (count: int, size: int) *void { +pub const calloc -> fn (count: int, size: int) *void { let total_size: int = count * size; let ptr: *void = alloc(total_size); @@ -91,7 +91,7 @@ pub const calloc = fn (count: int, size: int) *void { // Reallocate memory (simplified version - allocates new and copies) #returns_ownership -pub const realloc = fn (ptr: *void, new_size: int) *void { +pub const realloc -> fn (ptr: *void, new_size: int) *void { if (ptr == cast<*void>(0)) { return alloc(new_size); } @@ -104,7 +104,7 @@ pub const realloc = fn (ptr: *void, new_size: int) *void { } // Memory swap (swap contents of two memory regions) -pub const memswap = fn (a: *void, b: *void, n: int) void { +pub const memswap -> fn (a: *void, b: *void, n: int) void { let p1: *char = cast<*char>(a); let p2: *char = cast<*char>(b); @@ -115,7 +115,7 @@ pub const memswap = fn (a: *void, b: *void, n: int) void { } } -pub const memswapn = fn (a: *void, b: *void, count: int, size: int) void { +pub const memswapn -> fn (a: *void, b: *void, count: int, size: int) void { let temp: *void = alloc(size); loop [i: int = 0](i < count) : (++i) { @@ -130,7 +130,7 @@ pub const memswapn = fn (a: *void, b: *void, count: int, size: int) void { free(temp); } -pub const memfill = fn (dest: *void, value: int, size: int, count: int) *void { +pub const memfill -> fn (dest: *void, value: int, size: int, count: int) *void { if (size == 1) { // Fill char/byte let d: *char = cast<*char>(dest); @@ -158,7 +158,7 @@ pub const memfill = fn (dest: *void, value: int, size: int, count: int) *void { } // Reverse bytes in memory region -pub const memrev = fn (ptr: *void, n: int) *void { +pub const memrev -> fn (ptr: *void, n: int) *void { let p: *char = cast<*char>(ptr); let start: int = 0; let end: int = n - 1; @@ -174,7 +174,7 @@ pub const memrev = fn (ptr: *void, n: int) *void { } // Count occurrences of a byte in memory -pub const memcount = fn (ptr: *void, value: int, n: int) int { +pub const memcount -> fn (ptr: *void, value: int, n: int) int { let p: *char = cast<*char>(ptr); let target: char = cast(value); let count: int = 0; @@ -190,7 +190,7 @@ pub const memcount = fn (ptr: *void, value: int, n: int) int { // Duplicate memory region #returns_ownership -pub const memdup = fn (src: *void, n: int) *void { +pub const memdup -> fn (src: *void, n: int) *void { let dest: *void = alloc(n); if (dest != cast<*void>(0)) { memcpy(dest, src, n); @@ -199,12 +199,12 @@ pub const memdup = fn (src: *void, n: int) *void { } // Check if memory regions are equal -pub const memeq = fn (a: *void, b: *void, n: int) bool { +pub const memeq -> fn (a: *void, b: *void, n: int) bool { return memcmp(a, b, n) == 0; } // Find substring in memory -pub const memmem = fn (haystack: *void, haystack_len: int, needle: *void, needle_len: int) *void { +pub const memmem -> fn (haystack: *void, haystack_len: int, needle: *void, needle_len: int) *void { if (needle_len == 0) { return haystack; } if (needle_len > haystack_len) { return cast<*void>(0); } @@ -228,7 +228,7 @@ pub const memmem = fn (haystack: *void, haystack_len: int, needle: *void, needle return cast<*void>(0); } -pub const align = fn (member_alignments: *int, count: int) int { +pub const align -> fn (member_alignments: *int, count: int) int { let max: int = 1; loop [i: int = 0](i < count) : (++i) { if (max < cast<*int>(member_alignments)[i]) { diff --git a/std/stl/stack.lx b/std/stl/stack.lx index 7fc2b667..c51f26ed 100644 --- a/std/stl/stack.lx +++ b/std/stl/stack.lx @@ -1,8 +1,9 @@ @module "stack" + @use "memory" as mem // auto incrementing stack -const Stack = struct { +const Stack -> struct { top: int, // top value in the stack capacity: int, // total `length` of the stack currentAmount: int, // spaces from 0 - capacity that are full @@ -11,7 +12,7 @@ const Stack = struct { }; #returns_ownership -pub const createStack = fn (stackCeiling: int) *Stack { +pub const createStack -> fn (stackCeiling: int) *Stack { let stack: *Stack = cast<*Stack>(alloc(sizeof)); // check if allocation failed and return a void* @@ -35,7 +36,7 @@ pub const createStack = fn (stackCeiling: int) *Stack { return stack; } -const extendStack = fn (stack: *Stack, capacity: int) int { +const extendStack -> fn (stack: *Stack, capacity: int) int { // Cannot extend stack past ceiling if (capacity > stack.stackCeiling) { return 0; @@ -49,44 +50,44 @@ const extendStack = fn (stack: *Stack, capacity: int) int { } #takes_ownership -pub const freeStack = fn (stack: *Stack) void { +pub const freeStack -> fn (stack: *Stack) void { free(stack.array); free(stack); } -const isEmpty = fn(stack: *Stack) int { +const isEmpty -> fn(stack: *Stack) int { // goes to -1 instead of 1 so add - return -cast(stack.top == -1); } -const isFull = fn(stack: *Stack) int { +const isFull -> fn(stack: *Stack) int { // goes to -1 instead of 1 so add - return -cast(stack.top == (stack.capacity - 1)); } -pub const push = fn(stack: *Stack, value: int) void { - if (isFull(stack) == 1) { - if (stack.capacity >= stack.stackCeiling) { - output("Stack ceiling reached\nCan not push ", value, "\n"); - return; - } - stack.currentAmount = stack.currentAmount + 1; - let newCapacity: int = stack.capacity * 2; - - if (newCapacity > stack.stackCeiling) { - newCapacity = stack.stackCeiling; - } - if (extendStack(stack, newCapacity) == 0) { - output("Failed to extend stack, can not push ", value "\n"); - } - output("Stack extended to capacity: ", stack.capacity, "\n"); +pub const push -> fn(stack: *Stack, value: int) void { + if (isFull(stack) == 1) { + if (stack.capacity >= stack.stackCeiling) { + output("Stack ceiling reached\nCan not push ", value, "\n"); + return; + } + stack.currentAmount = stack.currentAmount + 1; + let newCapacity: int = stack.capacity * 2; + + if (newCapacity > stack.stackCeiling) { + newCapacity = stack.stackCeiling; } - stack.top = stack.top + 1; - stack.array[stack.top] = value; - output("Pushed ", value, " to the stack\n"); + if (extendStack(stack, newCapacity) == 0) { + output("Failed to extend stack, can not push ", value "\n"); + } + output("Stack extended to capacity: ", stack.capacity, "\n"); + } + stack.top = stack.top + 1; + stack.array[stack.top] = value; + output("Pushed ", value, " to the stack\n"); } -pub const pop = fn(stack: *Stack) int { +pub const pop -> fn(stack: *Stack) int { if (isEmpty(stack) == 1) { output("Stack underflow (empty stack)\n"); return 0; @@ -100,7 +101,7 @@ pub const pop = fn(stack: *Stack) int { return value; } -pub const peek = fn(stack: *Stack) int { +pub const peek -> fn(stack: *Stack) int { if (isEmpty(stack) == 1) { output("Stack is empty\n"); return 0; diff --git a/std/string.lx b/std/string.lx index f0280e7c..5fce10e8 100644 --- a/std/string.lx +++ b/std/string.lx @@ -1,7 +1,7 @@ @module "string" #returns_ownership -pub const from_char = fn (c: char) *char { +pub const from_char -> fn (c: char) *char { let s: *char = cast<*char>(alloc(2 * sizeof)); s[0] = c; s[1] = cast(0); @@ -9,7 +9,7 @@ pub const from_char = fn (c: char) *char { } #returns_ownership -pub const from_int = fn (n: int) *char { +pub const from_int -> fn (n: int) *char { if (n == 0) { return from_char(cast('0')); } @@ -45,13 +45,13 @@ pub const from_int = fn (n: int) *char { return s; } -pub const strlen = fn (s: *char) int { +pub const strlen -> fn (s: *char) int { let length: int = 0; loop (s[length] != cast(0)) : (++length) {} return length; } -pub const strcmp = fn (s1: *char, s2: *char) int { +pub const strcmp -> fn (s1: *char, s2: *char) int { let ls1: int = strlen(s1); let ls2: int = strlen(s2); @@ -64,7 +64,7 @@ pub const strcmp = fn (s1: *char, s2: *char) int { return 0; } -pub const s_char = fn (s: *char, c: int) char{ +pub const s_char -> fn (s: *char, c: int) char{ loop [i: int = 0](s[i] != cast(0)) : (++i) { if (s[i] == cast(c)) { return s[i]; @@ -74,13 +74,13 @@ pub const s_char = fn (s: *char, c: int) char{ return cast(0); } -pub const copy = fn (dest: *char, src: *char) *char { +pub const copy -> fn (dest: *char, src: *char) *char { let i: int = 0; loop((dest[i] = src[i]) != cast(0)) : (++i) {} return dest; } -pub const n_copy = fn (dest: *char, src: *char, n: int) *char { +pub const n_copy -> fn (dest: *char, src: *char, n: int) *char { let i: int = 0; loop(i < n && src[i] != cast(0)) : (++i) { dest[i] = src[i]; @@ -88,7 +88,7 @@ pub const n_copy = fn (dest: *char, src: *char, n: int) *char { return dest; } -pub const cat = fn (dest: *char, s1: *char, s2: *char) *char { +pub const cat -> fn (dest: *char, s1: *char, s2: *char) *char { let ls1: int = strlen(s1); let lt: int = ls1 + strlen(s2) + 1; @@ -106,7 +106,7 @@ pub const cat = fn (dest: *char, s1: *char, s2: *char) *char { return dest; } -pub const putchar = fn(c: char) int { +pub const putchar -> fn(c: char) int { // allocate buffer for command + escaped char (32 bytes is enough) let cmd: *char = cast<*char>(alloc(32 * sizeof)); defer { free(cmd); } @@ -116,15 +116,15 @@ pub const putchar = fn(c: char) int { let char_val: int = cast(c); switch(char_val) { - 10 => { system("echo"); } // '\n' - 9 => { system("printf '\\t'"); } // '\t' - 37 => cat(cmd, cast<*char>("printf '\\%'"), cast<*char>("")); // '%' - 92 => cat(cmd, cast<*char>("printf '\\\\'"), cast<*char>("")); // '\\' - 39 => cat(cmd, cast<*char>("printf '\\\''"), cast<*char>("")); // '\'' - 34 => cat(cmd, cast<*char>("printf '\\'"), cast<*char>("")); // '"' - 36 => cat(cmd, cast<*char>("printf '\\$'"), cast<*char>("")); // '$' - 96 => cat(cmd, cast<*char>("printf '\\`'"), cast<*char>("")); // '`' - _ => { + 10 -> { system("echo"); } // '\n' + 9 -> { system("printf '\\t'"); } // '\t' + 37 -> cat(cmd, cast<*char>("printf '\\%'"), cast<*char>("")); // '%' + 92 -> cat(cmd, cast<*char>("printf '\\\\'"), cast<*char>("")); // '\\' + 39 -> cat(cmd, cast<*char>("printf '\\\''"), cast<*char>("")); // '\'' + 34 -> cat(cmd, cast<*char>("printf '\\'"), cast<*char>("")); // '"' + 36 -> cat(cmd, cast<*char>("printf '\\$'"), cast<*char>("")); // '$' + 96 -> cat(cmd, cast<*char>("printf '\\`'"), cast<*char>("")); // '`' + _ -> { let s: *char = from_char(c); defer { free(s); } cat(cmd, cast<*char>("printf '%s' "), s); diff --git a/std/termfx.lx b/std/termfx.lx index 400791a9..afe4d031 100644 --- a/std/termfx.lx +++ b/std/termfx.lx @@ -61,7 +61,7 @@ pub const CLEAR_TO_EOL: *char = "\x1b[K"; pub const CLEAR_TO_EOS: *char = "\x1b[J"; #returns_ownership -pub const fg_rgb = fn (r: int, g: int, b: int) *char { +pub const fg_rgb -> fn (r: int, g: int, b: int) *char { let msg: *char = cast<*char>(alloc(20 * sizeof)); string::cat(msg, msg, "\x1b[38;2;"); @@ -76,7 +76,7 @@ pub const fg_rgb = fn (r: int, g: int, b: int) *char { } #returns_ownership -pub const bg_rgb = fn (r: int, g: int, b: int) *char { +pub const bg_rgb -> fn (r: int, g: int, b: int) *char { let msg: *char = cast<*char>(alloc(20 * sizeof)); string::cat(msg, msg, "\x1b[48;2;"); @@ -91,7 +91,7 @@ pub const bg_rgb = fn (r: int, g: int, b: int) *char { } #returns_ownership -pub const move_cursor = fn (row: int, col: int) *char { +pub const move_cursor -> fn (row: int, col: int) *char { let msg: *char = cast<*char>(alloc(20 * sizeof)); string::cat(msg, msg, "\x1b["); diff --git a/std/terminal.lx b/std/terminal.lx index da970c4b..6e611fb8 100644 --- a/std/terminal.lx +++ b/std/terminal.lx @@ -1,9 +1,9 @@ @module "terminal" -@use "string" as string +// @use "string" as string // Get a single character without waiting for Enter -pub const getch = fn () char { +pub const getch -> fn () char { // Disable canonical mode and echo system("stty -icanon -echo"); @@ -17,7 +17,7 @@ pub const getch = fn () char { } // Get a single character without waiting for Enter (no echo) -pub const getch_silent = fn () char { +pub const getch_silent -> fn () char { // Already has -echo, so it won't display system("stty -icanon -echo"); let c: char = input(""); @@ -26,7 +26,7 @@ pub const getch_silent = fn () char { } #returns_ownership -pub const getche = fn () char { +pub const getche -> fn () char { // Disable canonical mode but keep echo system("stty -icanon echo"); let c: char = input(""); @@ -35,7 +35,7 @@ pub const getche = fn () char { } // Check if a key is pressed (non-blocking) -pub const kbhit = fn () int { +pub const kbhit -> fn () int { system("stty -icanon -echo min 0 time 0"); let c: char = input(""); system("stty icanon echo"); @@ -47,14 +47,14 @@ pub const kbhit = fn () int { } // Wait for any key press -pub const wait_for_key = fn () void { +pub const wait_for_key -> fn () void { output("Press any key to continue..."); getch(); output("\n"); } // Clear input buffer -pub const clear_input_buffer = fn () void { +pub const clear_input_buffer -> fn () void { system("stty -icanon -echo"); // Read until no more input @@ -73,7 +73,7 @@ pub const clear_input_buffer = fn () void { // Get password input (hidden) #returns_ownership -pub const getpass = fn (prompt: *char) *char { +pub const getpass -> fn (prompt: *char) *char { output(prompt); // Allocate buffer for password diff --git a/tests/3d_spinning_cube.lx b/tests/3d_spinning_cube.lx index 31f2bd39..4480b6f9 100644 --- a/tests/3d_spinning_cube.lx +++ b/tests/3d_spinning_cube.lx @@ -25,7 +25,7 @@ const k1: double = 40.0; let cube_gradient_size: int = 12; -const calculateX = fn (i: int, j: int, k: int) double { +const calculateX -> fn (i: int, j: int, k: int) double { let sA: double = math::sin(A); let cA: double = math::cos(A); let sB: double = math::sin(B); @@ -37,7 +37,7 @@ const calculateX = fn (i: int, j: int, k: int) double { j * cA * sC + k * sA * sC + i * cB * cC; } -const calculateY = fn (i: int, j: int, k: int) double { +const calculateY -> fn (i: int, j: int, k: int) double { let sA: double = math::sin(A); let cA: double = math::cos(A); let sB: double = math::sin(B); @@ -50,7 +50,7 @@ const calculateY = fn (i: int, j: int, k: int) double { i * cB * sC; } -const calculateZ = fn (i: int, j: int, k: int) double { +const calculateZ -> fn (i: int, j: int, k: int) double { let sA: double = math::sin(A); let cA: double = math::cos(A); let sB: double = math::sin(B); @@ -59,7 +59,7 @@ const calculateZ = fn (i: int, j: int, k: int) double { return k * cA * cB - j * sA * cB + i * sB; } -const calculateForSurface = fn (cX: double, cY: double, cZ: double, +const calculateForSurface -> fn (cX: double, cY: double, cZ: double, ch: char, color: *char) void { let x: double = calculateX(cast(cX), cast(cY), cast(cZ)); let y: double = calculateY(cast(cX), cast(cY), cast(cZ)); @@ -84,7 +84,7 @@ const calculateForSurface = fn (cX: double, cY: double, cZ: double, } } -const print_cube = fn () void { +const print_cube -> fn () void { loop [cubeX: double = -cube_width](cubeX < cube_width) : (cubeX = cubeX + increment_speed) { loop [cubeY: double = -cube_width](cubeY < cube_width) : (cubeY = cubeY + increment_speed) { calculateForSurface(cubeX, cubeY, -cube_width, '@', fx::BRIGHT_RED); @@ -97,7 +97,7 @@ const print_cube = fn () void { } } -pub const main = fn () int { +pub const main -> fn () int { zBuffer = cast<*double>(alloc(160 * 44 * sizeof)); _colorBuffer = cast<**char>(alloc(160 * 44 * 8)); _buffer = cast<*char>(alloc(160 * 44)); diff --git a/tests/bubble_sort.lx b/tests/bubble_sort.lx index 86f0de53..b47cc0d4 100644 --- a/tests/bubble_sort.lx +++ b/tests/bubble_sort.lx @@ -1,12 +1,12 @@ @module "main" -const swap = fn (a: *int, b: *int) void { +const swap -> fn (a: *int, b: *int) void { let tmp: int = *a; *a = *b; *b = tmp; } -const bubble_sort = fn (n: int, arr: *int) void { +const bubble_sort -> fn (n: int, arr: *int) void { loop [i: int = 0, j: int = 0](i < n-1) : (++i) { let swapped: int = 0; j = 0; @@ -22,16 +22,16 @@ const bubble_sort = fn (n: int, arr: *int) void { } } -const print_arr = fn (n: int, arr: *int) void { +const print_arr -> fn (n: int, arr: *int) void { loop [i: int = 0](i < n) : (++i) { output(arr[i], " "); } output("\n"); } -#takes_ownership const free_arr = fn (arr: *int) void { free(arr); } +#takes_ownership const free_arr -> fn (arr: *int) void { free(arr); } -pub const main = fn () int { +pub const main -> fn () int { let arr: *int = cast<*int>(alloc(7 * sizeof)); let n: int = 7; diff --git a/tests/mem_test.lx b/tests/mem_test.lx index ea18da3b..ecb2563d 100644 --- a/tests/mem_test.lx +++ b/tests/mem_test.lx @@ -5,7 +5,7 @@ @use "memory" as mem -const test_memset = fn () void { +const test_memset -> fn () void { let buf: *void = alloc(10); defer { free(buf); } @@ -21,7 +21,7 @@ const test_memset = fn () void { output("memset passed!\n"); } -const test_memcmp = fn () void { +const test_memcmp -> fn () void { let a: *void = alloc(5 * sizeof); let b: *void = alloc(5 * sizeof); defer { free(a); free(b); } @@ -46,7 +46,7 @@ const test_memcmp = fn () void { output("memcmp passed!\n"); } -const test_memcpy = fn () void { +const test_memcpy -> fn () void { let src: *void = alloc(10 * sizeof); let dest: *void = alloc(10 * sizeof); defer { free(src); free(dest); } @@ -70,7 +70,7 @@ const test_memcpy = fn () void { output("memcpy passed!\n"); } -const test_memmove = fn () void { +const test_memmove -> fn () void { let buf: *void = alloc(20 * sizeof); defer { free(buf); } @@ -93,7 +93,7 @@ const test_memmove = fn () void { output("memmove passed!\n"); } -const test_memchr = fn () void { +const test_memchr -> fn () void { let buf: *void = alloc(10 * sizeof); defer { free(buf); } @@ -130,7 +130,7 @@ const test_memchr = fn () void { output("memchr passed!\n"); } -const test_memzero = fn () void { +const test_memzero -> fn () void { let buf: *void = alloc(10 * sizeof); defer { free(buf); } @@ -151,7 +151,7 @@ const test_memzero = fn () void { output("memzero passed!\n"); } -const test_calloc = fn () void { +const test_calloc -> fn () void { let buf: *void = mem::calloc(10, sizeof); defer { free(buf); } @@ -171,7 +171,7 @@ const test_calloc = fn () void { output("calloc passed!\n"); } -const test_realloc = fn () void { +const test_realloc -> fn () void { let buf: *void = alloc(5 * sizeof); // Fill original buffer @@ -200,7 +200,7 @@ const test_realloc = fn () void { output("realloc passed!\n"); } -const test_memswap = fn () void { +const test_memswap -> fn () void { let a: *void = alloc(5 * sizeof); let b: *void = alloc(5 * sizeof); defer { free(a); free(b); } @@ -227,7 +227,7 @@ const test_memswap = fn () void { output("memswap passed!\n"); } -const test_memswapn = fn () void { +const test_memswapn -> fn () void { // Allocate arrays for swapping let a: *int = cast<*int>(alloc(5 * sizeof)); let b: *int = cast<*int>(alloc(5 * sizeof)); @@ -257,7 +257,7 @@ const test_memswapn = fn () void { output("memswapn passed!\n"); } -const test_memfill = fn () void { +const test_memfill -> fn () void { // === Test 1: Fill with int pattern === let arr: *int = cast<*int>(alloc(5 * sizeof)); let pattern: int = 42; @@ -289,7 +289,7 @@ const test_memfill = fn () void { output("memfill passed!\n"); } -const test_memrev = fn () void { +const test_memrev -> fn () void { let buf: *void = alloc(5 * sizeof); defer { free(buf); } @@ -313,7 +313,7 @@ const test_memrev = fn () void { output("memrev passed!\n"); } -const test_memcount = fn () void { +const test_memcount -> fn () void { let buf: *void = alloc(10 * sizeof); defer { free(buf); } @@ -335,7 +335,7 @@ const test_memcount = fn () void { output("memcount passed!\n"); } -const test_align = fn () void { +const test_align -> fn () void { let arr: *int; { arr = cast<*int>(alloc(3 * sizeof)); @@ -376,7 +376,7 @@ const test_align = fn () void { // Helper function to run all tests -const run_all_tests = fn () void { +const run_all_tests -> fn () void { output("=== Memory Function Tests ===\n"); test_memset(); @@ -397,7 +397,7 @@ const run_all_tests = fn () void { output("=== All Tests Complete ===\n"); } -pub const main = fn () int { +pub const main -> fn () int { run_all_tests(); return 0; } diff --git a/tests/str_test.lx b/tests/str_test.lx index bafd47be..ee7edb83 100644 --- a/tests/str_test.lx +++ b/tests/str_test.lx @@ -6,7 +6,7 @@ @use "string" as string @use "memory" as mem -const test_strlen = fn () void { +const test_strlen -> fn () void { let empty_str: *char = cast<*char>(mem::calloc(1, sizeof)); defer { free(empty_str); } @@ -34,7 +34,7 @@ const test_strlen = fn () void { output("strlen passed!\n"); } -const test_strcmp = fn () void { +const test_strcmp -> fn () void { // Create test strings let str1: *char = cast<*char>(mem::calloc(6, sizeof)); let str2: *char = cast<*char>(mem::calloc(6, sizeof)); @@ -84,7 +84,7 @@ const test_strcmp = fn () void { output("strcmp passed!\n"); } -const test_s_char = fn () void { +const test_s_char -> fn () void { // Create test string "Hello World" let test_str: *char = cast<*char>(mem::calloc(12, sizeof)); defer { free(test_str); } @@ -119,7 +119,7 @@ const test_s_char = fn () void { output("s_char passed!\n"); } -const test_copy = fn () void { +const test_copy -> fn () void { // Create source string "Test" let src: *char = cast<*char>(mem::calloc(5, sizeof)); let dest: *char = cast<*char>(mem::calloc(10, sizeof)); @@ -145,7 +145,7 @@ const test_copy = fn () void { output("copy passed!\n"); } -const test_n_copy = fn () void { +const test_n_copy -> fn () void { // Create source string "Testing" let src: *char = cast<*char>(mem::calloc(8, sizeof)); let dest: *char = cast<*char>(mem::calloc(10, sizeof)); @@ -183,7 +183,7 @@ const test_n_copy = fn () void { output("n_copy passed!\n"); } -const test_cat = fn () void { +const test_cat -> fn () void { // Create strings "Hello" and " World" let s1: *char = cast<*char>(mem::calloc(6, sizeof)); let s2: *char = cast<*char>(mem::calloc(7, sizeof)); @@ -239,7 +239,7 @@ const test_cat = fn () void { output("cat passed!\n"); } -const test_edge_cases = fn () void { +const test_edge_cases -> fn () void { // Test strlen with single character let single_char: *char = cast<*char>(mem::calloc(2, sizeof)); defer { free(single_char); } @@ -267,7 +267,7 @@ const test_edge_cases = fn () void { output("edge cases passed!\n"); } -const run_all_string_tests = fn () void { +const run_all_string_tests -> fn () void { output("=== String Function Tests ===\n"); test_strlen(); @@ -281,7 +281,7 @@ const run_all_string_tests = fn () void { output("=== All String Tests Complete ===\n"); } -pub const main = fn () int { +pub const main -> fn () int { run_all_string_tests(); return 0; } diff --git a/tests/terminal_test.lx b/tests/terminal_test.lx index cc3b4707..05b685e8 100644 --- a/tests/terminal_test.lx +++ b/tests/terminal_test.lx @@ -4,7 +4,7 @@ @use "terminal" as term @use "termfx" as fx -const menu_demo = fn () void { +const menu_demo -> fn () void { output(fx::CLEAR_SCREEN, fx::CURSOR_HOME); output(fx::BOLD, fx::BRIGHT_CYAN, "=== Interactive Menu ===\n", fx::RESET); output("1. Option One\n"); @@ -29,7 +29,7 @@ const menu_demo = fn () void { } } -const password_demo = fn () void { +const password_demo -> fn () void { output(fx::CLEAR_SCREEN, fx::CURSOR_HOME); output(fx::BOLD, fx::BRIGHT_MAGENTA, "=== Password Input Demo ===\n", fx::RESET); @@ -40,7 +40,7 @@ const password_demo = fn () void { output("Password length: ", string::strlen(password), "\n"); } -const keystroke_demo = fn () void { +const keystroke_demo -> fn () void { output(fx::CLEAR_SCREEN, fx::CURSOR_HOME); output(fx::BOLD, fx::BRIGHT_YELLOW, "=== Keystroke Demo ===\n", fx::RESET); output("Press keys (ESC to exit)\n\n"); @@ -68,7 +68,7 @@ const keystroke_demo = fn () void { } } -const reaction_game = fn () void { +const reaction_game -> fn () void { output(fx::CLEAR_SCREEN, fx::CURSOR_HOME); output(fx::BOLD, fx::BRIGHT_RED, "=== Reaction Time Game ===\n", fx::RESET); output("Press SPACE as fast as you can when you see GO!\n\n"); @@ -86,7 +86,7 @@ const reaction_game = fn () void { } } -const yes_no_prompt = fn (question: *char) int { +const yes_no_prompt -> fn (question: *char) int { output(question, " (y/n): "); loop { @@ -105,7 +105,7 @@ const yes_no_prompt = fn (question: *char) int { return 0; } -pub const main = fn () int { +pub const main -> fn () int { loop { output(fx::CLEAR_SCREEN, fx::CURSOR_HOME); output(fx::BOLD, fx::BRIGHT_CYAN, "╔════════════════════════════╗\n", fx::RESET); diff --git a/tests/test.lx b/tests/test.lx index bd59fb93..cb35f662 100644 --- a/tests/test.lx +++ b/tests/test.lx @@ -1,127 +1,20 @@ @module "main" -@use "memory" as mem +@use "stack" as st -// auto incrementing stack -const Stack = struct { - top: int, // top value in the stack - capacity: int, // total `length` of the stack - currentAmount: int, // spaces from 0 - capacity that are full - stackCeiling: int, // hard cap on the limit - array: *int // stack representation -}; +pub const main -> fn () int { + let stack: *Stack = st::createStack(20); -#returns_ownership -const createStack = fn (stackCeiling: int) *Stack { - let stack: *Stack = cast<*Stack>(alloc(sizeof)); + st::push(stack, 20); + st::push(stack, 30); + st::push(stack, 50); + st::push(stack, 12); + st::push(stack, 311); + output("Peeked: ", st::peek(stack), "\n"); + st::pop(stack); + st::pop(stack); - // check if allocation failed and return a void* - if (stack == cast<*Stack>(0)) { - return cast<*Stack>(0); - } - - stack.top = -1; - stack.capacity = 1; - stack.currentAmount = 0; - stack.stackCeiling = stackCeiling; - - // assume stack.array is empty - stack.array = cast<*int>(alloc(sizeof)); - - if (stack.array == cast<*int>(0)) { - free(stack); - return cast<*Stack>(0); - } - - return stack; -} - -const extendStack = fn (stack: *Stack, capacity: int) int { - // Cannot extend stack past ceiling - if (capacity > stack.stackCeiling) { - return 0; - } - - // frees itself on fail - stack.array = cast<*int>(mem::realloc(cast<*void>(stack.array), capacity * sizeof)); - - stack.capacity = capacity; - return 1; -} - -#takes_ownership -const freeStack = fn (stack: *Stack) void { - free(stack.array); - free(stack); -} - -const isEmpty = fn(stack: *Stack) int { - // goes to -1 instead of 1 so add - - return -cast(stack.top == -1); -} - -const isFull = fn(stack: *Stack) int { - // goes to -1 instead of 1 so add - - return -cast(stack.top == stack.capacity - 1); -} - -const push = fn(stack: *Stack, value: int) void { - if ((isFull(stack) == 1)) { - if (stack.capacity >= stack.stackCeiling) { - output("Stack ceiling reached\nCan not push ", value, "\n"); - return; - } - stack.currentAmount = stack.currentAmount + 1; - let newCapacity: int = stack.capacity * 2; - - if (newCapacity > stack.stackCeiling) { - newCapacity = stack.stackCeiling; - } - if (extendStack(stack, newCapacity) == 0) { - output("Failed to extend stack, can not push ", value "\n"); - } - output("Stack extended to capacity: ", stack.capacity, "\n"); - } - stack.top = stack.top + 1; - stack.array[stack.top] = value; - output("Pushed ", value, " to the stack\n"); -} - -const pop = fn(stack: *Stack) int { - if (isEmpty(stack) == 0) { - output("Stack underflow (empty stack)\n"); - return 0; - } - - let value: int = stack.array[stack.top]; - output("Popping ", value, " from the stack\n"); - - stack.currentAmount = stack.currentAmount - 1; - stack.top = stack.top - 1; - return value; -} - -const peek = fn(stack: *Stack) int { - if (isEmpty(stack) == 1) { - output("Stack is empty\n"); - return 0; - } - return stack.array[stack.top]; -} - -pub const main = fn () int { - let stack: *Stack = createStack(20); - - push(stack, 20); - push(stack, 30); - push(stack, 50); - push(stack, 12); - push(stack, 311); - peek(stack); - pop(stack); - pop(stack); - - free(stack); + st::freeStack(stack); return 0; -} \ No newline at end of file +}