Some more opcode refactoring. (0.3.1)
This commit is contained in:
parent
f0f93689c3
commit
228615db18
12 changed files with 42 additions and 59 deletions
|
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
project(fun VERSION 0.2.2 LANGUAGES C)
|
||||
project(fun VERSION 0.3.1 LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
|
|
|||
|
|
@ -86,11 +86,11 @@ static const char *opcode_name(OpCode op) {
|
|||
case OP_INDEX_GET: return "INDEX_GET";
|
||||
case OP_INDEX_SET: return "INDEX_SET";
|
||||
case OP_LEN: return "LEN";
|
||||
case OP_ARR_PUSH: return "ARR_PUSH";
|
||||
case OP_ARR_POP: return "ARR_POP";
|
||||
case OP_ARR_SET: return "ARR_SET";
|
||||
case OP_ARR_INSERT: return "ARR_INSERT";
|
||||
case OP_ARR_REMOVE: return "ARR_REMOVE";
|
||||
case OP_PUSH: return "ARR_PUSH";
|
||||
case OP_APOP: return "ARR_POP";
|
||||
case OP_SET: return "ARR_SET";
|
||||
case OP_INSERT: return "ARR_INSERT";
|
||||
case OP_REMOVE: return "ARR_REMOVE";
|
||||
case OP_SLICE: return "SLICE";
|
||||
case OP_TO_NUMBER: return "TO_NUMBER";
|
||||
case OP_TO_STRING: return "TO_STRING";
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ typedef enum {
|
|||
|
||||
// array and builtin helpers
|
||||
OP_LEN, // pops array or string; pushes length
|
||||
OP_ARR_PUSH, // pops value, array; pushes new length
|
||||
OP_ARR_POP, // pops array; pushes removed element
|
||||
OP_ARR_SET, // pops value, index, array; pushes value
|
||||
OP_ARR_INSERT, // pops value, index, array; pushes new length
|
||||
OP_ARR_REMOVE, // pops index, array; pushes removed element
|
||||
OP_PUSH, // pops value, array; pushes new length
|
||||
OP_APOP, // pops array; pushes removed element
|
||||
OP_SET, // pops value, index, array; pushes value
|
||||
OP_INSERT, // pops value, index, array; pushes new length
|
||||
OP_REMOVE, // pops index, array; pushes removed element
|
||||
OP_SLICE, // pops end, start, array; pushes new array
|
||||
|
||||
// conversions
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* This file is part of the Fun programming language.
|
||||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
*/
|
||||
|
||||
#include "vm.h"
|
||||
|
||||
const char *opcode_names[] = {
|
||||
"OP_NOP", "OP_LOAD_CONST", "OP_LOAD_LOCAL", "OP_STORE_LOCAL",
|
||||
"OP_LOAD_GLOBAL", "OP_STORE_GLOBAL", "OP_ADD", "OP_SUB",
|
||||
"OP_MUL", "OP_DIV", "OP_LT", "OP_LTE",
|
||||
"OP_GT", "OP_GTE", "OP_EQ", "OP_NEQ",
|
||||
"OP_POP", "OP_JUMP", "OP_JUMP_IF_FALSE", "OP_CALL",
|
||||
"OP_RETURN", "OP_PRINT", "OP_MOD", "OP_AND",
|
||||
"OP_OR", "OP_NOT", "OP_DUP", "OP_SWAP"
|
||||
};
|
||||
|
||||
14
src/parser.c
14
src/parser.c
|
|
@ -386,7 +386,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
if (*pos < len && src[*pos] == ',') { (*pos)++; skip_spaces(src, len, pos); } else { parser_fail(*pos, "push expects 2 args"); free(name); return 0; }
|
||||
if (!emit_expression(bc, src, len, pos)) { parser_fail(*pos, "push expects value"); free(name); return 0; }
|
||||
if (!consume_char(src, len, pos, ')')) { parser_fail(*pos, "Expected ')' after push args"); free(name); return 0; }
|
||||
bytecode_add_instruction(bc, OP_ARR_PUSH, 0);
|
||||
bytecode_add_instruction(bc, OP_PUSH, 0);
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -394,7 +394,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
(*pos)++; /* '(' */
|
||||
if (!emit_expression(bc, src, len, pos)) { parser_fail(*pos, "pop expects array"); free(name); return 0; }
|
||||
if (!consume_char(src, len, pos, ')')) { parser_fail(*pos, "Expected ')' after pop arg"); free(name); return 0; }
|
||||
bytecode_add_instruction(bc, OP_ARR_POP, 0);
|
||||
bytecode_add_instruction(bc, OP_APOP, 0);
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -406,7 +406,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
if (*pos < len && src[*pos] == ',') { (*pos)++; skip_spaces(src, len, pos); } else { parser_fail(*pos, "set expects 3 args"); free(name); return 0; }
|
||||
if (!emit_expression(bc, src, len, pos)) { parser_fail(*pos, "set expects value"); free(name); return 0; }
|
||||
if (!consume_char(src, len, pos, ')')) { parser_fail(*pos, "Expected ')' after set args"); free(name); return 0; }
|
||||
bytecode_add_instruction(bc, OP_ARR_SET, 0);
|
||||
bytecode_add_instruction(bc, OP_SET, 0);
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -418,7 +418,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
if (*pos < len && src[*pos] == ',') { (*pos)++; skip_spaces(src, len, pos); } else { parser_fail(*pos, "insert expects 3 args"); free(name); return 0; }
|
||||
if (!emit_expression(bc, src, len, pos)) { parser_fail(*pos, "insert expects value"); free(name); return 0; }
|
||||
if (!consume_char(src, len, pos, ')')) { parser_fail(*pos, "Expected ')' after insert args"); free(name); return 0; }
|
||||
bytecode_add_instruction(bc, OP_ARR_INSERT, 0);
|
||||
bytecode_add_instruction(bc, OP_INSERT, 0);
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -428,7 +428,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
if (*pos < len && src[*pos] == ',') { (*pos)++; skip_spaces(src, len, pos); } else { parser_fail(*pos, "remove expects 2 args"); free(name); return 0; }
|
||||
if (!emit_expression(bc, src, len, pos)) { parser_fail(*pos, "remove expects index"); free(name); return 0; }
|
||||
if (!consume_char(src, len, pos, ')')) { parser_fail(*pos, "Expected ')' after remove args"); free(name); return 0; }
|
||||
bytecode_add_instruction(bc, OP_ARR_REMOVE, 0);
|
||||
bytecode_add_instruction(bc, OP_REMOVE, 0);
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -641,7 +641,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
else { bytecode_add_instruction(bc, OP_LOAD_GLOBAL, gv); }
|
||||
|
||||
/* Append via insert: res.insert(index=len(res), value) */
|
||||
bytecode_add_instruction(bc, OP_ARR_INSERT, 0);
|
||||
bytecode_add_instruction(bc, OP_INSERT, 0);
|
||||
/* discard returned new length */
|
||||
bytecode_add_instruction(bc, OP_POP, 0);
|
||||
|
||||
|
|
@ -720,7 +720,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
else { bytecode_add_instruction(bc, OP_LOAD_GLOBAL, gvf); }
|
||||
|
||||
/* Append via insert: res.insert(index=len(res), value) */
|
||||
bytecode_add_instruction(bc, OP_ARR_INSERT, 0);
|
||||
bytecode_add_instruction(bc, OP_INSERT, 0);
|
||||
/* discard returned new length */
|
||||
bytecode_add_instruction(bc, OP_POP, 0);
|
||||
|
||||
|
|
|
|||
14
src/vm.c
14
src/vm.c
|
|
@ -207,12 +207,16 @@ void vm_run(VM *vm, Bytecode *entry) {
|
|||
#include "vm/arithmetic/mul.c"
|
||||
#include "vm/arithmetic/sub.c"
|
||||
|
||||
#include "vm/arrays/arr_insert.c"
|
||||
#include "vm/arrays/arr_pop.c"
|
||||
#include "vm/arrays/arr_push.c"
|
||||
#include "vm/arrays/arr_remove.c"
|
||||
#include "vm/arrays/arr_set.c"
|
||||
#include "vm/arrays/insert.c"
|
||||
|
||||
#include "vm/arrays/apop.c"
|
||||
|
||||
|
||||
#include "vm/arrays/push.c"
|
||||
#include "vm/arrays/remove.c"
|
||||
#include "vm/arrays/set.c"
|
||||
#include "vm/arrays/clear.c"
|
||||
|
||||
#include "vm/arrays/contains.c"
|
||||
#include "vm/arrays/enumerate.c"
|
||||
#include "vm/arrays/index_get.c"
|
||||
|
|
|
|||
2
src/vm.h
2
src/vm.h
|
|
@ -34,7 +34,7 @@ static const char *opcode_names[] = {
|
|||
"JUMP_IF_FALSE","CALL","RETURN","PRINT","HALT",
|
||||
"MOD","AND","OR","NOT","DUP","SWAP",
|
||||
"MAKE_ARRAY","INDEX_GET","INDEX_SET",
|
||||
"LEN","ARR_PUSH","ARR_POP","ARR_SET","ARR_INSERT","ARR_REMOVE","SLICE",
|
||||
"LEN","PUSH","APOP","SET","INSERT","REMOVE","SLICE",
|
||||
"TO_NUMBER","TO_STRING","TYPEOF",
|
||||
"SPLIT","JOIN","SUBSTR","FIND",
|
||||
"CONTAINS","INDEX_OF","CLEAR",
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file arr_pop.c
|
||||
* @brief Implements the OP_ARR_POP opcode for removing elements from arrays in the VM.
|
||||
* @file apop.c
|
||||
* @brief Implements the OP_APOP opcode for removing elements from arrays in the VM.
|
||||
*
|
||||
* This file handles the OP_ARR_POP instruction, which removes the last element from an array
|
||||
* This file handles the OP_APOP instruction, which removes the last element from an array
|
||||
* and pushes the removed element onto the stack. The array is popped from the stack.
|
||||
*
|
||||
* Behavior:
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
* - Exits with an error if the array is empty.
|
||||
*
|
||||
* Example:
|
||||
* // Bytecode: OP_ARR_POP
|
||||
* // Bytecode: OP_APOP
|
||||
* // Stack before: [[10, 20, 30]]
|
||||
* // Stack after: [30]
|
||||
*
|
||||
|
|
@ -32,10 +32,10 @@
|
|||
* @date 2025-10-16
|
||||
*/
|
||||
|
||||
case OP_ARR_POP: {
|
||||
case OP_APOP: {
|
||||
Value arr = pop_value(vm);
|
||||
if (arr.type != VAL_ARRAY) {
|
||||
fprintf(stderr, "Runtime type error: ARR_POP expects array\n");
|
||||
fprintf(stderr, "Runtime type error: ARR_APOP expects array\n");
|
||||
exit(1);
|
||||
}
|
||||
Value out;
|
||||
|
|
@ -8,10 +8,10 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file arr_insert.c
|
||||
* @brief Implements the OP_ARR_INSERT opcode for inserting elements into arrays in the VM.
|
||||
* @file insert.c
|
||||
* @brief Implements the OP_INSERT opcode for inserting elements into arrays in the VM.
|
||||
*
|
||||
* This file handles the OP_ARR_INSERT instruction, which inserts a value into an array
|
||||
* This file handles the OP_INSERT instruction, which inserts a value into an array
|
||||
* at a specified index. The array, index, and value are popped from the stack, and the
|
||||
* new length of the array is pushed back onto the stack.
|
||||
*
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
* - Exits with an error if memory allocation fails during the insertion.
|
||||
*
|
||||
* Example:
|
||||
* // Bytecode: OP_ARR_INSERT
|
||||
* // Bytecode: OP_INSERT
|
||||
* // Stack before: [42, 1, [10, 20, 30]]
|
||||
* // Stack after: [4]
|
||||
*
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
* @date 2025-10-16
|
||||
*/
|
||||
|
||||
case OP_ARR_INSERT: {
|
||||
case OP_INSERT: {
|
||||
Value v = pop_value(vm);
|
||||
Value idx = pop_value(vm);
|
||||
Value arr = pop_value(vm);
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
* @date 2025-10-16
|
||||
*/
|
||||
|
||||
case OP_ARR_PUSH: {
|
||||
case OP_PUSH: {
|
||||
Value v = pop_value(vm);
|
||||
Value arr = pop_value(vm);
|
||||
if (arr.type != VAL_ARRAY) {
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
* @date 2025-10-16
|
||||
*/
|
||||
|
||||
case OP_ARR_REMOVE: {
|
||||
case OP_REMOVE: {
|
||||
Value idx = pop_value(vm);
|
||||
Value arr = pop_value(vm);
|
||||
if (arr.type != VAL_ARRAY || idx.type != VAL_INT) {
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
* @date 2025-10-16
|
||||
*/
|
||||
|
||||
case OP_ARR_SET: {
|
||||
case OP_SET: {
|
||||
Value v = pop_value(vm);
|
||||
Value idx = pop_value(vm);
|
||||
Value arr = pop_value(vm);
|
||||
Loading…
Add table
Add a link
Reference in a new issue