mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
Compare commits
11 Commits
O1.20.0-E1
...
O1.20.1-E1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4af76cc3ae | ||
|
|
93c431be04 | ||
|
|
63acf7b0ee | ||
|
|
14a3ea51c4 | ||
|
|
18ccc0c771 | ||
|
|
f65881420c | ||
|
|
8eeae5f161 | ||
|
|
2dce8a1343 | ||
|
|
b9a6298ffa | ||
|
|
2040a2cd5b | ||
|
|
73037e3faf |
@@ -19,7 +19,7 @@ Omega is a fork of Numworks' Epsilon, the OS that runs on their calculator, whic
|
||||
- ~~32 KB Python heap instead of 16 KB~~ Now available on Epsilon `>=13.2.0`!
|
||||
- And more...
|
||||
|
||||
The main new features are listed [here](https://github.com/Omega-Numworks/Omega/wiki/Main-features), and the complete changelog can be found [here](https://github.com/Omega-Numworks/Omega/wiki/Complete-changelog).
|
||||
The main new features are listed [here](https://github.com/Omega-Numworks/Omega/wiki/Main-features), and the complete changelog can be found [here](https://github.com/Omega-Numworks/Omega/wiki/Changelog).
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ def mandelbrot(N_iteration):
|
||||
z = z*z+c
|
||||
# Choose the color of the dot from the Mandelbrot sequence
|
||||
rgb = int(255*i/N_iteration)
|
||||
col = kandinsky.color(int(rgb),int(rgb*0.75),int(rgb*0.25))
|
||||
col = kandinsky.color(int(rgb*0.82),int(rgb*0.13),int(rgb*0.18))
|
||||
# Draw a pixel colored in 'col' at position (x,y)
|
||||
kandinsky.set_pixel(x,y,col))");
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ bool AboutController::handleEvent(Ion::Events::Event event) {
|
||||
if (childLabel == I18n::Message::OmegaVersion) {
|
||||
MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)m_selectableTableView.selectedCell();
|
||||
if (strcmp(myCell->accessoryText(), Ion::omegaVersion()) == 0) {
|
||||
myCell->setAccessoryText("Dev"); //Change for public/dev
|
||||
myCell->setAccessoryText("Public"); //Change for public/dev
|
||||
return true;
|
||||
}
|
||||
myCell->setAccessoryText(Ion::omegaVersion());
|
||||
|
||||
@@ -5,7 +5,7 @@ DEBUG ?= 0
|
||||
|
||||
HOME_DISPLAY_EXTERNALS ?= 1
|
||||
EPSILON_VERSION ?= 14.4.1
|
||||
OMEGA_VERSION ?= 1.20.0
|
||||
OMEGA_VERSION ?= 1.20.1
|
||||
# USERNAME ?= N/A
|
||||
EPSILON_APPS ?= calculation rpn graph code statistics probability solver atom sequence regression settings external
|
||||
EPSILON_I18N ?= en fr nl pt it de es hu
|
||||
|
||||
@@ -122,6 +122,10 @@ public:
|
||||
|
||||
// Useful
|
||||
static bool FullNameCompliant(const char * name);
|
||||
|
||||
// User by Python OS module
|
||||
int numberOfRecords();
|
||||
Record recordAtIndex(int index);
|
||||
|
||||
private:
|
||||
constexpr static uint32_t Magic = 0xEE0BDDBA;
|
||||
|
||||
@@ -208,6 +208,37 @@ int Storage::numberOfRecordsWithExtension(const char * extension) {
|
||||
return count;
|
||||
}
|
||||
|
||||
int Storage::numberOfRecords() {
|
||||
int count = 0;
|
||||
for (char * p : *this) {
|
||||
const char * name = fullNameOfRecordStarting(p);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Storage::Record Storage::recordAtIndex(int index) {
|
||||
int currentIndex = -1;
|
||||
const char * name = nullptr;
|
||||
char * recordAddress = nullptr;
|
||||
for (char * p : *this) {
|
||||
const char * currentName = fullNameOfRecordStarting(p);
|
||||
currentIndex++;
|
||||
if (currentIndex == index) {
|
||||
recordAddress = p;
|
||||
name = currentName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (name == nullptr) {
|
||||
return Record();
|
||||
}
|
||||
Record r = Record(name);
|
||||
m_lastRecordRetrieved = r;
|
||||
m_lastRecordRetrievedPointer = recordAddress;
|
||||
return Record(name);
|
||||
}
|
||||
|
||||
Storage::Record Storage::recordWithExtensionAtIndex(const char * extension, int index) {
|
||||
int currentIndex = -1;
|
||||
const char * name = nullptr;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SFLAGS += -Ipython/src
|
||||
SFLAGS += -Ipython/port
|
||||
SFLAGS += -I$(BUILD_DIR)/python/port
|
||||
SFLAGS += -DEPSILON_VERSION="$(EPSILON_VERSION)" -DOMEGA_VERSION="$(OMEGA_VERSION)"
|
||||
|
||||
# How to maintain this Makefile
|
||||
# - Copy PY_CORE_O_BASENAME from py.mk into py_src
|
||||
@@ -148,6 +149,8 @@ port_src += $(addprefix python/port/,\
|
||||
mod/matplotlib/pyplot/plot_view.cpp \
|
||||
mod/time/modtime.c \
|
||||
mod/time/modtime_table.c \
|
||||
mod/os/modos.cpp \
|
||||
mod/os/modos_table.c \
|
||||
mod/turtle/modturtle.cpp \
|
||||
mod/turtle/modturtle_table.c \
|
||||
mod/turtle/turtle.cpp \
|
||||
|
||||
@@ -526,3 +526,14 @@ Q(SEEK_SET)
|
||||
Q(SEEK_CUR)
|
||||
Q(SEEK_END)
|
||||
|
||||
// os QSTRs
|
||||
Q(os)
|
||||
Q(uname)
|
||||
Q(sysname)
|
||||
Q(nodename)
|
||||
Q(release)
|
||||
Q(version)
|
||||
Q(machine)
|
||||
Q(rename)
|
||||
Q(listdir)
|
||||
|
||||
|
||||
@@ -464,15 +464,22 @@ STATIC mp_obj_t file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
|
||||
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
|
||||
break;
|
||||
case APPEND:
|
||||
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
|
||||
file->position = 0;
|
||||
if (file->record == Ion::Storage::Record()) {
|
||||
status = Ion::Storage::sharedStorage()->createRecordWithFullName(file_name, "", 0);
|
||||
if (status == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable) {
|
||||
status = Ion::Storage::sharedStorage()->createRecordWithFullName(file_name, "", 0);
|
||||
switch (status) {
|
||||
case Ion::Storage::Record::ErrorStatus::NameTaken:
|
||||
// setValue messes with empty buffer, so we delete record and re-create it.
|
||||
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
|
||||
file->record.destroy();
|
||||
|
||||
break;
|
||||
case Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable:
|
||||
mp_raise_OSError(28);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
file->position = file->record.value().size;
|
||||
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -520,6 +527,17 @@ STATIC mp_obj_t file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
|
||||
void check_closed(file_obj_t* file) {
|
||||
if (file->closed)
|
||||
mp_raise_ValueError("I/O operation on closed file");
|
||||
|
||||
// This is VERY imports, as it eliminates concurrency
|
||||
// issues (eg. removing the file and then writing to it,
|
||||
// having file move in the store, etc.)
|
||||
size_t l;
|
||||
const char* file_name = mp_obj_str_get_data(file->name, &l);
|
||||
file->record = Ion::Storage::sharedStorage()->recordNamed(file_name);
|
||||
|
||||
if (file->record == Ion::Storage::Record()) {
|
||||
mp_raise_OSError(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
115
python/port/mod/os/modos.cpp
Normal file
115
python/port/mod/os/modos.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
extern "C" {
|
||||
#include "modos.h"
|
||||
#include <string.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/objstr.h>
|
||||
#include <py/objtuple.h>
|
||||
}
|
||||
|
||||
#include <ion/storage.h>
|
||||
|
||||
#ifndef OMEGA_VERSION
|
||||
#error This file expects OMEGA_VERSION to be defined
|
||||
#endif
|
||||
|
||||
#ifndef EPSILON_VERSION
|
||||
#error This file expects EPSILON_VERSION to be defined
|
||||
#endif
|
||||
|
||||
|
||||
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_sysname_obj, "NumWorks");
|
||||
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_nodename_obj, "");
|
||||
|
||||
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_release_obj, "O" MP_STRINGIFY(OMEGA_VERSION) "E-" MP_STRINGIFY(EPSILON_VERSION));
|
||||
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_version_obj, MICROPY_VERSION_STRING);
|
||||
|
||||
#if defined(DEVICE_N0110)
|
||||
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_machine_obj, "NumWorks N0110");
|
||||
#elif defined(DEVICE_N0100)
|
||||
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_machine_obj, "NumWorks N0100");
|
||||
#else
|
||||
STATIC const MP_DEFINE_STR_OBJ(modos_uname_info_machine_obj, "NumWorks Simulator");
|
||||
#endif
|
||||
|
||||
STATIC const mp_rom_map_elem_t modos_uname_info_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_sysname), &modos_uname_info_sysname_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_nodename), &modos_uname_info_nodename_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_release), &modos_uname_info_release_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_version), &modos_uname_info_version_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_machine), &modos_uname_info_machine_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(modos_uname_info_obj, modos_uname_info_table);
|
||||
|
||||
mp_obj_t modos_uname(void) {
|
||||
return (mp_obj_t)&modos_uname_info_obj;
|
||||
}
|
||||
|
||||
mp_obj_t modos_remove(mp_obj_t o_file_name) {
|
||||
|
||||
size_t len;
|
||||
const char* file_name;
|
||||
file_name = mp_obj_str_get_data(o_file_name, &len);
|
||||
|
||||
Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(file_name);
|
||||
|
||||
if (record == Ion::Storage::Record()) {
|
||||
mp_raise_OSError(2);
|
||||
}
|
||||
|
||||
record.destroy();
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t modos_rename(mp_obj_t o_old_name, mp_obj_t o_new_name) {
|
||||
|
||||
size_t len;
|
||||
const char* old_name;
|
||||
const char* new_name;
|
||||
old_name = mp_obj_str_get_data(o_old_name, &len);
|
||||
new_name = mp_obj_str_get_data(o_new_name, &len);
|
||||
|
||||
Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(old_name);
|
||||
|
||||
if (record == Ion::Storage::Record()) {
|
||||
mp_raise_OSError(2);
|
||||
}
|
||||
|
||||
Ion::Storage::Record::ErrorStatus status = record.setName(new_name);
|
||||
|
||||
switch (status) {
|
||||
case Ion::Storage::Record::ErrorStatus::NameTaken:
|
||||
mp_raise_OSError(17);
|
||||
break;
|
||||
case Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable:
|
||||
mp_raise_OSError(28);
|
||||
break;
|
||||
case Ion::Storage::Record::ErrorStatus::NonCompliantName:
|
||||
mp_raise_OSError(22);
|
||||
break;
|
||||
case Ion::Storage::Record::ErrorStatus::RecordDoesNotExist:
|
||||
mp_raise_OSError(2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t modos_listdir(void) {
|
||||
mp_obj_t list = mp_obj_new_list(0, NULL);
|
||||
|
||||
for(size_t i = 0; i < (size_t)Ion::Storage::sharedStorage()->numberOfRecords(); i++) {
|
||||
Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordAtIndex(i);
|
||||
size_t file_name_length = strlen(record.fullName());
|
||||
|
||||
mp_obj_t file_name = mp_obj_new_str(record.fullName(), file_name_length);
|
||||
mp_obj_list_append(list, file_name);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
6
python/port/mod/os/modos.h
Normal file
6
python/port/mod/os/modos.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <py/obj.h>
|
||||
|
||||
mp_obj_t modos_uname();
|
||||
mp_obj_t modos_remove(mp_obj_t o_file_name);
|
||||
mp_obj_t modos_rename(mp_obj_t o_old_name, mp_obj_t o_new_name);
|
||||
mp_obj_t modos_listdir();
|
||||
21
python/port/mod/os/modos_table.c
Normal file
21
python/port/mod/os/modos_table.c
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "modos.h"
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(modos_uname_obj, modos_uname);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(modos_remove_obj, modos_remove);
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(modos_rename_obj, modos_rename);
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(modos_listdir_obj, modos_listdir);
|
||||
|
||||
STATIC const mp_rom_map_elem_t modos_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_uname), &modos_uname_obj},
|
||||
{ MP_ROM_QSTR(MP_QSTR_remove), &modos_remove_obj},
|
||||
{ MP_ROM_QSTR(MP_QSTR_rename), &modos_rename_obj},
|
||||
{ MP_ROM_QSTR(MP_QSTR_listdir), &modos_listdir_obj},
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(modos_module_globals, modos_module_globals_table);
|
||||
|
||||
const mp_obj_module_t modos_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&modos_module_globals,
|
||||
};
|
||||
18
python/port/mod/os/uname_result.cpp
Normal file
18
python/port/mod/os/uname_result.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
extern "C" {
|
||||
#include <py/smallint.h>
|
||||
#include <py/objint.h>
|
||||
#include <py/objstr.h>
|
||||
#include <py/objtype.h>
|
||||
#include <py/runtime.h>
|
||||
#include <py/stream.h>
|
||||
#include <py/builtin.h>
|
||||
#include <py/obj.h>
|
||||
#include <py/misc.h>
|
||||
#include "uname_result.h"
|
||||
}
|
||||
|
||||
STATIC void uname_result_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
|
||||
STATIC mp_obj_t uname_result_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
|
||||
STATIC void uname_result_attr(mp_obj_t self_in, qstr attribute, mp_obj_t *destination);
|
||||
|
||||
|
||||
0
python/port/mod/os/uname_result.h
Normal file
0
python/port/mod/os/uname_result.h
Normal file
@@ -131,6 +131,7 @@ extern const struct _mp_obj_module_t modkandinsky_module;
|
||||
extern const struct _mp_obj_module_t modmatplotlib_module;
|
||||
extern const struct _mp_obj_module_t modpyplot_module;
|
||||
extern const struct _mp_obj_module_t modtime_module;
|
||||
extern const struct _mp_obj_module_t modos_module;
|
||||
extern const struct _mp_obj_module_t modturtle_module;
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
@@ -139,5 +140,6 @@ extern const struct _mp_obj_module_t modturtle_module;
|
||||
{ MP_ROM_QSTR(MP_QSTR_matplotlib), MP_ROM_PTR(&modmatplotlib_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_matplotlib_dot_pyplot), MP_ROM_PTR(&modpyplot_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&modtime_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_os), MP_ROM_PTR(&modos_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_turtle), MP_ROM_PTR(&modturtle_module) }, \
|
||||
|
||||
|
||||
Reference in New Issue
Block a user