peak software

This commit is contained in:
2026-06-13 22:17:53 +02:00
parent 268d1be18b
commit c98790621d
4 changed files with 136 additions and 67 deletions

View File

@@ -6,6 +6,7 @@ typedef struct noomC_Local {
unsigned int startpc; unsigned int startpc;
unsigned int endpc; unsigned int endpc;
const char *name; const char *name;
noom_uint_t namelen;
noom_bool_t dropped; noom_bool_t dropped;
noom_bool_t constant; noom_bool_t constant;
noom_bool_t close; noom_bool_t close;
@@ -17,7 +18,8 @@ typedef struct noomC_Compiler {
unsigned localc, constc; unsigned localc, constc;
unsigned localcap, constcap; unsigned localcap, constcap;
// constants index in the stack. // constants index in the stack.
// We put it there so GC doesn't free them. // We put it there so GC doesn't free them, and
// so we can allocate the function's consts arrays *ONCE*
unsigned constidx; unsigned constidx;
unsigned curstack; unsigned curstack;
noomC_Local *locals; noomC_Local *locals;

View File

@@ -243,12 +243,16 @@ int main(int argc, char **argv) {
if (code == 0) return 1; if (code == 0) return 1;
int offset = 0; int offset = 0;
if (code[0] == '#' && code[1] == '!') for (offset = 2; code[offset] && code[offset] != '\n'; offset++); if (code[0] == '#' && code[1] == '!') for (offset = 2; code[offset] && code[offset] != '\n'; offset++);
return the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code + offset, argv[0], params.script_path); int e = the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code + offset, argv[0], params.script_path);
noom_free(code);
return e;
} }
if (params.use_stdin) { if (params.use_stdin) {
char* code = read_stdin(); char* code = read_stdin();
if (code == 0) return 1; if (code == 0) return 1;
return the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code, argv[0], "stdin"); int e = the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code, argv[0], "stdin");
noom_free(code);
return e;
} }
if (params.enter_repl) { if (params.enter_repl) {
puts(NOOM_VERSION_TEXT); puts(NOOM_VERSION_TEXT);

View File

@@ -57,6 +57,60 @@ typedef enum noom_Exit {
NOOM_EERROR, NOOM_EERROR,
} noom_Exit; } noom_Exit;
typedef enum noom_UnaryOp {
// -x
NOOM_UNARY_NEGATE,
// ~x
NOOM_UNARY_BNOT,
// #x
NOOM_UNARY_LEN,
// not x
NOOM_UNARY_NOT,
} noom_UnaryOp;
typedef enum noom_BinOp {
// Algebruh (Noom knows maths)
// a + b
NOOM_BIN_ADD,
// a - b
NOOM_BIN_SUB,
// a * b
NOOM_BIN_MLT,
// a / b
NOOM_BIN_DIV,
// a // b
NOOM_BIN_IDIV,
// a ^ b
NOOM_BIN_EXP,
// Comparison (thief of joy)
// a == b
NOOM_BIN_EQL,
// a ~= b
NOOM_BIN_NEQL,
// a < b
NOOM_BIN_LESS,
// a <= b
NOOM_BIN_LESSEQL,
// a > b
NOOM_BIN_GREATER,
// a >= b
NOOM_BIN_GREATEREQL,
// a & b
NOOM_BIN_BAND,
// a | b
NOOM_BIN_BOR,
// a ~ b
NOOM_BIN_BXOR,
// a << b
NOOM_BIN_BSHIFTL,
// a >> b
NOOM_BIN_BSHIFTR,
} noom_BinOp;
typedef struct noom_LuaVM noom_LuaVM; typedef struct noom_LuaVM noom_LuaVM;
typedef noom_Exit noom_CFunction(noom_LuaVM *vm); typedef noom_Exit noom_CFunction(noom_LuaVM *vm);

137
src/vm.h
View File

@@ -84,76 +84,83 @@ typedef struct noomV_Pointer {
typedef enum noomV_Opcode : unsigned char { typedef enum noomV_Opcode : unsigned char {
NOOMV_INSTR_NOP = 0, NOOMV_INSTR_NOP = 0,
// A = consts[uD]
NOOMV_INSTR_LOADC,
// load from A an array of uD nils
NOOMV_INSTR_LOAD_NILARR,
// load from A an array of uD/2 booleans, stored in uD&1
NOOMV_INSTR_LOAD_BOOLARR,
// A = B
NOOMV_INSTR_COPY,
// pc = uD // Push data on the stack
// Pushes the value at stack[op.uD]
NOOMV_INSTR_PUSHVAL,
// Pushes consts[op.uD]
NOOMV_INSTR_PUSHCONST,
// Pushes op.sD itself as an integer
NOOMV_INSTR_PUSHINT,
// Pushes op.uD nils
NOOMV_INSTR_PUSHNIL,
// Pushes op.a+1 booleans, encoded in op.uD, where the ith (0-indexed) boolean is encoded in `uD & (1 << i)`
NOOMV_INSTR_PUSHBOOLS,
// Pushes *upvals[op.uD]
NOOMV_INSTR_PUSHUPVAL,
// Pushes op.a varargs. If op.a is 0, it will push all of them, regardless of how many
NOOMV_INSTR_PUSHARGS,
// Pushes a new table. op.uD is the initial capacity
NOOMV_INSTR_CREATETABLE,
// Pushes a closure, using the prototype in protos[op.uD]
NOOMV_INSTR_PUSHCLOSURE,
// High-level ops
// Call the function stored at stack[op.a]. All values after that are treated at arguments. op.uD is the expected return count plus one, and if op.uD is 0,
// all returns are pushed.
NOOMV_INSTR_CALL,
// pops (table, field), and pushes table[field]
NOOMV_INSTR_GETTABLE,
// pops (table, field, value), and sets table[field] = value
NOOMV_INSTR_SETTABLE,
// pops op.uD values, then sets it as an array starting at op.a+1 in the table at the new top;
// if that is confused, it basically does this:
// int table = stacksize - op.uD - 1;
// for(int i = 0; i < op.uD; i++) stack[table][op.a + 1 + i] = stack[table + i + 1];
NOOMV_INSTR_SETLIST,
// pops table, pushes table[consts[op.uD]], an optimization for indexing fields
NOOMV_INSTR_GETFIELD,
// pops (table, value), sets table[consts[op.uD]] = value, an optimization for changing fields
NOOMV_INSTR_SETFIELD,
// does a unary or binary operation.
// if op.a == 1, its a unary operation.
// if op.a == 2, its a binary operation.
// op.b stores the operation type.
NOOMV_INSTR_OP,
// Control flow
// returns from a function. The amount returned is from op.uD
NOOMV_INSTR_RET,
// computes T = op.a << 16 + op.uD, jumps to T.
NOOMV_INSTR_JMP, NOOMV_INSTR_JMP,
// if(A) pc = uD // pops value, if value is truthy, does the same as JMP.
NOOMV_INSTR_JC, NOOMV_INSTR_CJMP,
// if(not A) pc = uD // pops value, if value is falsy, does the same as JMP.
NOOMV_INSTR_JNC, NOOMV_INSTR_CNJMP,
// A = B + C // For bullshit
NOOMV_INSTR_ADD,
// A = B - C
NOOMV_INSTR_SUB,
// A = -B
NOOMV_INSTR_NEG,
// A = B * C
NOOMV_INSTR_MUL,
// A = B / C
NOOMV_INSTR_DIV,
// A = B % C
NOOMV_INSTR_MOD,
// A = B // C
NOOMV_INSTR_FLOOR_DIV,
// A = B ^ C
NOOMV_INSTR_POW,
// A = B == C // Take the top value without popping it, push value[consts[op.uD]] like GETFIELD would, then swap the top 2 values.
NOOMV_INSTR_EQ, // This is for a:foo() and such
// A = B ~= C NOOMV_INSTR_GETMETHOD,
NOOMV_INSTR_NEQ, // rotate the the top op.a items by op.sD
// A = B < C NOOMV_INSTR_ROTATE,
NOOMV_INSTR_LT, // pop op.uD values
// A = B <= C NOOMV_INSTR_POP,
NOOMV_INSTR_LTE, // set the stack size to op.uD, inserting nils if need be, good for labels
// A = B > C NOOMV_INSTR_SETSTACK,
NOOMV_INSTR_GT,
// A = B >= C
NOOMV_INSTR_GTE,
// A = not B // pop and concatenate the top op.uD values to a string and push it
NOOMV_INSTR_NOT,
// A = B & C
NOOMV_INSTR_BAND,
// A = B | C
NOOMV_INSTR_BOR,
// A = B ~ C
NOOMV_INSTR_BXOR,
// A = ~B
NOOMV_INSTR_BNOT,
// A = B << C
NOOMV_INSTR_LSHIFT,
// A = B >> C
NOOMV_INSTR_RSHIFT,
// A = B .. C
NOOMV_INSTR_CONCAT, NOOMV_INSTR_CONCAT,
// A = #B
NOOMV_INSTR_LEN, // mark stack slot op.uD as to-be-closed
// A = B[C] NOOMV_INSTR_CLOSE,
NOOMV_INSTR_GET,
// A[B] = C
NOOMV_INSTR_SET,
NOOMV_INSTR_NOP2 = 0xff, NOOMV_INSTR_NOP2 = 0xff,
} noomV_Opcode; } noomV_Opcode;
@@ -181,6 +188,8 @@ typedef struct noomV_UpvalDesc {
typedef struct noomV_LocalDesc { typedef struct noomV_LocalDesc {
char *name; char *name;
unsigned char stackIdx; unsigned char stackIdx;
// to forbid changing it with debug.setlocal
noom_bool_t isConst;
// offset of first instruction where local exists // offset of first instruction where local exists
unsigned int pcStart; unsigned int pcStart;
// offset of first instruction where local is dropped // offset of first instruction where local is dropped