Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

281 lines
8.3 KiB
C
Raw Normal View History

2025-10-13 15:42:15 +08:00
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <setjmp.h>
#include <math.h>
#include <errno.h>
#include "py/obj.h"
//#include "py/mpconfig.h"
#include "py/misc.h"
#include "py/runtime.h"
#include "py/objstr.h"
#include "shared/readline/readline.h"
#include "py/binary.h"
#include "py/gc.h"
#include "py/stream.h"
#include "eigenmath.h"
#include "eheap.h"
//-DPICO_STACK_SIZE=0x4000 ??
typedef struct _mp_obj_eigenmath_t {
mp_obj_base_t base;
size_t heapSize;
uint8_t *pHeap;
} mp_obj_eigenmath_t;
static void eigenmath_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
mp_printf(print, "<EigenMath instance>");
}
static mp_obj_t eigenmath_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 1, false);
mp_obj_eigenmath_t *self = mp_obj_malloc(mp_obj_eigenmath_t, type);
self->base.type = type;
self->heapSize = mp_obj_get_int(args[0]); // 350 * 1024; // 350KB
//mp_printf(&mp_plat_print,"heapSize = %d\n", self->heapSize);
self->pHeap = (uint8_t *)m_malloc(self->heapSize);
//mp_printf(&mp_plat_print,"ptemp = %x\n", (uint32_t)(ptemp));
//mp_printf(&mp_plat_print,"self->pHeap = %x\n", (uint32_t)(self->pHeap));
if (self->pHeap == NULL){
mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Failed to initialize heap"));
return MP_OBJ_NULL;
}
eigenmath_init(self->pHeap,self->heapSize);
return MP_OBJ_FROM_PTR(self);
}
static mp_obj_t eigenmath_run(size_t n_args, const mp_obj_t *args) {
//mp_obj_eigenmath_t *self = MP_OBJ_TO_PTR(self_in);mp_obj_t input_str_obj
size_t len;
if (n_args >= 3){
mp_obj_t arg = args[2];
if (mp_obj_is_bool(arg) || mp_obj_is_int(arg)) {
noprint = mp_obj_is_true(arg);
} else {
mp_raise_TypeError(MP_ERROR_TEXT("expected a bool"));
}
} else {
noprint = false;
}
if (!mp_obj_is_str(args[1])) {
mp_raise_TypeError(MP_ERROR_TEXT("expected a string as input"));
}
const char *buf = mp_obj_str_get_data(args[1], &len);
//GET_STR_DATA_LEN(input_str_obj, str, str_len);
run((char *)buf);
if (noprint == true){
return mp_obj_new_bytearray_by_ref(outbuf_index-1, outbuf);
// return memoryview
//return mp_obj_new_memoryview(BYTEARRAY_TYPECODE, outbuf);
}else{
return mp_const_none;
}
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(eigenmath_run_obj,2,3, eigenmath_run);
static mp_obj_t eigenmath_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
//mp_obj_eigenmath_t *self = MP_OBJ_TO_PTR(self_in);
noprint = false;
if (n_args != 1 || n_kw != 0) {
mp_raise_TypeError(MP_ERROR_TEXT("Expected 1 positional argument"));
}
const char *cmd = mp_obj_str_get_str(args[0]);
run((char *)cmd); //
return mp_const_none;
}
static mp_obj_t eigenmath_cmd(mp_obj_t self_in) {
//mp_obj_eigenmath_t *self = MP_OBJ_TO_PTR(self_in);
vstr_t* vstr_inbuf = vstr_new(1);
for (;;) {
vstr_clear(vstr_inbuf);
int res = readline(vstr_inbuf,"eigenmath> ");
mp_printf(&mp_plat_print, "Eigenmath run:\n");
mp_printf(&mp_plat_print, "res=%d\n", res);
mp_printf(&mp_plat_print, "%s\n", vstr_inbuf->buf);
run(vstr_inbuf->buf);
}
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(eigenmath_cmd_obj, eigenmath_cmd);
static mp_obj_t eigenmath_runfile(size_t n_args, const mp_obj_t *args ) {//mp_obj_t input_file_obj
if (n_args >= 3){
mp_obj_t arg = args[2];
if (mp_obj_is_bool(arg) || mp_obj_is_int(arg)) {
noprint = mp_obj_is_true(arg);
} else {
mp_raise_TypeError(MP_ERROR_TEXT("expected a bool"));
}
} else {
noprint = false;
}
const mp_stream_p_t *stream_p = mp_get_stream_raise(args[1], MP_STREAM_OP_READ | MP_STREAM_OP_IOCTL);
if (stream_p == NULL) {
mp_raise_TypeError(MP_ERROR_TEXT("expected a file-like object"));
}
int error = 0;
// get file size
struct mp_stream_seek_t seek = {
.offset = 0,
.whence = MP_SEEK_END,
};
mp_obj_t input_file_obj = args[1];
if (stream_p->ioctl(input_file_obj, MP_STREAM_SEEK, (uintptr_t)&seek, &error) == MP_STREAM_ERROR) {
mp_raise_OSError(error);
}
mp_off_t size = seek.offset;
// move to front
seek.offset = 0;
seek.whence = MP_SEEK_SET;
if (stream_p->ioctl(input_file_obj, MP_STREAM_SEEK, (uintptr_t)&seek, &error) == MP_STREAM_ERROR) {
mp_raise_OSError(error);
}
// get buffer
char *buf = m_new(char, size + 1);
// read file
mp_uint_t out_sz = stream_p->read(input_file_obj, buf, size, &error);
if (error != 0 || out_sz != size) {
m_del(char, buf, size + 1);
mp_raise_OSError(error);
}
// add end
buf[out_sz] = '\0';
// run
run(buf);
// release buffer
m_del(char, buf, size + 1);
if (noprint == true){
return mp_obj_new_bytearray_by_ref(outbuf_index-1, outbuf);
// return memoryview
//return mp_obj_new_memoryview(BYTEARRAY_TYPECODE, bytearray);
}else{
return mp_const_none;
}
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(eigenmath_runfile_obj, 2,3,eigenmath_runfile);
extern int free_count;
extern int MAXATOMS;
static mp_obj_t eigenmath_status(mp_obj_t self_in) {
//mp_obj_eigenmath_t *self = MP_OBJ_TO_PTR(self_in);
int fragmentation = e_heap_fragmentation();
size_t free_bytes = e_heap_free();
size_t min_free = e_heap_min_free();
int num_atoms = free_count;
mp_printf(&mp_plat_print,"Heap fragmentation: %d%%\n", fragmentation);
mp_printf(&mp_plat_print,"Free bytes in Heap: %d\n", (int)free_bytes);
mp_printf(&mp_plat_print,"Minimum free bytes in Heap: %d\n", (int)min_free);
mp_printf(&mp_plat_print,"Number of free atoms: %d of %d\n", num_atoms,MAXATOMS);
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(eigenmath_status_obj, eigenmath_status);
extern struct atom *zero;
static mp_obj_t eigenmath_del(mp_obj_t self_in) {
mp_obj_eigenmath_t *self = MP_OBJ_TO_PTR(self_in);
m_free(&self->pHeap); // deinitialize the hea
zero = NULL;
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(eigenmath_del_obj, eigenmath_del);
extern struct atom *zero;
static mp_obj_t eigenmath_reset(mp_obj_t self_in) {
mp_obj_eigenmath_t *self = MP_OBJ_TO_PTR(self_in);
eigenmath_init(self->pHeap,self->heapSize);
zero = NULL;//triger the symbol table initialization
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(eigenmath_reset_obj, eigenmath_reset);
mp_obj_t eigenmath_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
if (dest[0] == MP_OBJ_NULL && attr == MP_QSTR___del__) {
dest[0] = MP_OBJ_FROM_PTR(&eigenmath_del_obj);
dest[1] = self_in;
}else{
// For any other attribute, indicate that lookup should continue in the locals dict
dest[1] = MP_OBJ_SENTINEL;
return MP_OBJ_NULL;
}
return MP_OBJ_NULL;
}
static const mp_rom_map_elem_t eigenmath_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_run), MP_ROM_PTR(&eigenmath_run_obj) },
{ MP_ROM_QSTR(MP_QSTR_runfile), MP_ROM_PTR(&eigenmath_runfile_obj) },
{ MP_ROM_QSTR(MP_QSTR_cmd), MP_ROM_PTR(&eigenmath_cmd_obj) },
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&eigenmath_reset_obj) },
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&eigenmath_status_obj) },
};
static MP_DEFINE_CONST_DICT(eigenmath_locals_dict, eigenmath_locals_dict_table);
MP_DEFINE_CONST_OBJ_TYPE(
eigenmath_type,
MP_QSTR_EigenMath,
MP_TYPE_FLAG_NONE,
make_new, eigenmath_make_new,
call,eigenmath_call, // call handler for the run method
attr, eigenmath_attr, // attr handler before locals_dict
locals_dict, &eigenmath_locals_dict,
print, eigenmath_print
);
static const mp_rom_map_elem_t eigenmath_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_eigenmath) },
{ MP_ROM_QSTR(MP_QSTR_EigenMath), MP_ROM_PTR(&eigenmath_type) },
};
static MP_DEFINE_CONST_DICT(mp_module_eigenmath_globals, eigenmath_module_globals_table);
const mp_obj_module_t eigenmath_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_eigenmath_globals,
};
MP_REGISTER_MODULE(MP_QSTR_eigenmath, eigenmath_user_cmodule);