From 1b6693d9784ea0a2797fd20661e36725d56d9f2b Mon Sep 17 00:00:00 2001 From: Reboy2000 Date: Tue, 20 Jan 2026 18:07:06 -0500 Subject: [PATCH 1/6] Added Detailed Errors --- bin/Splice | Bin 35752 -> 35816 bytes bin/spbuild | Bin 35080 -> 51592 bytes build.sh | 6 +- recurse | Bin 0 -> 33464 bytes recurse.c | 13 ++++ recurse.spc | Bin 0 -> 76 bytes recurse.spl | 5 ++ src/build.c | 98 ++++++++++++------------- src/splice.c | 1 - src/splice.h | 202 +++++++++++++++++++++++++++++---------------------- 10 files changed, 183 insertions(+), 142 deletions(-) create mode 100755 recurse create mode 100644 recurse.c create mode 100644 recurse.spc create mode 100644 recurse.spl diff --git a/bin/Splice b/bin/Splice index 42d4a1f7a1548588fe36ed5b4dcdbc49c11b6c31..69248626e0ff9a1fa7b077a9190fa19543df6849 100755 GIT binary patch literal 35816 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 LKPGEDU)8?=8r@jt diff --git a/build.sh b/build.sh index 4ae474b..3ed1c8b 100755 --- a/build.sh +++ b/build.sh @@ -20,16 +20,16 @@ echo "Proceeding with build on $OS/$ARCH..." echo "Building Splice runtime and native module..." # Compile Splice runtime (with SDK globals) -gcc -DSDK_IMPLEMENTATION -Isrc -Wall -Wextra -c -DNDEBUG -O3 -flto src/splice.c -o "$BIN_DIR/Splice.o" +gcc -DSDK_IMPLEMENTATION -Isrc -Wall -Wextra -c -Ofast -march=native -mtune=native -flto -fomit-frame-pointer -funroll-loops -fno-semantic-interposition -fno-math-errno -fno-trapping-math -fstrict-aliasing -DNDEBUG src/splice.c -o "$BIN_DIR/Splice.o" # Compile native module without SDK_IMPLEMENTATION -gcc -Isrc -Wall -Wextra -c -DNDEBUG -O3 -flto src/module_stubs.c -o "$BIN_DIR/module_stubs.o" +gcc -Isrc -Wall -Wextra -c -Ofast -march=native -mtune=native -flto -fomit-frame-pointer -funroll-loops -fno-semantic-interposition -fno-math-errno -fno-trapping-math -fstrict-aliasing -DNDEBUG src/module_stubs.c -o "$BIN_DIR/module_stubs.o" # Link executable (local binary: Splice) gcc "$BIN_DIR/Splice.o" "$BIN_DIR/module_stubs.o" -o "$BIN_DIR/Splice" echo "Building spbuild (bytecode compiler)..." -gcc -Isrc -Wall -Wextra -DNDEBUG -O3 -flto src/build.c -o "$BIN_DIR/spbuild" +gcc -Isrc -Wall -Wextra -Ofast -march=native -mtune=native -flto -fomit-frame-pointer -funroll-loops -fno-semantic-interposition -fno-math-errno -fno-trapping-math -fstrict-aliasing -DNDEBUG src/build.c -o "$BIN_DIR/spbuild" # --- Install section --- INSTALL_DIR="" diff --git a/recurse b/recurse new file mode 100755 index 0000000000000000000000000000000000000000..fb173dd991d66f3c8c4d64ed4eace5084435337c GIT binary patch literal 33464 zcmeI*U2GIp7zW@ovxT&_NRh@WYC16~L4%Z3V~mN(RA{8J&<2{Y>c!b^cNbRaw%H#n zl*pi|(RgDGA|@sjys!;=qa-Xb#wHlO@~0>miNU=gX*DQBE`(U?`<cRqP9WDS7`PB}XvN zLrQtFKjkSELG_^DkD%|OFU#&gjC;jz>LTj3=+`2;5y29C=HPg+J?;Io_pP|dLCAN} zlFOu9b|j-Mv0Xc2=u5c^A^X_-?at_u5$ zRo#!uJfHMYR^j<1&lui&u*iKMLC9Q@suO=BYhf?g&z4=8Y`lNX<7=?5WVEYlR7^WQlqOZbp?xF zSA)w(mn*ej#_>mAc6n~@t=ZwW39K8P4Cyn$_0`JTJYB0!e2P2{+B3MeQ0txuUcVMO z>uvXnvYXB{$8Irpcl)~w)?yNYnTuLN{?}4m^SkgP?sdpgZ!($j3h9Mw*`fdiC_n)U zP=Epypa2CZKmiI+fC3bt00k&O0SZun0u-PC1t>rP3Q&Lo6rcbFC_n)UP=Epypa2CZ zKmiI+fC3bt00k&O0SZun0u-RYO%m{KQXZzE00k&O0SZun0u-PC1t>rP3Q&Lo6rcbF zC_n)UP=Epypa2CZKmiI+fC3bt00k&O0SZun0u-PC1t>rP3Q&Lo6rcbFC_n)UP=Epy zpa2CZKmiI+;C~7@Sl5k^BiH3f@8GfC!NacQEb&q?Z5OAwyQL9-t&P4OOea&>gqg9l zYLteIhtyaNehN5PJf!=#>-bQ-FPDw$?eX4NJgsW_dy^@(B#pszCa!LiWrb>2Dzkj4 zB`1#;?{hoqrP!#PdoKHxv%RG+XL?J&8G%}wrj*WdcW_euwRhI$&boBx!2YkEtD8ic z{YX;E)qpWPjpZpDH?z&wBA5>&q|_+2&v9&X^m}pS-+u@FX{&VmsXtFO4j*{u*^NUR zk3R6&);}U!FCOZgzBl)CzUKUwKRkNmgT3#67#{e1CNWv{{nXTRc2{`O+@525c8{F> z^wLjUVj5qmu9m7 literal 0 HcmV?d00001 diff --git a/recurse.c b/recurse.c new file mode 100644 index 0000000..00388d3 --- /dev/null +++ b/recurse.c @@ -0,0 +1,13 @@ +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "ctype.h" + +void recurse(int a) { + printf("%d\n", a); + recurse(a + 1); +} +int main() { + recurse(1); + return 0; +} \ No newline at end of file diff --git a/recurse.spc b/recurse.spc new file mode 100644 index 0000000000000000000000000000000000000000..8f00a2df59dc62daa055ffc73a79e07db5cf9a9b GIT binary patch literal 76 zcmWFzaAsf>U}9ik5M*M=$YcaE7#R}50&Gk`mJm#onUO&oBmh(Z0w3(*G7tfv2mlE& B2YLVi literal 0 HcmV?d00001 diff --git a/recurse.spl b/recurse.spl new file mode 100644 index 0000000..f1af01a --- /dev/null +++ b/recurse.spl @@ -0,0 +1,5 @@ +func hi(a) { + print(a); + hi(a + 1); +} +hi(1); \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3181211..8dd2934 100644 --- a/src/build.c +++ b/src/build.c @@ -110,7 +110,7 @@ static void tv_push(TokVec *v, Tok x) { if (v->count >= v->cap) { v->cap = v->cap ? v->cap*2 : 256; Tok *nd = (Tok*)realloc(v->data, sizeof(Tok) * (size_t)v->cap); - if (!nd) error(0, "oom realloc tokens"); + if (!nd) error(0, "Splice/SystemError oom realloc tokens"); v->data = nd; } v->data[v->count++] = x; @@ -140,7 +140,7 @@ static void tokenize(const char *src, TokVec *out) { while (*p && *p!='"') p++; size_t n = (size_t)(p - s); char *str = (char*)malloc(n+1); - if (!str) error(line, "oom string"); + if (!str) error(line, "Splice/SystemErroroom string"); memcpy(str, s, n); str[n]=0; Tok t = { .t=TK_STRING, .lex=str, .line=line }; @@ -155,7 +155,7 @@ static void tokenize(const char *src, TokVec *out) { while (isdigit((unsigned char)*p) || *p=='.') p++; char tmp[128]; size_t n = (size_t)(p - s); - if (n >= sizeof(tmp)) error(line, "number too long"); + if (n >= sizeof(tmp)) error(line, "Splice/OverflowError number too long"); memcpy(tmp, s, n); tmp[n]=0; Tok t = { .t=TK_NUMBER, .num=strtod(tmp,NULL), .line=line }; @@ -169,7 +169,7 @@ static void tokenize(const char *src, TokVec *out) { while (isalnum((unsigned char)*p) || *p=='_') p++; size_t n = (size_t)(p - s); char *id = (char*)malloc(n+1); - if (!id) error(line, "oom ident"); + if (!id) error(line, "Splice/SystemErroroom ident"); memcpy(id, s, n); id[n]=0; @@ -228,7 +228,7 @@ static void tokenize(const char *src, TokVec *out) { case '>': tv_push(out,(Tok){.t=TK_GT,.line=line}); p++; break; default: - error(line, "Unknown char: '%c'", *p); + error(line, "Splice/SyntaxError Unknown char: '%c'", *p); } } @@ -284,7 +284,7 @@ static ASTNode *parse_primary(void) { if (!match(TK_COMMA)) break; } } - consume(TK_RPAREN, "Expected ')' after call args"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after call args"); ASTNode *c = ast_new(AST_FUNCTION_CALL); c->funccall.funcname = name; @@ -296,7 +296,7 @@ static ASTNode *parse_primary(void) { /* ident[index] */ if (match(TK_LBRACKET)) { ASTNode *idx = parse_expression(); - consume(TK_RBRACKET, "Expected ']' after index"); + consume(TK_RBRACKET, "Splice/SyntaxError Expected ']' after index"); ASTNode *id = ast_new(AST_IDENTIFIER); id->string = name; @@ -333,7 +333,7 @@ static ASTNode *parse_primary(void) { items[count++] = parse_expression(); } while (match(TK_COMMA)); - consume(TK_RPAREN, "Expected ')' after tuple"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after tuple"); ASTNode *t = ast_new(AST_TUPLE); t->tuple.items = items; @@ -342,23 +342,23 @@ static ASTNode *parse_primary(void) { } /* otherwise normal grouping */ - consume(TK_RPAREN, "Expected ')'"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')'"); return first; } if (match(TK_READ)) { - consume(TK_LPAREN, "Expected '(' after read"); + consume(TK_LPAREN, "Splice/SyntaxError Expected '(' after read"); ASTNode *e = parse_expression(); - consume(TK_RPAREN, "Expected ')' after read"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after read"); ASTNode *n = ast_new(AST_READ); n->read.expr = e; return n; } if (match(TK_INPUT)) { - consume(TK_LPAREN, "Expected '(' after input"); + consume(TK_LPAREN, "Splice/SyntaxError Expected '(' after input"); ASTNode *e = parse_expression(); - consume(TK_RPAREN, "Expected ')' after input prompt"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after input prompt"); ASTNode *n = ast_new(AST_INPUT); n->input.prompt = e; return n; @@ -375,7 +375,7 @@ static ASTNode *parse_primary(void) { if (!match(TK_COMMA)) break; } } - consume(TK_RBRACKET, "Expected ']' after array literal"); + consume(TK_RBRACKET, "Splice/SyntaxError Expected ']' after array literal"); ASTNode *a = ast_new(AST_ARRAY_LITERAL); a->arraylit.elements = els; @@ -383,7 +383,7 @@ static ASTNode *parse_primary(void) { return a; } - error(peek()->line, "Expected expression"); + error(peek()->line, "Splice/SyntaxError Expected expression"); return NULL; } @@ -486,8 +486,8 @@ static ASTNode *parse_statements_until(TokType end) { static ASTNode *parse_statement(void) { if (match(TK_LET)) { - Tok *id = consume(TK_IDENT, "Expected identifier after let"); - consume(TK_ASSIGN, "Expected '=' after let name"); + Tok *id = consume(TK_IDENT, "Splice/SyntaxError Expected identifier after let"); + consume(TK_ASSIGN, "Splice/SyntaxError Expected '=' after let name"); ASTNode *rhs = parse_expression(); ASTNode *n = ast_new(AST_LET); @@ -497,15 +497,15 @@ static ASTNode *parse_statement(void) { } if (match(TK_PRINT)) { - consume(TK_LPAREN, "Expected '(' after print"); + consume(TK_LPAREN, "Splice/SyntaxError Expected '(' after print"); ASTNode *e = parse_expression(); - consume(TK_RPAREN, "Expected ')' after print expr"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after print expr"); ASTNode *n = ast_new(AST_PRINT); n->print.expr = e; return n; } if (match(TK_IMPORT)) { - Tok *f = consume(TK_STRING, "Expected string filename after import"); + Tok *f = consume(TK_STRING, "Splice/SyntaxError Expected string filename after import"); ASTNode *n = ast_new(AST_IMPORT); @@ -517,12 +517,11 @@ static ASTNode *parse_statement(void) { } if (match(TK_WRITE)) { - consume(TK_LPAREN, "Expected '(' after write"); + consume(TK_LPAREN, "Splice/SyntaxError Expected '(' after write"); ASTNode *path = parse_expression(); - consume(TK_COMMA, "Expected ',' after write path"); + consume(TK_COMMA, "Splice/SyntaxError Expected ',' after write path"); ASTNode *val = parse_expression(); - consume(TK_RPAREN, "Expected ')' after write"); - + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after write"); ASTNode *n = ast_new(AST_WRITE); n->write.path = path; n->write.value = val; @@ -530,9 +529,9 @@ static ASTNode *parse_statement(void) { } if (match(TK_RAISE)) { - consume(TK_LPAREN, "Expected '(' after raise"); + consume(TK_LPAREN, "Splice/SyntaxError Expected '(' after raise"); ASTNode *e = parse_expression(); - consume(TK_RPAREN, "Expected ')' after raise expr"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after raise expr"); ASTNode *n = ast_new(AST_RAISE); n->raise.expr = e; return n; @@ -547,26 +546,25 @@ static ASTNode *parse_statement(void) { } if (match(TK_FUNC)) { - Tok *id = consume(TK_IDENT, "Expected function name"); - consume(TK_LPAREN, "Expected '(' after func name"); + Tok *id = consume(TK_IDENT, "Splice/SyntaxError Expected function name"); + consume(TK_LPAREN, "Splice/SyntaxError Expected '(' after func name"); char **params=NULL; int pc=0, cap=0; if (!at(TK_RPAREN)) { for (;;) { - Tok *p = consume(TK_IDENT, "Expected param name"); + Tok *p = consume(TK_IDENT, "Splice/SyntaxError Expected param name"); if (pc>=cap) { cap=cap?cap*2:8; params=(char**)realloc(params,sizeof(char*)*(size_t)cap); } params[pc++] = strdup(p->lex); if (!match(TK_COMMA)) break; } } - consume(TK_RPAREN, "Expected ')' after params"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after params"); - consume(TK_LBRACE, "Expected '{' before func body"); + consume(TK_LBRACE, "Splice/SyntaxError Expected '{' before func body"); ASTNode *body = parse_statements_until(TK_RBRACE); - consume(TK_RBRACE, "Expected '}' after func body"); - + consume(TK_RBRACE, "Splice/SyntaxError Expected '}' after func body"); ASTNode *n = ast_new(AST_FUNC_DEF); n->funcdef.funcname = strdup(id->lex); n->funcdef.params = params; @@ -576,18 +574,18 @@ static ASTNode *parse_statement(void) { } if (match(TK_IF)) { - consume(TK_LPAREN, "Expected '(' after if"); + consume(TK_LPAREN, "Splice/SyntaxError Expected '(' after if"); ASTNode *cond = parse_expression(); - consume(TK_RPAREN, "Expected ')' after if cond"); - consume(TK_LBRACE, "Expected '{' after if"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after if cond"); + consume(TK_LBRACE, "Splice/SyntaxError Expected '{' after if"); ASTNode *thenb = parse_statements_until(TK_RBRACE); - consume(TK_RBRACE, "Expected '}' after if body"); + consume(TK_RBRACE, "Splice/SyntaxError Expected '}' after if body"); ASTNode *elseb = NULL; if (match(TK_ELSE)) { - consume(TK_LBRACE, "Expected '{' after else"); + consume(TK_LBRACE, "Splice/SyntaxError Expected '{' after else"); elseb = parse_statements_until(TK_RBRACE); - consume(TK_RBRACE, "Expected '}' after else body"); + consume(TK_RBRACE, "Splice/SyntaxError Expected '}' after else body"); } ASTNode *n = ast_new(AST_IF); @@ -598,12 +596,12 @@ static ASTNode *parse_statement(void) { } if (match(TK_WHILE)) { - consume(TK_LPAREN, "Expected '(' after while"); + consume(TK_LPAREN, "Splice/SyntaxError Expected '(' after while"); ASTNode *cond = parse_expression(); - consume(TK_RPAREN, "Expected ')' after while cond"); - consume(TK_LBRACE, "Expected '{' after while"); + consume(TK_RPAREN, "Splice/SyntaxError Expected ')' after while cond"); + consume(TK_LBRACE, "Splice/SyntaxError Expected '{' after while"); ASTNode *body = parse_statements_until(TK_RBRACE); - consume(TK_RBRACE, "Expected '}' after while body"); + consume(TK_RBRACE, "Splice/SyntaxError Expected '}' after while body"); ASTNode *n = ast_new(AST_WHILE); n->whilestmt.cond = cond; @@ -612,14 +610,14 @@ static ASTNode *parse_statement(void) { } if (match(TK_FOR)) { - Tok *id = consume(TK_IDENT, "Expected for variable"); - consume(TK_IN, "Expected 'in' after for var"); + Tok *id = consume(TK_IDENT, "Splice/SyntaxError Expected for variable"); + consume(TK_IN, "Splice/SyntaxError Expected 'in' after for var"); ASTNode *start = parse_expression(); - consume(TK_DOT, "Expected '.' in for range"); + consume(TK_DOT, "Splice/SyntaxError Expected '.' in for range"); ASTNode *end = parse_expression(); - consume(TK_LBRACE, "Expected '{' after for range"); + consume(TK_LBRACE, "Splice/SyntaxError Expected '{' after for range"); ASTNode *body = parse_statements_until(TK_RBRACE); - consume(TK_RBRACE, "Expected '}' after for body"); + consume(TK_RBRACE, "Splice/SyntaxError Expected '}' after for body"); ASTNode *n = ast_new(AST_FOR); n->forstmt.for_var = strdup(id->lex); @@ -645,8 +643,8 @@ static ASTNode *parse_statement(void) { /* ident[expr] = expr */ if (match(TK_LBRACKET)) { ASTNode *idx = parse_expression(); - consume(TK_RBRACKET, "Expected ']' after index"); - consume(TK_ASSIGN, "Expected '=' after index"); + consume(TK_RBRACKET, "Splice/SyntaxError Expected ']' after index"); + consume(TK_ASSIGN, "Splice/SyntaxError Expected '=' after index"); ASTNode *rhs = parse_expression(); ASTNode *target = ast_new(AST_IDENTIFIER); diff --git a/src/splice.c b/src/splice.c index 00fabb8..a17453a 100644 --- a/src/splice.c +++ b/src/splice.c @@ -23,7 +23,6 @@ int main(int argc, char **argv) { ASTNode *root = read_ast_from_spc(arg); info(0, "Loaded AST from %s", arg); - interpret(root); free_ast(root); diff --git a/src/splice.h b/src/splice.h index a07bb81..d46a78d 100644 --- a/src/splice.h +++ b/src/splice.h @@ -310,7 +310,7 @@ static inline void free_object(void *obj) { } static inline void set_var_object(const char *name, void *obj) { - if (!name) error(0, "set_var_object: NULL name"); + if (!name) error(0, "Splice/NullError set_var_object: NULL name"); unsigned h = hash_str(name); unsigned idx = h & (VAR_TABLE_SIZE - 1); @@ -347,7 +347,7 @@ static inline void set_var( double value, const char *str ) { - if (!name) error(0, "set_var: NULL name"); + if (!name) error(0, "Splice/NullError set_var: NULL name"); unsigned h = hash_str(name); unsigned idx = h & (VAR_TABLE_SIZE - 1); @@ -390,40 +390,66 @@ static ASTNode *clone_ast(const ASTNode *n); static inline void interpret(ASTNode *node); #define MAX_FUNCS 32 typedef struct { char *name; ASTNode *def; } Func; -static Func funcs[MAX_FUNCS]; -static int func_count = 0; +#define FUNC_TABLE_SIZE 128 + +typedef struct { + char *name; + ASTNode *def; + int used; +} FuncSlot; + +static FuncSlot func_table[FUNC_TABLE_SIZE]; + static inline void add_func(const char *name, ASTNode *def) { - if (!name) { - error(0, "add_func: NULL function name"); - } + if (!name) error(0, "Splice/NullError add_func: NULL name"); + + unsigned idx = hash_str(name) & (FUNC_TABLE_SIZE - 1); + + for (;;) { + FuncSlot *f = &func_table[idx]; - for (int j = 0; j < func_count; ++j) { - if (!funcs[j].name) continue; - if (strcmp(funcs[j].name, name) == 0) { - funcs[j].def = def; + if (!f->used) { + f->used = 1; + f->name = strdup(name); + f->def = def; + return; + } + + if (strcmp(f->name, name) == 0) { + f->def = def; // overwrite allowed return; } - } - funcs[func_count].name = strdup(name); - funcs[func_count].def = def; - func_count++; + idx = (idx + 1) & (FUNC_TABLE_SIZE - 1); + } } + static inline ASTNode *get_func(const char *name) { if (!name) return NULL; - for (int j = 0; j < func_count; ++j) { - if (!funcs[j].name) continue; - if (strcmp(funcs[j].name, name) == 0) - return funcs[j].def; + unsigned idx = hash_str(name) & (FUNC_TABLE_SIZE - 1); + + for (unsigned i = 0; i < FUNC_TABLE_SIZE; i++) { + FuncSlot *f = &func_table[idx]; + + if (!f->used) + return NULL; + + if (strcmp(f->name, name) == 0) + return f->def; + + idx = (idx + 1) & (FUNC_TABLE_SIZE - 1); } + return NULL; } + + static ASTNode *clone_ast(const ASTNode *n) { if (!n) return NULL; @@ -558,30 +584,32 @@ static ASTNode *clone_ast(const ASTNode *n) { break; default: - error(0, "clone_ast: unsupported AST node %d", n->type); + error(0, "Splice/VMError clone_ast: unsupported AST node %d", n->type); } return c; } -static int already_imported(const char *path) { - if (!path) { - error(0, "already_imported: NULL path"); - } +static int strcmp_ptr(const void *a, const void *b) { + return strcmp(*(char**)a, *(char**)b); +} - for (int i = 0; i < imported_count; i++) { - if (!imported_files[i]) continue; - if (strcmp(imported_files[i], path) == 0) - return 1; - } - return 0; +static int already_imported(const char *path) { + return bsearch( + &path, + imported_files, + imported_count, + sizeof(char*), + strcmp_ptr + ) != NULL; } + /* ========================= AST alloc/free ========================= */ static inline ASTNode *ast_new(ASTNodeType t) { ASTNode *n = (ASTNode*)calloc(1, sizeof(ASTNode)); - if (!n) error(0, "OOM allocating ASTNode"); + if (!n) error(0, "Splice/SystemError OOM allocating ASTNode"); n->type = t; return n; } @@ -692,49 +720,49 @@ static inline void free_ast(ASTNode *node) { #define AST_NULL_SENTINEL 0xFF static inline void w_u8(FILE *f, unsigned char v) { - if (fputc(v, f) == EOF) error(0, "write u8 failed"); + if (fputc(v, f) == EOF) error(0, "Splice/SystemError write u8 failed"); } static inline void w_u32(FILE *f, unsigned int v) { - if (fwrite(&v, 4, 1, f) != 1) error(0, "write u32 failed"); + if (fwrite(&v, 4, 1, f) != 1) error(0, "Splice/SystemError write u32 failed"); } static inline void w_u16(FILE *f, unsigned short v) { - if (fwrite(&v, 2, 1, f) != 1) error(0, "write u16 failed"); + if (fwrite(&v, 2, 1, f) != 1) error(0, "Splice/SystemError write u16 failed"); } static inline void w_double(FILE *f, double d) { - if (fwrite(&d, sizeof(double), 1, f) != 1) error(0, "write double failed"); + if (fwrite(&d, sizeof(double), 1, f) != 1) error(0, "Splice/SystemError write double failed"); } static inline void w_str(FILE *f, const char *s) { if (!s) s = ""; unsigned short len = (unsigned short)strlen(s); w_u16(f, len); - if (len && fwrite(s, 1, len, f) != len) error(0, "write string failed"); + if (len && fwrite(s, 1, len, f) != len) error(0, "Splice/SystemError write string failed"); } static inline unsigned char r_u8(FILE *f) { int c = fgetc(f); - if (c == EOF) error(0, "Unexpected EOF (u8)"); + if (c == EOF) error(0, "Splice/SyntaxError Unexpected EOF (u8)"); return (unsigned char)c; } static inline unsigned int r_u32(FILE *f) { unsigned int v; - if (fread(&v, 4, 1, f) != 1) error(0, "Unexpected EOF (u32)"); + if (fread(&v, 4, 1, f) != 1) error(0, "Splice/SyntaxError Unexpected EOF (u32)"); return v; } static inline unsigned short r_u16(FILE *f) { unsigned short v; - if (fread(&v, 2, 1, f) != 1) error(0, "Unexpected EOF (u16)"); + if (fread(&v, 2, 1, f) != 1) error(0, "Splice/SyntaxError Unexpected EOF (u16)"); return v; } static inline double r_double(FILE *f) { double d; - if (fread(&d, sizeof(double), 1, f) != 1) error(0, "Unexpected EOF (double)"); + if (fread(&d, sizeof(double), 1, f) != 1) error(0, "Splice/SyntaxError Unexpected EOF (double)"); return d; } static inline char *r_str(FILE *f) { unsigned short len = r_u16(f); char *s = (char*)malloc((size_t)len + 1); if (!s) error(0, "OOM reading string"); - if (len && fread(s, 1, len, f) != len) error(0, "Unexpected EOF (string)"); + if (len && fread(s, 1, len, f) != len) error(0, "Splice/SyntaxError Unexpected EOF (string)"); s[len] = 0; return s; } @@ -845,7 +873,7 @@ static void write_ast_node(FILE *f, const ASTNode *n) { break; default: - error(0, "write_ast_node: unsupported type %d", (int)n->type); + error(0, "Splice/SystemError write_ast_node: unsupported type %d", (int)n->type); } } @@ -930,7 +958,7 @@ static ASTNode *read_ast_node(FILE *f) { unsigned int count = r_u32(f); n->arraylit.count = (int)count; n->arraylit.elements = (ASTNode**)calloc(count ? count : 1, sizeof(ASTNode*)); - if (!n->arraylit.elements) error(0, "OOM arraylit elements"); + if (!n->arraylit.elements) error(0, "Splice/SystemError OOM arraylit elements"); for (unsigned int i = 0; i < count; ++i) n->arraylit.elements[i] = read_ast_node(f); break; } @@ -951,7 +979,7 @@ static ASTNode *read_ast_node(FILE *f) { unsigned int pc = r_u32(f); n->funcdef.param_count = (int)pc; n->funcdef.params = (char**)calloc(pc ? pc : 1, sizeof(char*)); - if (!n->funcdef.params) error(0, "OOM func params"); + if (!n->funcdef.params) error(0, "Splice/SystemError OOM func params"); for (unsigned int i = 0; i < pc; ++i) n->funcdef.params[i] = r_str(f); n->funcdef.body = read_ast_node(f); break; @@ -962,7 +990,7 @@ static ASTNode *read_ast_node(FILE *f) { unsigned int ac = r_u32(f); n->funccall.arg_count = (int)ac; n->funccall.args = (ASTNode**)calloc(ac ? ac : 1, sizeof(ASTNode*)); - if (!n->funccall.args) error(0, "OOM funccall args"); + if (!n->funccall.args) error(0, "Splice/SystemError OOM funccall args"); for (unsigned int i = 0; i < ac; ++i) n->funccall.args[i] = read_ast_node(f); break; } @@ -971,7 +999,7 @@ static ASTNode *read_ast_node(FILE *f) { unsigned int c = r_u32(f); n->statements.count = (int)c; n->statements.stmts = (ASTNode**)calloc(c ? c : 1, sizeof(ASTNode*)); - if (!n->statements.stmts) error(0, "OOM statements"); + if (!n->statements.stmts) error(0, "Splice/SystemError OOM statements"); for (unsigned int i = 0; i < c; ++i) n->statements.stmts[i] = read_ast_node(f); break; } @@ -981,7 +1009,7 @@ static ASTNode *read_ast_node(FILE *f) { break; default: - error(0, "read_ast_node: unknown type %d", (int)type); + error(0, "Splice/SystemError read_ast_node: unknown type %d", (int)type); } return n; } @@ -992,15 +1020,14 @@ static ASTNode *read_ast_node(FILE *f) { #if !SPLICE_EMBED static inline ASTNode *read_ast_from_spc(const char *filename) { FILE *f = fopen(filename, "rb"); - if (!f) { error(0, "Could not open bytecode file: %s", filename); return NULL; } + if (!f) { error(0, "Splice/SPCError Could not open bytecode file: %s", filename); return NULL; } char magic[5] = {0}; - if (fread(magic, 1, 4, f) != 4) error(0, "Invalid SPC (short)"); - if (memcmp(magic, SPC_MAGIC, 4) != 0) error(0, "Invalid SPC magic"); + if (fread(magic, 1, 4, f) != 4) error(0, "Splice/SPCError Invalid SPC (short)"); + if (memcmp(magic, SPC_MAGIC, 4) != 0) error(0, "Splice/SPCError Invalid SPC magic"); unsigned char ver = r_u8(f); - if (ver != SPC_VERSION) error(0, "Unsupported SPC version: %u", ver); - + if (ver != SPC_VERSION) error(0, "Splice/SPCError Unsupported SPC version: %u", ver); ASTNode *root = read_ast_node(f); fclose(f); return root; @@ -1048,7 +1075,7 @@ static inline Value eval(ASTNode *node) { rewind(f); char *buf = (char*)malloc(size + 1); - if (!buf) error(0, "OOM in read()"); + if (!buf) error(0, "Splice/SystemError OOM in read()"); fread(buf, 1, size, f); buf[size] = 0; @@ -1076,7 +1103,7 @@ static inline Value eval(ASTNode *node) { } case AST_TUPLE: { ObjArray *oa = (ObjArray*)calloc(1, sizeof(ObjArray)); - if (!oa) error(0, "OOM tuple"); + if (!oa) error(0, "Splice/SystemError OOM tuple"); oa->type = OBJ_TUPLE; oa->count = node->tuple.count; @@ -1131,12 +1158,12 @@ static inline Value eval(ASTNode *node) { case AST_ARRAY_LITERAL: { ObjArray *oa = (ObjArray*)calloc(1, sizeof(ObjArray)); - if (!oa) error(0, "OOM array"); + if (!oa) error(0, "Splice/SystemError OOM array"); oa->type = OBJ_ARRAY; oa->count = node->arraylit.count; oa->capacity = node->arraylit.count; oa->items = (Value*)calloc((size_t)(oa->capacity ? oa->capacity : 1), sizeof(Value)); - if (!oa->items) error(0, "OOM array items"); + if (!oa->items) error(0, "Splice/SystemError OOM array items"); for (int j = 0; j < node->arraylit.count; ++j) oa->items[j] = eval(node->arraylit.elements[j]); Value tmp; tmp.type = VAL_OBJECT; @@ -1149,9 +1176,9 @@ static inline Value eval(ASTNode *node) { Value idxv = eval(node->indexexpr.index); int idx = (int)idxv.number; - if (target.type != VAL_OBJECT) error(0, "index: target is not array"); + if (target.type != VAL_OBJECT) error(0, "Splice/IndexError index: target is not array"); ObjArray *oa = (ObjArray*)target.object; - if (!oa || oa->type != OBJ_ARRAY) error(0, "index: not an array"); + if (!oa || oa->type != OBJ_ARRAY) error(0, "Splice/IndexError index: not an array"); if (idx < 0 || idx >= oa->count) { Value tmp; @@ -1193,29 +1220,29 @@ static inline Value eval(ASTNode *node) { case AST_INDEX_ASSIGN: { if (!node->indexassign.target || node->indexassign.target->type != AST_IDENTIFIER) - error(0, "index assign: target must be identifier"); + error(0, "Splice/IndexError index assign: target must be identifier"); VarSlot *slot = get_var(node->indexassign.target->string); double d = slot ? slot->value : 0.0; if (!slot || slot->type != VAR_OBJECT) - error(0, "index assign: variable is not array"); + error(0, "Splice/IndexError index assign: variable is not array"); ObjArray *oa = (ObjArray*)slot->obj; if (oa->type == OBJ_TUPLE) { - error(0, "cannot assign to tuple (immutable)"); + error(0, "Splice/TypeError cannot assign to tuple (immutable)"); } int idx = (int)eval(node->indexassign.index).number; Value val = eval(node->indexassign.value); - if (idx < 0) error(0, "index assign: negative index"); + if (idx < 0) error(0, "Splice/IndexError index assign: negative index"); if (idx >= oa->count) { while (idx >= oa->capacity) { int newcap = oa->capacity ? oa->capacity * 2 : 4; Value *ni = (Value*)realloc(oa->items, sizeof(Value) * (size_t)newcap); - if (!ni) error(0, "OOM realloc array"); + if (!ni) error(0, "Splice/SystemError OOM realloc array"); oa->items = ni; oa->capacity = newcap; } @@ -1254,7 +1281,7 @@ static inline Value eval(ASTNode *node) { const char *rs = (right.type == VAL_STRING) ? right.string : (snprintf(rb, sizeof(rb), "%g", right.number), rb); char *out = (char*)malloc(strlen(ls) + strlen(rs) + 1); - if (!out) error(0, "OOM concat"); + if (!out) error(0, "Splice/SystemError OOM concat"); strcpy(out, ls); strcat(out, rs); @@ -1322,19 +1349,18 @@ static inline Value eval(ASTNode *node) { if (strcmp(node->funccall.funcname, "append") == 0 && node->funccall.arg_count == 2) { Value a = eval(node->funccall.args[0]); Value v = eval(node->funccall.args[1]); - if (a.type != VAL_OBJECT) error(0, "append: first arg must be array"); + if (a.type != VAL_OBJECT) error(0, "Splice/ArrayError append: first arg must be array"); ObjArray *oa = (ObjArray*)a.object; - if (!oa) error(0, "append: invalid object"); + if (!oa) error(0, "Splice/ArrayError append: invalid object"); if (oa->type == OBJ_TUPLE) - error(0, "append: cannot modify tuple (immutable)"); + error(0, "Splice/ArrayError append: cannot modify tuple (immutable)"); if (oa->type != OBJ_ARRAY) - error(0, "append: not an array"); - + error(0, "Splice/ArrayError append: not an array"); if (oa->count >= oa->capacity) { int newcap = oa->capacity ? oa->capacity * 2 : 4; Value *ni = (Value*)realloc(oa->items, sizeof(Value) * (size_t)newcap); - if (!ni) error(0, "OOM append realloc"); + if (!ni) error(0, "Splice/SystemError OOM append realloc"); oa->items = ni; oa->capacity = newcap; } @@ -1349,7 +1375,7 @@ static inline Value eval(ASTNode *node) { SpliceCFunc native = Splice_get_native(node->funccall.funcname); if (native) { Value *args = (Value*)malloc(sizeof(Value) * (size_t)node->funccall.arg_count); - if (!args) error(0, "OOM native args"); + if (!args) error(0, "Splice/SystemError OOM native args"); for (int j = 0; j < node->funccall.arg_count; ++j) args[j] = eval(node->funccall.args[j]); Value r = native(node->funccall.arg_count, args); for (int j = 0; j < node->funccall.arg_count; ++j) @@ -1360,7 +1386,7 @@ static inline Value eval(ASTNode *node) { /* user-defined */ ASTNode *func = get_func(node->funccall.funcname); - if (!func) error(0, "Undefined function: %s", node->funccall.funcname); + if (!func) error(0, "Splice/SyntaxError Undefined function: %s", node->funccall.funcname); for (int j = 0; j < func->funcdef.param_count; ++j) { Value av; @@ -1413,7 +1439,7 @@ static inline void sb_ensure(char **buf, size_t *cap, size_t need) { if (need <= *cap) return; while (*cap < need) *cap *= 2; *buf = (char*)realloc(*buf, *cap); - if (!*buf) error(0, "OOM stringify"); + if (!*buf) error(0, "Splice/SystemError OOM stringify"); } static inline char *value_item_to_tmp(Value v, char tmp[128]) { @@ -1446,7 +1472,7 @@ static inline char *eval_to_string(ASTNode *node) { size_t cap = 128; size_t len = 0; char *out = (char*)malloc(cap); - if (!out) error(0, "OOM stringify"); + if (!out) error(0, "Splice/SystemError OOM stringify"); char open = (oa->type == OBJ_TUPLE) ? '(' : '['; char close = (oa->type == OBJ_TUPLE) ? ')' : ']'; @@ -1515,14 +1541,14 @@ static inline void interpret(ASTNode *node) { } ASTNode *mod = read_ast_from_spc(path); - if (!mod) error(0, "import failed: %s", path); + if (!mod) error(0, "Splice/ImportError import failed: %s", path); imported_files[imported_count++] = strdup(path); interpret(mod); // executes + registers funcs free_ast(mod); #else - error(0, "import not supported on embedded builds"); + error(0, "Splice/ImportError import not supported on embedded builds"); #endif break; } @@ -1574,7 +1600,7 @@ static inline void interpret(ASTNode *node) { Value val = eval(node->write.value); if (path.type != VAL_STRING) { - error(0, "write(): path must be string"); + error(0, "Splice/IOError write(): path must be string"); } char *out; @@ -1591,7 +1617,7 @@ static inline void interpret(ASTNode *node) { if (!f) { free(path.string); if (val.type == VAL_STRING) free(val.string); - error(0, "write(): cannot open file"); + error(0, "Splice/IOError write(): cannot open file"); } fwrite(out, 1, strlen(out), f); @@ -1612,7 +1638,7 @@ static inline void interpret(ASTNode *node) { case AST_FOR: { if (!node->forstmt.for_var) { - error(0, "for-loop variable name is NULL"); + error(0, "Splice/NULLError for-loop variable name is NULL"); } int start = (int)eval(node->forstmt.for_start).number; @@ -1664,12 +1690,12 @@ typedef struct { } SpcMemReader; static inline unsigned char m_u8(SpcMemReader *r) { - if (r->pos >= r->size) error(0, "Unexpected EOF (mem u8)"); + if (r->pos >= r->size) error(0, "Splice/IOError Unexpected EOF (mem u8)"); return r->data[r->pos++]; } static inline unsigned short m_u16(SpcMemReader *r) { - if (r->pos + 2 > r->size) error(0, "Unexpected EOF (mem u16)"); + if (r->pos + 2 > r->size) error(0, "Splice/IOError Unexpected EOF (mem u16)"); unsigned short v; memcpy(&v, r->data + r->pos, 2); r->pos += 2; @@ -1677,7 +1703,7 @@ static inline unsigned short m_u16(SpcMemReader *r) { } static inline unsigned int m_u32(SpcMemReader *r) { - if (r->pos + 4 > r->size) error(0, "Unexpected EOF (mem u32)"); + if (r->pos + 4 > r->size) error(0, "Splice/IOError Unexpected EOF (mem u32)"); unsigned int v; memcpy(&v, r->data + r->pos, 4); r->pos += 4; @@ -1686,7 +1712,7 @@ static inline unsigned int m_u32(SpcMemReader *r) { static inline double m_double(SpcMemReader *r) { if (r->pos + sizeof(double) > r->size) - error(0, "Unexpected EOF (mem double)"); + error(0, "Splice/IOError Unexpected EOF (mem double)"); double d; memcpy(&d, r->data + r->pos, sizeof(double)); r->pos += sizeof(double); @@ -1695,7 +1721,7 @@ static inline double m_double(SpcMemReader *r) { static inline char *m_str(SpcMemReader *r) { unsigned short len = m_u16(r); - if (r->pos + len > r->size) error(0, "Unexpected EOF (mem string)"); + if (r->pos + len > r->size) error(0, "Splice/IOError Unexpected EOF (mem string)"); char *s = (char*)malloc(len + 1); memcpy(s, r->data + r->pos, len); r->pos += len; @@ -1755,7 +1781,7 @@ static ASTNode *read_ast_node_mem(SpcMemReader *r) { } default: - error(0, "Unsupported AST type in mem reader: %d", n->type); + error(0, "Splice/IOError Unsupported AST type in mem reader: %d", n->type); } return n; @@ -1764,12 +1790,12 @@ static inline ASTNode *read_ast_from_spc_mem( const unsigned char *data, size_t size ) { - if (size < 5) error(0, "Invalid SPC (too small)"); + if (size < 5) error(0, "Splice/SPCrror Invalid SPC (too small)"); if (memcmp(data, SPC_MAGIC, 4) != 0) - error(0, "Invalid SPC magic"); + error(0, "Splice/SPCrror Invalid SPC magic"); if (data[4] != SPC_VERSION) - error(0, "Unsupported SPC version"); + error(0, "Splice/SPCrror Unsupported SPC version"); SpcMemReader r; r.data = data; From 07baa0334c663db06cbd8eaa7dcfbe28d4d91fc9 Mon Sep 17 00:00:00 2001 From: Reboy2000 Date: Tue, 20 Jan 2026 19:08:08 -0500 Subject: [PATCH 2/6] Added Detailed Errors --- .github/workflows/main.yml | 92 +++++++++++--------------------------- 1 file changed, 25 insertions(+), 67 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d303d94..7d64134 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,84 +2,42 @@ name: Splice CI on: push: - branches: [ main ] + branches: [ main, Development, Test, Testing ] pull_request: branches: [ main ] jobs: - build-test: - name: Build & Test (${{ matrix.os }} - ${{ matrix.arch }}) - runs-on: ${{ matrix.runner }} + build-and-test: strategy: fail-fast: false matrix: - include: - # macOS - - os: macos - arch: x64 - runner: macos-15-intel - - os: macos - arch: arm64 - runner: macos-14 - # Linux - - os: linux - arch: x64 - runner: ubuntu-22.04 - - os: linux - arch: arm64 - runner: ubuntu-22.04 - # Windows - - os: windows - arch: x64 - runner: windows-2022 - - os: windows - arch: arm64 - runner: windows-2022 + os: [ubuntu-latest, macos-latest, windows-latest] + + runs-on: ${{ matrix.os }} steps: - - name: Checkout source + - name: Checkout repository uses: actions/checkout@v4 - - name: Make build script executable - run: chmod +x build.sh - shell: bash - - - name: Run build script (CI mode) - run: CI=true ./build.sh + # ------------------------- + # Linux / macOS + # ------------------------- + - name: Build & Run Splice (Unix) + if: runner.os != 'Windows' shell: bash - - - name: Verify binaries exist run: | - ls -lh ./Splice || true - ls -lh ./spbuild || true - shell: bash - - - name: Run tests + set -e + chmod +x bin/spbuild bin/Splice + ./bin/spbuild test/main.spl main.spc + ./bin/Splice main.spc + + # ------------------------- + # Windows (PowerShell ONLY) + # ------------------------- + - name: Build & Run Splice (Windows) + if: runner.os == 'Windows' + shell: pwsh run: | - if [ -d build ]; then - cd build - ctest --output-on-failure || true - else - echo "No build dir found, skipping tests" - fi - shell: bash - - name: Testing Splice Code - shell: bash - run: | - if [[ "${{ matrix.os }}" == "windows" ]]; then - ./bin/spbuild.exe test/main.spl main.spc - ./bin/Splice.exe main.spc - else - ./bin/spbuild test/main.spl main.spc - ./bin/Splice main.spc - fi - - - name: Mark as finished - run: echo "Build completed on ${{ matrix.os }}-${{ matrix.arch }}" > finish.txt - shell: bash - - - name: Upload finish artifact - uses: actions/upload-artifact@v4 - with: - name: splice-finish-${{ matrix.os }}-${{ matrix.arch }} - path: finish.txt + $ErrorActionPreference = "Stop" + .\bin\spbuild.exe test\main.spl main.spc + .\bin\Splice.exe main.spc From cbe466e45e31ab82e79ce3edc6eb1fb29b7fb90f Mon Sep 17 00:00:00 2001 From: Reboy2000 Date: Tue, 20 Jan 2026 19:09:09 -0500 Subject: [PATCH 3/6] Added Detailed Errors --- .github/workflows/main.yml | 92 +++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 25 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7d64134..d303d94 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,42 +2,84 @@ name: Splice CI on: push: - branches: [ main, Development, Test, Testing ] + branches: [ main ] pull_request: branches: [ main ] jobs: - build-and-test: + build-test: + name: Build & Test (${{ matrix.os }} - ${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - - runs-on: ${{ matrix.os }} + include: + # macOS + - os: macos + arch: x64 + runner: macos-15-intel + - os: macos + arch: arm64 + runner: macos-14 + # Linux + - os: linux + arch: x64 + runner: ubuntu-22.04 + - os: linux + arch: arm64 + runner: ubuntu-22.04 + # Windows + - os: windows + arch: x64 + runner: windows-2022 + - os: windows + arch: arm64 + runner: windows-2022 steps: - - name: Checkout repository + - name: Checkout source uses: actions/checkout@v4 - # ------------------------- - # Linux / macOS - # ------------------------- - - name: Build & Run Splice (Unix) - if: runner.os != 'Windows' + - name: Make build script executable + run: chmod +x build.sh + shell: bash + + - name: Run build script (CI mode) + run: CI=true ./build.sh shell: bash + + - name: Verify binaries exist run: | - set -e - chmod +x bin/spbuild bin/Splice - ./bin/spbuild test/main.spl main.spc - ./bin/Splice main.spc - - # ------------------------- - # Windows (PowerShell ONLY) - # ------------------------- - - name: Build & Run Splice (Windows) - if: runner.os == 'Windows' - shell: pwsh + ls -lh ./Splice || true + ls -lh ./spbuild || true + shell: bash + + - name: Run tests run: | - $ErrorActionPreference = "Stop" - .\bin\spbuild.exe test\main.spl main.spc - .\bin\Splice.exe main.spc + if [ -d build ]; then + cd build + ctest --output-on-failure || true + else + echo "No build dir found, skipping tests" + fi + shell: bash + - name: Testing Splice Code + shell: bash + run: | + if [[ "${{ matrix.os }}" == "windows" ]]; then + ./bin/spbuild.exe test/main.spl main.spc + ./bin/Splice.exe main.spc + else + ./bin/spbuild test/main.spl main.spc + ./bin/Splice main.spc + fi + + - name: Mark as finished + run: echo "Build completed on ${{ matrix.os }}-${{ matrix.arch }}" > finish.txt + shell: bash + + - name: Upload finish artifact + uses: actions/upload-artifact@v4 + with: + name: splice-finish-${{ matrix.os }}-${{ matrix.arch }} + path: finish.txt From 3ed74b5599b24b85e3f382d4449fa969f11bdf9e Mon Sep 17 00:00:00 2001 From: Reboy2000 Date: Tue, 20 Jan 2026 19:12:45 -0500 Subject: [PATCH 4/6] Added Detailed Errors --- .github/workflows/main.yml | 64 +++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d303d94..c1f41c0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,6 +10,7 @@ jobs: build-test: name: Build & Test (${{ matrix.os }} - ${{ matrix.arch }}) runs-on: ${{ matrix.runner }} + strategy: fail-fast: false matrix: @@ -21,6 +22,7 @@ jobs: - os: macos arch: arm64 runner: macos-14 + # Linux - os: linux arch: x64 @@ -28,6 +30,7 @@ jobs: - os: linux arch: arm64 runner: ubuntu-22.04 + # Windows - os: windows arch: x64 @@ -37,46 +40,49 @@ jobs: runner: windows-2022 steps: - - name: Checkout source - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Make build script executable - run: chmod +x build.sh + # ======================== + # UNIX (Linux + macOS) + # ======================== + - name: Build Splice (Unix) + if: matrix.os != 'windows' shell: bash + run: | + set -e + chmod +x build.sh + CI=true ./build.sh - - name: Run build script (CI mode) - run: CI=true ./build.sh + - name: Run Splice (Unix) + if: matrix.os != 'windows' shell: bash - - - name: Verify binaries exist run: | - ls -lh ./Splice || true - ls -lh ./spbuild || true - shell: bash + ./bin/spbuild test/main.spl main.spc + ./bin/Splice main.spc - - name: Run tests + # ======================== + # WINDOWS (PowerShell ONLY) + # ======================== + - name: Build Splice (Windows) + if: matrix.os == 'windows' + shell: pwsh run: | - if [ -d build ]; then - cd build - ctest --output-on-failure || true - else - echo "No build dir found, skipping tests" - fi - shell: bash - - name: Testing Splice Code - shell: bash + $ErrorActionPreference = "Stop" + CI=true ./build.ps1 + + - name: Run Splice (Windows) + if: matrix.os == 'windows' + shell: pwsh run: | - if [[ "${{ matrix.os }}" == "windows" ]]; then - ./bin/spbuild.exe test/main.spl main.spc - ./bin/Splice.exe main.spc - else - ./bin/spbuild test/main.spl main.spc - ./bin/Splice main.spc - fi + .\bin\spbuild.exe test\main.spl main.spc + .\bin\Splice.exe main.spc + # ======================== + # Finish + # ======================== - name: Mark as finished - run: echo "Build completed on ${{ matrix.os }}-${{ matrix.arch }}" > finish.txt shell: bash + run: echo "Build completed on ${{ matrix.os }}-${{ matrix.arch }}" > finish.txt - name: Upload finish artifact uses: actions/upload-artifact@v4 From 9d29cbea6aa082cb674fd3bcd9ad7fd09016d5c5 Mon Sep 17 00:00:00 2001 From: Reboy2000 Date: Tue, 20 Jan 2026 19:15:56 -0500 Subject: [PATCH 5/6] Fixing yml --- .github/workflows/main.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c1f41c0..e8a8c44 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,7 +43,7 @@ jobs: - uses: actions/checkout@v4 # ======================== - # UNIX (Linux + macOS) + # UNIX: build + run # ======================== - name: Build Splice (Unix) if: matrix.os != 'windows' @@ -61,19 +61,14 @@ jobs: ./bin/Splice main.spc # ======================== - # WINDOWS (PowerShell ONLY) + # WINDOWS: run only (NO BASH) # ======================== - - name: Build Splice (Windows) - if: matrix.os == 'windows' - shell: pwsh - run: | - $ErrorActionPreference = "Stop" - CI=true ./build.ps1 - - name: Run Splice (Windows) if: matrix.os == 'windows' shell: pwsh run: | + $ErrorActionPreference = "Stop" + Get-Item .\bin\spbuild.exe .\bin\spbuild.exe test\main.spl main.spc .\bin\Splice.exe main.spc From 17dd4fc208cfa910d59166429f7ce98e9929fd44 Mon Sep 17 00:00:00 2001 From: Reboy2000 Date: Tue, 20 Jan 2026 19:29:11 -0500 Subject: [PATCH 6/6] Fixing yml --- .github/workflows/main.yml | 13 +++++++++---- bin/Splice | Bin 35816 -> 0 bytes bin/spbuild | Bin 51592 -> 0 bytes 3 files changed, 9 insertions(+), 4 deletions(-) delete mode 100755 bin/Splice delete mode 100755 bin/spbuild diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e8a8c44..c1f41c0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,7 +43,7 @@ jobs: - uses: actions/checkout@v4 # ======================== - # UNIX: build + run + # UNIX (Linux + macOS) # ======================== - name: Build Splice (Unix) if: matrix.os != 'windows' @@ -61,14 +61,19 @@ jobs: ./bin/Splice main.spc # ======================== - # WINDOWS: run only (NO BASH) + # WINDOWS (PowerShell ONLY) # ======================== - - name: Run Splice (Windows) + - name: Build Splice (Windows) if: matrix.os == 'windows' shell: pwsh run: | $ErrorActionPreference = "Stop" - Get-Item .\bin\spbuild.exe + CI=true ./build.ps1 + + - name: Run Splice (Windows) + if: matrix.os == 'windows' + shell: pwsh + run: | .\bin\spbuild.exe test\main.spl main.spc .\bin\Splice.exe main.spc diff --git a/bin/Splice b/bin/Splice deleted file mode 100755 index 69248626e0ff9a1fa7b077a9190fa19543df6849..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35816 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